import { useEffect, useRef, useState, type PropsWithChildren, type ReactNode } from 'react'; interface ModalProps { /** Class applied to the element itself (it is the visible card). */ className?: string; /** Blocks Escape/backdrop dismissal while a mutation is in flight. */ isDismissLocked?: boolean; /** Close when the backdrop (the ::backdrop area of the dialog) is pressed. */ closeOnBackdrop?: boolean; label?: string; labelledBy?: string; onClose(): void; } /** * Shared modal built on native .showModal(): the browser provides * focus trapping, inert background, and Escape handling. Render conditionally; * mounting opens the dialog and unmounting restores focus to the opener. */ export function Modal({ children, className, closeOnBackdrop = false, isDismissLocked = false, label, labelledBy, onClose, }: PropsWithChildren): ReactNode { const dialogRef = useRef(null); const onCloseRef = useRef(onClose); onCloseRef.current = onClose; const dismissLockedRef = useRef(isDismissLocked); dismissLockedRef.current = isDismissLocked; // Captured at first render, before autoFocus moves focus into the dialog. const [previouslyFocused] = useState(() => document.activeElement); useEffect(() => { const dialog = dialogRef.current; if (!dialog) return; if (!dialog.open) { if (typeof dialog.showModal === 'function') dialog.showModal(); else dialog.setAttribute('open', ''); } return () => { if (previouslyFocused instanceof HTMLElement && previouslyFocused.isConnected) { previouslyFocused.focus(); } }; }, [previouslyFocused]); function requestClose(): void { if (!dismissLockedRef.current) onCloseRef.current(); } return ( { event.preventDefault(); requestClose(); }} onKeyDown={(event) => { if (event.key === 'Escape') { event.preventDefault(); requestClose(); } }} onMouseDown={(event) => { if (closeOnBackdrop && event.target === event.currentTarget) requestClose(); }} ref={dialogRef} > {children} ); }