diff options
| author | Anjana Vakil <contact@anjana.dev> | 2025-08-26 12:40:16 -0500 |
|---|---|---|
| committer | Anjana Vakil <contact@anjana.dev> | 2025-08-26 12:40:16 -0500 |
| commit | 1dc4f56425209d4ce1d7bb78ec8b5e7b5a755a82 (patch) | |
| tree | 58d06cd695ae17302daff7a87d9096f1d39ea54a /frontend/src/components/Modal.js | |
reset
Diffstat (limited to 'frontend/src/components/Modal.js')
| -rw-r--r-- | frontend/src/components/Modal.js | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/frontend/src/components/Modal.js b/frontend/src/components/Modal.js new file mode 100644 index 0000000..d72385b --- /dev/null +++ b/frontend/src/components/Modal.js @@ -0,0 +1,80 @@ +/* + * Modal + * + * Pico.css - https://picocss.com + * Copyright 2019-2024 - Licensed under MIT + */ + +// Config +const isOpenClass = "modal-is-open"; +const openingClass = "modal-is-opening"; +const closingClass = "modal-is-closing"; +const scrollbarWidthCssVar = "--pico-scrollbar-width"; +const animationDuration = 400; // ms +let visibleModal = null; + +// Toggle modal +const toggleModal = (event) => { + event.preventDefault(); + const modal = document.getElementById(event.currentTarget.dataset.target); + if (!modal) return; + modal && (modal.open ? closeModal(modal) : openModal(modal)); +}; + +// Open modal +const openModal = (modal) => { + const { documentElement: html } = document; + const scrollbarWidth = getScrollbarWidth(); + if (scrollbarWidth) { + html.style.setProperty(scrollbarWidthCssVar, `${scrollbarWidth}px`); + } + html.classList.add(isOpenClass, openingClass); + setTimeout(() => { + visibleModal = modal; + html.classList.remove(openingClass); + }, animationDuration); + modal.showModal(); +}; + +// Close modal +const closeModal = (modal) => { + visibleModal = null; + const { documentElement: html } = document; + html.classList.add(closingClass); + setTimeout(() => { + html.classList.remove(closingClass, isOpenClass); + html.style.removeProperty(scrollbarWidthCssVar); + modal.close(); + }, animationDuration); +}; + +// Close with a click outside +document.addEventListener("click", (event) => { + if (visibleModal === null) return; + const modalContent = visibleModal.querySelector("article"); + const isClickInside = modalContent.contains(event.target); + !isClickInside && closeModal(visibleModal); +}); + +// Close with Esc key +document.addEventListener("keydown", (event) => { + if (event.key === "Escape" && visibleModal) { + closeModal(visibleModal); + } +}); + +// Get scrollbar width +const getScrollbarWidth = () => { + const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; + return scrollbarWidth; +}; + + +// Initialize event listeners to open/close event pages +export const setupModals = () => { + // Add open/close button handlers + const togglers = document.querySelectorAll('.toggle-modal'); + for (let el of togglers) { + el.addEventListener("click", toggleModal); + } +};
\ No newline at end of file |
