Skip to content

Commit

Permalink
Fix: Utilise Navigation and Tooltip APIs (fixes #83).
Browse files Browse the repository at this point in the history
  • Loading branch information
danielghost committed Jul 31, 2023
1 parent 54def7a commit 38b4d32
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 28 deletions.
10 changes: 9 additions & 1 deletion example.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
46 changes: 29 additions & 17 deletions js/adapt-languagePicker.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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
}));
}
}

Expand Down
46 changes: 46 additions & 0 deletions js/languagePickerNavigationButton.js
Original file line number Diff line number Diff line change
@@ -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'));
}

}
65 changes: 61 additions & 4 deletions properties.schema
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
55 changes: 49 additions & 6 deletions schema/course.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
}
}
Expand Down
25 changes: 25 additions & 0 deletions templates/languagePickerNavigationButton.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<React.Fragment>
<span
className={classes([
'icon',
_iconClasses
])}
aria-hidden="true"
/>
<span
className="nav__btn-label"
aria-hidden="true"
dangerouslySetInnerHTML={{ __html: compile(text, props) }}
/>
</React.Fragment>
);
}

0 comments on commit 38b4d32

Please sign in to comment.