import React, { useEffect, useRef } from 'react'; import { X } from 'lucide-react'; import { Button } from '@/components/ui/button'; interface CustomDialogProps { isOpen: boolean; onClose: () => void; title: string; description?: string; children: React.ReactNode; size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | 'full'; showCloseButton?: boolean; closeOnOverlayClick?: boolean; className?: string; } const CustomDialog: React.FC = ({ isOpen, onClose, title, description, children, size = 'md', showCloseButton = true, closeOnOverlayClick = true, className = '', }) => { const dialogRef = useRef(null); const titleRef = useRef(null); // Focus management useEffect(() => { if (isOpen) { // Focus the title for screen readers titleRef.current?.focus(); // Trap focus within the dialog const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose(); } if (e.key === 'Tab') { const focusableElements = dialogRef.current?.querySelectorAll( 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' ); if (focusableElements && focusableElements.length > 0) { const firstElement = focusableElements[0] as HTMLElement; const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement; if (e.shiftKey) { if (document.activeElement === firstElement) { e.preventDefault(); lastElement.focus(); } } else { if (document.activeElement === lastElement) { e.preventDefault(); firstElement.focus(); } } } } }; document.addEventListener('keydown', handleKeyDown); // Prevent body scroll document.body.style.overflow = 'hidden'; return () => { document.removeEventListener('keydown', handleKeyDown); document.body.style.overflow = 'unset'; }; } }, [isOpen, onClose]); if (!isOpen) return null; const handleOverlayClick = (e: React.MouseEvent) => { if (closeOnOverlayClick && e.target === e.currentTarget) { onClose(); } }; const getSizeClasses = () => { switch (size) { case 'sm': return 'max-w-sm'; case 'md': return 'max-w-md'; case 'lg': return 'max-w-lg'; case 'xl': return 'max-w-xl'; case '2xl': return 'max-w-2xl'; case '3xl': return 'max-w-3xl'; case '4xl': return 'max-w-4xl'; case '5xl': return 'max-w-5xl'; case '6xl': return 'max-w-6xl'; case '7xl': return 'max-w-7xl w-[95vw]'; case 'full': return 'max-w-full w-full h-full md:max-w-2xl md:w-auto md:h-auto md:mx-4'; default: return 'max-w-md'; } }; return (
{/* Overlay */} ); }; export default CustomDialog;