import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from "@headlessui/react"; import clsx from "clsx"; import { Fragment, ReactElement, useCallback, useEffect, useState } from "react"; interface Props { isOpen: boolean; onClose: () => void; maxWidth?: string; title?: string; className?: string; titleClassName?: string; children?: ReactElement; } export default function Modal({ isOpen, maxWidth, title, className, titleClassName, onClose, children }: Props) { const [isClosing, setIsClosing] = useState(false); const [mounted, setMounted] = useState(false); useEffect(() => { if (isOpen) { setMounted(true); } }, [isOpen]); useEffect(() => { if (!isOpen && mounted) { const timer = setTimeout(() => { setMounted(false); setIsClosing(false); }, 300); return () => clearTimeout(timer); } }, [isOpen, mounted]); const blockMultipleClicksClose = useCallback(() => { if (isClosing) return; setIsClosing(true); onClose(); const timer = setTimeout(() => { setIsClosing(false); }, 300); return () => clearTimeout(timer); }, [isClosing, onClose]); if (!mounted && !isOpen) return null; return ( setIsClosing(false)} beforeLeave={() => setIsClosing(true)} afterLeave={() => { setIsClosing(false); setMounted(false); }} > blockMultipleClicksClose()}>
{title && ( {title} )} {children}
); }