diff --git a/README.md b/README.md index b12baff..0b2b43c 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ The first value is the horizontal position and the second value is the vertical. >>>**\_small** (number): The minimum height should only be used in instances where the menu header height needs to be greater than the content e.g. to prevent a background image being cropped. +>>>**\_areEntireItemsClickable** (boolean): Indicates if the entire menu item can be clicked to go to the target page. If `true`, the View button will be hidden. + **\_globals** (object): The Globals object that contains value for **\_menu**. >**\_menu** (object): The menu object that contains value for **\_boxMenu**. diff --git a/example.json b/example.json index 6ca5a4b..966493f 100644 --- a/example.json +++ b/example.json @@ -1,5 +1,6 @@ // course.json "_boxMenu": { + "_areEntireItemsClickable": false, "_graphic": { "alt": "", "_src": "course/en/images/logo-graphic.jpg" diff --git a/js/BoxMenuItemView.js b/js/BoxMenuItemView.js index 11817a4..ab3b6fc 100644 --- a/js/BoxMenuItemView.js +++ b/js/BoxMenuItemView.js @@ -1,23 +1,34 @@ import MenuItemView from 'core/js/views/menuItemView'; +import Adapt from 'core/js/adapt'; import router from 'core/js/router'; class BoxMenuItemView extends MenuItemView { className() { - return `${super.className()} boxmenu-item`; + return [ + super.className(), + 'boxmenu-item', + this.areEntireItemsClickable && 'is-entire-item-clickable' + ].filter(Boolean).join(' '); } events() { return { - 'click .js-btn-click': 'onClickMenuItemButton' + 'click .js-btn-click': 'onClickMenuItemButton', + 'keydown .js-btn-click': 'onClickMenuItemButton' }; } onClickMenuItemButton(event) { - if (event && event.preventDefault) event.preventDefault(); + if (event.code && !['Space', 'Enter'].includes(event.code)) return; + if (event?.preventDefault) event.preventDefault(); if (this.model.get('_isLocked')) return; router.navigateToElement(this.model.get('_id')); } + + get areEntireItemsClickable() { + return Adapt.course.get('_boxMenu')?._areEntireItemsClickable; + } } BoxMenuItemView.template = 'boxMenuItem'; diff --git a/less/boxMenuItem.less b/less/boxMenuItem.less index 577fb05..581edf7 100644 --- a/less/boxMenuItem.less +++ b/less/boxMenuItem.less @@ -8,4 +8,8 @@ @media (min-width: @device-width-medium) { width: 50%; } + + &.is-entire-item-clickable:not(.is-locked) { + cursor: pointer; + } } diff --git a/properties.schema b/properties.schema index e94566a..7e67d27 100644 --- a/properties.schema +++ b/properties.schema @@ -37,6 +37,15 @@ "type": "object", "required": false, "properties": { + "_areEntireItemsClickable": { + "type": "boolean", + "required": false, + "default": false, + "title": "Are entire menu items clickable?", + "inputType": "Checkbox", + "validators": [], + "help": "Enable this option to make each menu item clickable. The menu item button will be hidden." + }, "_graphic": { "type": "object", "required": false, diff --git a/schema/course.schema.json b/schema/course.schema.json index d755b19..86dc6e9 100644 --- a/schema/course.schema.json +++ b/schema/course.schema.json @@ -48,6 +48,12 @@ "title": "Box Menu", "default": {}, "properties": { + "_areEntireItemsClickable": { + "type": "boolean", + "title": "Are entire menu items clickable?", + "description": "Enable this option to make each menu item clickable. The menu item button will be hidden.", + "default": false + }, "_graphic": { "type": "object", "title": "Menu logo image", diff --git a/templates/boxMenuItem.hbs b/templates/boxMenuItem.hbs index 145f44a..0ecd36e 100644 --- a/templates/boxMenuItem.hbs +++ b/templates/boxMenuItem.hbs @@ -1,6 +1,12 @@ {{import_globals}} +{{import_adapt}} -<div class="menu-item__inner boxmenu-item__inner"> +<div class="menu-item__inner boxmenu-item__inner{{#if Adapt.course._boxMenu._areEntireItemsClickable}} js-btn-click{{/if}}"{{#if Adapt.course._boxMenu._areEntireItemsClickable}} role="link" tabindex="0"{{/if}}{{#if _isLocked}} aria-disabled="true"{{/if}}> + {{#if Adapt.course._boxMenu._areEntireItemsClickable}} + <span class="aria-label"> + {{#if _isComplete}}{{_globals._accessibility._ariaLabels.complete}}. {{else _isVisited}}{{_globals._accessibility._ariaLabels.visited}}. {{/if}}{{#if _isLocked}}{{_globals._accessibility._ariaLabels.locked}}. {{else}}{{linkText}} {{/if}}{{title}}. {{{compile _globals._menu._boxMenu.itemCount}}}.{{#if _isOptional}} {{_globals._accessibility._ariaLabels.optional}}{{/if}} + </span> + {{/if}} {{#if _graphic.src}} <div class="menu-item__image-container boxmenu-item__image-container"> @@ -40,9 +46,11 @@ </div> <div class="menu-item__button-container boxmenu-item__button-container"> + {{#unless Adapt.course._boxMenu._areEntireItemsClickable}} <button class="btn-text menu-item__button boxmenu-item__button js-btn-click{{#if _isVisited}} is-visited{{/if}}{{#if _isLocked}} is-locked{{/if}}" aria-label="{{#if _isComplete}}{{_globals._accessibility._ariaLabels.complete}}. {{else _isVisited}}{{_globals._accessibility._ariaLabels.visited}}. {{/if}}{{#if _isLocked}}{{_globals._accessibility._ariaLabels.locked}}. {{else}}{{linkText}} {{/if}}{{title}}. {{{compile _globals._menu._boxMenu.itemCount}}}.{{#if _isOptional}} {{_globals._accessibility._ariaLabels.optional}}{{/if}}"{{#if _isLocked}} aria-disabled="true"{{/if}} role="link"> {{{linkText}}} </button> + {{/unless}} <span class='menu-item__status boxmenu-item__status'> <span class='icon' aria-hidden="true"></span>