/* * 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; };