UNPKG

@liveblocks/react-ui

Version:

A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.

89 lines (84 loc) 2.93 kB
"use client"; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var core = require('@liveblocks/core'); var _private = require('@liveblocks/react/_private'); var react = require('react'); var reactDom = require('react-dom'); const PERSIST_NAME = "Persist"; const PersistContext = react.createContext(null); function usePersist() { const persistContext = react.useContext(PersistContext); return core.nn(persistContext, "Persist is missing from the React tree."); } function getChild(children) { const child = Array.isArray(children) ? react.Children.only(children) : children; return react.isValidElement(child) ? child : void 0; } function useAnimationPersist(ref) { const [isPresent, unmount] = usePersist(); const previousAnimationName = react.useRef(null); const unmountAnimationName = react.useRef(null); _private.useLayoutEffect(() => { const element = ref.current; if (!element) { return; } const handleAnimationEnd = (event) => { if (event.animationName === unmountAnimationName.current) { unmount(); } previousAnimationName.current = event.animationName; }; element.addEventListener("animationcancel", handleAnimationEnd); element.addEventListener("animationend", handleAnimationEnd); return () => { element.removeEventListener("animationcancel", handleAnimationEnd); element.removeEventListener("animationend", handleAnimationEnd); }; }, [ref, unmount]); _private.useLayoutEffect(() => { const element = ref.current; let animationFrameId; if (!element) { return; } if (!isPresent) { animationFrameId = requestAnimationFrame(() => { const styles = getComputedStyle(element); unmountAnimationName.current = styles.animationName; if (styles.animationName === "none" || styles.animationName === previousAnimationName.current || styles.display === "none") { unmount(); } }); } return () => { cancelAnimationFrame(animationFrameId); }; }, [isPresent, ref, unmount]); } function Persist({ children }) { const [isPersisting, setPersisting] = react.useState(true); const lastPresentChild = react.useRef(null); const child = getChild(children); const unmount = react.useCallback(() => { reactDom.flushSync(() => setPersisting(false)); }, []); _private.useLayoutEffect(() => { if (child) { setPersisting(true); lastPresentChild.current = child; } }, [child]); return /* @__PURE__ */ jsxRuntime.jsx(PersistContext.Provider, { value: [Boolean(child), unmount], children: child ?? (isPersisting ? lastPresentChild.current : null) }); } if (process.env.NODE_ENV !== "production") { Persist.displayName = PERSIST_NAME; } exports.Persist = Persist; exports.useAnimationPersist = useAnimationPersist; exports.usePersist = usePersist; //# sourceMappingURL=Persist.cjs.map