UNPKG

@randstad-design/orbit-multitheme

Version:

multitheme Front-end code based on Randstad Human Forward components

205 lines (185 loc) 5.68 kB
/** * navigation.js */ import ElementHelpers from '../helpers/element-helpers'; /** * Declare constants */ const attributeBase = 'data-rs-navigation'; export class Navigation { constructor(element) { this.element = element; this.menuIcon = ElementHelpers.getElementByAttribute( this.attributes.menuIcon ); this.modalMain = ElementHelpers.getElementByAttributeWithinElement( this.element, this.attributes.modalMain ); this.collapsibles = ElementHelpers.getElementsByAttributeWithinElement( this.element, this.attributes.collapsible ); this.toggables = ElementHelpers.getElementsByAttributeWithinElement( this.element, this.attributes.toggable ); this.modalHeader = ElementHelpers.getElementByAttributeWithinElement( this.element, this.attributes.modalHeader ); this.menuLabelsAttribute = ElementHelpers.getElementByAttribute( this.attributes.menuLabels ); this.menuLabels = this.menuLabelsAttribute.getAttribute( this.attributes.menuLabels ); this.scrollPos = 0; this.addEventHandlers(); } /** * Declare classes */ get classes() { return { hidden: 'hidden', modalOpen: 'modal-open', modalNavOpen: 'modal-nav-open', modalActive: 'modal--active', modalHeaderDivider: 'modal__header--divider', modalHeaderDividerIn: 'modal__header--divider-in', modalHeaderDividerOut: 'modal__header--divider-out', collapsibleTriggerExpanded: 'collapsible__trigger--expanded' }; } /** * Declare attribute constants */ get attributes() { return { ariaExpanded: 'aria-expanded', ariaHidden: 'aria-hidden', collapsibleContent: 'data-rs-collapsible-content', collapsible: 'data-rs-collapsible', toggable: 'data-rs-toggable', content: 'data-rs-collapsible-content', headerDivider: `${attributeBase}-header-divider`, menuIcon: `${attributeBase}-menu-icon`, menuLabels: `${attributeBase}-menu-labels`, modalMain: `${attributeBase}-modal-main`, modalHeader: `${attributeBase}-modal-header` }; } get getMenuLabels() { const defaultLabels = { openMenu: 'open menu', closeMenu: 'close menu' }; const labels = this.menuLabels ? JSON.parse(this.menuLabels) : defaultLabels; return labels; } /** * Add event handlers */ addEventHandlers() { this.menuIcon.addEventListener('click', () => { // close all menu items on mobile when menu is closed if ( document .querySelector('html') .classList.contains(this.classes.modalOpen) ) { this.setMenuAriaLabelToOpen(); setTimeout(() => { this.closeCollapsible(); }, 500); } else { this.setMenuAriaLabelToClose(); } // add classes to HTML document .querySelector('html') .classList.toggle(`${this.classes.modalOpen}`); document .querySelector('html') .classList.toggle(`${this.classes.modalNavOpen}`); // add active classes to modal this.element.classList.toggle(`${this.classes.modalActive}`); // remove animated border classes on modal const modalHeaderDivider = ElementHelpers.getElementByAttributeWithinElement( this.element, this.attributes.headerDivider ); if (modalHeaderDivider !== null) { modalHeaderDivider.classList.remove( `${this.classes.modalHeaderDividerIn}` ); modalHeaderDivider.classList.remove( `${this.classes.modalHeaderDividerOut}` ); } }); this.modalMain.addEventListener( 'scroll', () => { this.checkPosition(); }, { passive: true } ); } setMenuAriaLabelToOpen() { this.menuLabelsAttribute.setAttribute( 'aria-label', this.getMenuLabels.openMenu ); } setMenuAriaLabelToClose() { this.menuLabelsAttribute.setAttribute( 'aria-label', this.getMenuLabels.closeMenu ); } closeCollapsible() { this.collapsibles.forEach((element) => { this.content = element.parentElement.querySelector( `[${this.attributes.collapsibleContent}]` ); element.classList.remove(this.classes.collapsibleTriggerExpanded); element.setAttribute(this.attributes.ariaExpanded, 'false'); element.removeAttribute(this.attributes.expanded); this.content.style.maxHeight = '0px'; this.content.setAttribute(this.attributes.content, ''); this.content.setAttribute(this.attributes.ariaHidden, 'true'); }); this.toggables.forEach((element) => { element.classList.remove('icon__toggler--active'); }); } /** * Check position */ checkPosition() { const modalMainY = this.modalMain.scrollTop; if (modalMainY > this.scrollPos) { this.modalHeader.classList.add(this.classes.modalHeaderDivider); this.modalHeader.setAttribute(this.attributes.headerDivider, ''); this.modalHeader.classList.add(this.classes.modalHeaderDividerIn); this.modalHeader.classList.remove(this.classes.modalHeaderDividerOut); } if (modalMainY === 0) { this.modalHeader.classList.add(this.classes.modalHeaderDividerOut); this.modalHeader.classList.remove(this.classes.modalHeaderDivider); this.modalHeader.removeAttribute(this.attributes.headerDivider); this.modalHeader.classList.remove(this.classes.modalHeaderDividerIn); } } /** * Get selector */ static getSelector() { return `[${attributeBase}]`; } }