Skip to content

Navigation

kirsty-hames edited this page Dec 6, 2023 · 9 revisions

Navigation

The following covers Core navigation functionality: sorting order, button API and tooltip API.

Navigation sorting order

The sorting order was introduced to give flexibility in the visual display of the navigation bar as well as accessibility compliance with WCAG 2.0 Making the DOM order match the visual order. The sorting of buttons is according to a data-order attribute in the DOM which is configured by _navOrder in course.json _globals._extensions.

Core navigation:

    "_extensions": {
      "_drawer": {
        "_navOrder": 100
      },
      "_navigation": {
        "_skipButton": {
          "_navOrder": -100
        },
        "_backButton": {
          "_navOrder": 0
        },
        "_spacers": [
          {
            "_navOrder": 0
          }
        ]
      }
    }

Navigation plugins also support _navOrder, for example pageLevelProgress or Visua11y.

Sorting order is typically defined by a range from 0 (far left for LTR) to 100 (far right for LTR). Items positioned between 0 to 100 are usually in increments of 10.

_spacers can be used to create space between nav items. The default separates out the left and right aligned items. Multiple spacers can be used depending on the desired layout e.g. two spacers would give you left, centered and right aligned items (see below).

Visual navigation display:

navOrder_example

DOM order:

navOrder_dom

JSON in course.json _globals:

    "_extensions": {
      "_drawer": {
        "_navOrder": 100
      },
      "_navigation": {
        "_skipButton": {
          "_navOrder": -100
        },
        "_backButton": {
          "_navOrder": 0
        },
        "_spacers": [
          {
            "_navOrder": 20
          },
          {
            "_navOrder": 80
          }
        ]
      },
      "_navigationTitle": {
        "_navOrder": "30"
      },
      "_close": {
        "_navOrder": "150"
      }
    }

Navigation button API

The navigation button API was created to allow extensions to define buttons and add them to the navigation bar rather than allowing DOM injection. API features include:

  • Backward compatible with injection
  • Text label based upon the button aria label
  • Ordering
  • Icons
  • Show/hide text

Navigation model

  • NavigationButtonModel To hold the properties for each button
  • NavigationButtonView For extensions to make their own buttons and for legacy injected button management
  • NavigationModel To hold the navigation configuration
  • All model updates will be reflected in the DOM.

General API layout

import navigation from 'core/js/navigation';
navigation.model.set('_showLabel', true); // Show all labels

const backButton = navigation.getButton('back');
backButton.set('_order', 400); // Move the back button to the right
backButton.set('text', 'New Label'); // Change the back button label text


navigation.removeButton(backButton); // Remove back button

// Remove all buttons
navigation.buttons.forEach(button => navigation.removeButton(button));

Example, making a home button:

image

import Adapt from 'core/js/adapt';
import navigation from 'core/js/navigation';
import NavigationButtonModel from 'core/js/models/NavigationButtonModel';
import NavigationButtonView from 'core/js/views/NavigationButtonView';

// Extend the model and view classes to add own behaviour

Adapt.on('navigation:ready', () => {
  const model = new NavigationButtonModel({
    _id: 'home',
    _order: 0,
    _event: 'homeButton',
    _showLabel: null,
    _classes: '',
    _iconClasses: 'icon-medal',
    _role: 'link',
    ariaLabel: 'Home',
    text: '{{ariaLabel}}'
  });
  const view = new NavigationButtonView({ model });
  navigation.addButton(view);
});

Each button has the potential for custom _id, _order, _event, _showLabel, _classes, _iconClasses, _role, ariaLabel and text, with global settings for _showLabel, _navigationAlignment and _isBottomOnTouchDevices.

_event has some default behaviour at "backButton", "homeButton", "parentButton", "skipNavigation" and "returnToStart".

Example, added visua11y and the above home button to the vanilla course:

image

Backward compatibility

Older buttons should have an aria-label attribute or an .aria-label element in order for a text label to be automatically generated. A <span class="label" aria-hidden="true">{{ariaLabel}}</span> will be appended automatically to any existing button, if it doesn't exist, and will otherwise be automatically updated from the value of the aria-label attribute or .aria-label element. This is as model text defaults to {{ariaLabel}}. On older buttons "ariaLabel", "_role" and "_classes" have no effect when changed from the model as they should be supplied by the injected buttons themselves. "text", "_order", "_showLabel", "_id" and "_event" should work as expected on older injected buttons.


Navigation tooltip API

Tooltips display on mouseover and focus. Tooltips are read by a screenreader on mouseover, on focus the screen reader will read the target's aria label. The button aria-label is used to set the default tooltip text.

JSON in course.json to enable / disable globally:

"_tooltips": {
  "_isEnabled": true
}

Core navigation:
JSON in course.json _globals._extensions to configure Back button and Drawer button:

"_extensions": {
  "_navigation": {
    "_backNavTooltip": {
      "_isEnabled": true,
      "text": "{{ariaLabel}}"
    }
  },
  "_drawer": {
    "_navTooltip": {
      "_isEnabled": true,
      "text": "{{ariaLabel}}"
    }
  }
}

Navigation plugins also support _navTooltip, for example pageLevelProgress or Visua11y.

Clone this wiki locally