UNPKG

@carbon/react

Version:

React components for the Carbon Design System

60 lines (58 loc) 1.69 kB
/** * Copyright IBM Corp. 2016, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { usePrefix } from "./usePrefix.js"; import useIsomorphicEffect from "./useIsomorphicEffect.js"; import { useState } from "react"; //#region src/internal/usePresence.ts /** * Copyright IBM Corp. 2025, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const usePresence = (ref, isOpen) => { const prefix = usePrefix(); const [exitState, setExitState] = useState(isOpen ? "idle" : "finished"); const isExiting = exitState === "active"; useIsomorphicEffect(() => { setExitState((prev) => { if (!isOpen && prev === "idle") return "active"; if (isOpen && prev !== "idle") return "idle"; return prev; }); }, [isOpen]); useIsomorphicEffect(() => { if (!ref.current || !isExiting) return; if (!("getAnimations" in ref.current)) { setExitState("finished"); return; } const animations = ref.current.getAnimations({ subtree: true }).filter((animation) => animation instanceof CSSAnimation && animation.animationName.startsWith(`${prefix}--presence`)); if (!animations.length) { setExitState("finished"); return; } let cancelled = false; Promise.all(animations.map((animation) => animation.finished)).finally(() => { if (cancelled) return; setExitState("finished"); }); return () => { cancelled = true; }; }, [ ref, isExiting, prefix ]); return { isPresent: isOpen || exitState !== "finished", isExiting }; }; //#endregion export { usePresence };