{"mappings":";;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;AASM,SAAS,0CACd,GAAkC,EAClC,UAAmB,IAAI,EACvB,OAAwD;IAExD,IAAI,CAAC,YAAY,YAAY,GAAG,CAAA,GAAA,qBAAO,EAAE;IACzC,IAAI,mBAAmB,cAAc;IAErC,4FAA4F;IAC5F,8FAA8F;IAC9F,6FAA6F;IAC7F,CAAA,GAAA,yCAAc,EAAE;QACd,IAAI,CAAC,WAAW,IAAI,OAAO,EACzB,OAAO,CAAA,GAAA,+BAAI,EACT,CAAA,GAAA,kCAAO,EAAE,IAAI,OAAO,EAAE,WAAW,MACjC,CAAA,GAAA,kCAAO,EAAE,IAAI,OAAO,EAAE,QAAQ,kBAC9B,CAAA,GAAA,kCAAO,EAAE,IAAI,OAAO,EAAE,aAAa,eACnC,CAAA,GAAA,kCAAO,EAAE,IAAI,OAAO,EAAE,cAAc;IAG1C,GAAG;QAAC;QAAK;KAAQ;IAEjB,4CAA4C;IAC5C,kIAAkI;IAClI,4IAA4I;IAC5I,EAAE;IACF,mJAAmJ;IACnJ,+FAA+F;IAC/F,CAAA,GAAA,yCAAc,EAAE;QACd,IAAI,oBAAoB,IAAI,OAAO,IAAI,mBAAmB,IAAI,OAAO,EAAE;YACrE,KAAK,IAAI,aAAa,IAAI,OAAO,CAAC,aAAa,GAC7C,IAAI,qBAAqB,eACvB,UAAU,MAAM;QAGtB;IACF,GAAG;QAAC;QAAK;KAAiB;IAE1B,mCACE,KACA,kBACA,SACA,CAAA,GAAA,wBAAU,EAAE,IAAM,YAAY,QAAQ,EAAE;IAE1C,OAAO;AACT;AAEO,SAAS,0CACd,GAAkC,EAClC,MAAe,EACf,MAAuD;IAEvD,IAAI,CAAC,WAAW,aAAa,GAAG,CAAA,GAAA,qBAAO,EACrC,SAAS,SAAS;IAGpB,OAAQ;QACN,KAAK;YACH,qDAAqD;YACrD,IAAI,CAAC,QACH,aAAa;YAEf;QACF,KAAK;QACL,KAAK;YACH,4EAA4E;YAC5E,2BAA2B;YAC3B,IAAI,QACF,aAAa;YAEf;IACJ;IAEA,IAAI,YAAY,cAAc;IAC9B,mCACE,KACA,WACA,QACA,CAAA,GAAA,wBAAU,EAAE;QACV,yEAAyE;QACzE,aAAa,CAAA,QAAU,UAAU,YAAY,WAAW;IAC1D,GAAG,EAAE;IAGP,OAAO;AACT;AAEA,SAAS,mCACP,GAAkC,EAClC,QAAiB,EACjB,OAAqE,EACrE,KAAiB;IAEjB,IAAI,cAAc,CAAA,GAAA,mBAAK,EAAkB;IACzC,IAAI,QAAQ,CAAA,GAAA,wCAAa,EAAE;IAC3B,CAAA,GAAA,yCAAc,EAAE;QACd,IAAI,YAAY,IAAI,OAAO,IAAI,YAAY,OAAO,KAAK,UAAU;YAC/D,YAAY,OAAO,GAAG;YACtB,IAAI,CAAE,CAAA,mBAAmB,IAAI,OAAO,AAAD,GAAI;gBACrC,QAAQ;gBACR;gBACA;YACF;YAEA,IAAI,eAAe,QAAQ,IAAI,OAAO;YAEtC,IAAI,aAAa,IAAI,OAAO,CACzB,aAAa,GACb,MAAM,CACL,CAAA,IACE,AAAC,CAAA,OAAO,qBAAqB,eAAe,EAAE,QAAQ,YAAY,gBAAe,KACjF,EAAE,SAAS,KAAK;YAEtB,IAAI,WAAW,MAAM,KAAK,KAAK,CAAC,cAAc;gBAC5C;gBACA;YACF;YAEA,QAAQ,GAAG,CAAC;gBAAC;mBAAiB,WAAW,GAAG,CAAC,CAAA,IAAK,EAAE,QAAQ;aAAE,EAC3D,IAAI,CAAC;gBACJ,CAAA,GAAA,yBAAQ,EAAE;oBACR;gBACF;YACF,GACC,KAAK,CAAC,KAAO;QAClB;QAEA,YAAY,OAAO,GAAG;IACxB,GAAG;QAAC;QAAK;QAAU;KAAM;AAC3B","sources":["packages/react-aria/src/utils/animation.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {chain} from './chain';\nimport {flushSync} from 'react-dom';\nimport {RefObject, useCallback, useRef, useState} from 'react';\nimport {setStyle} from './domHelpers';\nimport {useEffectEvent} from './useEffectEvent';\nimport {useLayoutEffect} from './useLayoutEffect';\n\nexport function useEnterAnimation(\n  ref: RefObject<HTMLElement | null>,\n  isReady: boolean = true,\n  onEnter?: (element: HTMLElement) => void | Promise<void>\n): boolean {\n  let [isEntering, setEntering] = useState(true);\n  let isAnimationReady = isEntering && isReady;\n\n  // Hide the element while it prepares for entry, using only non-layout-thrashing attributes.\n  // This prevents accidental flashes of content in scenarios where no hidden styling is applied\n  // while the enter animation is not yet ready (e.g. popovers prior to placement calculation).\n  useLayoutEffect(() => {\n    if (!isReady && ref.current) {\n      return chain(\n        setStyle(ref.current, 'opacity', '0'),\n        setStyle(ref.current, 'clip', 'rect(0 0 0 0)'),\n        setStyle(ref.current, 'clip-path', 'inset(50%)'),\n        setStyle(ref.current, 'mask-image', 'linear-gradient(#0000, #0000)')\n      );\n    }\n  }, [ref, isReady]);\n\n  // There are two cases for entry animations:\n  // 1. CSS @keyframes. The `animation` property is set during the isEntering state, and it is removed after the animation finishes.\n  // 2. CSS transitions. The initial styles are applied during the isEntering state, and removed immediately, causing the transition to occur.\n  //\n  // In the second case, cancel any transitions that were triggered prior to the isEntering = false state (when the transition is supposed to start).\n  // This can happen when isReady starts as false (e.g. popovers prior to placement calculation).\n  useLayoutEffect(() => {\n    if (isAnimationReady && ref.current && 'getAnimations' in ref.current) {\n      for (let animation of ref.current.getAnimations()) {\n        if (animation instanceof CSSTransition) {\n          animation.cancel();\n        }\n      }\n    }\n  }, [ref, isAnimationReady]);\n\n  useAnimation(\n    ref,\n    isAnimationReady,\n    onEnter,\n    useCallback(() => setEntering(false), [])\n  );\n  return isAnimationReady;\n}\n\nexport function useExitAnimation(\n  ref: RefObject<HTMLElement | null>,\n  isOpen: boolean,\n  onExit?: (element: HTMLElement) => void | Promise<void>\n): boolean {\n  let [exitState, setExitState] = useState<'closed' | 'open' | 'exiting'>(\n    isOpen ? 'open' : 'closed'\n  );\n\n  switch (exitState) {\n    case 'open':\n      // If isOpen becomes false, set the state to exiting.\n      if (!isOpen) {\n        setExitState('exiting');\n      }\n      break;\n    case 'closed':\n    case 'exiting':\n      // If we are exiting and isOpen becomes true, the animation was interrupted.\n      // Reset the state to open.\n      if (isOpen) {\n        setExitState('open');\n      }\n      break;\n  }\n\n  let isExiting = exitState === 'exiting';\n  useAnimation(\n    ref,\n    isExiting,\n    onExit,\n    useCallback(() => {\n      // Set the state to closed, which will cause the element to be unmounted.\n      setExitState(state => (state === 'exiting' ? 'closed' : state));\n    }, [])\n  );\n\n  return isExiting;\n}\n\nfunction useAnimation(\n  ref: RefObject<HTMLElement | null>,\n  isActive: boolean,\n  onStart: ((element: HTMLElement) => void | Promise<void>) | undefined,\n  onEnd: () => void\n): void {\n  let isActiveRef = useRef<boolean | null>(null);\n  let start = useEffectEvent(onStart);\n  useLayoutEffect(() => {\n    if (isActive && ref.current && isActiveRef.current !== isActive) {\n      isActiveRef.current = isActive;\n      if (!('getAnimations' in ref.current)) {\n        // JSDOM\n        onEnd();\n        return;\n      }\n\n      let startPromise = start?.(ref.current);\n\n      let animations = ref.current\n        .getAnimations()\n        .filter(\n          a =>\n            (typeof DocumentTimeline === 'undefined' || a.timeline instanceof DocumentTimeline) &&\n            a.playState === 'running'\n        );\n      if (animations.length === 0 && !startPromise) {\n        onEnd();\n        return;\n      }\n\n      Promise.all([startPromise, ...animations.map(a => a.finished)])\n        .then(() => {\n          flushSync(() => {\n            onEnd();\n          });\n        })\n        .catch(() => {});\n    }\n\n    isActiveRef.current = isActive;\n  }, [ref, isActive, onEnd]);\n}\n"],"names":[],"version":3,"file":"animation.cjs.map"}