@@ -27,21 +27,61 @@ const { id = 'modal', open = false, closeOnOutsideClick = false } = Astro.props;
2727</div >
2828<script is:inline >
2929 document.addEventListener('DOMContentLoaded', () => {
30+ // Function to toggle body scroll
31+ const toggleBodyScroll = (disable) => {
32+ if (disable) {
33+ // Save the current scroll position
34+ const scrollY = window.scrollY;
35+ document.body.style.position = 'fixed';
36+ document.body.style.top = `-${scrollY}px`;
37+ document.body.style.width = '100%';
38+ document.body.dataset.scrollPosition = scrollY.toString();
39+ } else {
40+ // Restore scroll position
41+ const scrollY = parseInt(document.body.dataset.scrollPosition || '0');
42+ document.body.style.position = '';
43+ document.body.style.top = '';
44+ document.body.style.width = '';
45+ window.scrollTo(0, scrollY);
46+ delete document.body.dataset.scrollPosition;
47+ }
48+ };
49+
50+ // Function to open modal
51+ const openModal = (modal) => {
52+ if (modal) {
53+ // Disable body scroll
54+ toggleBodyScroll(true);
55+ // Show modal
56+ modal.classList.remove('opacity-0', 'invisible');
57+ modal.classList.add('opacity-100', 'visible');
58+ }
59+ };
60+
61+ // Function to close modal
62+ const closeModal = (modal) => {
63+ if (modal) {
64+ // Enable body scroll
65+ toggleBodyScroll(false);
66+ // Hide modal
67+ modal.classList.remove('opacity-100', 'visible');
68+ modal.classList.add('opacity-0', 'invisible');
69+ }
70+ };
71+
3072 // Open modal buttons
3173 document.querySelectorAll('[data-open-modal]').forEach(button => {
3274 button.addEventListener('click', () => {
3375 const modal = document.getElementById(button.dataset.openModal);
34- modal?.classList.remove('opacity-0', 'invisible');
35- modal?.classList.add('opacity-100', 'visible');
76+ openModal(modal);
3677 });
3778 });
3879
3980 // Close modal buttons
4081 document.querySelectorAll('[data-close-modal]').forEach(button => {
4182 button.addEventListener('click', () => {
4283 const modal = button.closest('[data-modal-wrapper]');
43- modal?.classList.remove('opacity-100', 'visible');
44- modal?.classList.add('opacity-0', 'invisible');
84+ closeModal(modal);
4585 });
4686 });
4787
@@ -53,11 +93,23 @@ const { id = 'modal', open = false, closeOnOutsideClick = false } = Astro.props;
5393 modal.addEventListener('click', (event) => {
5494 // Check if the click was on the wrapper but not on the content
5595 if (event.target === modal) {
56- modal.classList.remove('opacity-100', 'visible');
57- modal.classList.add('opacity-0', 'invisible');
96+ closeModal(modal);
5897 }
5998 });
6099 }
100+
101+ // Initialize any modal that's set to open by default
102+ if (modal.classList.contains('opacity-100') && modal.classList.contains('visible')) {
103+ toggleBodyScroll(true);
104+ }
105+ });
106+
107+ // Handle escape key to close all modals
108+ document.addEventListener('keydown', (event) => {
109+ if (event.key === 'Escape') {
110+ const visibleModals = document.querySelectorAll('[data-modal-wrapper].visible, [data-modal-wrapper].opacity-100');
111+ visibleModals.forEach(modal => closeModal(modal));
112+ }
61113 });
62114 });
63115</script >
0 commit comments