/* * Modal * * Pico.css - https://picocss.com * Copyright 2019-2023 - Licensed under MIT */ // Config const isOpenClass = "modal-is-open" const openingClass = "modal-is-opening" const closingClass = "modal-is-closing" const animationDuration = 400 // ms let visibleModal = null // Toggle modal const toggleModal = event => { event.preventDefault() const modal = document.getElementById( event.currentTarget.getAttribute("data-target") ) typeof modal != "undefined" && modal != null && isModalOpen(modal) ? closeModal(modal) : openModal(modal) } // Is modal open const isModalOpen = modal => { return modal.hasAttribute("open") && modal.getAttribute("open") != "false" ? true : false } // Open modal const openModal = modal => { if (isScrollbarVisible()) { document.documentElement.style.setProperty( "--scrollbar-width", `${getScrollbarWidth()}px` ) } document.documentElement.classList.add(isOpenClass, openingClass) setTimeout(() => { visibleModal = modal document.documentElement.classList.remove(openingClass) }, animationDuration) modal.setAttribute("open", true) } // Close modal const closeModal = modal => { visibleModal = null document.documentElement.classList.add(closingClass) setTimeout(() => { document.documentElement.classList.remove(closingClass, isOpenClass) document.documentElement.style.removeProperty("--scrollbar-width") modal.removeAttribute("open") }, animationDuration) } // Close with a click outside document.addEventListener("click", event => { if (visibleModal != null) { 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 != null) { closeModal(visibleModal) } }) // Get scrollbar width const getScrollbarWidth = () => { // Creating invisible container const outer = document.createElement("div") outer.style.visibility = "hidden" outer.style.overflow = "scroll" // forcing scrollbar to appear outer.style.msOverflowStyle = "scrollbar" // needed for WinJS apps document.body.appendChild(outer) // Creating inner element and placing it in the container const inner = document.createElement("div") outer.appendChild(inner) // Calculating difference between container's full width and the child width const scrollbarWidth = outer.offsetWidth - inner.offsetWidth // Removing temporary elements from the DOM outer.parentNode.removeChild(outer) return scrollbarWidth } // Is scrollbar visible const isScrollbarVisible = () => { return document.body.scrollHeight > screen.height }