// src/components/ui/Modal.tsx import React, { ReactNode, useEffect } from "react"; import { FaTimes } from "react-icons/fa"; interface ModalProps { isOpen: boolean; onClose: () => void; title?: string; children: ReactNode; size?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl"; // Optional size control } const Modal: React.FC = ({ isOpen, onClose, title, children, size = "2xl", // Default size }) => { // Close modal on Escape key press useEffect(() => { const handleEscape = (event: KeyboardEvent) => { if (event.key === "Escape") { onClose(); } }; if (isOpen) { document.addEventListener("keydown", handleEscape); } // Cleanup listener on component unmount or when modal closes return () => { document.removeEventListener("keydown", handleEscape); }; }, [isOpen, onClose]); // Prevent scrolling on the body when the modal is open useEffect(() => { if (isOpen) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = "auto"; } // Cleanup overflow style on component unmount return () => { document.body.style.overflow = "auto"; }; }, [isOpen]); if (!isOpen) return null; // Map size prop to Tailwind max-width classes const sizeClasses = { sm: "max-w-sm", md: "max-w-md", lg: "max-w-lg", xl: "max-w-xl", "2xl": "max-w-2xl", "3xl": "max-w-3xl", "4xl": "max-w-4xl", "5xl": "max-w-5xl", }; return ( // Backdrop
{/* Modal Panel */}
e.stopPropagation()} // Prevent clicks inside the modal from closing it > {/* Modal Header (Optional) */} {title && (
{title && ( )}
)} {/* Modal Body */}
{" "} {/* Added max-height and scroll */} {children}
{/* Add animation keyframes to your global CSS (e.g., src/app/globals.css) */}
); }; export default Modal;