diff --git a/example.json b/example.json index f93ea39..ea84f0c 100644 --- a/example.json +++ b/example.json @@ -48,5 +48,13 @@ // to be added to the _extensions object in course.json "_languagePicker": { - "navigationBarLabel" : "Select course language" + "languageSelector": "Language selector", + "_navOrder": 0, + "_navTooltip": { + "_isEnabled": true, + "text": "Select course language" + }, + "_showLabel": true, + "navLabel": "Select course language", + "_drawerPosition": "auto" } diff --git a/js/adapt-languagePicker.js b/js/adapt-languagePicker.js index cb8377a..80531fb 100644 --- a/js/adapt-languagePicker.js +++ b/js/adapt-languagePicker.js @@ -1,7 +1,9 @@ import Adapt from 'core/js/adapt'; import offlineStorage from 'core/js/offlineStorage'; +import navigation from 'core/js/navigation'; +import NavigationButtonModel from 'core/js/models/NavigationButtonModel'; import LanguagePickerView from './languagePickerView'; -import LanguagePickerNavView from './languagePickerNavView'; +import LanguagePickerNavigationButton from './languagePickerNavigationButton'; import LanguagePickerModel from './languagePickerModel'; class LanguagePicker extends Backbone.Controller { @@ -71,23 +73,33 @@ class LanguagePicker extends Backbone.Controller { setupNavigationView() { /* - * On the framework this isn't an issue, but courses built in the authoring tool before the ARIA label - * was added will break unless the extension is removed then added again. - */ - const courseGlobals = Adapt.course.get('_globals')._extensions; - let navigationBarLabel = ''; - if (courseGlobals._languagePicker) { - navigationBarLabel = courseGlobals._languagePicker.navigationBarLabel; - } - - const languagePickerNavView = new LanguagePickerNavView({ - model: this.languagePickerModel, - attributes: { - 'aria-label': navigationBarLabel - } + * On the framework this isn't an issue, but courses built in the authoring tool before the ARIA label + * was added will break unless the extension is removed then added again. + */ + const globalsConfig = Adapt.course.get('_globals')?._extensions?._languagePicker; + const { + _navOrder = 0, + _showLabel = true, + navLabel = '', + _drawerPosition = 'auto', + _navTooltip = {} + } = globalsConfig ?? {}; + const model = new NavigationButtonModel({ + _id: 'languagepicker', + _order: _navOrder, + _showLabel, + _classes: 'nav__languagepicker-btn languagepicker__nav-btn', + _iconClasses: this.languagePickerModel.get('_languagePickerIconClass') || 'icon-language-2', + _role: 'button', + ariaLabel: navLabel, + text: navLabel, + _drawerPosition, + _navTooltip }); - - languagePickerNavView.$el.appendTo('.nav__inner'); + navigation.addButton(new LanguagePickerNavigationButton({ + model: model, + drawerModel: this.languagePickerModel + })); } } diff --git a/js/languagePickerNavigationButton.js b/js/languagePickerNavigationButton.js new file mode 100644 index 0000000..9db61ed --- /dev/null +++ b/js/languagePickerNavigationButton.js @@ -0,0 +1,46 @@ +import Adapt from 'core/js/adapt'; +import drawer from 'core/js/drawer'; +import NavigationButtonView from 'core/js/views/NavigationButtonView'; +import tooltips from 'core/js/tooltips'; +import LanguagePickerDrawerView from './languagePickerDrawerView'; + +export default class LanguagePickerNavigationButton extends NavigationButtonView { + + attributes() { + const attributes = super.attributes(); + return Object.assign(attributes, { + 'data-tooltip-id': 'languagepicker' + }); + } + + static get template() { + return 'languagePickerNavigationButton.jsx'; + } + + events() { + return { + click: 'onClick' + }; + } + + initialize(options) { + super.initialize(options); + this.drawerModel = options.drawerModel; + this.setupEventListeners(); + tooltips.register({ + _id: 'languagepicker', + ...this.model.get('_navTooltip') + }); + } + + setupEventListeners() { + this.listenTo(Adapt, { + remove: this.remove + }); + } + + onClick(event) { + drawer.openCustomView(new LanguagePickerDrawerView({ model: this.drawerModel }).$el, false, this.model.get('_drawerPosition')); + } + +} diff --git a/properties.schema b/properties.schema index 17e17e5..bb39af6 100644 --- a/properties.schema +++ b/properties.schema @@ -4,21 +4,78 @@ "id": "http://jsonschema.net", "required": false, "globals": { - "navigationBarLabel": { + "languageSelector": { "type": "string", "required": true, - "default": "Select course language", + "default": "Language selector", "inputType": "Text", "validators": [], "translatable": true }, - "languageSelector": { + "_navOrder": { + "type": "number", + "required": true, + "title": "Navigation bar order", + "help": "Determines the order in which the button is displayed in the navigation bar. Negative numbers (e.g. -100) are left-aligned. Positive numbers (e.g. 100) are right-aligned.", + "default": 0, + "inputType": "Text", + "validators": [] + }, + "_navTooltip": { + "type": "object", + "title": "Navigation tooltip", + "properties": { + "_isEnabled": { + "type": "boolean", + "default": true, + "title": "Enable tooltip for navigation button", + "inputType": "Checkbox", + "validators": [] + }, + "text": { + "type": "string", + "title": "", + "default": "Select course language", + "help": "The tooltip text to display on hover.", + "inputType": "Text", + "validators": [], + "translatable": true + } + } + }, + "_showLabel": { + "type": "boolean", + "required": true, + "default": true, + "title": "Enable navigation button label", + "inputType": "Checkbox", + "validators": [], + "help": "Determines whether a label is shown on the navigation bar button." + }, + "navLabel": { "type": "string", "required": true, - "default": "Language selector", + "default": "Select course language", + "title": "Navigation bar button label", "inputType": "Text", "validators": [], "translatable": true + }, + "_drawerPosition": { + "type": "string", + "required": true, + "default": "auto", + "title": "Drawer position", + "help": "Determines the starting position of the drawer to open.", + "inputType": { + "type": "Select", + "options": [ + "auto", + "left", + "right" + ] + }, + "validators": [] } }, "properties": { diff --git a/schema/course.schema.json b/schema/course.schema.json index f4921c7..dc85643 100644 --- a/schema/course.schema.json +++ b/schema/course.schema.json @@ -21,21 +21,64 @@ "title": "Language Picker", "default": {}, "properties": { - "navigationBarLabel": { + "languageSelector": { "type": "string", - "title": "Navigation bar label", - "default": "Select course language", + "title": "Language selector", + "default": "Language selector", "_adapt": { "translatable": true } }, - "languageSelector": { + "_navOrder": { + "type": "number", + "title": "Navigation bar order", + "description": "Determines the order in which the button is displayed in the navigation bar. Negative numbers (e.g. -100) are left-aligned. Positive numbers (e.g. 100) are right-aligned.", + "default": 0 + }, + "_navTooltip": { + "type": "object", + "title": "Navigation tooltip", + "properties": { + "_isEnabled": { + "type": "boolean", + "title": "Enable tooltip for navigation button", + "default": true + }, + "text": { + "type": "string", + "title": "", + "default": "Select course language", + "_adapt": { + "translatable": true + } + } + } + }, + "_showLabel": { + "type": "boolean", + "title": "Enable navigation button label", + "description": "Determines whether a label is shown on the navigation bar button.", + "default": true + }, + "navLabel": { "type": "string", - "title": "Language selector", - "default": "Language selector", + "title": "Navigation button label", + "description": "The tooltip text to display on hover.", + "default": "Select course language", "_adapt": { "translatable": true } + }, + "_drawerPosition": { + "type": "string", + "default": "auto", + "title": "Drawer position", + "description": "Determines the starting position of the drawer to open.", + "enum": [ + "auto", + "left", + "right" + ] } } } diff --git a/templates/languagePickerNavigationButton.jsx b/templates/languagePickerNavigationButton.jsx new file mode 100644 index 0000000..ca03444 --- /dev/null +++ b/templates/languagePickerNavigationButton.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { classes, compile } from 'core/js/reactHelpers'; + +export default function LanguagePickerNavigationButton(props) { + const { + text, + _iconClasses + } = props; + return ( + + + ); +}