144 lines
6.5 KiB
JavaScript
144 lines
6.5 KiB
JavaScript
var $fnLeV$react = require("react");
|
|
var $fnLeV$reactdom = require("react-dom");
|
|
var $fnLeV$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
|
|
var $fnLeV$radixuireactuselayouteffect = require("@radix-ui/react-use-layout-effect");
|
|
|
|
function $parcel$export(e, n, v, s) {
|
|
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
}
|
|
|
|
$parcel$export(module.exports, "Presence", () => $a2fa0214bb2735a1$export$99c2b779aa4e8b8b);
|
|
|
|
|
|
|
|
|
|
|
|
function $8f63844556d0d3cd$export$3e6543de14f8614f(initialState, machine) {
|
|
return $fnLeV$react.useReducer((state, event)=>{
|
|
const nextState = machine[state][event];
|
|
return nextState !== null && nextState !== void 0 ? nextState : state;
|
|
}, initialState);
|
|
}
|
|
|
|
|
|
const $a2fa0214bb2735a1$export$99c2b779aa4e8b8b = (props)=>{
|
|
const { present: present , children: children } = props;
|
|
const presence = $a2fa0214bb2735a1$var$usePresence(present);
|
|
const child = typeof children === 'function' ? children({
|
|
present: presence.isPresent
|
|
}) : $fnLeV$react.Children.only(children);
|
|
const ref = $fnLeV$radixuireactcomposerefs.useComposedRefs(presence.ref, child.ref);
|
|
const forceMount = typeof children === 'function';
|
|
return forceMount || presence.isPresent ? /*#__PURE__*/ $fnLeV$react.cloneElement(child, {
|
|
ref: ref
|
|
}) : null;
|
|
};
|
|
$a2fa0214bb2735a1$export$99c2b779aa4e8b8b.displayName = 'Presence';
|
|
/* -------------------------------------------------------------------------------------------------
|
|
* usePresence
|
|
* -----------------------------------------------------------------------------------------------*/ function $a2fa0214bb2735a1$var$usePresence(present) {
|
|
const [node1, setNode] = $fnLeV$react.useState();
|
|
const stylesRef = $fnLeV$react.useRef({});
|
|
const prevPresentRef = $fnLeV$react.useRef(present);
|
|
const prevAnimationNameRef = $fnLeV$react.useRef('none');
|
|
const initialState = present ? 'mounted' : 'unmounted';
|
|
const [state, send] = $8f63844556d0d3cd$export$3e6543de14f8614f(initialState, {
|
|
mounted: {
|
|
UNMOUNT: 'unmounted',
|
|
ANIMATION_OUT: 'unmountSuspended'
|
|
},
|
|
unmountSuspended: {
|
|
MOUNT: 'mounted',
|
|
ANIMATION_END: 'unmounted'
|
|
},
|
|
unmounted: {
|
|
MOUNT: 'mounted'
|
|
}
|
|
});
|
|
$fnLeV$react.useEffect(()=>{
|
|
const currentAnimationName = $a2fa0214bb2735a1$var$getAnimationName(stylesRef.current);
|
|
prevAnimationNameRef.current = state === 'mounted' ? currentAnimationName : 'none';
|
|
}, [
|
|
state
|
|
]);
|
|
$fnLeV$radixuireactuselayouteffect.useLayoutEffect(()=>{
|
|
const styles = stylesRef.current;
|
|
const wasPresent = prevPresentRef.current;
|
|
const hasPresentChanged = wasPresent !== present;
|
|
if (hasPresentChanged) {
|
|
const prevAnimationName = prevAnimationNameRef.current;
|
|
const currentAnimationName = $a2fa0214bb2735a1$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
|
|
]);
|
|
$fnLeV$radixuireactuselayouteffect.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 = $a2fa0214bb2735a1$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.
|
|
$fnLeV$reactdom.flushSync(()=>send('ANIMATION_END')
|
|
);
|
|
};
|
|
const handleAnimationStart = (event)=>{
|
|
if (event.target === node1) // if animation occurred, store its name as the previous animation.
|
|
prevAnimationNameRef.current = $a2fa0214bb2735a1$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: $fnLeV$react.useCallback((node)=>{
|
|
if (node) stylesRef.current = getComputedStyle(node);
|
|
setNode(node);
|
|
}, [])
|
|
};
|
|
}
|
|
/* -----------------------------------------------------------------------------------------------*/ function $a2fa0214bb2735a1$var$getAnimationName(styles) {
|
|
return (styles === null || styles === void 0 ? void 0 : styles.animationName) || 'none';
|
|
}
|
|
|
|
|
|
|
|
|
|
//# sourceMappingURL=index.js.map
|