Files
Webklar.com/node_modules/cmdk/node_modules/@radix-ui/react-presence/dist/index.mjs
Basilosaurusrex f027651f9b main repo
2025-11-24 18:09:40 +01:00

140 lines
6.4 KiB
JavaScript

import {Children as $iqq3r$Children, cloneElement as $iqq3r$cloneElement, useState as $iqq3r$useState, useRef as $iqq3r$useRef, useEffect as $iqq3r$useEffect, useCallback as $iqq3r$useCallback, useReducer as $iqq3r$useReducer} from "react";
import {flushSync as $iqq3r$flushSync} from "react-dom";
import {useComposedRefs as $iqq3r$useComposedRefs} from "@radix-ui/react-compose-refs";
import {useLayoutEffect as $iqq3r$useLayoutEffect} from "@radix-ui/react-use-layout-effect";
function $fe963b355347cc68$export$3e6543de14f8614f(initialState, machine) {
return $iqq3r$useReducer((state, event)=>{
const nextState = machine[state][event];
return nextState !== null && nextState !== void 0 ? nextState : state;
}, initialState);
}
const $921a889cee6df7e8$export$99c2b779aa4e8b8b = (props)=>{
const { present: present , children: children } = props;
const presence = $921a889cee6df7e8$var$usePresence(present);
const child = typeof children === 'function' ? children({
present: presence.isPresent
}) : $iqq3r$Children.only(children);
const ref = $iqq3r$useComposedRefs(presence.ref, child.ref);
const forceMount = typeof children === 'function';
return forceMount || presence.isPresent ? /*#__PURE__*/ $iqq3r$cloneElement(child, {
ref: ref
}) : null;
};
$921a889cee6df7e8$export$99c2b779aa4e8b8b.displayName = 'Presence';
/* -------------------------------------------------------------------------------------------------
* usePresence
* -----------------------------------------------------------------------------------------------*/ function $921a889cee6df7e8$var$usePresence(present) {
const [node1, setNode] = $iqq3r$useState();
const stylesRef = $iqq3r$useRef({});
const prevPresentRef = $iqq3r$useRef(present);
const prevAnimationNameRef = $iqq3r$useRef('none');
const initialState = present ? 'mounted' : 'unmounted';
const [state, send] = $fe963b355347cc68$export$3e6543de14f8614f(initialState, {
mounted: {
UNMOUNT: 'unmounted',
ANIMATION_OUT: 'unmountSuspended'
},
unmountSuspended: {
MOUNT: 'mounted',
ANIMATION_END: 'unmounted'
},
unmounted: {
MOUNT: 'mounted'
}
});
$iqq3r$useEffect(()=>{
const currentAnimationName = $921a889cee6df7e8$var$getAnimationName(stylesRef.current);
prevAnimationNameRef.current = state === 'mounted' ? currentAnimationName : 'none';
}, [
state
]);
$iqq3r$useLayoutEffect(()=>{
const styles = stylesRef.current;
const wasPresent = prevPresentRef.current;
const hasPresentChanged = wasPresent !== present;
if (hasPresentChanged) {
const prevAnimationName = prevAnimationNameRef.current;
const currentAnimationName = $921a889cee6df7e8$var$getAnimationName(styles);
if (present) send('MOUNT');
else if (currentAnimationName === 'none' || (styles === null || styles === void 0 ? void 0 : styles.display) === 'none') // If there is no exit animation or the element is hidden, animations won't run
// so we unmount instantly
send('UNMOUNT');
else {
/**
* When `present` changes to `false`, we check changes to animation-name to
* determine whether an animation has started. We chose this approach (reading
* computed styles) because there is no `animationrun` event and `animationstart`
* fires after `animation-delay` has expired which would be too late.
*/ const isAnimating = prevAnimationName !== currentAnimationName;
if (wasPresent && isAnimating) send('ANIMATION_OUT');
else send('UNMOUNT');
}
prevPresentRef.current = present;
}
}, [
present,
send
]);
$iqq3r$useLayoutEffect(()=>{
if (node1) {
/**
* Triggering an ANIMATION_OUT during an ANIMATION_IN will fire an `animationcancel`
* event for ANIMATION_IN after we have entered `unmountSuspended` state. So, we
* make sure we only trigger ANIMATION_END for the currently active animation.
*/ const handleAnimationEnd = (event)=>{
const currentAnimationName = $921a889cee6df7e8$var$getAnimationName(stylesRef.current);
const isCurrentAnimation = currentAnimationName.includes(event.animationName);
if (event.target === node1 && isCurrentAnimation) // With React 18 concurrency this update is applied
// a frame after the animation ends, creating a flash of visible content.
// By manually flushing we ensure they sync within a frame, removing the flash.
$iqq3r$flushSync(()=>send('ANIMATION_END')
);
};
const handleAnimationStart = (event)=>{
if (event.target === node1) // if animation occurred, store its name as the previous animation.
prevAnimationNameRef.current = $921a889cee6df7e8$var$getAnimationName(stylesRef.current);
};
node1.addEventListener('animationstart', handleAnimationStart);
node1.addEventListener('animationcancel', handleAnimationEnd);
node1.addEventListener('animationend', handleAnimationEnd);
return ()=>{
node1.removeEventListener('animationstart', handleAnimationStart);
node1.removeEventListener('animationcancel', handleAnimationEnd);
node1.removeEventListener('animationend', handleAnimationEnd);
};
} else // Transition to the unmounted state if the node is removed prematurely.
// We avoid doing so during cleanup as the node may change but still exist.
send('ANIMATION_END');
}, [
node1,
send
]);
return {
isPresent: [
'mounted',
'unmountSuspended'
].includes(state),
ref: $iqq3r$useCallback((node)=>{
if (node) stylesRef.current = getComputedStyle(node);
setNode(node);
}, [])
};
}
/* -----------------------------------------------------------------------------------------------*/ function $921a889cee6df7e8$var$getAnimationName(styles) {
return (styles === null || styles === void 0 ? void 0 : styles.animationName) || 'none';
}
export {$921a889cee6df7e8$export$99c2b779aa4e8b8b as Presence};
//# sourceMappingURL=index.mjs.map