'use client'; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { PRESENCE_MOTION_DEFINITION: function() { return PRESENCE_MOTION_DEFINITION; }, createPresenceComponent: function() { return createPresenceComponent; } }); const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); const _reactutilities = require("@fluentui/react-utilities"); const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); const _PresenceGroupChildContext = require("../contexts/PresenceGroupChildContext"); const _useAnimateAtoms = require("../hooks/useAnimateAtoms"); const _useMotionImperativeRef = require("../hooks/useMotionImperativeRef"); const _useMountedState = require("../hooks/useMountedState"); const _useIsReducedMotion = require("../hooks/useIsReducedMotion"); const _useChildElement = require("../utils/useChildElement"); const _MotionBehaviourContext = require("../contexts/MotionBehaviourContext"); const _createMotionComponent = require("./createMotionComponent"); const PRESENCE_MOTION_DEFINITION = Symbol('PRESENCE_MOTION_DEFINITION'); const INTERRUPTABLE_MOTION_SYMBOL = Symbol.for('interruptablePresence'); function createPresenceComponent(value) { return Object.assign((props)=>{ 'use no memo'; const itemContext = _react.useContext(_PresenceGroupChildContext.PresenceGroupChildContext); const merged = { ...itemContext, ...props }; const skipMotions = (0, _MotionBehaviourContext.useMotionBehaviourContext)() === 'skip'; const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, onMotionCancel, visible, unmountOnExit, ..._rest } = merged; const params = _rest; const [mounted, setMounted] = (0, _useMountedState.useMountedState)(visible, unmountOnExit); const [child, childRef] = (0, _useChildElement.useChildElement)(children, mounted); const handleRef = (0, _useMotionImperativeRef.useMotionImperativeRef)(imperativeRef); const optionsRef = _react.useRef({ appear, params, skipMotions }); const animateAtoms = (0, _useAnimateAtoms.useAnimateAtoms)(); const isFirstMount = (0, _reactutilities.useFirstMount)(); const isReducedMotion = (0, _useIsReducedMotion.useIsReducedMotion)(); const handleMotionStart = (0, _reactutilities.useEventCallback)((direction)=>{ onMotionStart === null || onMotionStart === void 0 ? void 0 : onMotionStart(null, { direction }); }); const handleMotionFinish = (0, _reactutilities.useEventCallback)((direction)=>{ onMotionFinish === null || onMotionFinish === void 0 ? void 0 : onMotionFinish(null, { direction }); if (direction === 'exit' && unmountOnExit) { setMounted(false); onExit === null || onExit === void 0 ? void 0 : onExit(); } }); const handleMotionCancel = (0, _reactutilities.useEventCallback)((direction)=>{ onMotionCancel === null || onMotionCancel === void 0 ? void 0 : onMotionCancel(null, { direction }); }); (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{ // Heads up! // We store the params in a ref to avoid re-rendering the component when the params change. optionsRef.current = { appear, params, skipMotions }; }); (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{ const element = childRef.current; if (!element) { return; } let handle; function cleanup() { if (!handle) { return; } // Heads up! // // If the animation is interruptible & is running, we don't want to cancel it as it will be reversed in // the next effect. if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION && handle.isRunning()) { return; } handle.cancel(); handleRef.current = undefined; } const presenceMotion = typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : value; const IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION = presenceMotion[INTERRUPTABLE_MOTION_SYMBOL]; if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION) { handle = handleRef.current; if (handle && handle.isRunning()) { handle.reverse(); return cleanup; } } const atoms = visible ? presenceMotion.enter : presenceMotion.exit; const direction = visible ? 'enter' : 'exit'; // Heads up! // Initial styles are applied when the component is mounted for the first time and "appear" is set to "false" (otherwise animations are triggered) const applyInitialStyles = !optionsRef.current.appear && isFirstMount; const skipAnimationByConfig = optionsRef.current.skipMotions; if (!applyInitialStyles) { handleMotionStart(direction); } handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() }); if (applyInitialStyles) { // Heads up! // .finish() is used in this case to skip animation and apply animation styles immediately handle.finish(); return cleanup; } handleRef.current = handle; handle.setMotionEndCallbacks(()=>handleMotionFinish(direction), ()=>handleMotionCancel(direction)); if (skipAnimationByConfig) { handle.finish(); } return cleanup; }, // Excluding `isFirstMount` from deps to prevent re-triggering the animation on subsequent renders // eslint-disable-next-line react-hooks/exhaustive-deps [ animateAtoms, childRef, handleRef, isReducedMotion, handleMotionFinish, handleMotionStart, handleMotionCancel, visible ]); _react.useEffect(()=>{ // Heads up! // // Dispose the handle when unmounting the component to clean up retained references. Doing it in a separate // effect to ensure that the component is unmounted. if (unmountOnExit && !mounted) { var _handleRef_current; (_handleRef_current = handleRef.current) === null || _handleRef_current === void 0 ? void 0 : _handleRef_current.dispose(); } }, [ handleRef, unmountOnExit, mounted ]); if (mounted) { return child; } return null; }, { // Heads up! // Always normalize it to a function to simplify types [PRESENCE_MOTION_DEFINITION]: typeof value === 'function' ? value : ()=>value }, { // Wrap `enter` in its own motion component as a static method, e.g. In: (0, _createMotionComponent.createMotionComponent)(// If we have a motion function, wrap it to forward the runtime params and pick `enter`. // Otherwise, pass the `enter` motion object directly. typeof value === 'function' ? (...args)=>value(...args).enter : value.enter), // Wrap `exit` in its own motion component as a static method, e.g. Out: (0, _createMotionComponent.createMotionComponent)(// If we have a motion function, wrap it to forward the runtime params and pick `exit`. // Otherwise, pass the `exit` motion object directly. typeof value === 'function' ? (...args)=>value(...args).exit : value.exit) }); }