UNPKG

@atlassian/aui

Version:

Atlassian User Interface library

126 lines (105 loc) 3.75 kB
import { I18n } from './i18n'; import $ from './jquery'; import skate from './internal/skate'; import globalize from './internal/globalize'; import widget from './internal/widget'; /** * Navigation (".aui-nav" elements). * * @param {(string|HtmlElement|jQuery)} selector - An expression * representing a single .aui-nav element; you may also pass an expression * for a descendent element, in which case the closest containing * .aui-nav element is used. * @constructor */ function Navigation(selector) { this.$el = $(selector).closest('.aui-nav'); // If there are multiple objects, initialise them separately if (this.$el.length > 1) { return this.$el.map(function (idx, elm) { return new Navigation(elm); })[0]; } // If already initialised, return existing object if (this.$el.data('aui-navigation')) { return this.$el.data('aui-navigation'); } this.$el.data('aui-navigation', this); this.$treeParent = this.$el.parent('li[aria-expanded]'); this.$subtreeToggleIcon = this.$treeParent .children('.aui-nav-subtree-toggle') .children('span.aui-icon'); // Add child-selected class to relevant attributes this.$el.children('li:has(.aui-nav-selected)').addClass('aui-nav-child-selected'); // Auto-expand if child is selected var $selected = this.$el.children('.aui-nav-selected'); $selected .parents('.aui-nav > [aria-expanded=false]') .add($selected.filter('[aria-expanded=false]')) .each(function () { var nav = navigationWidget($(this).children('.aui-nav')); nav.expand(); }); // Toggle expand on click var $togglers = this.$el.find('> li[aria-expanded] > .aui-nav-subtree-toggle'); $togglers.on('click', function () { var nav = navigationWidget($(this).siblings('.aui-nav')); nav.toggle(); }); // Make sure subtree togglers have proper a11y label $togglers.each(function () { var $parent = $(this).parent('li[aria-expanded]'); var $icon = $(this).find('.aui-icon'); var isListItemExpanded = $parent.attr('aria-expanded') === 'true'; $icon.text( isListItemExpanded ? I18n.getText('aui.words.collapse') : I18n.getText('aui.words.expand') ); }); return this; } Navigation.prototype.isNested = function () { return this.$treeParent.length === 1; }; Navigation.prototype.isCollapsed = function () { return this.$treeParent.attr('aria-expanded') === 'false'; }; Navigation.prototype.expand = function () { this.$treeParent.attr('aria-expanded', 'true'); this.$subtreeToggleIcon .removeClass('aui-iconfont-collapsed') .addClass('aui-iconfont-expanded') .text(I18n.getText('aui.words.collapse')); return this; }; Navigation.prototype.collapse = function () { this.$treeParent.attr('aria-expanded', 'false'); this.$subtreeToggleIcon .removeClass('aui-iconfont-expanded') .addClass('aui-iconfont-collapsed') .text(I18n.getText('aui.words.expand')); return this; }; Navigation.prototype.toggle = function () { if (this.isCollapsed()) { this.expand(); } else { this.collapse(); } return this; }; const navigationWidget = widget('navigation', Navigation); // Initialise nav elements const NavigationEl = skate('aui-nav', { type: skate.type.CLASSNAME, attached: function (element) { new Navigation(element); }, detached: function (element) { $(element).removeData(); }, }); globalize('navigation', navigationWidget); export default navigationWidget; export { NavigationEl };