1import { o as __toESM } from "./chunk-6z4oVpB-.js"; 2import { t as require_react } from "./react-CCT1erMQ.js"; 3import { r as useLayoutEffect2 } from "./dist-9_GVLiOM.js"; 4import { n as useComposedRefs } from "./dist-CuFlg_4O.js"; 5var import_react = /* @__PURE__ */ __toESM(require_react(), 1); 6function useStateMachine(initialState, machine) { 7 return import_react.useReducer((state, event) => { 8 return machine[state][event] ?? state; 9 }, initialState); 10} 11var Presence = (props) => { 12 const { present, children } = props; 13 const presence = usePresence(present); 14 const child = typeof children === "function" ? children({ present: presence.isPresent }) : import_react.Children.only(children); 15 const ref = useComposedRefs(presence.ref, getElementRef(child)); 16 return typeof children === "function" || presence.isPresent ? import_react.cloneElement(child, { ref }) : null; 17}; 18Presence.displayName = "Presence"; 19function usePresence(present) { 20 const [node, setNode] = import_react.useState(); 21 const stylesRef = import_react.useRef(null); 22 const prevPresentRef = import_react.useRef(present); 23 const prevAnimationNameRef = import_react.useRef("none"); 24 const [state, send] = useStateMachine(present ? "mounted" : "unmounted", { 25 mounted: { 26 UNMOUNT: "unmounted", 27 ANIMATION_OUT: "unmountSuspended" 28 }, 29 unmountSuspended: { 30 MOUNT: "mounted", 31 ANIMATION_END: "unmounted" 32 }, 33 unmounted: { MOUNT: "mounted" } 34 }); 35 import_react.useEffect(() => { 36 const currentAnimationName = getAnimationName(stylesRef.current); 37 prevAnimationNameRef.current = state === "mounted" ? currentAnimationName : "none"; 38 }, [state]); 39 useLayoutEffect2(() => { 40 const styles = stylesRef.current; 41 const wasPresent = prevPresentRef.current; 42 if (wasPresent !== present) { 43 const prevAnimationName = prevAnimationNameRef.current; 44 const currentAnimationName = getAnimationName(styles); 45 if (present) send("MOUNT"); 46 else if (currentAnimationName === "none" || styles?.display === "none") send("UNMOUNT"); 47 else if (wasPresent && prevAnimationName !== currentAnimationName) send("ANIMATION_OUT"); 48 else send("UNMOUNT"); 49 prevPresentRef.current = present; 50 } 51 }, [present, send]); 52 useLayoutEffect2(() => { 53 if (node) { 54 let timeoutId; 55 const ownerWindow = node.ownerDocument.defaultView ?? window; 56 const handleAnimationEnd = (event) => { 57 const isCurrentAnimation = getAnimationName(stylesRef.current).includes(CSS.escape(event.animationName)); 58 if (event.target === node && isCurrentAnimation) { 59 send("ANIMATION_END"); 60 if (!prevPresentRef.current) { 61 const currentFillMode = node.style.animationFillMode; 62 node.style.animationFillMode = "forwards"; 63 timeoutId = ownerWindow.setTimeout(() => { 64 if (node.style.animationFillMode === "forwards") node.style.animationFillMode = currentFillMode; 65 }); 66 } 67 } 68 }; 69 const handleAnimationStart = (event) => { 70 if (event.target === node) prevAnimationNameRef.current = getAnimationName(stylesRef.current); 71 }; 72 node.addEventListener("animationstart", handleAnimationStart); 73 node.addEventListener("animationcancel", handleAnimationEnd); 74 node.addEventListener("animationend", handleAnimationEnd); 75 return () => { 76 ownerWindow.clearTimeout(timeoutId); 77 node.removeEventListener("animationstart", handleAnimationStart); 78 node.removeEventListener("animationcancel", handleAnimationEnd); 79 node.removeEventListener("animationend", handleAnimationEnd); 80 }; 81 } else send("ANIMATION_END"); 82 }, [node, send]); 83 return { 84 isPresent: ["mounted", "unmountSuspended"].includes(state), 85 ref: import_react.useCallback((node2) => { 86 stylesRef.current = node2 ? getComputedStyle(node2) : null; 87 setNode(node2); 88 }, []) 89 }; 90} 91function getAnimationName(styles) { 92 return styles?.animationName || "none"; 93} 94function getElementRef(element) { 95 let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get; 96 let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning; 97 if (mayWarn) return element.ref; 98 getter = Object.getOwnPropertyDescriptor(element, "ref")?.get; 99 mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning; 100 if (mayWarn) return element.props.ref; 101 return element.props.ref || element.ref; 102} 103export { Presence as t }; 104 105//# sourceMappingURL=dist-auk7r2og.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.