diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx new file mode 100644 index 0000000..429b3c4 --- /dev/null +++ b/src/components/ui/Modal.tsx @@ -0,0 +1,90 @@ +'use client' + +import { cn } from "@/lib/utils" +import { X } from 'lucide-react' +import React, { useEffect, useRef } from "react" + +interface ModalProps { + isOpen: boolean + onClose: () => void + title?: string + children: React.ReactNode + className?: string +} + +export default function Modal({ + isOpen, + onClose, + title, + children, + className +}: ModalProps) { + const overlayRef = useRef(null) + const contentRef = useRef(null) + + // Close on escape + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + onClose() + } + } + if (isOpen) { + document.addEventListener("keydown", handleKeyDown) + document.body.style.overflow = "hidden" + } + return () => { + document.removeEventListener("keydown", handleKeyDown) + document.body.style.overflow = "" + } + }, [isOpen, onClose]) + + // Focus trap on open + useEffect(() => { + if (isOpen && contentRef.current) { + contentRef.current.focus() + } + }, [isOpen]) + + if (!isOpen) return null + + const handleOverlayClick = (e: React.MouseEvent) => { + if (e.target === overlayRef.current) { + onClose() + } + } + + return ( +
+
+
+ {title && ( +

{title}

+ )} + +
+
{children}
+
+
+ ) +} \ No newline at end of file