import React, { ReactNode, useEffect } from 'react'; interface ModalProps { open: boolean; onClose: () => void; title: string; children: ReactNode; /** Rendered in the footer (right side). */ footer?: ReactNode; /** * Container width. "md" (default) ~ 520px, "lg" ~ 720px, "xl" ~ 960px. */ size?: 'sm' | 'md' | 'lg' | 'xl'; } const sizeClasses: Record, string> = { sm: 'max-w-md', md: 'max-w-xl', lg: 'max-w-3xl', xl: 'max-w-5xl', }; /** * Lightweight Tailwind modal used by the visibility feature. Provides the * overlay, close-on-Escape, and a consistent header/body/footer slot * structure so every visibility modal looks the same. */ const Modal = ({ open, onClose, title, children, footer, size = 'md', }: ModalProps): JSX.Element | null => { useEffect(() => { if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, [open, onClose]); if (!open) return null; return (
); }; export default Modal;