Files

62 lines
1.9 KiB
JavaScript

export function initNav() {
const header = document.querySelector('[data-header]');
if (!header) return;
const root = document.documentElement;
const toggle = header.querySelector('[data-menu-toggle]');
const nav = header.querySelector('[data-nav]');
const label = toggle.querySelector('.menu-toggle__label');
const outside = [document.querySelector('main'), document.querySelector('.site-footer')];
let lastY = scrollY;
let ticking = false;
function onScroll() {
const y = scrollY;
header.classList.toggle('is-scrolled', y > 24);
if (!root.classList.contains('menu-open')) {
// hide while scrolling down, come back as soon as the user scrolls up
if (y > lastY + 4 && y > 240) header.classList.add('is-hidden');
else if (y < lastY - 4 || y <= 240) header.classList.remove('is-hidden');
}
lastY = y;
ticking = false;
}
addEventListener(
'scroll',
() => {
if (!ticking) requestAnimationFrame(onScroll);
ticking = true;
},
{ passive: true },
);
onScroll();
header.addEventListener('focusin', () => header.classList.remove('is-hidden'));
function setOpen(open) {
toggle.setAttribute('aria-expanded', String(open));
root.classList.toggle('menu-open', open);
label.textContent = open ? label.dataset.labelClose : label.dataset.labelOpen;
for (const element of outside) if (element) element.inert = open;
if (open) header.classList.remove('is-hidden');
}
toggle.addEventListener('click', () => setOpen(toggle.getAttribute('aria-expanded') !== 'true'));
nav.addEventListener('click', (event) => {
if (event.target.closest('a')) setOpen(false);
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && root.classList.contains('menu-open')) {
setOpen(false);
toggle.focus();
}
});
matchMedia('(min-width: 48em)').addEventListener('change', (event) => {
if (event.matches) setOpen(false);
});
}