More modal patches and a bug in level that I'm still trying to solve
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import {Dialog, DialogPanel, DialogTitle, Transition, TransitionChild} from "@headlessui/react";
|
||||
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from "@headlessui/react";
|
||||
import clsx from "clsx";
|
||||
import {Fragment, ReactElement} from "react";
|
||||
import { Fragment, ReactElement, useCallback, useEffect, useState } from "react";
|
||||
|
||||
interface Props {
|
||||
isOpen: boolean;
|
||||
@@ -12,10 +12,55 @@ interface Props {
|
||||
children?: ReactElement;
|
||||
}
|
||||
|
||||
export default function Modal({isOpen, maxWidth, title, className, titleClassName, onClose, children}: Props) {
|
||||
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 (
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-[200]" onClose={onClose}>
|
||||
<Transition
|
||||
appear
|
||||
show={isOpen}
|
||||
as={Fragment}
|
||||
beforeEnter={() => setIsClosing(false)}
|
||||
beforeLeave={() => setIsClosing(true)}
|
||||
afterLeave={() => {
|
||||
setIsClosing(false);
|
||||
setMounted(false);
|
||||
}}
|
||||
>
|
||||
<Dialog as="div" className="relative z-[200]" onClose={() => blockMultipleClicksClose()}>
|
||||
<TransitionChild
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
|
||||
Reference in New Issue
Block a user