@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
JavaScript
"use client";
;
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