function groups() {
return [...document.querySelectorAll('.z-site-group-button')];
}
function closeGroups(keep) {
for (const b of groups()) {
if (b === keep || b.getAttribute('aria-expanded') !== 'true') continue;
b.setAttribute('aria-expanded', 'false');
document.getElementById(b.getAttribute('aria-controls'))?.setAttribute('hidden', '');
}
}
function setGroup(button, open) {
if (open) closeGroups(button);
button.setAttribute('aria-expanded', String(open));
const list = document.getElementById(button.getAttribute('aria-controls'));
if (open) list?.removeAttribute('hidden');
else list?.setAttribute('hidden', '');
return list;
}
function setMenu(open) {
const toggle = document.querySelector('[data-zeyn-site-toggle]');
const nav = toggle && document.getElementById(toggle.getAttribute('aria-controls').split(' ')[0]);
if (!toggle || !nav) return;
toggle.setAttribute('aria-expanded', String(open));
nav.toggleAttribute('data-open', open);
toggle.closest('[data-zeyn-site-header]')?.toggleAttribute('data-open', open);
}
function setCenter(open, focus) {
const toggle = document.querySelector('[data-zeyn-site-center-toggle]');
const slot = toggle && document.getElementById(toggle.getAttribute('aria-controls'));
if (!toggle || !slot) return;
toggle.setAttribute('aria-expanded', String(open));
slot.toggleAttribute('data-open', open);
if (open && focus) slot.querySelector('input, select, textarea, button, a[href], [tabindex="0"]')?.focus();
if (!open && focus) toggle.focus();
}
function init() {
for (const b of groups()) {
const list = document.getElementById(b.getAttribute('aria-controls'));
b.toggleAttribute('data-current', Boolean(list?.querySelector('a[aria-current="page"]')));
}
const center = document.querySelector('[data-zeyn-site-center-toggle]');
if (center) center.hidden = false;
const toggle = document.querySelector('[data-zeyn-site-toggle]');
if (!toggle || !toggle.hidden) return;
toggle.hidden = false;
toggle.closest('[data-zeyn-site-header]')?.setAttribute('data-zeyn-collapsible', '');
}
function topItems() {
return [...document.querySelectorAll('.z-site-menu > li > a, .z-site-menu > li > .z-site-group-button')];
}
document.addEventListener('click', (e) => {
const center = e.target.closest?.('[data-zeyn-site-center-toggle]');
if (center) {
setCenter(center.getAttribute('aria-expanded') !== 'true', true);
return;
}
const toggle = e.target.closest?.('[data-zeyn-site-toggle]');
if (toggle) {
setMenu(toggle.getAttribute('aria-expanded') !== 'true');
return;
}
const button = e.target.closest?.('.z-site-group-button');
if (button) {
setGroup(button, button.getAttribute('aria-expanded') !== 'true');
return;
}
if (e.target.closest?.('.z-site-nav a')) {
closeGroups();
setMenu(false);
return;
}
if (!e.target.closest?.('.z-site-group')) closeGroups();
});
document.addEventListener('keydown', (e) => {
const nav = e.target.closest?.('.z-site-nav');
if (!nav) return;
const group = e.target.closest('.z-site-group');
const button = group?.querySelector('.z-site-group-button');
const links = group ? [...group.querySelectorAll('.z-site-sub a')] : [];
const inList = e.target.closest('.z-site-sub') !== null;
if (e.key === 'Escape') {
if (button && button.getAttribute('aria-expanded') === 'true') {
setGroup(button, false);
button.focus();
e.preventDefault();
} else if (document.querySelector('[data-zeyn-site-toggle][aria-expanded="true"]')) {
setMenu(false);
document.querySelector('[data-zeyn-site-toggle]')?.focus();
e.preventDefault();
}
return;
}
if (inList && links.length) {
const at = links.indexOf(e.target);
const next = { ArrowDown: at + 1, ArrowUp: at - 1, Home: 0, End: links.length - 1 }[e.key];
if (next === undefined) return;
e.preventDefault();
links[Math.max(0, Math.min(links.length - 1, next))].focus();
return;
}
if (e.target === button && e.key === 'ArrowDown') {
e.preventDefault();
setGroup(button, true);
links[0]?.focus();
return;
}
const top = topItems();
const at = top.indexOf(e.target);
if (at < 0) return;
const rtl = e.target.closest('[dir="rtl"]') !== null;
const step = { ArrowRight: rtl ? -1 : 1, ArrowLeft: rtl ? 1 : -1 }[e.key];
const jump = { Home: 0, End: top.length - 1 }[e.key];
if (step === undefined && jump === undefined) return;
e.preventDefault();
top[jump ?? (at + step + top.length) % top.length].focus();
});
document.addEventListener('focusout', (e) => {
const group = e.target.closest?.('.z-site-group');
if (group && !group.contains(e.relatedTarget)) {
const button = group.querySelector('.z-site-group-button');
if (button?.getAttribute('aria-expanded') === 'true' && e.relatedTarget) setGroup(button, false);
}
});
window.addEventListener('keydown', (e) => {
if (e.key !== 'Escape' || e.defaultPrevented) return;
const slot = e.target.closest?.('.z-site-slot-center[data-open]');
if (slot) {
e.preventDefault();
setCenter(false, true);
}
});
document.addEventListener('zeyn:leave', () => {
closeGroups();
setMenu(false);
setCenter(false, false);
});
document.addEventListener('zeyn:content', init);
init();