const initializedRoots = new WeakSet();
function getDrawerForToggle(toggle, root) {
const id = toggle.getAttribute("aria-controls");
if(id) {
return root.getElementById?.(id) || document.getElementById(id);
}
return root.querySelector?.("[data-navigation-drawer]") || document.querySelector("[data-navigation-drawer]");
}
function open(drawer, toggle) {
if(!drawer) {
return;
}
drawer.classList.add("is-open");
drawer.setAttribute("aria-hidden", "false");
drawer.removeAttribute("inert");
toggle?.setAttribute("aria-expanded", "true");
document.body.classList.add("nav-drawer-open");
const firstControl = drawer.querySelector("[data-navigation-close], a, button, input, select, textarea");
firstControl?.focus?.();
}
function close(drawer, toggle, shouldRestoreFocus = true) {
if(!drawer) {
return;
}
drawer.classList.remove("is-open");
drawer.setAttribute("aria-hidden", "true");
drawer.setAttribute("inert", "");
toggle?.setAttribute("aria-expanded", "false");
document.body.classList.remove("nav-drawer-open");
if(shouldRestoreFocus) {
toggle?.focus?.();
}
}
function init(root = document) {
if(initializedRoots.has(root)) {
return;
}
root.addEventListener("click", event => {
const toggle = event.target.closest("[data-navigation-toggle]");
if(!toggle) {
return;
}
const drawer = getDrawerForToggle(toggle, root);
if(drawer?.classList.contains("is-open")) {
close(drawer, toggle);
} else {
open(drawer, toggle);
}
});
root.addEventListener("click", event => {
const closeControl = event.target.closest("[data-navigation-close], [data-navigation-link], .nav-drawer .list-action");
if(!closeControl) {
return;
}
const drawer = closeControl.closest("[data-navigation-drawer]") || root.querySelector("[data-navigation-drawer]");
const toggle = drawer?.id ? root.querySelector(`[data-navigation-toggle][aria-controls="${drawer.id}"]`) : root.querySelector("[data-navigation-toggle]");
const shouldRestoreFocus = !closeControl.matches("[data-navigation-link]");
close(drawer, toggle, shouldRestoreFocus);
});
document.addEventListener("keydown", event => {
if(event.key !== "Escape") {
return;
}
root.querySelectorAll("[data-navigation-drawer].is-open").forEach(drawer => {
const toggle = drawer.id ? root.querySelector(`[data-navigation-toggle][aria-controls="${drawer.id}"]`) : root.querySelector("[data-navigation-toggle]");
close(drawer, toggle);
});
});
initializedRoots.add(root);
}
export default {
init,
open,
close
};