import { X } from 'lucide-react'; import { ReactNode, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { Box } from '@/ui/Box'; import { Button } from '@/ui/Button'; import { Heading } from '@/ui/Heading'; import { IconButton } from '@/ui/IconButton'; import { Surface } from '@/ui/Surface'; import { Text } from '@/ui/Text'; export interface ModalProps { children: ReactNode; isOpen: boolean; onClose?: () => void; onOpenChange?: (isOpen: boolean) => void; title?: string; size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'; primaryActionLabel?: string; onPrimaryAction?: () => void; secondaryActionLabel?: string; onSecondaryAction?: () => void; footer?: ReactNode; description?: string; icon?: ReactNode; actions?: ReactNode; } export const Modal = ({ children, isOpen, onClose, onOpenChange, title, size = 'md', primaryActionLabel, onPrimaryAction, secondaryActionLabel, onSecondaryAction, footer, description, icon, actions }: ModalProps) => { useEffect(() => { if (isOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = 'unset'; } return () => { document.body.style.overflow = 'unset'; }; }, [isOpen]); if (!isOpen) return null; const sizeMap = { sm: '24rem', md: '32rem', lg: '48rem', xl: '64rem', full: '100%', }; const handleClose = () => { if (onClose) onClose(); if (onOpenChange) onOpenChange(false); }; return createPortal( {icon} {title && {title}} {description && {description}} {actions} {children} {(footer || primaryActionLabel || secondaryActionLabel) && ( {footer} {secondaryActionLabel && ( )} {primaryActionLabel && ( )} )} , document.body ); };