/** * Mobile Hamburger Menu * * Handles the slide-in mobile navigation drawer with hamburger toggle, * overlay, sub-menu accordions, and keyboard/focus-trap support. * * @package Blog Eye */ (function () { 'use strict'; const hamburgerBtn = document.getElementById('mmenu-btn'); const closeBtn = document.getElementById('mmenu-close'); const drawer = document.getElementById('mobile-navigation'); const overlay = document.getElementById('mobile-menu-overlay'); if (!hamburgerBtn || !drawer) { return; } // ── Open / Close helpers ────────────────────────────────── function openMenu() { drawer.classList.add('is-open'); overlay.classList.add('is-visible'); hamburgerBtn.classList.add('is-active'); hamburgerBtn.setAttribute('aria-expanded', 'true'); document.body.classList.add('mobile-menu-open'); // focus first link inside drawer const firstLink = drawer.querySelector('a'); if (firstLink) { firstLink.focus(); } } function closeMenu() { drawer.classList.remove('is-open'); overlay.classList.remove('is-visible'); hamburgerBtn.classList.remove('is-active'); hamburgerBtn.setAttribute('aria-expanded', 'false'); document.body.classList.remove('mobile-menu-open'); hamburgerBtn.focus(); } // ── Event listeners ─────────────────────────────────────── hamburgerBtn.addEventListener('click', function (e) { e.stopPropagation(); if (drawer.classList.contains('is-open')) { closeMenu(); } else { openMenu(); } }); if (closeBtn) { closeBtn.addEventListener('click', closeMenu); } if (overlay) { overlay.addEventListener('click', closeMenu); } // Close on Escape key document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && drawer.classList.contains('is-open')) { closeMenu(); } }); // ── Sub-menu accordion toggles ──────────────────────────── const subMenuParents = drawer.querySelectorAll( '.menu-item-has-children, .page_item_has_children' ); subMenuParents.forEach(function (item) { // Create toggle button const toggleBtn = document.createElement('button'); toggleBtn.className = 'sub-menu-toggle'; toggleBtn.setAttribute('aria-expanded', 'false'); toggleBtn.setAttribute('aria-label', 'Toggle submenu'); toggleBtn.innerHTML = ''; // Insert toggle after the link const link = item.querySelector(':scope > a'); if (link) { link.after(toggleBtn); } toggleBtn.addEventListener('click', function () { const isOpen = item.classList.toggle('sub-open'); toggleBtn.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); }); }); // ── Focus trap inside drawer ────────────────────────────── const focusableSelector = 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])'; document.addEventListener('keydown', function (e) { if (e.key !== 'Tab' || !drawer.classList.contains('is-open')) { return; } const focusable = drawer.querySelectorAll(focusableSelector); if (!focusable.length) { return; } const first = focusable[0]; const last = focusable[focusable.length - 1]; if (e.shiftKey) { if (document.activeElement === first) { e.preventDefault(); last.focus(); } } else { if (document.activeElement === last) { e.preventDefault(); first.focus(); } } }); })();