import { useCallback, useEffect, useId, useRef } from 'react'; import GlassSurface from './GlassSurface'; import useFocusTrap from '../../lib/use-focus-trap'; const SIZE_MAX_WIDTH = { sm: '24rem', md: '32rem', lg: '48rem', 'fullscreen-on-mobile': '32rem', }; export default function Modal({ open, onClose, title, description, size = 'md', closeOnBackdrop = true, closeOnEsc = true, initialFocusRef, hideCloseButton = false, children, }) { const panelRef = useRef(null); const titleId = useId(); const descriptionId = useId(); useFocusTrap({ active: open, containerRef: panelRef, initialFocusRef }); useEffect(() => { if (!open || !closeOnEsc) return undefined; const handler = (e) => { if (e.key === 'Escape') onClose?.(); }; document.addEventListener('keydown', handler); return () => document.removeEventListener('keydown', handler); }, [open, closeOnEsc, onClose]); useEffect(() => { if (!open) return undefined; const previousOverflow = document.body.style.overflow; const previousPadRight = document.body.style.paddingRight; const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; document.body.style.overflow = 'hidden'; if (scrollbarWidth > 0) { document.body.style.paddingRight = `${scrollbarWidth}px`; } return () => { document.body.style.overflow = previousOverflow; document.body.style.paddingRight = previousPadRight; }; }, [open]); const handleBackdropClick = useCallback( (e) => { if (!closeOnBackdrop) return; if (e.target === e.currentTarget) onClose?.(); }, [closeOnBackdrop, onClose] ); if (!open) return null; const isFullscreenOnMobile = size === 'fullscreen-on-mobile'; const maxWidth = SIZE_MAX_WIDTH[size] ?? SIZE_MAX_WIDTH.md; return (
{description}
)}