UNPKG

carbon-components

Version:

The Carbon Design System is IBM’s open-source design system for products and experiences.

106 lines (99 loc) 4.07 kB
/** * Copyright IBM Corp. 2016, 2018 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import mixin from '../../globals/js/misc/mixin'; import createComponent from '../../globals/js/mixins/create-component'; import initComponentByLauncher from '../../globals/js/mixins/init-component-by-launcher'; import eventedShowHideState from '../../globals/js/mixins/evented-show-hide-state'; import handles from '../../globals/js/mixins/handles'; import eventedState from '../../globals/js/mixins/evented-state'; import toggleAttribute from '../../globals/js/misc/toggle-attribute'; import settings from '../../globals/js/settings'; export default class NavigationMenuPanel extends mixin( createComponent, initComponentByLauncher, eventedShowHideState, handles, eventedState ) { createdByLauncher = (event) => { const isExpanded = !this.element.hasAttribute('hidden'); const newState = isExpanded ? 'collapsed' : 'expanded'; this.triggerButton = event.delegateTarget; this.changeState(newState); }; /** * Determine whether or not the state should change based on comparison with * the current state * @param {string} state * @returns {boolean} true if given state is different from current state */ shouldStateBeChanged = (state) => (state === 'expanded') === this.element.hasAttribute('hidden'); /** * Changes the expanded/collapsed state. * @private * @param {string} state The new state. * @param {Function} callback Callback called when change in state completes. */ _changeState = (state, callback) => { toggleAttribute(this.element, 'hidden', state !== 'expanded'); if (this.triggerButton) { if (state === 'expanded') { const focusableMenuItems = this.element.querySelector( this.options.selectorFocusableMenuItem ); if (focusableMenuItems) { focusableMenuItems.focus(); } } const label = state === 'expanded' ? this.triggerButton.getAttribute(this.options.attribLabelCollapse) : this.triggerButton.getAttribute(this.options.attribLabelExpand); this.triggerButton.classList.toggle( this.options.classNavigationMenuPanelHeaderActionActive, state === 'expanded' ); this.triggerButton.setAttribute('aria-label', label); this.triggerButton.setAttribute('title', label); } callback(); }; /** * The map associating DOM element and NavigationMenuPanel instance. * @member NavigationMenuPanel.components * @type {WeakMap} */ static components /* #__PURE_CLASS_PROPERTY__ */ = new WeakMap(); /** * The component options. * If `options` is specified in the constructor, * {@linkcode NavigationMenuPanel.create .create()}, or * {@linkcode NavigationMenuPanel.init .init()}, * properties in this object are overridden for the instance being create and * how {@linkcode NavigationMenuPanel.init .init()} works. * @member NavigationMenuPanel.options * @type {object} * @property {string} selectorInit The CSS class to find popup navs. * @property {string} attribInitTarget The attribute name in the launcher buttons to find target popup nav. * @property {string[]} initEventNames The events that the component will handles */ static get options() { const { prefix } = settings; return { initEventNames: ['click'], eventBeforeExpanded: 'navigation-menu-being-expanded', eventAfterExpanded: 'navigation-menu-expanded', eventBeforeCollapsed: 'navigation-menu-being-collapsed', eventAfterCollapsed: 'navigation-menu-collapsed', selectorFocusableMenuItem: `.${prefix}--navigation__category-toggle, .${prefix}--navigation-link`, classNavigationMenuPanelHeaderActionActive: `${prefix}--header__action--active`, attribLabelExpand: 'data-navigation-menu-panel-label-expand', attribLabelCollapse: 'data-navigation-menu-panel-label-collapse', }; } }