index.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. var $fnLeV$react = require("react");
  2. var $fnLeV$reactdom = require("react-dom");
  3. var $fnLeV$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
  4. var $fnLeV$radixuireactuselayouteffect = require("@radix-ui/react-use-layout-effect");
  5. function $parcel$export(e, n, v, s) {
  6. Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
  7. }
  8. $parcel$export(module.exports, "Presence", () => $a2fa0214bb2735a1$export$99c2b779aa4e8b8b);
  9. function $8f63844556d0d3cd$export$3e6543de14f8614f(initialState, machine) {
  10. return $fnLeV$react.useReducer((state, event)=>{
  11. const nextState = machine[state][event];
  12. return nextState !== null && nextState !== void 0 ? nextState : state;
  13. }, initialState);
  14. }
  15. const $a2fa0214bb2735a1$export$99c2b779aa4e8b8b = (props)=>{
  16. const { present: present , children: children } = props;
  17. const presence = $a2fa0214bb2735a1$var$usePresence(present);
  18. const child = typeof children === 'function' ? children({
  19. present: presence.isPresent
  20. }) : $fnLeV$react.Children.only(children);
  21. const ref = $fnLeV$radixuireactcomposerefs.useComposedRefs(presence.ref, child.ref);
  22. const forceMount = typeof children === 'function';
  23. return forceMount || presence.isPresent ? /*#__PURE__*/ $fnLeV$react.cloneElement(child, {
  24. ref: ref
  25. }) : null;
  26. };
  27. $a2fa0214bb2735a1$export$99c2b779aa4e8b8b.displayName = 'Presence';
  28. /* -------------------------------------------------------------------------------------------------
  29. * usePresence
  30. * -----------------------------------------------------------------------------------------------*/ function $a2fa0214bb2735a1$var$usePresence(present) {
  31. const [node1, setNode] = $fnLeV$react.useState();
  32. const stylesRef = $fnLeV$react.useRef({});
  33. const prevPresentRef = $fnLeV$react.useRef(present);
  34. const prevAnimationNameRef = $fnLeV$react.useRef('none');
  35. const initialState = present ? 'mounted' : 'unmounted';
  36. const [state, send] = $8f63844556d0d3cd$export$3e6543de14f8614f(initialState, {
  37. mounted: {
  38. UNMOUNT: 'unmounted',
  39. ANIMATION_OUT: 'unmountSuspended'
  40. },
  41. unmountSuspended: {
  42. MOUNT: 'mounted',
  43. ANIMATION_END: 'unmounted'
  44. },
  45. unmounted: {
  46. MOUNT: 'mounted'
  47. }
  48. });
  49. $fnLeV$react.useEffect(()=>{
  50. const currentAnimationName = $a2fa0214bb2735a1$var$getAnimationName(stylesRef.current);
  51. prevAnimationNameRef.current = state === 'mounted' ? currentAnimationName : 'none';
  52. }, [
  53. state
  54. ]);
  55. $fnLeV$radixuireactuselayouteffect.useLayoutEffect(()=>{
  56. const styles = stylesRef.current;
  57. const wasPresent = prevPresentRef.current;
  58. const hasPresentChanged = wasPresent !== present;
  59. if (hasPresentChanged) {
  60. const prevAnimationName = prevAnimationNameRef.current;
  61. const currentAnimationName = $a2fa0214bb2735a1$var$getAnimationName(styles);
  62. if (present) send('MOUNT');
  63. 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
  64. // so we unmount instantly
  65. send('UNMOUNT');
  66. else {
  67. /**
  68. * When `present` changes to `false`, we check changes to animation-name to
  69. * determine whether an animation has started. We chose this approach (reading
  70. * computed styles) because there is no `animationrun` event and `animationstart`
  71. * fires after `animation-delay` has expired which would be too late.
  72. */ const isAnimating = prevAnimationName !== currentAnimationName;
  73. if (wasPresent && isAnimating) send('ANIMATION_OUT');
  74. else send('UNMOUNT');
  75. }
  76. prevPresentRef.current = present;
  77. }
  78. }, [
  79. present,
  80. send
  81. ]);
  82. $fnLeV$radixuireactuselayouteffect.useLayoutEffect(()=>{
  83. if (node1) {
  84. /**
  85. * Triggering an ANIMATION_OUT during an ANIMATION_IN will fire an `animationcancel`
  86. * event for ANIMATION_IN after we have entered `unmountSuspended` state. So, we
  87. * make sure we only trigger ANIMATION_END for the currently active animation.
  88. */ const handleAnimationEnd = (event)=>{
  89. const currentAnimationName = $a2fa0214bb2735a1$var$getAnimationName(stylesRef.current);
  90. const isCurrentAnimation = currentAnimationName.includes(event.animationName);
  91. if (event.target === node1 && isCurrentAnimation) // With React 18 concurrency this update is applied
  92. // a frame after the animation ends, creating a flash of visible content.
  93. // By manually flushing we ensure they sync within a frame, removing the flash.
  94. $fnLeV$reactdom.flushSync(()=>send('ANIMATION_END')
  95. );
  96. };
  97. const handleAnimationStart = (event)=>{
  98. if (event.target === node1) // if animation occurred, store its name as the previous animation.
  99. prevAnimationNameRef.current = $a2fa0214bb2735a1$var$getAnimationName(stylesRef.current);
  100. };
  101. node1.addEventListener('animationstart', handleAnimationStart);
  102. node1.addEventListener('animationcancel', handleAnimationEnd);
  103. node1.addEventListener('animationend', handleAnimationEnd);
  104. return ()=>{
  105. node1.removeEventListener('animationstart', handleAnimationStart);
  106. node1.removeEventListener('animationcancel', handleAnimationEnd);
  107. node1.removeEventListener('animationend', handleAnimationEnd);
  108. };
  109. } else // Transition to the unmounted state if the node is removed prematurely.
  110. // We avoid doing so during cleanup as the node may change but still exist.
  111. send('ANIMATION_END');
  112. }, [
  113. node1,
  114. send
  115. ]);
  116. return {
  117. isPresent: [
  118. 'mounted',
  119. 'unmountSuspended'
  120. ].includes(state),
  121. ref: $fnLeV$react.useCallback((node)=>{
  122. if (node) stylesRef.current = getComputedStyle(node);
  123. setNode(node);
  124. }, [])
  125. };
  126. }
  127. /* -----------------------------------------------------------------------------------------------*/ function $a2fa0214bb2735a1$var$getAnimationName(styles) {
  128. return (styles === null || styles === void 0 ? void 0 : styles.animationName) || 'none';
  129. }
  130. //# sourceMappingURL=index.js.map