From fd786ba641201f93cfd190565499f34661f92fa6 Mon Sep 17 00:00:00 2001 From: Vula Builder Date: Fri, 31 Jul 2026 14:12:34 +0000 Subject: [PATCH] Deploy --- src/components/ui/Modal.tsx | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/components/ui/Modal.tsx diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx new file mode 100644 index 0000000..7219f14 --- /dev/null +++ b/src/components/ui/Modal.tsx @@ -0,0 +1,102 @@ +'use client' + +import { cn } from "@/lib/utils" +import { X } from 'lucide-react' +import { ReactNode, useEffect, useId, useRef } from "react" + +interface ModalProps { + open: boolean + onClose: () => void + title?: string + description?: string + children: ReactNode + className?: string + closeOnBackdrop?: boolean +} + +export default function Modal({ + open, + onClose, + title, + description, + children, + className, + closeOnBackdrop = true, +}: ModalProps) { + const panelRef = useRef(null) + const titleId = useId() + const descriptionId = useId() + + useEffect(() => { + if (!open) return + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + onClose() + } + } + + document.addEventListener("keydown", handleKeyDown) + const originalOverflow = document.body.style.overflow + document.body.style.overflow = "hidden" + + return () => { + document.removeEventListener("keydown", handleKeyDown) + document.body.style.overflow = originalOverflow + } + }, [open, onClose]) + + useEffect(() => { + if (open) { + panelRef.current?.focus() + } + }, [open]) + + if (!open) return null + + return ( +
+ + ) +} \ No newline at end of file