Loading core/themes/olivero/js/second-level-navigation.js +111 −77 Original line number Diff line number Diff line Loading @@ -5,9 +5,11 @@ ((Drupal) => { const { isDesktopNav } = Drupal.olivero; const secondLevelNavMenus = document.querySelectorAll( '[data-drupal-selector="primary-nav-menu-item-has-children"]', ); /** * NodeList of second level navigation <ul>'s. */ let secondLevelNavMenus; /** * Shows and hides the specified menu item's second level submenu. Loading Loading @@ -77,6 +79,59 @@ }, 200); } /** * Close all second level sub navigation menus. */ function closeAllSubNav() { secondLevelNavMenus.forEach((el) => { // Return focus to the toggle button if the submenu contains focus. if (el.contains(document.activeElement)) { el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ).focus(); } toggleSubNav(el, false); }); } Drupal.olivero.closeAllSubNav = closeAllSubNav; /** * Checks if any sub navigation items are currently active. * * @return {boolean} * If sub navigation is currently open. */ function areAnySubNavsOpen() { let subNavsAreOpen = false; secondLevelNavMenus.forEach((el) => { const button = el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ); const state = button.getAttribute('aria-expanded') === 'true'; if (state) { subNavsAreOpen = true; } }); return subNavsAreOpen; } Drupal.olivero.areAnySubNavsOpen = areAnySubNavsOpen; /** * Initializes second level navigation behavior. * * @param {Element} navElement * The primary navigation menu element. */ function init(navElement) { secondLevelNavMenus = navElement.querySelectorAll( '[data-drupal-selector="primary-nav-menu-item-has-children"]', ); // Add event listeners onto each sub navigation parent and button. secondLevelNavMenus.forEach((el) => { const button = el.querySelector( Loading Loading @@ -130,48 +185,8 @@ el.addEventListener('blur', handleBlur, true); }); /** * Close all second level sub navigation menus. */ function closeAllSubNav() { secondLevelNavMenus.forEach((el) => { // Return focus to the toggle button if the submenu contains focus. if (el.contains(document.activeElement)) { el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ).focus(); } toggleSubNav(el, false); }); } Drupal.olivero.closeAllSubNav = closeAllSubNav; /** * Checks if any sub navigation items are currently active. * * @return {boolean} * If sub navigation is currently open. */ function areAnySubNavsOpen() { let subNavsAreOpen = false; secondLevelNavMenus.forEach((el) => { const button = el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ); const state = button.getAttribute('aria-expanded') === 'true'; if (state) { subNavsAreOpen = true; } }); return subNavsAreOpen; } Drupal.olivero.areAnySubNavsOpen = areAnySubNavsOpen; // Add document-level listeners only once to prevent duplication. once('olivero-second-level-nav-document', document).forEach(() => { // Ensure that desktop submenus close when escape key is pressed. document.addEventListener('keyup', (e) => { if (e.key === 'Escape') { Loading @@ -194,4 +209,23 @@ }, { passive: true }, ); }); } /** * Attaches the primary navigation behavior to the primary navigation list. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach */ Drupal.behaviors.secondLevelNav = { attach(context) { once( 'second-level-navigation', '[data-drupal-selector="primary-nav-menu--level-1"]', context, ).forEach(init); }, }; })(Drupal); Loading
core/themes/olivero/js/second-level-navigation.js +111 −77 Original line number Diff line number Diff line Loading @@ -5,9 +5,11 @@ ((Drupal) => { const { isDesktopNav } = Drupal.olivero; const secondLevelNavMenus = document.querySelectorAll( '[data-drupal-selector="primary-nav-menu-item-has-children"]', ); /** * NodeList of second level navigation <ul>'s. */ let secondLevelNavMenus; /** * Shows and hides the specified menu item's second level submenu. Loading Loading @@ -77,6 +79,59 @@ }, 200); } /** * Close all second level sub navigation menus. */ function closeAllSubNav() { secondLevelNavMenus.forEach((el) => { // Return focus to the toggle button if the submenu contains focus. if (el.contains(document.activeElement)) { el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ).focus(); } toggleSubNav(el, false); }); } Drupal.olivero.closeAllSubNav = closeAllSubNav; /** * Checks if any sub navigation items are currently active. * * @return {boolean} * If sub navigation is currently open. */ function areAnySubNavsOpen() { let subNavsAreOpen = false; secondLevelNavMenus.forEach((el) => { const button = el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ); const state = button.getAttribute('aria-expanded') === 'true'; if (state) { subNavsAreOpen = true; } }); return subNavsAreOpen; } Drupal.olivero.areAnySubNavsOpen = areAnySubNavsOpen; /** * Initializes second level navigation behavior. * * @param {Element} navElement * The primary navigation menu element. */ function init(navElement) { secondLevelNavMenus = navElement.querySelectorAll( '[data-drupal-selector="primary-nav-menu-item-has-children"]', ); // Add event listeners onto each sub navigation parent and button. secondLevelNavMenus.forEach((el) => { const button = el.querySelector( Loading Loading @@ -130,48 +185,8 @@ el.addEventListener('blur', handleBlur, true); }); /** * Close all second level sub navigation menus. */ function closeAllSubNav() { secondLevelNavMenus.forEach((el) => { // Return focus to the toggle button if the submenu contains focus. if (el.contains(document.activeElement)) { el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ).focus(); } toggleSubNav(el, false); }); } Drupal.olivero.closeAllSubNav = closeAllSubNav; /** * Checks if any sub navigation items are currently active. * * @return {boolean} * If sub navigation is currently open. */ function areAnySubNavsOpen() { let subNavsAreOpen = false; secondLevelNavMenus.forEach((el) => { const button = el.querySelector( '[data-drupal-selector="primary-nav-submenu-toggle-button"]', ); const state = button.getAttribute('aria-expanded') === 'true'; if (state) { subNavsAreOpen = true; } }); return subNavsAreOpen; } Drupal.olivero.areAnySubNavsOpen = areAnySubNavsOpen; // Add document-level listeners only once to prevent duplication. once('olivero-second-level-nav-document', document).forEach(() => { // Ensure that desktop submenus close when escape key is pressed. document.addEventListener('keyup', (e) => { if (e.key === 'Escape') { Loading @@ -194,4 +209,23 @@ }, { passive: true }, ); }); } /** * Attaches the primary navigation behavior to the primary navigation list. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach */ Drupal.behaviors.secondLevelNav = { attach(context) { once( 'second-level-navigation', '[data-drupal-selector="primary-nav-menu--level-1"]', context, ).forEach(init); }, }; })(Drupal);