diff --git a/src/implementations/vanilla/components/site-header/site-header.js b/src/implementations/vanilla/components/site-header/site-header.js index 666c92d071c..d97e63e700b 100644 --- a/src/implementations/vanilla/components/site-header/site-header.js +++ b/src/implementations/vanilla/components/site-header/site-header.js @@ -15,6 +15,7 @@ import { createFocusTrap } from 'focus-trap'; * @param {String} options.loginBoxSelector * @param {Boolean} options.attachClickListener Whether or not to bind click events * @param {Boolean} options.attachKeyListener Whether or not to bind keyboard events + * @param {Boolean} options.attachResizeListener Whether or not to bind resize events */ export class SiteHeader { /** @@ -47,6 +48,7 @@ export class SiteHeader { loginBoxSelector = '[data-ecl-login-box]', attachClickListener = true, attachKeyListener = true, + attachResizeListener = true, } = {} ) { // Check element @@ -71,6 +73,7 @@ export class SiteHeader { this.loginBoxSelector = loginBoxSelector; this.attachClickListener = attachClickListener; this.attachKeyListener = attachKeyListener; + this.attachResizeListener = attachResizeListener; // Private variables this.languageMaxColumnItems = 8; @@ -84,6 +87,7 @@ export class SiteHeader { this.searchForm = null; this.loginToggle = null; this.loginBox = null; + this.resizeTimer = null; // Bind `this` for use in callbacks this.openOverlay = this.openOverlay.bind(this); @@ -94,6 +98,7 @@ export class SiteHeader { this.handleKeyboardLanguage = this.handleKeyboardLanguage.bind(this); this.handleKeyboardGlobal = this.handleKeyboardGlobal.bind(this); this.handleClickGlobal = this.handleClickGlobal.bind(this); + this.handleResize = this.handleResize.bind(this); } /** @@ -107,6 +112,9 @@ export class SiteHeader { if (this.attachClickListener) { document.addEventListener('click', this.handleClickGlobal); } + if (this.attachResizeListener) { + window.addEventListener('resize', this.handleResize); + } // Site header elements this.container = queryOne(this.containerSelector); @@ -195,15 +203,19 @@ export class SiteHeader { document.removeEventListener('click', this.handleClickGlobal); } + if (this.attachResizeListener) { + window.removeEventListener('resize', this.handleResize); + } + if (this.element) { this.element.removeAttribute('data-ecl-auto-initialized'); } } /** - * Shows the modal language list overlay. + * Update display of the modal language list overlay. */ - openOverlay() { + updateOverlay() { // Check number of items and adapt display let columnsEu = 1; let columnsNonEu = 1; @@ -242,11 +254,6 @@ export class SiteHeader { } } - // Display language list - this.languageListOverlay.hidden = false; - this.languageListOverlay.setAttribute('aria-modal', 'true'); - this.languageLink.setAttribute('aria-expanded', 'true'); - // Check total width, and change display if needed this.languageListEu.parentNode.classList.remove( 'ecl-site-header__language-content--stack' @@ -333,6 +340,16 @@ export class SiteHeader { } } + /** + * Shows the modal language list overlay. + */ + openOverlay() { + // Display language list + this.languageListOverlay.hidden = false; + this.languageListOverlay.setAttribute('aria-modal', 'true'); + this.languageLink.setAttribute('aria-expanded', 'true'); + } + /** * Hides the modal language list overlay. */ @@ -354,12 +371,26 @@ export class SiteHeader { if (this.languageListOverlay.hasAttribute('hidden')) { this.openOverlay(); + this.updateOverlay(); this.focusTrap.activate(); } else { this.focusTrap.deactivate(); } } + /** + * Trigger events on resize + * Uses a debounce, for performance + */ + handleResize() { + if (this.languageListOverlay.hasAttribute('hidden')) return; + + clearTimeout(this.resizeTimer); + this.resizeTimer = setTimeout(() => { + this.updateOverlay(); + }, 200); + } + /** * Handles keyboard events specific to the language list. *