// Tiny modal helper. Registers a single document-level Esc + backdrop-click // handler so individual modals don't have to. Public API: openModal(id) / // closeModal(id) / closeAllModals(). "use strict"; let bound = false; function bindGlobal() { if (bound) return; bound = true; document.addEventListener("keydown", e => { if (e.key === "Escape") closeAllModals(); }); document.addEventListener("click", e => { // Backdrop click closes the topmost open modal. const backdrop = e.target.closest(".modal-backdrop"); if (backdrop) closeModal(backdrop.parentElement.id); const closeBtn = e.target.closest(".modal-close"); if (closeBtn) closeModal(closeBtn.closest(".modal").id); }); } export function openModal(id) { bindGlobal(); const m = document.getElementById(id); if (!m) return; m.hidden = false; document.body.classList.add("modal-open"); // Focus first input/button for keyboard users. setTimeout(() => { const focusable = m.querySelector("input, button:not(.modal-close), select, textarea"); focusable?.focus(); }, 50); } export function closeModal(id) { const m = document.getElementById(id); if (!m) return; m.hidden = true; if (!document.querySelector(".modal:not([hidden])")) { document.body.classList.remove("modal-open"); } } export function closeAllModals() { document.querySelectorAll(".modal:not([hidden])").forEach(m => m.hidden = true); document.body.classList.remove("modal-open"); } /// Wires `data-open-modal="someId"` on any element to opening the modal. export function setupModalTriggers() { bindGlobal(); document.addEventListener("click", e => { const trigger = e.target.closest("[data-open-modal]"); if (trigger) openModal(trigger.getAttribute("data-open-modal")); }); }