Properly unload popups when not displayed

This commit is contained in:
DrMint 2023-05-02 22:46:37 +02:00
parent 4f78b4f006
commit b9c7c0828a
1 changed files with 23 additions and 5 deletions

View File

@ -1,4 +1,4 @@
import { useEffect } from "react"; import { useEffect, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook"; import { useHotkeys } from "react-hotkeys-hook";
import { cIf, cJoin } from "helpers/className"; import { cIf, cJoin } from "helpers/className";
import { atoms } from "contexts/atoms"; import { atoms } from "contexts/atoms";
@ -32,6 +32,8 @@ export const Popup = ({
withCloseButton = true, withCloseButton = true,
}: Props): JSX.Element => { }: Props): JSX.Element => {
const setMenuGesturesEnabled = useAtomSetter(atoms.layout.menuGesturesEnabled); const setMenuGesturesEnabled = useAtomSetter(atoms.layout.menuGesturesEnabled);
const [isHidden, setHidden] = useState(!isVisible);
const [isActuallyVisible, setActuallyVisible] = useState(isVisible && !isHidden);
useHotkeys("escape", () => onCloseRequest?.(), { enabled: isVisible }, [onCloseRequest]); useHotkeys("escape", () => onCloseRequest?.(), { enabled: isVisible }, [onCloseRequest]);
@ -39,16 +41,32 @@ export const Popup = ({
setMenuGesturesEnabled(!isVisible); setMenuGesturesEnabled(!isVisible);
}, [isVisible, setMenuGesturesEnabled]); }, [isVisible, setMenuGesturesEnabled]);
return ( // 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), 100));
} else {
setActuallyVisible(false);
timeouts.push(setTimeout(() => setHidden(true), 600));
}
return () => timeouts.forEach(clearTimeout);
}, [isVisible]);
return isHidden ? (
<></>
) : (
<div <div
className={cJoin( className={cJoin(
"fixed inset-0 z-50 grid place-content-center transition-filter duration-500", "fixed inset-0 z-50 grid place-content-center transition-filter duration-500",
cIf(isVisible, "backdrop-blur", "pointer-events-none touch-none") cIf(isActuallyVisible, "backdrop-blur", "pointer-events-none touch-none")
)}> )}>
<div <div
className={cJoin( className={cJoin(
"fixed inset-0 transition-colors duration-500", "fixed inset-0 transition-colors duration-500",
cIf(isVisible, "bg-shade/50", "bg-shade/0") cIf(isActuallyVisible, "bg-shade/50", "bg-shade/0")
)} )}
onClick={onCloseRequest} onClick={onCloseRequest}
/> />
@ -57,7 +75,7 @@ export const Popup = ({
className={cJoin( className={cJoin(
"grid place-items-center gap-4 transition-transform", "grid place-items-center gap-4 transition-transform",
cIf(padding, "p-10"), cIf(padding, "p-10"),
cIf(isVisible, "scale-100", "scale-0"), cIf(isActuallyVisible, "scale-100", "scale-0"),
cIf( cIf(
fillViewport, fillViewport,
"absolute inset-10 content-start overflow-scroll", "absolute inset-10 content-start overflow-scroll",