import { useEffect, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; import { cIf, cJoin } from "helpers/className"; import { atoms } from "contexts/atoms"; import { useAtomSetter } from "helpers/atoms"; import { Button } from "components/Inputs/Button"; /* * ╭─────────────╮ * ───────────────────────────────────────╯ COMPONENT ╰─────────────────────────────────────────── */ interface Props { onOpen?: () => void; onCloseRequest?: () => void; isVisible: boolean; children: React.ReactNode; fillViewport?: boolean; hideBackground?: boolean; padding?: boolean; withCloseButton?: boolean; } // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const Popup = ({ onOpen, onCloseRequest, isVisible, children, fillViewport, hideBackground = false, padding = true, withCloseButton = true, }: Props): JSX.Element => { const setMenuGesturesEnabled = useAtomSetter(atoms.layout.menuGesturesEnabled); const [isHidden, setHidden] = useState(!isVisible); const [isActuallyVisible, setActuallyVisible] = useState(isVisible && !isHidden); useHotkeys("escape", () => onCloseRequest?.(), { enabled: isVisible }, [onCloseRequest]); useEffect(() => { setMenuGesturesEnabled(!isVisible); }, [isVisible, setMenuGesturesEnabled]); // Used to unload the component if not visible useEffect(() => { const timeouts: NodeJS.Timeout[] = []; if (isVisible) { setHidden(false); // We delay the visiblity of the element so that the opening animation is played timeouts.push( setTimeout(() => { setActuallyVisible(true); onOpen?.(); }, 100) ); } else { setActuallyVisible(false); timeouts.push(setTimeout(() => setHidden(true), 600)); } return () => timeouts.forEach(clearTimeout); }, [isVisible, onOpen]); return isHidden ? ( <>> ) : (