From 78a9857fecf98734e51e46c381062162e17fe581 Mon Sep 17 00:00:00 2001 From: ajvpot <553597+ajvpot@users.noreply.github.com> Date: Sat, 2 Aug 2025 04:35:17 +0200 Subject: [PATCH] fix modal shade --- src/components/Modal.tsx | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/components/Modal.tsx diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx new file mode 100644 index 0000000..2d635fa --- /dev/null +++ b/src/components/Modal.tsx @@ -0,0 +1,67 @@ +"use client"; +import React, { useEffect, useRef } from "react"; + +interface ModalProps { + isOpen: boolean; + onClose: () => void; + title: string; + children: React.ReactNode; + maxWidth?: string; +} + +export default function Modal({ isOpen, onClose, title, children, maxWidth = "500px" }: ModalProps) { + const modalRef = useRef(null); + + useEffect(() => { + const handleEscape = (e: KeyboardEvent) => { + if (e.key === "Escape") { + onClose(); + } + }; + + const handleClickOutside = (e: MouseEvent) => { + if (modalRef.current && !modalRef.current.contains(e.target as Node)) { + onClose(); + } + }; + + if (isOpen) { + document.addEventListener("keydown", handleEscape); + document.addEventListener("mousedown", handleClickOutside); + // Prevent body scroll when modal is open + document.body.style.overflow = "hidden"; + } + + return () => { + document.removeEventListener("keydown", handleEscape); + document.removeEventListener("mousedown", handleClickOutside); + document.body.style.overflow = "unset"; + }; + }, [isOpen, onClose]); + + if (!isOpen) return null; + + return ( +
+
+ + +

{title}

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