// Nova toolbar interactions // - dropdown menus via [data-dropdown] // - mobile menu toggle via [data-mobile-toggle] + #mobileMenu (function () { function closest(el, selector) { while (el && el.nodeType === 1) { if (el.matches(selector)) return el; el = el.parentElement; } return null; } function canHover() { return window.matchMedia && window.matchMedia('(hover: hover) and (pointer: fine)').matches; } function setExpanded(toggleEl, expanded) { if (!toggleEl) return; toggleEl.setAttribute('aria-expanded', expanded ? 'true' : 'false'); } function closeAllDropdowns(except) { var dropdowns = document.querySelectorAll('[data-dropdown]'); dropdowns.forEach(function (dropdown) { if (except && dropdown === except) return; var menu = dropdown.querySelector('[data-dropdown-menu]'); var toggle = dropdown.querySelector('[data-dropdown-toggle]'); if (menu) menu.classList.add('hidden'); setExpanded(toggle, false); // Close any submenus dropdown.querySelectorAll('[data-submenu-menu]').forEach(function (sm) { sm.classList.add('hidden'); }); dropdown.querySelectorAll('[data-submenu-toggle]').forEach(function (st) { setExpanded(st, false); }); }); } function openDropdown(dropdown) { var menu = dropdown.querySelector('[data-dropdown-menu]'); var toggle = dropdown.querySelector('[data-dropdown-toggle]'); if (!menu || !toggle) return; closeAllDropdowns(dropdown); menu.classList.remove('hidden'); setExpanded(toggle, true); } function closeDropdown(dropdown) { var menu = dropdown.querySelector('[data-dropdown-menu]'); var toggle = dropdown.querySelector('[data-dropdown-toggle]'); if (menu) menu.classList.add('hidden'); setExpanded(toggle, false); } function toggleDropdown(dropdown) { var menu = dropdown.querySelector('[data-dropdown-menu]'); var toggle = dropdown.querySelector('[data-dropdown-toggle]'); if (!menu || !toggle) return; var isOpen = !menu.classList.contains('hidden'); closeAllDropdowns(isOpen ? null : dropdown); if (isOpen) { menu.classList.add('hidden'); setExpanded(toggle, false); } else { menu.classList.remove('hidden'); setExpanded(toggle, true); } } function getMobileMenu() { return document.getElementById('mobileMenu'); } function closeMobileMenu() { var menu = getMobileMenu(); if (!menu) return; menu.classList.add('hidden'); var toggle = document.querySelector('[data-mobile-toggle]'); setExpanded(toggle, false); } function toggleMobileMenu() { var menu = getMobileMenu(); if (!menu) return; var isOpen = !menu.classList.contains('hidden'); if (isOpen) { closeMobileMenu(); } else { menu.classList.remove('hidden'); var toggle = document.querySelector('[data-mobile-toggle]'); setExpanded(toggle, true); closeAllDropdowns(); } } document.addEventListener('click', function (e) { var dropdownToggle = closest(e.target, '[data-dropdown-toggle]'); if (dropdownToggle) { e.preventDefault(); var dropdown = closest(dropdownToggle, '[data-dropdown]'); if (dropdown) toggleDropdown(dropdown); return; } var mobileToggle = closest(e.target, '[data-mobile-toggle]'); if (mobileToggle) { e.preventDefault(); toggleMobileMenu(); return; } // Submenu toggle (touch/click fallback) var submenuToggle = closest(e.target, '[data-submenu-toggle]'); if (submenuToggle) { if (canHover()) { // On desktop, submenu opens on hover via CSS. e.preventDefault(); return; } e.preventDefault(); var submenu = closest(submenuToggle, '[data-submenu]'); if (!submenu) return; var menu = submenu.querySelector('[data-submenu-menu]'); if (!menu) return; // Close other submenus within the same dropdown var dropdown = closest(submenuToggle, '[data-dropdown]'); if (dropdown) { dropdown.querySelectorAll('[data-submenu-menu]').forEach(function (sm) { if (sm !== menu) sm.classList.add('hidden'); }); dropdown.querySelectorAll('[data-submenu-toggle]').forEach(function (st) { if (st !== submenuToggle) setExpanded(st, false); }); } var isOpen = !menu.classList.contains('hidden'); if (isOpen) { menu.classList.add('hidden'); setExpanded(submenuToggle, false); } else { menu.classList.remove('hidden'); setExpanded(submenuToggle, true); } return; } if (!closest(e.target, '[data-dropdown]')) { closeAllDropdowns(); } }); // Hover-to-open for desktop pointers var hoverCloseTimers = new WeakMap(); function clearHoverTimer(dropdown) { var t = hoverCloseTimers.get(dropdown); if (t) window.clearTimeout(t); hoverCloseTimers.delete(dropdown); } function scheduleClose(dropdown) { clearHoverTimer(dropdown); hoverCloseTimers.set( dropdown, window.setTimeout(function () { closeDropdown(dropdown); }, 140) ); } function bindHoverHandlers() { if (!canHover()) return; document.querySelectorAll('[data-dropdown]').forEach(function (dropdown) { dropdown.addEventListener('mouseenter', function () { clearHoverTimer(dropdown); openDropdown(dropdown); }); dropdown.addEventListener('mouseleave', function () { scheduleClose(dropdown); }); }); } bindHoverHandlers(); // Submenu hover handlers: ensure flyouts open on pointer devices if (canHover()) { document.querySelectorAll('[data-submenu]').forEach(function (group) { var toggle = group.querySelector('[data-submenu-toggle]'); var menu = group.querySelector('[data-submenu-menu]'); if (!menu) return; group.addEventListener('mouseenter', function () { menu.classList.remove('hidden'); if (toggle) setExpanded(toggle, true); }); group.addEventListener('mouseleave', function () { menu.classList.add('hidden'); if (toggle) setExpanded(toggle, false); }); }); } document.addEventListener('keydown', function (e) { if (e.key !== 'Escape') return; closeAllDropdowns(); closeMobileMenu(); }); window.addEventListener('resize', function () { if (window.matchMedia('(min-width: 768px)').matches) { closeMobileMenu(); } }); })();