"use client"; import { useEffect, useState } from "react"; import { createPortal } from "react-dom"; import { X } from "lucide-react"; import { cn } from "@/lib/utils"; interface ModalProps { open: boolean; title: string; description?: string; onClose: () => void; children: React.ReactNode; footer?: React.ReactNode; width?: "md" | "lg" | "xl"; } /** * Dialog per Portal am body. * * Ohne Portal waere "position: fixed" wirkungslos: Dialoge werden aus Karten * heraus geoeffnet, und deren backdrop-filter erzeugt einen neuen * Bezugsrahmen. Der Dialog wuerde sich dann an der Karte ausrichten statt am * Fenster. */ export function Modal({ open, title, description, onClose, children, footer, width = "lg", }: ModalProps) { const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); useEffect(() => { if (!open) return; const onKey = (event: KeyboardEvent) => { if (event.key === "Escape") onClose(); }; document.addEventListener("keydown", onKey); const previous = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = previous; }; }, [open, onClose]); if (!mounted || !open) return null; return createPortal(
{children} {footer ?
{footer}
: null} , document.body, ); }