/** * @deprecated S1.4: Prefer using `Dialog` from `@/components/ui/dialog/` for new code. * This modal component is kept for backward compatibility with existing consumers. */ import { useEffect, useId, useRef } from 'react'; import { createPortal } from 'react-dom'; import { motion, AnimatePresence } from 'framer-motion'; import { FocusTrap } from './focus-trap'; import { X } from 'lucide-react'; import { Button } from './button'; import { cn } from '@/lib/utils'; export interface ModalProps { open: boolean; onClose: () => void; children: React.ReactNode; title?: string; closeOnOverlayClick?: boolean; closeOnEscape?: boolean; size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'; className?: string; footer?: React.ReactNode; } const sizeClasses = { sm: 'max-w-sm', md: 'max-w-md', lg: 'max-w-2xl', xl: 'max-w-4xl', full: 'max-w-full m-4 h-layout-modal-full', }; /** * Composant Modal avec design SUMI */ export function Modal({ open, onClose, children, title, closeOnOverlayClick = true, closeOnEscape = true, size = 'md', className, footer, }: ModalProps) { const modalRef = useRef(null); const titleId = useId(); // EmpĂȘcher le scroll du body quand le modal est ouvert useEffect(() => { if (open) { document.body.style.overflow = 'hidden'; return () => { document.body.style.overflow = ''; }; } return undefined; }, [open]); // Gestion de la touche Escape useEffect(() => { if (!closeOnEscape || !open) return; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose(); } }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [open, closeOnEscape, onClose]); const handleOverlayClick = (e: React.MouseEvent) => { if (closeOnOverlayClick && e.target === e.currentTarget) { onClose(); } }; return createPortal( {open && ( {/* Backdrop */} {/* Modal Content */} e.stopPropagation()} > {/* Header */} {title && (

{title}

)} {/* Body */}
{children}
{/* Footer */} {footer && (
{footer}
)}
)}
, document.body, ); }