diff --git a/js/BoxMenuGroupView.js b/js/BoxMenuGroupView.js index 5bd6937..638b4a0 100644 --- a/js/BoxMenuGroupView.js +++ b/js/BoxMenuGroupView.js @@ -23,7 +23,7 @@ class BoxMenuGroupView extends MenuItemView { } } -BoxMenuGroupView.template = 'boxMenuGroup'; +BoxMenuGroupView.template = 'boxMenuGroup.jsx'; BoxMenuGroupView.childContainer = '.js-group-children'; BoxMenuGroupView.childView = BoxMenuItemView; diff --git a/js/BoxMenuItemView.js b/js/BoxMenuItemView.js index 11817a4..be94335 100644 --- a/js/BoxMenuItemView.js +++ b/js/BoxMenuItemView.js @@ -20,6 +20,6 @@ class BoxMenuItemView extends MenuItemView { } } -BoxMenuItemView.template = 'boxMenuItem'; +BoxMenuItemView.template = 'boxMenuItem.jsx'; export default BoxMenuItemView; diff --git a/js/BoxMenuModel.js b/js/BoxMenuModel.js new file mode 100644 index 0000000..06cc613 --- /dev/null +++ b/js/BoxMenuModel.js @@ -0,0 +1,3 @@ +import MenuModel from 'core/js/models/menuModel'; + +export default class BoxMenuModel extends MenuModel {} diff --git a/js/BoxMenuView.js b/js/BoxMenuView.js index fe2aeca..f504fac 100644 --- a/js/BoxMenuView.js +++ b/js/BoxMenuView.js @@ -1,4 +1,3 @@ -import Adapt from 'core/js/adapt'; import device from 'core/js/device'; import MenuView from 'core/js/views/menuView'; import BoxMenuItemView from './BoxMenuItemView'; @@ -7,18 +6,21 @@ import BoxMenuGroupView from './BoxMenuGroupView'; class BoxMenuView extends MenuView { className() { - return `${super.className()} boxmenu`; + const backgroundImages = this.model.get('_boxMenu')?._backgroundImage; + const backgroundImage = backgroundImages[`_${device.screenSize}`] ?? backgroundImages._small; + const textAlignment = this.model.get('_boxMenu')?._menuHeader?._textAlignment; + + return [ + `${super.className()} boxmenu`, + backgroundImage && 'has-bg-image', + textAlignment._title && `title-align-${textAlignment._title}`, + textAlignment._body && `body-align-${textAlignment._body}`, + textAlignment._instruction && `instruction-align-${textAlignment._instruction}` + ].join(' '); } initialize() { super.initialize(); - this.setStyles(); - - this.listenTo(Adapt, 'device:changed', this.onDeviceResize); - } - - onDeviceResize() { - this.setStyles(); } addChildren() { @@ -40,7 +42,8 @@ class BoxMenuView extends MenuView { nthChild++; model.set({ _nthChild: nthChild, - _totalChild: totalChild + _totalChild: totalChild, + _isRendered: true }); const ChildView = (model.get('_type') === 'menu' && model.get('_boxMenu') && model.get('_boxMenu')._renderAsGroup) ? @@ -58,96 +61,8 @@ class BoxMenuView extends MenuView { this.setChildViews(childViews); } - setStyles() { - this.addBackgroundLayer(); - this.setBackgroundImage(); - this.setBackgroundStyles(); - this.processHeader(); - } - - addBackgroundLayer() { - if (this.$el.find(' > .background').length) return; - this.$background = $('') - .prependTo(this.$el); - } - - setBackgroundImage() { - const config = this.model.get('_boxMenu'); - const backgroundImages = config?._backgroundImage; - if (!backgroundImages) return; - const backgroundImage = backgroundImages[`_${device.screenSize}`] ?? backgroundImages._small; - this.$el.toggleClass('has-bg-image', Boolean(backgroundImage)); - this.$background - .css('background-image', backgroundImage ? 'url(' + backgroundImage + ')' : ''); - } - - setBackgroundStyles() { - const config = this.model.get('_boxMenu'); - const styles = config?._backgroundStyles; - if (!styles) return; - this.$background.css({ - 'background-repeat': styles._backgroundRepeat, - 'background-size': styles._backgroundSize, - 'background-position': styles._backgroundPosition - }); - } - - processHeader() { - const config = this.model.get('_boxMenu'); - const header = config?._menuHeader; - if (!header) return; - const $header = this.$('.menu__header'); - this.setHeaderTextAlignment(header); - this.addHeaderBackgroundLayer($header); - this.setHeaderBackgroundImage(header, $header); - this.setHeaderBackgroundStyles(header, $header); - this.setHeaderMinimumHeight(header, $header); - } - - setHeaderTextAlignment(config) { - const textAlignment = config._textAlignment; - if (!textAlignment) return; - - if (textAlignment._title) this.$el.addClass(`title-align-${textAlignment._title}`); - if (textAlignment._body) this.$el.addClass(`body-align-${textAlignment._body}`); - if (textAlignment._instruction) this.$el.addClass(`instruction-align-${textAlignment._instruction}`); - } - - addHeaderBackgroundLayer($header) { - if ($header.find(' > .background').length) return; - this.$headerBackground = $('') - .prependTo($header); - } - - setHeaderBackgroundImage(config, $header) { - const backgroundImages = config._backgroundImage; - if (!backgroundImages) return; - const backgroundImage = backgroundImages[`_${device.screenSize}`] ?? backgroundImages._small; - $header.toggleClass('has-bg-image', Boolean(backgroundImage)); - this.$headerBackground.css('background-image', backgroundImage ? 'url(' + backgroundImage + ')' : ''); - } - - setHeaderBackgroundStyles(config, $header) { - const styles = config._backgroundStyles; - if (!styles) return; - this.$headerBackground.css({ - 'background-repeat': styles._backgroundRepeat, - 'background-size': styles._backgroundSize, - 'background-position': styles._backgroundPosition - }); - } - - setHeaderMinimumHeight(config, $header) { - const minimumHeights = config._minimumHeights; - if (!minimumHeights) return; - const minimumHeight = minimumHeights[`_${device.screenSize}`] ?? minimumHeights._small; - $header - .toggleClass('has-min-height', Boolean(minimumHeight)) - .css('min-height', minimumHeight ? minimumHeight + 'px' : ''); - } - } -BoxMenuView.template = 'boxMenu'; +BoxMenuView.template = 'boxMenu.jsx'; export default BoxMenuView; diff --git a/js/adapt-contrib-boxMenu.js b/js/adapt-contrib-boxMenu.js index befeddb..32d85b9 100644 --- a/js/adapt-contrib-boxMenu.js +++ b/js/adapt-contrib-boxMenu.js @@ -1,17 +1,18 @@ import components from 'core/js/components'; -import MenuModel from 'core/js/models/menuModel'; import BoxMenuView from './BoxMenuView'; +import BoxMenuModel from './BoxMenuModel'; // Use as default "_type": "course" or "_type": "menu" view. // Note: This is necessary to maintain legacy behaviour in the AAT where // only one menu is usable per course and the course / menu is assumed to be // a core model and use the only installed MenuView. components.register('course menu', { - view: BoxMenuView + view: BoxMenuView, + model: BoxMenuModel }); // Use for "_component": "boxMenu", or "_view": "boxMenu" and "_model": "boxMenu" components.register('boxMenu', { view: BoxMenuView, - model: MenuModel.extend({}) + model: BoxMenuModel }); diff --git a/templates/boxMenu.hbs b/templates/boxMenu.hbs deleted file mode 100644 index 533347b..0000000 --- a/templates/boxMenu.hbs +++ /dev/null @@ -1,63 +0,0 @@ -{{import_globals}} - - diff --git a/templates/boxMenu.jsx b/templates/boxMenu.jsx new file mode 100644 index 0000000..b98908d --- /dev/null +++ b/templates/boxMenu.jsx @@ -0,0 +1,151 @@ +import React from 'react'; +import Adapt from 'core/js/adapt'; +import device from 'core/js/device'; +import { classes, compile } from 'core/js/reactHelpers'; + +export default function BoxMenu (props) { + const { + displayTitle, + subtitle, + body, + pageBody, + instruction + } = props; + + const _boxMenu = Adapt.course.get('_boxMenu'); + + // set menu logo image + const _graphic = _boxMenu?._graphic; + + // set menu background image + const backgroundImages = _boxMenu?._backgroundImage; + const backgroundImage = backgroundImages[`_${device.screenSize}`] ?? backgroundImages._small; + // set menu background styles + const styles = _boxMenu._backgroundStyles; + + // set header background image + const header = _boxMenu?._menuHeader; + const headerBackgroundImages = header._backgroundImage; + const headerBackgroundImage = headerBackgroundImages[`_${device.screenSize}`] ?? headerBackgroundImages._small; + // set header background styles + const headerBackgroundStyles = header._backgroundStyles; + // set header minimum height + const headerMinimumHeights = header._minimumHeights; + const headerMinimumHeight = headerMinimumHeights[`_${device.screenSize}`] ?? headerMinimumHeights._small; + + return ( + <> + {backgroundImages && +