@fluentui/react-motion 9.1.0 → 9.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,33 @@
1
1
  # Change Log - @fluentui/react-motion
2
2
 
3
- This log was last generated on Wed, 12 Jun 2024 13:16:08 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 01 Jul 2024 20:25:35 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.2.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.2.1)
8
+
9
+ Mon, 01 Jul 2024 20:25:35 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.2.0..@fluentui/react-motion_v9.2.1)
11
+
12
+ ### Patches
13
+
14
+ - chore: add eslint react-compiler ([PR #31457](https://github.com/microsoft/fluentui/pull/31457) by seanmonahan@microsoft.com)
15
+ - fix: improve Jest compat ([PR #31715](https://github.com/microsoft/fluentui/pull/31715) by olfedias@microsoft.com)
16
+ - chore: adds 'use no memo' directive ([PR #31787](https://github.com/microsoft/fluentui/pull/31787) by seanmonahan@microsoft.com)
17
+ - Bump @fluentui/react-utilities to v9.18.11 ([PR #31861](https://github.com/microsoft/fluentui/pull/31861) by beachball)
18
+
19
+ ## [9.2.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.2.0)
20
+
21
+ Mon, 17 Jun 2024 07:34:16 GMT
22
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.1.0..@fluentui/react-motion_v9.2.0)
23
+
24
+ ### Minor changes
25
+
26
+ - feat: Implement `onMotionCancel` callback handler ([PR #31698](https://github.com/microsoft/fluentui/pull/31698) by lingfangao@hotmail.com)
27
+
7
28
  ## [9.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.1.0)
8
29
 
9
- Wed, 12 Jun 2024 13:16:08 GMT
30
+ Wed, 12 Jun 2024 13:17:19 GMT
10
31
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.0.0..@fluentui/react-motion_v9.1.0)
11
32
 
12
33
  ### Minor changes
package/dist/index.d.ts CHANGED
@@ -51,6 +51,13 @@ export declare type MotionComponentProps = {
51
51
  * triggered once all animations have finished with "null" instead of an event object to avoid ambiguity.
52
52
  */
53
53
  onMotionFinish?: (ev: null) => void;
54
+ /**
55
+ * Callback that is called when the whole motion is cancelled.
56
+ *
57
+ * A motion definition can contain multiple animations and therefore multiple "cancel" events. The callback is
58
+ * triggered once all animations have been cancelled with "null" instead of an event object to avoid ambiguity.
59
+ */
60
+ onMotionCancel?: (ev: null) => void;
54
61
  /**
55
62
  * Callback that is called when the whole motion starts.
56
63
  *
@@ -115,6 +122,16 @@ export declare type PresenceComponentProps = {
115
122
  onMotionFinish?: (ev: null, data: {
116
123
  direction: 'enter' | 'exit';
117
124
  }) => void;
125
+ /**
126
+ * Callback that is called when the whole motion is cancelled. When a motion is cancelled it does not
127
+ * emit a finish event but a specific cancel event
128
+ *
129
+ * A motion definition can contain multiple animations and therefore multiple "finish" events. The callback is
130
+ * triggered once all animations have finished with "null" instead of an event object to avoid ambiguity.
131
+ */
132
+ onMotionCancel?: (ev: null, data: {
133
+ direction: 'enter' | 'exit';
134
+ }) => void;
118
135
  /**
119
136
  * Callback that is called when the whole motion starts.
120
137
  *
@@ -1,8 +1,8 @@
1
1
  import { useEventCallback, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';
2
2
  import * as React from 'react';
3
- import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
3
+ import { useAnimateAtoms } from '../hooks/useAnimateAtoms';
4
4
  import { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';
5
- import { animateAtoms } from '../utils/animateAtoms';
5
+ import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
6
6
  import { getChildElement } from '../utils/getChildElement';
7
7
  /**
8
8
  * Creates a component that will animate the children using the provided motion.
@@ -10,12 +10,14 @@ import { getChildElement } from '../utils/getChildElement';
10
10
  * @param value - A motion definition.
11
11
  */ export function createMotionComponent(value) {
12
12
  const Atom = (props)=>{
13
- const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, ..._rest } = props;
13
+ 'use no memo';
14
+ const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, onMotionCancel: onMotionCancelProp, ..._rest } = props;
14
15
  const params = _rest;
15
16
  const child = getChildElement(children);
16
17
  const handleRef = useMotionImperativeRef(imperativeRef);
17
18
  const elementRef = React.useRef();
18
19
  const paramsRef = React.useRef(params);
20
+ const animateAtoms = useAnimateAtoms();
19
21
  const isReducedMotion = useIsReducedMotion();
20
22
  const onMotionStart = useEventCallback(()=>{
21
23
  onMotionStartProp === null || onMotionStartProp === void 0 ? void 0 : onMotionStartProp(null);
@@ -23,6 +25,9 @@ import { getChildElement } from '../utils/getChildElement';
23
25
  const onMotionFinish = useEventCallback(()=>{
24
26
  onMotionFinishProp === null || onMotionFinishProp === void 0 ? void 0 : onMotionFinishProp(null);
25
27
  });
28
+ const onMotionCancel = useEventCallback(()=>{
29
+ onMotionCancelProp === null || onMotionCancelProp === void 0 ? void 0 : onMotionCancelProp(null);
30
+ });
26
31
  useIsomorphicLayoutEffect(()=>{
27
32
  // Heads up!
28
33
  // We store the params in a ref to avoid re-rendering the component when the params change.
@@ -39,17 +44,19 @@ import { getChildElement } from '../utils/getChildElement';
39
44
  const handle = animateAtoms(element, atoms, {
40
45
  isReducedMotion: isReducedMotion()
41
46
  });
42
- handle.onfinish = onMotionFinish;
47
+ handle.setMotionEndCallbacks(onMotionFinish, onMotionCancel);
43
48
  handleRef.current = handle;
44
49
  return ()=>{
45
50
  handle.cancel();
46
51
  };
47
52
  }
48
53
  }, [
54
+ animateAtoms,
49
55
  handleRef,
50
56
  isReducedMotion,
51
57
  onMotionFinish,
52
- onMotionStart
58
+ onMotionStart,
59
+ onMotionCancel
53
60
  ]);
54
61
  return React.cloneElement(children, {
55
62
  ref: useMergedRefs(elementRef, child.ref)
@@ -1 +1 @@
1
- {"version":3,"sources":["createMotionComponent.ts"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { animateAtoms } from '../utils/animateAtoms';\nimport { getChildElement } from '../utils/getChildElement';\nimport type { AtomMotion, AtomMotionFn, MotionParam, MotionImperativeRef } from '../types';\n\nexport type MotionComponentProps = {\n children: React.ReactElement;\n\n /** Provides imperative controls for the animation. */\n imperativeRef?: React.Ref<MotionImperativeRef | undefined>;\n\n /**\n * Callback that is called when the whole motion finishes.\n *\n * A motion definition can contain multiple animations and therefore multiple \"finish\" events. The callback is\n * triggered once all animations have finished with \"null\" instead of an event object to avoid ambiguity.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionFinish?: (ev: null) => void;\n\n /**\n * Callback that is called when the whole motion starts.\n *\n * A motion definition can contain multiple animations and therefore multiple \"start\" events. The callback is\n * triggered when the first animation is started. There is no official \"start\" event with the Web Animations API.\n * so the callback is triggered with \"null\".\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionStart?: (ev: null) => void;\n};\n\n/**\n * Creates a component that will animate the children using the provided motion.\n *\n * @param value - A motion definition.\n */\nexport function createMotionComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: AtomMotion | AtomMotion[] | AtomMotionFn<MotionParams>,\n) {\n const Atom: React.FC<MotionComponentProps & MotionParams> = props => {\n const {\n children,\n imperativeRef,\n onMotionFinish: onMotionFinishProp,\n onMotionStart: onMotionStartProp,\n ..._rest\n } = props;\n const params = _rest as Exclude<typeof props, MotionComponentProps>;\n const child = getChildElement(children);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef<HTMLElement>();\n const paramsRef = React.useRef<MotionParams>(params);\n\n const isReducedMotion = useIsReducedMotion();\n\n const onMotionStart = useEventCallback(() => {\n onMotionStartProp?.(null);\n });\n\n const onMotionFinish = useEventCallback(() => {\n onMotionFinishProp?.(null);\n });\n\n useIsomorphicLayoutEffect(() => {\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n paramsRef.current = params;\n });\n\n useIsomorphicLayoutEffect(() => {\n const element = elementRef.current;\n\n if (element) {\n const atoms = typeof value === 'function' ? value({ element, ...paramsRef.current }) : value;\n onMotionStart();\n\n const handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n handle.onfinish = onMotionFinish;\n handleRef.current = handle;\n\n return () => {\n handle.cancel();\n };\n }\n }, [handleRef, isReducedMotion, onMotionFinish, onMotionStart]);\n\n return React.cloneElement(children, { ref: useMergedRefs(elementRef, child.ref) });\n };\n\n return Atom;\n}\n"],"names":["useEventCallback","useIsomorphicLayoutEffect","useMergedRefs","React","useIsReducedMotion","useMotionImperativeRef","animateAtoms","getChildElement","createMotionComponent","value","Atom","props","children","imperativeRef","onMotionFinish","onMotionFinishProp","onMotionStart","onMotionStartProp","_rest","params","child","handleRef","elementRef","useRef","paramsRef","isReducedMotion","current","element","atoms","handle","onfinish","cancel","cloneElement","ref"],"mappings":"AAAA,SAASA,gBAAgB,EAAEC,yBAAyB,EAAEC,aAAa,QAAQ,4BAA4B;AACvG,YAAYC,WAAW,QAAQ;AAE/B,SAASC,kBAAkB,QAAQ,8BAA8B;AACjE,SAASC,sBAAsB,QAAQ,kCAAkC;AACzE,SAASC,YAAY,QAAQ,wBAAwB;AACrD,SAASC,eAAe,QAAQ,2BAA2B;AA6B3D;;;;CAIC,GACD,OAAO,SAASC,sBACdC,KAA6D;IAE7D,MAAMC,OAAsDC,CAAAA;QAC1D,MAAM,EACJC,QAAQ,EACRC,aAAa,EACbC,gBAAgBC,kBAAkB,EAClCC,eAAeC,iBAAiB,EAChC,GAAGC,OACJ,GAAGP;QACJ,MAAMQ,SAASD;QACf,MAAME,QAAQb,gBAAgBK;QAE9B,MAAMS,YAAYhB,uBAAuBQ;QACzC,MAAMS,aAAanB,MAAMoB,MAAM;QAC/B,MAAMC,YAAYrB,MAAMoB,MAAM,CAAeJ;QAE7C,MAAMM,kBAAkBrB;QAExB,MAAMY,gBAAgBhB,iBAAiB;YACrCiB,8BAAAA,wCAAAA,kBAAoB;QACtB;QAEA,MAAMH,iBAAiBd,iBAAiB;YACtCe,+BAAAA,yCAAAA,mBAAqB;QACvB;QAEAd,0BAA0B;YACxB,YAAY;YACZ,2FAA2F;YAC3FuB,UAAUE,OAAO,GAAGP;QACtB;QAEAlB,0BAA0B;YACxB,MAAM0B,UAAUL,WAAWI,OAAO;YAElC,IAAIC,SAAS;gBACX,MAAMC,QAAQ,OAAOnB,UAAU,aAAaA,MAAM;oBAAEkB;oBAAS,GAAGH,UAAUE,OAAO;gBAAC,KAAKjB;gBACvFO;gBAEA,MAAMa,SAASvB,aAAaqB,SAASC,OAAO;oBAAEH,iBAAiBA;gBAAkB;gBAEjFI,OAAOC,QAAQ,GAAGhB;gBAClBO,UAAUK,OAAO,GAAGG;gBAEpB,OAAO;oBACLA,OAAOE,MAAM;gBACf;YACF;QACF,GAAG;YAACV;YAAWI;YAAiBX;YAAgBE;SAAc;QAE9D,OAAOb,MAAM6B,YAAY,CAACpB,UAAU;YAAEqB,KAAK/B,cAAcoB,YAAYF,MAAMa,GAAG;QAAE;IAClF;IAEA,OAAOvB;AACT"}
1
+ {"version":3,"sources":["createMotionComponent.ts"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { useAnimateAtoms } from '../hooks/useAnimateAtoms';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { getChildElement } from '../utils/getChildElement';\nimport type { AtomMotion, AtomMotionFn, MotionParam, MotionImperativeRef } from '../types';\n\nexport type MotionComponentProps = {\n children: React.ReactElement;\n\n /** Provides imperative controls for the animation. */\n imperativeRef?: React.Ref<MotionImperativeRef | undefined>;\n\n /**\n * Callback that is called when the whole motion finishes.\n *\n * A motion definition can contain multiple animations and therefore multiple \"finish\" events. The callback is\n * triggered once all animations have finished with \"null\" instead of an event object to avoid ambiguity.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionFinish?: (ev: null) => void;\n\n /**\n * Callback that is called when the whole motion is cancelled.\n *\n * A motion definition can contain multiple animations and therefore multiple \"cancel\" events. The callback is\n * triggered once all animations have been cancelled with \"null\" instead of an event object to avoid ambiguity.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionCancel?: (ev: null) => void;\n\n /**\n * Callback that is called when the whole motion starts.\n *\n * A motion definition can contain multiple animations and therefore multiple \"start\" events. The callback is\n * triggered when the first animation is started. There is no official \"start\" event with the Web Animations API.\n * so the callback is triggered with \"null\".\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionStart?: (ev: null) => void;\n};\n\n/**\n * Creates a component that will animate the children using the provided motion.\n *\n * @param value - A motion definition.\n */\nexport function createMotionComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: AtomMotion | AtomMotion[] | AtomMotionFn<MotionParams>,\n) {\n const Atom: React.FC<MotionComponentProps & MotionParams> = props => {\n 'use no memo';\n\n const {\n children,\n imperativeRef,\n onMotionFinish: onMotionFinishProp,\n onMotionStart: onMotionStartProp,\n onMotionCancel: onMotionCancelProp,\n ..._rest\n } = props;\n const params = _rest as Exclude<typeof props, MotionComponentProps>;\n const child = getChildElement(children);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef<HTMLElement>();\n const paramsRef = React.useRef<MotionParams>(params);\n\n const animateAtoms = useAnimateAtoms();\n const isReducedMotion = useIsReducedMotion();\n\n const onMotionStart = useEventCallback(() => {\n onMotionStartProp?.(null);\n });\n\n const onMotionFinish = useEventCallback(() => {\n onMotionFinishProp?.(null);\n });\n\n const onMotionCancel = useEventCallback(() => {\n onMotionCancelProp?.(null);\n });\n\n useIsomorphicLayoutEffect(() => {\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n paramsRef.current = params;\n });\n\n useIsomorphicLayoutEffect(() => {\n const element = elementRef.current;\n\n if (element) {\n const atoms = typeof value === 'function' ? value({ element, ...paramsRef.current }) : value;\n onMotionStart();\n\n const handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n handle.setMotionEndCallbacks(onMotionFinish, onMotionCancel);\n handleRef.current = handle;\n\n return () => {\n handle.cancel();\n };\n }\n }, [animateAtoms, handleRef, isReducedMotion, onMotionFinish, onMotionStart, onMotionCancel]);\n\n return React.cloneElement(children, { ref: useMergedRefs(elementRef, child.ref) });\n };\n\n return Atom;\n}\n"],"names":["useEventCallback","useIsomorphicLayoutEffect","useMergedRefs","React","useAnimateAtoms","useMotionImperativeRef","useIsReducedMotion","getChildElement","createMotionComponent","value","Atom","props","children","imperativeRef","onMotionFinish","onMotionFinishProp","onMotionStart","onMotionStartProp","onMotionCancel","onMotionCancelProp","_rest","params","child","handleRef","elementRef","useRef","paramsRef","animateAtoms","isReducedMotion","current","element","atoms","handle","setMotionEndCallbacks","cancel","cloneElement","ref"],"mappings":"AAAA,SAASA,gBAAgB,EAAEC,yBAAyB,EAAEC,aAAa,QAAQ,4BAA4B;AACvG,YAAYC,WAAW,QAAQ;AAE/B,SAASC,eAAe,QAAQ,2BAA2B;AAC3D,SAASC,sBAAsB,QAAQ,kCAAkC;AACzE,SAASC,kBAAkB,QAAQ,8BAA8B;AACjE,SAASC,eAAe,QAAQ,2BAA2B;AAsC3D;;;;CAIC,GACD,OAAO,SAASC,sBACdC,KAA6D;IAE7D,MAAMC,OAAsDC,CAAAA;QAC1D;QAEA,MAAM,EACJC,QAAQ,EACRC,aAAa,EACbC,gBAAgBC,kBAAkB,EAClCC,eAAeC,iBAAiB,EAChCC,gBAAgBC,kBAAkB,EAClC,GAAGC,OACJ,GAAGT;QACJ,MAAMU,SAASD;QACf,MAAME,QAAQf,gBAAgBK;QAE9B,MAAMW,YAAYlB,uBAAuBQ;QACzC,MAAMW,aAAarB,MAAMsB,MAAM;QAC/B,MAAMC,YAAYvB,MAAMsB,MAAM,CAAeJ;QAE7C,MAAMM,eAAevB;QACrB,MAAMwB,kBAAkBtB;QAExB,MAAMU,gBAAgBhB,iBAAiB;YACrCiB,8BAAAA,wCAAAA,kBAAoB;QACtB;QAEA,MAAMH,iBAAiBd,iBAAiB;YACtCe,+BAAAA,yCAAAA,mBAAqB;QACvB;QAEA,MAAMG,iBAAiBlB,iBAAiB;YACtCmB,+BAAAA,yCAAAA,mBAAqB;QACvB;QAEAlB,0BAA0B;YACxB,YAAY;YACZ,2FAA2F;YAC3FyB,UAAUG,OAAO,GAAGR;QACtB;QAEApB,0BAA0B;YACxB,MAAM6B,UAAUN,WAAWK,OAAO;YAElC,IAAIC,SAAS;gBACX,MAAMC,QAAQ,OAAOtB,UAAU,aAAaA,MAAM;oBAAEqB;oBAAS,GAAGJ,UAAUG,OAAO;gBAAC,KAAKpB;gBACvFO;gBAEA,MAAMgB,SAASL,aAAaG,SAASC,OAAO;oBAAEH,iBAAiBA;gBAAkB;gBAEjFI,OAAOC,qBAAqB,CAACnB,gBAAgBI;gBAC7CK,UAAUM,OAAO,GAAGG;gBAEpB,OAAO;oBACLA,OAAOE,MAAM;gBACf;YACF;QACF,GAAG;YAACP;YAAcJ;YAAWK;YAAiBd;YAAgBE;YAAeE;SAAe;QAE5F,OAAOf,MAAMgC,YAAY,CAACvB,UAAU;YAAEwB,KAAKlC,cAAcsB,YAAYF,MAAMc,GAAG;QAAE;IAClF;IAEA,OAAO1B;AACT"}
@@ -1,22 +1,23 @@
1
1
  import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';
2
2
  import * as React from 'react';
3
3
  import { PresenceGroupChildContext } from '../contexts/PresenceGroupChildContext';
4
- import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
4
+ import { useAnimateAtoms } from '../hooks/useAnimateAtoms';
5
5
  import { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';
6
6
  import { useMountedState } from '../hooks/useMountedState';
7
- import { animateAtoms } from '../utils/animateAtoms';
7
+ import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
8
8
  import { getChildElement } from '../utils/getChildElement';
9
9
  function shouldSkipAnimation(appear, isFirstMount, visible) {
10
10
  return !appear && isFirstMount && !!visible;
11
11
  }
12
12
  export function createPresenceComponent(value) {
13
13
  const Presence = (props)=>{
14
+ 'use no memo';
14
15
  const itemContext = React.useContext(PresenceGroupChildContext);
15
16
  const merged = {
16
17
  ...itemContext,
17
18
  ...props
18
19
  };
19
- const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, visible, unmountOnExit, ..._rest } = merged;
20
+ const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, onMotionCancel, visible, unmountOnExit, ..._rest } = merged;
20
21
  const params = _rest;
21
22
  const [mounted, setMounted] = useMountedState(visible, unmountOnExit);
22
23
  const child = getChildElement(children);
@@ -27,6 +28,7 @@ export function createPresenceComponent(value) {
27
28
  appear,
28
29
  params
29
30
  });
31
+ const animateAtoms = useAnimateAtoms();
30
32
  const isFirstMount = useFirstMount();
31
33
  const isReducedMotion = useIsReducedMotion();
32
34
  const handleMotionStart = useEventCallback((direction)=>{
@@ -43,6 +45,11 @@ export function createPresenceComponent(value) {
43
45
  onExit === null || onExit === void 0 ? void 0 : onExit();
44
46
  }
45
47
  });
48
+ const handleMotionCancel = useEventCallback((direction)=>{
49
+ onMotionCancel === null || onMotionCancel === void 0 ? void 0 : onMotionCancel(null, {
50
+ direction
51
+ });
52
+ });
46
53
  useIsomorphicLayoutEffect(()=>{
47
54
  // Heads up!
48
55
  // We store the params in a ref to avoid re-rendering the component when the params change.
@@ -76,19 +83,19 @@ export function createPresenceComponent(value) {
76
83
  return;
77
84
  }
78
85
  handleRef.current = handle;
79
- handle.onfinish = ()=>{
80
- handleMotionFinish(direction);
81
- };
86
+ handle.setMotionEndCallbacks(()=>handleMotionFinish(direction), ()=>handleMotionCancel(direction));
82
87
  return ()=>{
83
88
  handle.cancel();
84
89
  };
85
90
  }, // Excluding `isFirstMount` from deps to prevent re-triggering the animation on subsequent renders
86
91
  // eslint-disable-next-line react-hooks/exhaustive-deps
87
92
  [
93
+ animateAtoms,
88
94
  handleRef,
89
95
  isReducedMotion,
90
96
  handleMotionFinish,
91
97
  handleMotionStart,
98
+ handleMotionCancel,
92
99
  visible
93
100
  ]);
94
101
  if (mounted) {
@@ -1 +1 @@
1
- {"version":3,"sources":["createPresenceComponent.ts"],"sourcesContent":["import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { PresenceGroupChildContext } from '../contexts/PresenceGroupChildContext';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { useMountedState } from '../hooks/useMountedState';\nimport { animateAtoms } from '../utils/animateAtoms';\nimport { getChildElement } from '../utils/getChildElement';\nimport type { MotionParam, PresenceMotion, MotionImperativeRef, PresenceMotionFn } from '../types';\n\nexport type PresenceComponentProps = {\n /**\n * By default, the child component won't execute the \"enter\" motion when it initially mounts, regardless of the value\n * of \"visible\". If you desire this behavior, ensure both \"appear\" and \"visible\" are set to \"true\".\n */\n appear?: boolean;\n\n /** A React element that will be cloned and will have motion effects applied to it. */\n children: React.ReactElement;\n\n /** Provides imperative controls for the animation. */\n imperativeRef?: React.Ref<MotionImperativeRef | undefined>;\n\n /**\n * Callback that is called when the whole motion finishes.\n *\n * A motion definition can contain multiple animations and therefore multiple \"finish\" events. The callback is\n * triggered once all animations have finished with \"null\" instead of an event object to avoid ambiguity.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionFinish?: (ev: null, data: { direction: 'enter' | 'exit' }) => void;\n\n /**\n * Callback that is called when the whole motion starts.\n *\n * A motion definition can contain multiple animations and therefore multiple \"start\" events. The callback is\n * triggered when the first animation is started. There is no official \"start\" event with the Web Animations API.\n * so the callback is triggered with \"null\".\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionStart?: (ev: null, data: { direction: 'enter' | 'exit' }) => void;\n\n /** Defines whether a component is visible; triggers the \"enter\" or \"exit\" motions. */\n visible?: boolean;\n\n /**\n * By default, the child component remains mounted after it reaches the \"finished\" state. Set \"unmountOnExit\" if\n * you prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit?: boolean;\n};\n\nfunction shouldSkipAnimation(appear: boolean | undefined, isFirstMount: boolean, visible: boolean | undefined) {\n return !appear && isFirstMount && !!visible;\n}\n\nexport function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: PresenceMotion | PresenceMotionFn<MotionParams>,\n) {\n const Presence: React.FC<PresenceComponentProps & MotionParams> = props => {\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = { ...itemContext, ...props };\n\n const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, visible, unmountOnExit, ..._rest } =\n merged;\n const params = _rest as Exclude<typeof merged, PresenceComponentProps | typeof itemContext>;\n\n const [mounted, setMounted] = useMountedState(visible, unmountOnExit);\n const child = getChildElement(children);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef<HTMLElement>();\n const ref = useMergedRefs(elementRef, child.ref);\n const optionsRef = React.useRef<{ appear?: boolean; params: MotionParams }>({ appear, params });\n\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n\n const handleMotionStart = useEventCallback((direction: 'enter' | 'exit') => {\n onMotionStart?.(null, { direction });\n });\n const handleMotionFinish = useEventCallback((direction: 'enter' | 'exit') => {\n onMotionFinish?.(null, { direction });\n\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit?.();\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n optionsRef.current = { appear, params };\n });\n\n useIsomorphicLayoutEffect(\n () => {\n const element = elementRef.current;\n\n if (!element || shouldSkipAnimation(optionsRef.current.appear, isFirstMount, visible)) {\n return;\n }\n\n const presenceMotion = typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : value;\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n\n const direction = visible ? 'enter' : 'exit';\n const forceFinishMotion = !visible && isFirstMount;\n\n if (!forceFinishMotion) {\n handleMotionStart(direction);\n }\n\n const handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n if (forceFinishMotion) {\n // Heads up!\n // .finish() is used there to skip animation on first mount, but apply animation styles immediately\n handle.finish();\n return;\n }\n\n handleRef.current = handle;\n handle.onfinish = () => {\n handleMotionFinish(direction);\n };\n\n return () => {\n handle.cancel();\n };\n },\n // Excluding `isFirstMount` from deps to prevent re-triggering the animation on subsequent renders\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [handleRef, isReducedMotion, handleMotionFinish, handleMotionStart, visible],\n );\n\n if (mounted) {\n return React.cloneElement(child, { ref });\n }\n\n return null;\n };\n\n return Presence;\n}\n"],"names":["useEventCallback","useFirstMount","useIsomorphicLayoutEffect","useMergedRefs","React","PresenceGroupChildContext","useIsReducedMotion","useMotionImperativeRef","useMountedState","animateAtoms","getChildElement","shouldSkipAnimation","appear","isFirstMount","visible","createPresenceComponent","value","Presence","props","itemContext","useContext","merged","children","imperativeRef","onExit","onMotionFinish","onMotionStart","unmountOnExit","_rest","params","mounted","setMounted","child","handleRef","elementRef","useRef","ref","optionsRef","isReducedMotion","handleMotionStart","direction","handleMotionFinish","current","element","presenceMotion","atoms","enter","exit","forceFinishMotion","handle","finish","onfinish","cancel","cloneElement"],"mappings":"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"}
1
+ {"version":3,"sources":["createPresenceComponent.ts"],"sourcesContent":["import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { PresenceGroupChildContext } from '../contexts/PresenceGroupChildContext';\nimport { useAnimateAtoms } from '../hooks/useAnimateAtoms';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { useMountedState } from '../hooks/useMountedState';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { getChildElement } from '../utils/getChildElement';\nimport type { MotionParam, PresenceMotion, MotionImperativeRef, PresenceMotionFn } from '../types';\n\nexport type PresenceComponentProps = {\n /**\n * By default, the child component won't execute the \"enter\" motion when it initially mounts, regardless of the value\n * of \"visible\". If you desire this behavior, ensure both \"appear\" and \"visible\" are set to \"true\".\n */\n appear?: boolean;\n\n /** A React element that will be cloned and will have motion effects applied to it. */\n children: React.ReactElement;\n\n /** Provides imperative controls for the animation. */\n imperativeRef?: React.Ref<MotionImperativeRef | undefined>;\n\n /**\n * Callback that is called when the whole motion finishes.\n *\n * A motion definition can contain multiple animations and therefore multiple \"finish\" events. The callback is\n * triggered once all animations have finished with \"null\" instead of an event object to avoid ambiguity.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionFinish?: (ev: null, data: { direction: 'enter' | 'exit' }) => void;\n\n /**\n * Callback that is called when the whole motion is cancelled. When a motion is cancelled it does not\n * emit a finish event but a specific cancel event\n *\n * A motion definition can contain multiple animations and therefore multiple \"finish\" events. The callback is\n * triggered once all animations have finished with \"null\" instead of an event object to avoid ambiguity.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionCancel?: (ev: null, data: { direction: 'enter' | 'exit' }) => void;\n\n /**\n * Callback that is called when the whole motion starts.\n *\n * A motion definition can contain multiple animations and therefore multiple \"start\" events. The callback is\n * triggered when the first animation is started. There is no official \"start\" event with the Web Animations API.\n * so the callback is triggered with \"null\".\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- EventHandler<T> does not support \"null\"\n onMotionStart?: (ev: null, data: { direction: 'enter' | 'exit' }) => void;\n\n /** Defines whether a component is visible; triggers the \"enter\" or \"exit\" motions. */\n visible?: boolean;\n\n /**\n * By default, the child component remains mounted after it reaches the \"finished\" state. Set \"unmountOnExit\" if\n * you prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit?: boolean;\n};\n\nfunction shouldSkipAnimation(appear: boolean | undefined, isFirstMount: boolean, visible: boolean | undefined) {\n return !appear && isFirstMount && !!visible;\n}\n\nexport function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: PresenceMotion | PresenceMotionFn<MotionParams>,\n) {\n const Presence: React.FC<PresenceComponentProps & MotionParams> = props => {\n 'use no memo';\n\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = { ...itemContext, ...props };\n\n const {\n appear,\n children,\n imperativeRef,\n onExit,\n onMotionFinish,\n onMotionStart,\n onMotionCancel,\n visible,\n unmountOnExit,\n ..._rest\n } = merged;\n const params = _rest as Exclude<typeof merged, PresenceComponentProps | typeof itemContext>;\n\n const [mounted, setMounted] = useMountedState(visible, unmountOnExit);\n const child = getChildElement(children);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef<HTMLElement>();\n const ref = useMergedRefs(elementRef, child.ref);\n const optionsRef = React.useRef<{ appear?: boolean; params: MotionParams }>({ appear, params });\n\n const animateAtoms = useAnimateAtoms();\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n\n const handleMotionStart = useEventCallback((direction: 'enter' | 'exit') => {\n onMotionStart?.(null, { direction });\n });\n const handleMotionFinish = useEventCallback((direction: 'enter' | 'exit') => {\n onMotionFinish?.(null, { direction });\n\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit?.();\n }\n });\n\n const handleMotionCancel = useEventCallback((direction: 'enter' | 'exit') => {\n onMotionCancel?.(null, { direction });\n });\n\n useIsomorphicLayoutEffect(() => {\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n optionsRef.current = { appear, params };\n });\n\n useIsomorphicLayoutEffect(\n () => {\n const element = elementRef.current;\n\n if (!element || shouldSkipAnimation(optionsRef.current.appear, isFirstMount, visible)) {\n return;\n }\n\n const presenceMotion = typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : value;\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n\n const direction = visible ? 'enter' : 'exit';\n const forceFinishMotion = !visible && isFirstMount;\n\n if (!forceFinishMotion) {\n handleMotionStart(direction);\n }\n\n const handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n if (forceFinishMotion) {\n // Heads up!\n // .finish() is used there to skip animation on first mount, but apply animation styles immediately\n handle.finish();\n return;\n }\n\n handleRef.current = handle;\n handle.setMotionEndCallbacks(\n () => handleMotionFinish(direction),\n () => handleMotionCancel(direction),\n );\n\n return () => {\n handle.cancel();\n };\n },\n // Excluding `isFirstMount` from deps to prevent re-triggering the animation on subsequent renders\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [animateAtoms, handleRef, isReducedMotion, handleMotionFinish, handleMotionStart, handleMotionCancel, visible],\n );\n\n if (mounted) {\n return React.cloneElement(child, { ref });\n }\n\n return null;\n };\n\n return Presence;\n}\n"],"names":["useEventCallback","useFirstMount","useIsomorphicLayoutEffect","useMergedRefs","React","PresenceGroupChildContext","useAnimateAtoms","useMotionImperativeRef","useMountedState","useIsReducedMotion","getChildElement","shouldSkipAnimation","appear","isFirstMount","visible","createPresenceComponent","value","Presence","props","itemContext","useContext","merged","children","imperativeRef","onExit","onMotionFinish","onMotionStart","onMotionCancel","unmountOnExit","_rest","params","mounted","setMounted","child","handleRef","elementRef","useRef","ref","optionsRef","animateAtoms","isReducedMotion","handleMotionStart","direction","handleMotionFinish","handleMotionCancel","current","element","presenceMotion","atoms","enter","exit","forceFinishMotion","handle","finish","setMotionEndCallbacks","cancel","cloneElement"],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ import * as React from 'react';
2
+ // Heads up! "Element." is a side-effect for minifiers, should be kept as IIFE to avoid leaking after minification.
3
+ const SUPPORTS_WEB_ANIMATIONS = /*@__PURE__*/ (()=>typeof Element.prototype.animate === 'function')();
4
+ /**
5
+ * In test environments, this hook is used to delay the execution of a callback until the next render. This is necessary
6
+ * to ensure that the callback is not executed synchronously, which would cause the test to fail.
7
+ *
8
+ * @see https://github.com/microsoft/fluentui/issues/31701
9
+ */ function useAnimateAtomsInTestEnvironment() {
10
+ const [count, setCount] = React.useState(0);
11
+ const callbackRef = React.useRef();
12
+ React.useEffect(()=>{
13
+ if (count > 0) {
14
+ var _callbackRef_current;
15
+ (_callbackRef_current = callbackRef.current) === null || _callbackRef_current === void 0 ? void 0 : _callbackRef_current.call(callbackRef);
16
+ }
17
+ }, [
18
+ count
19
+ ]);
20
+ return React.useCallback(()=>{
21
+ return {
22
+ setMotionEndCallbacks (onfinish) {
23
+ callbackRef.current = onfinish;
24
+ setCount((v)=>v + 1);
25
+ },
26
+ set playbackRate (rate){
27
+ /* no-op */ },
28
+ cancel () {
29
+ /* no-op */ },
30
+ pause () {
31
+ /* no-op */ },
32
+ play () {
33
+ /* no-op */ },
34
+ finish () {
35
+ /* no-op */ }
36
+ };
37
+ }, []);
38
+ }
39
+ /**
40
+ * @internal
41
+ */ export function useAnimateAtoms() {
42
+ 'use no memo';
43
+ if (process.env.NODE_ENV === 'test' && !SUPPORTS_WEB_ANIMATIONS) {
44
+ // eslint-disable-next-line react-hooks/rules-of-hooks
45
+ return useAnimateAtomsInTestEnvironment();
46
+ }
47
+ // eslint-disable-next-line react-hooks/rules-of-hooks
48
+ return React.useCallback((element, value, options)=>{
49
+ const atoms = Array.isArray(value) ? value : [
50
+ value
51
+ ];
52
+ const { isReducedMotion } = options;
53
+ const animations = atoms.map((motion)=>{
54
+ const { keyframes, ...params } = motion;
55
+ const animation = element.animate(keyframes, {
56
+ fill: 'forwards',
57
+ ...params,
58
+ ...isReducedMotion && {
59
+ duration: 1
60
+ }
61
+ });
62
+ animation.persist();
63
+ return animation;
64
+ });
65
+ return {
66
+ set playbackRate (rate){
67
+ animations.forEach((animation)=>{
68
+ animation.playbackRate = rate;
69
+ });
70
+ },
71
+ setMotionEndCallbacks (onfinish, oncancel) {
72
+ Promise.all(animations.map((animation)=>animation.finished)).then(()=>{
73
+ onfinish();
74
+ }).catch((err)=>{
75
+ var _element_ownerDocument_defaultView;
76
+ const DOMException = (_element_ownerDocument_defaultView = element.ownerDocument.defaultView) === null || _element_ownerDocument_defaultView === void 0 ? void 0 : _element_ownerDocument_defaultView.DOMException;
77
+ // Ignores "DOMException: The user aborted a request" that appears if animations are cancelled
78
+ if (DOMException && err instanceof DOMException && err.name === 'AbortError') {
79
+ oncancel();
80
+ return;
81
+ }
82
+ throw err;
83
+ });
84
+ },
85
+ cancel: ()=>{
86
+ animations.forEach((animation)=>{
87
+ animation.cancel();
88
+ });
89
+ },
90
+ pause: ()=>{
91
+ animations.forEach((animation)=>{
92
+ animation.pause();
93
+ });
94
+ },
95
+ play: ()=>{
96
+ animations.forEach((animation)=>{
97
+ animation.play();
98
+ });
99
+ },
100
+ finish: ()=>{
101
+ animations.forEach((animation)=>{
102
+ animation.finish();
103
+ });
104
+ }
105
+ };
106
+ }, []);
107
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["useAnimateAtoms.ts"],"sourcesContent":["import * as React from 'react';\nimport type { AnimationHandle, AtomMotion } from '../types';\n\n// Heads up! \"Element.\" is a side-effect for minifiers, should be kept as IIFE to avoid leaking after minification.\nconst SUPPORTS_WEB_ANIMATIONS = /*@__PURE__*/ (() => typeof Element.prototype.animate === 'function')();\n\n/**\n * In test environments, this hook is used to delay the execution of a callback until the next render. This is necessary\n * to ensure that the callback is not executed synchronously, which would cause the test to fail.\n *\n * @see https://github.com/microsoft/fluentui/issues/31701\n */\nfunction useAnimateAtomsInTestEnvironment() {\n const [count, setCount] = React.useState(0);\n const callbackRef = React.useRef<() => void>();\n\n React.useEffect(() => {\n if (count > 0) {\n callbackRef.current?.();\n }\n }, [count]);\n\n return React.useCallback((): AnimationHandle => {\n return {\n setMotionEndCallbacks(onfinish: () => void) {\n callbackRef.current = onfinish;\n setCount(v => v + 1);\n },\n\n set playbackRate(rate: number) {\n /* no-op */\n },\n cancel() {\n /* no-op */\n },\n pause() {\n /* no-op */\n },\n play() {\n /* no-op */\n },\n finish() {\n /* no-op */\n },\n };\n }, []);\n}\n\n/**\n * @internal\n */\nexport function useAnimateAtoms() {\n 'use no memo';\n\n if (process.env.NODE_ENV === 'test' && !SUPPORTS_WEB_ANIMATIONS) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useAnimateAtomsInTestEnvironment();\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return React.useCallback(\n (\n element: HTMLElement,\n value: AtomMotion | AtomMotion[],\n options: {\n isReducedMotion: boolean;\n },\n ): AnimationHandle => {\n const atoms = Array.isArray(value) ? value : [value];\n const { isReducedMotion } = options;\n\n const animations = atoms.map(motion => {\n const { keyframes, ...params } = motion;\n const animation = element.animate(keyframes, {\n fill: 'forwards',\n\n ...params,\n ...(isReducedMotion && { duration: 1 }),\n });\n\n animation.persist();\n\n return animation;\n });\n\n return {\n set playbackRate(rate: number) {\n animations.forEach(animation => {\n animation.playbackRate = rate;\n });\n },\n setMotionEndCallbacks(onfinish: () => void, oncancel: () => void) {\n Promise.all(animations.map(animation => animation.finished))\n .then(() => {\n onfinish();\n })\n .catch((err: unknown) => {\n const DOMException = element.ownerDocument.defaultView?.DOMException;\n\n // Ignores \"DOMException: The user aborted a request\" that appears if animations are cancelled\n if (DOMException && err instanceof DOMException && err.name === 'AbortError') {\n oncancel();\n return;\n }\n\n throw err;\n });\n },\n\n cancel: () => {\n animations.forEach(animation => {\n animation.cancel();\n });\n },\n pause: () => {\n animations.forEach(animation => {\n animation.pause();\n });\n },\n play: () => {\n animations.forEach(animation => {\n animation.play();\n });\n },\n finish: () => {\n animations.forEach(animation => {\n animation.finish();\n });\n },\n };\n },\n [],\n );\n}\n"],"names":["React","SUPPORTS_WEB_ANIMATIONS","Element","prototype","animate","useAnimateAtomsInTestEnvironment","count","setCount","useState","callbackRef","useRef","useEffect","current","useCallback","setMotionEndCallbacks","onfinish","v","playbackRate","rate","cancel","pause","play","finish","useAnimateAtoms","process","env","NODE_ENV","element","value","options","atoms","Array","isArray","isReducedMotion","animations","map","motion","keyframes","params","animation","fill","duration","persist","forEach","oncancel","Promise","all","finished","then","catch","err","DOMException","ownerDocument","defaultView","name"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAG/B,mHAAmH;AACnH,MAAMC,0BAAwC,AAAd,WAAW,GAAI,CAAA,IAAM,OAAOC,QAAQC,SAAS,CAACC,OAAO,KAAK,UAAS;AAEnG;;;;;CAKC,GACD,SAASC;IACP,MAAM,CAACC,OAAOC,SAAS,GAAGP,MAAMQ,QAAQ,CAAC;IACzC,MAAMC,cAAcT,MAAMU,MAAM;IAEhCV,MAAMW,SAAS,CAAC;QACd,IAAIL,QAAQ,GAAG;gBACbG;aAAAA,uBAAAA,YAAYG,OAAO,cAAnBH,2CAAAA,0BAAAA;QACF;IACF,GAAG;QAACH;KAAM;IAEV,OAAON,MAAMa,WAAW,CAAC;QACvB,OAAO;YACLC,uBAAsBC,QAAoB;gBACxCN,YAAYG,OAAO,GAAGG;gBACtBR,SAASS,CAAAA,IAAKA,IAAI;YACpB;YAEA,IAAIC,cAAaC,KAAc;YAC7B,SAAS,GACX;YACAC;YACE,SAAS,GACX;YACAC;YACE,SAAS,GACX;YACAC;YACE,SAAS,GACX;YACAC;YACE,SAAS,GACX;QACF;IACF,GAAG,EAAE;AACP;AAEA;;CAEC,GACD,OAAO,SAASC;IACd;IAEA,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,UAAU,CAACzB,yBAAyB;QAC/D,sDAAsD;QACtD,OAAOI;IACT;IAEA,sDAAsD;IACtD,OAAOL,MAAMa,WAAW,CACtB,CACEc,SACAC,OACAC;QAIA,MAAMC,QAAQC,MAAMC,OAAO,CAACJ,SAASA,QAAQ;YAACA;SAAM;QACpD,MAAM,EAAEK,eAAe,EAAE,GAAGJ;QAE5B,MAAMK,aAAaJ,MAAMK,GAAG,CAACC,CAAAA;YAC3B,MAAM,EAAEC,SAAS,EAAE,GAAGC,QAAQ,GAAGF;YACjC,MAAMG,YAAYZ,QAAQvB,OAAO,CAACiC,WAAW;gBAC3CG,MAAM;gBAEN,GAAGF,MAAM;gBACT,GAAIL,mBAAmB;oBAAEQ,UAAU;gBAAE,CAAC;YACxC;YAEAF,UAAUG,OAAO;YAEjB,OAAOH;QACT;QAEA,OAAO;YACL,IAAItB,cAAaC,KAAc;gBAC7BgB,WAAWS,OAAO,CAACJ,CAAAA;oBACjBA,UAAUtB,YAAY,GAAGC;gBAC3B;YACF;YACAJ,uBAAsBC,QAAoB,EAAE6B,QAAoB;gBAC9DC,QAAQC,GAAG,CAACZ,WAAWC,GAAG,CAACI,CAAAA,YAAaA,UAAUQ,QAAQ,GACvDC,IAAI,CAAC;oBACJjC;gBACF,GACCkC,KAAK,CAAC,CAACC;wBACevB;oBAArB,MAAMwB,gBAAexB,qCAAAA,QAAQyB,aAAa,CAACC,WAAW,cAAjC1B,yDAAAA,mCAAmCwB,YAAY;oBAEpE,8FAA8F;oBAC9F,IAAIA,gBAAgBD,eAAeC,gBAAgBD,IAAII,IAAI,KAAK,cAAc;wBAC5EV;wBACA;oBACF;oBAEA,MAAMM;gBACR;YACJ;YAEA/B,QAAQ;gBACNe,WAAWS,OAAO,CAACJ,CAAAA;oBACjBA,UAAUpB,MAAM;gBAClB;YACF;YACAC,OAAO;gBACLc,WAAWS,OAAO,CAACJ,CAAAA;oBACjBA,UAAUnB,KAAK;gBACjB;YACF;YACAC,MAAM;gBACJa,WAAWS,OAAO,CAACJ,CAAAA;oBACjBA,UAAUlB,IAAI;gBAChB;YACF;YACAC,QAAQ;gBACNY,WAAWS,OAAO,CAACJ,CAAAA;oBACjBA,UAAUjB,MAAM;gBAClB;YACF;QACF;IACF,GACA,EAAE;AAEN"}
package/lib/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["types.ts"],"sourcesContent":["export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions;\n\nexport type PresenceMotion = {\n enter: AtomMotion | AtomMotion[];\n exit: AtomMotion | AtomMotion[];\n};\n\n/**\n * @internal\n *\n * A motion param should be a primitive value that can be serialized to JSON and could be potentially used a plain\n * dependency for React hooks.\n */\nexport type MotionParam = boolean | number | string;\n\nexport type AtomMotionFn<MotionParams extends Record<string, MotionParam> = {}> = (\n params: { element: HTMLElement } & MotionParams,\n) => AtomMotion | AtomMotion[];\nexport type PresenceMotionFn<MotionParams extends Record<string, MotionParam> = {}> = (\n params: { element: HTMLElement } & MotionParams,\n) => PresenceMotion;\n\n// ---\n\nexport type AnimationHandle = Pick<Animation, 'cancel' | 'finish' | 'pause' | 'play' | 'playbackRate'> & {\n onfinish: () => void;\n};\n\nexport type MotionImperativeRef = {\n /** Sets the playback rate of the animation, where 1 is normal speed. */\n setPlaybackRate: (rate: number) => void;\n\n /** Sets the state of the animation to running or paused. */\n setPlayState: (state: 'running' | 'paused') => void;\n};\n"],"names":[],"mappings":"AAAA,WAkCE"}
1
+ {"version":3,"sources":["types.ts"],"sourcesContent":["export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions;\n\nexport type PresenceMotion = {\n enter: AtomMotion | AtomMotion[];\n exit: AtomMotion | AtomMotion[];\n};\n\n/**\n * @internal\n *\n * A motion param should be a primitive value that can be serialized to JSON and could be potentially used a plain\n * dependency for React hooks.\n */\nexport type MotionParam = boolean | number | string;\n\nexport type AtomMotionFn<MotionParams extends Record<string, MotionParam> = {}> = (\n params: { element: HTMLElement } & MotionParams,\n) => AtomMotion | AtomMotion[];\nexport type PresenceMotionFn<MotionParams extends Record<string, MotionParam> = {}> = (\n params: { element: HTMLElement } & MotionParams,\n) => PresenceMotion;\n\n// ---\n\nexport type AnimationHandle = Pick<Animation, 'cancel' | 'finish' | 'pause' | 'play' | 'playbackRate'> & {\n setMotionEndCallbacks: (onfinish: () => void, oncancel: () => void) => void;\n};\n\nexport type MotionImperativeRef = {\n /** Sets the playback rate of the animation, where 1 is normal speed. */\n setPlaybackRate: (rate: number) => void;\n\n /** Sets the state of the animation to running or paused. */\n setPlayState: (state: 'running' | 'paused') => void;\n};\n"],"names":[],"mappings":"AAAA,WAkCE"}
@@ -11,18 +11,20 @@ Object.defineProperty(exports, "createMotionComponent", {
11
11
  const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
12
  const _reactutilities = require("@fluentui/react-utilities");
13
13
  const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
14
- const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
14
+ const _useAnimateAtoms = require("../hooks/useAnimateAtoms");
15
15
  const _useMotionImperativeRef = require("../hooks/useMotionImperativeRef");
16
- const _animateAtoms = require("../utils/animateAtoms");
16
+ const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
17
17
  const _getChildElement = require("../utils/getChildElement");
18
18
  function createMotionComponent(value) {
19
19
  const Atom = (props)=>{
20
- const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, ..._rest } = props;
20
+ 'use no memo';
21
+ const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, onMotionCancel: onMotionCancelProp, ..._rest } = props;
21
22
  const params = _rest;
22
23
  const child = (0, _getChildElement.getChildElement)(children);
23
24
  const handleRef = (0, _useMotionImperativeRef.useMotionImperativeRef)(imperativeRef);
24
25
  const elementRef = _react.useRef();
25
26
  const paramsRef = _react.useRef(params);
27
+ const animateAtoms = (0, _useAnimateAtoms.useAnimateAtoms)();
26
28
  const isReducedMotion = (0, _useIsReducedMotion.useIsReducedMotion)();
27
29
  const onMotionStart = (0, _reactutilities.useEventCallback)(()=>{
28
30
  onMotionStartProp === null || onMotionStartProp === void 0 ? void 0 : onMotionStartProp(null);
@@ -30,6 +32,9 @@ function createMotionComponent(value) {
30
32
  const onMotionFinish = (0, _reactutilities.useEventCallback)(()=>{
31
33
  onMotionFinishProp === null || onMotionFinishProp === void 0 ? void 0 : onMotionFinishProp(null);
32
34
  });
35
+ const onMotionCancel = (0, _reactutilities.useEventCallback)(()=>{
36
+ onMotionCancelProp === null || onMotionCancelProp === void 0 ? void 0 : onMotionCancelProp(null);
37
+ });
33
38
  (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
34
39
  // Heads up!
35
40
  // We store the params in a ref to avoid re-rendering the component when the params change.
@@ -43,20 +48,22 @@ function createMotionComponent(value) {
43
48
  ...paramsRef.current
44
49
  }) : value;
45
50
  onMotionStart();
46
- const handle = (0, _animateAtoms.animateAtoms)(element, atoms, {
51
+ const handle = animateAtoms(element, atoms, {
47
52
  isReducedMotion: isReducedMotion()
48
53
  });
49
- handle.onfinish = onMotionFinish;
54
+ handle.setMotionEndCallbacks(onMotionFinish, onMotionCancel);
50
55
  handleRef.current = handle;
51
56
  return ()=>{
52
57
  handle.cancel();
53
58
  };
54
59
  }
55
60
  }, [
61
+ animateAtoms,
56
62
  handleRef,
57
63
  isReducedMotion,
58
64
  onMotionFinish,
59
- onMotionStart
65
+ onMotionStart,
66
+ onMotionCancel
60
67
  ]);
61
68
  return /*#__PURE__*/ _react.cloneElement(children, {
62
69
  ref: (0, _reactutilities.useMergedRefs)(elementRef, child.ref)
@@ -1 +1 @@
1
- {"version":3,"sources":["createMotionComponent.js"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { animateAtoms } from '../utils/animateAtoms';\nimport { getChildElement } from '../utils/getChildElement';\n/**\n * Creates a component that will animate the children using the provided motion.\n *\n * @param value - A motion definition.\n */ export function createMotionComponent(value) {\n const Atom = (props)=>{\n const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, ..._rest } = props;\n const params = _rest;\n const child = getChildElement(children);\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef();\n const paramsRef = React.useRef(params);\n const isReducedMotion = useIsReducedMotion();\n const onMotionStart = useEventCallback(()=>{\n onMotionStartProp === null || onMotionStartProp === void 0 ? void 0 : onMotionStartProp(null);\n });\n const onMotionFinish = useEventCallback(()=>{\n onMotionFinishProp === null || onMotionFinishProp === void 0 ? void 0 : onMotionFinishProp(null);\n });\n useIsomorphicLayoutEffect(()=>{\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n paramsRef.current = params;\n });\n useIsomorphicLayoutEffect(()=>{\n const element = elementRef.current;\n if (element) {\n const atoms = typeof value === 'function' ? value({\n element,\n ...paramsRef.current\n }) : value;\n onMotionStart();\n const handle = animateAtoms(element, atoms, {\n isReducedMotion: isReducedMotion()\n });\n handle.onfinish = onMotionFinish;\n handleRef.current = handle;\n return ()=>{\n handle.cancel();\n };\n }\n }, [\n handleRef,\n isReducedMotion,\n onMotionFinish,\n onMotionStart\n ]);\n return React.cloneElement(children, {\n ref: useMergedRefs(elementRef, child.ref)\n });\n };\n return Atom;\n}\n"],"names":["createMotionComponent","value","Atom","props","children","imperativeRef","onMotionFinish","onMotionFinishProp","onMotionStart","onMotionStartProp","_rest","params","child","getChildElement","handleRef","useMotionImperativeRef","elementRef","React","useRef","paramsRef","isReducedMotion","useIsReducedMotion","useEventCallback","useIsomorphicLayoutEffect","current","element","atoms","handle","animateAtoms","onfinish","cancel","cloneElement","ref","useMergedRefs"],"mappings":";;;;+BAUoBA;;;eAAAA;;;;gCAVuD;iEACpD;oCACY;wCACI;8BACV;iCACG;AAKrB,SAASA,sBAAsBC,KAAK;IAC3C,MAAMC,OAAO,CAACC;QACV,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAEC,gBAAgBC,kBAAkB,EAAEC,eAAeC,iBAAiB,EAAE,GAAGC,OAAO,GAAGP;QACpH,MAAMQ,SAASD;QACf,MAAME,QAAQC,IAAAA,gCAAe,EAACT;QAC9B,MAAMU,YAAYC,IAAAA,8CAAsB,EAACV;QACzC,MAAMW,aAAaC,OAAMC,MAAM;QAC/B,MAAMC,YAAYF,OAAMC,MAAM,CAACP;QAC/B,MAAMS,kBAAkBC,IAAAA,sCAAkB;QAC1C,MAAMb,gBAAgBc,IAAAA,gCAAgB,EAAC;YACnCb,sBAAsB,QAAQA,sBAAsB,KAAK,IAAI,KAAK,IAAIA,kBAAkB;QAC5F;QACA,MAAMH,iBAAiBgB,IAAAA,gCAAgB,EAAC;YACpCf,uBAAuB,QAAQA,uBAAuB,KAAK,IAAI,KAAK,IAAIA,mBAAmB;QAC/F;QACAgB,IAAAA,yCAAyB,EAAC;YACtB,YAAY;YACZ,2FAA2F;YAC3FJ,UAAUK,OAAO,GAAGb;QACxB;QACAY,IAAAA,yCAAyB,EAAC;YACtB,MAAME,UAAUT,WAAWQ,OAAO;YAClC,IAAIC,SAAS;gBACT,MAAMC,QAAQ,OAAOzB,UAAU,aAAaA,MAAM;oBAC9CwB;oBACA,GAAGN,UAAUK,OAAO;gBACxB,KAAKvB;gBACLO;gBACA,MAAMmB,SAASC,IAAAA,0BAAY,EAACH,SAASC,OAAO;oBACxCN,iBAAiBA;gBACrB;gBACAO,OAAOE,QAAQ,GAAGvB;gBAClBQ,UAAUU,OAAO,GAAGG;gBACpB,OAAO;oBACHA,OAAOG,MAAM;gBACjB;YACJ;QACJ,GAAG;YACChB;YACAM;YACAd;YACAE;SACH;QACD,qBAAOS,OAAMc,YAAY,CAAC3B,UAAU;YAChC4B,KAAKC,IAAAA,6BAAa,EAACjB,YAAYJ,MAAMoB,GAAG;QAC5C;IACJ;IACA,OAAO9B;AACX"}
1
+ {"version":3,"sources":["createMotionComponent.js"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { useAnimateAtoms } from '../hooks/useAnimateAtoms';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { getChildElement } from '../utils/getChildElement';\n/**\n * Creates a component that will animate the children using the provided motion.\n *\n * @param value - A motion definition.\n */ export function createMotionComponent(value) {\n const Atom = (props)=>{\n 'use no memo';\n const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, onMotionCancel: onMotionCancelProp, ..._rest } = props;\n const params = _rest;\n const child = getChildElement(children);\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef();\n const paramsRef = React.useRef(params);\n const animateAtoms = useAnimateAtoms();\n const isReducedMotion = useIsReducedMotion();\n const onMotionStart = useEventCallback(()=>{\n onMotionStartProp === null || onMotionStartProp === void 0 ? void 0 : onMotionStartProp(null);\n });\n const onMotionFinish = useEventCallback(()=>{\n onMotionFinishProp === null || onMotionFinishProp === void 0 ? void 0 : onMotionFinishProp(null);\n });\n const onMotionCancel = useEventCallback(()=>{\n onMotionCancelProp === null || onMotionCancelProp === void 0 ? void 0 : onMotionCancelProp(null);\n });\n useIsomorphicLayoutEffect(()=>{\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n paramsRef.current = params;\n });\n useIsomorphicLayoutEffect(()=>{\n const element = elementRef.current;\n if (element) {\n const atoms = typeof value === 'function' ? value({\n element,\n ...paramsRef.current\n }) : value;\n onMotionStart();\n const handle = animateAtoms(element, atoms, {\n isReducedMotion: isReducedMotion()\n });\n handle.setMotionEndCallbacks(onMotionFinish, onMotionCancel);\n handleRef.current = handle;\n return ()=>{\n handle.cancel();\n };\n }\n }, [\n animateAtoms,\n handleRef,\n isReducedMotion,\n onMotionFinish,\n onMotionStart,\n onMotionCancel\n ]);\n return React.cloneElement(children, {\n ref: useMergedRefs(elementRef, child.ref)\n });\n };\n return Atom;\n}\n"],"names":["createMotionComponent","value","Atom","props","children","imperativeRef","onMotionFinish","onMotionFinishProp","onMotionStart","onMotionStartProp","onMotionCancel","onMotionCancelProp","_rest","params","child","getChildElement","handleRef","useMotionImperativeRef","elementRef","React","useRef","paramsRef","animateAtoms","useAnimateAtoms","isReducedMotion","useIsReducedMotion","useEventCallback","useIsomorphicLayoutEffect","current","element","atoms","handle","setMotionEndCallbacks","cancel","cloneElement","ref","useMergedRefs"],"mappings":";;;;+BAUoBA;;;eAAAA;;;;gCAVuD;iEACpD;iCACS;wCACO;oCACJ;iCACH;AAKrB,SAASA,sBAAsBC,KAAK;IAC3C,MAAMC,OAAO,CAACC;QACV;QACA,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAEC,gBAAgBC,kBAAkB,EAAEC,eAAeC,iBAAiB,EAAEC,gBAAgBC,kBAAkB,EAAE,GAAGC,OAAO,GAAGT;QACxJ,MAAMU,SAASD;QACf,MAAME,QAAQC,IAAAA,gCAAe,EAACX;QAC9B,MAAMY,YAAYC,IAAAA,8CAAsB,EAACZ;QACzC,MAAMa,aAAaC,OAAMC,MAAM;QAC/B,MAAMC,YAAYF,OAAMC,MAAM,CAACP;QAC/B,MAAMS,eAAeC,IAAAA,gCAAe;QACpC,MAAMC,kBAAkBC,IAAAA,sCAAkB;QAC1C,MAAMjB,gBAAgBkB,IAAAA,gCAAgB,EAAC;YACnCjB,sBAAsB,QAAQA,sBAAsB,KAAK,IAAI,KAAK,IAAIA,kBAAkB;QAC5F;QACA,MAAMH,iBAAiBoB,IAAAA,gCAAgB,EAAC;YACpCnB,uBAAuB,QAAQA,uBAAuB,KAAK,IAAI,KAAK,IAAIA,mBAAmB;QAC/F;QACA,MAAMG,iBAAiBgB,IAAAA,gCAAgB,EAAC;YACpCf,uBAAuB,QAAQA,uBAAuB,KAAK,IAAI,KAAK,IAAIA,mBAAmB;QAC/F;QACAgB,IAAAA,yCAAyB,EAAC;YACtB,YAAY;YACZ,2FAA2F;YAC3FN,UAAUO,OAAO,GAAGf;QACxB;QACAc,IAAAA,yCAAyB,EAAC;YACtB,MAAME,UAAUX,WAAWU,OAAO;YAClC,IAAIC,SAAS;gBACT,MAAMC,QAAQ,OAAO7B,UAAU,aAAaA,MAAM;oBAC9C4B;oBACA,GAAGR,UAAUO,OAAO;gBACxB,KAAK3B;gBACLO;gBACA,MAAMuB,SAAST,aAAaO,SAASC,OAAO;oBACxCN,iBAAiBA;gBACrB;gBACAO,OAAOC,qBAAqB,CAAC1B,gBAAgBI;gBAC7CM,UAAUY,OAAO,GAAGG;gBACpB,OAAO;oBACHA,OAAOE,MAAM;gBACjB;YACJ;QACJ,GAAG;YACCX;YACAN;YACAQ;YACAlB;YACAE;YACAE;SACH;QACD,qBAAOS,OAAMe,YAAY,CAAC9B,UAAU;YAChC+B,KAAKC,IAAAA,6BAAa,EAAClB,YAAYJ,MAAMqB,GAAG;QAC5C;IACJ;IACA,OAAOjC;AACX"}
@@ -12,22 +12,23 @@ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildc
12
12
  const _reactutilities = require("@fluentui/react-utilities");
13
13
  const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
14
14
  const _PresenceGroupChildContext = require("../contexts/PresenceGroupChildContext");
15
- const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
15
+ const _useAnimateAtoms = require("../hooks/useAnimateAtoms");
16
16
  const _useMotionImperativeRef = require("../hooks/useMotionImperativeRef");
17
17
  const _useMountedState = require("../hooks/useMountedState");
18
- const _animateAtoms = require("../utils/animateAtoms");
18
+ const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
19
19
  const _getChildElement = require("../utils/getChildElement");
20
20
  function shouldSkipAnimation(appear, isFirstMount, visible) {
21
21
  return !appear && isFirstMount && !!visible;
22
22
  }
23
23
  function createPresenceComponent(value) {
24
24
  const Presence = (props)=>{
25
+ 'use no memo';
25
26
  const itemContext = _react.useContext(_PresenceGroupChildContext.PresenceGroupChildContext);
26
27
  const merged = {
27
28
  ...itemContext,
28
29
  ...props
29
30
  };
30
- const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, visible, unmountOnExit, ..._rest } = merged;
31
+ const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, onMotionCancel, visible, unmountOnExit, ..._rest } = merged;
31
32
  const params = _rest;
32
33
  const [mounted, setMounted] = (0, _useMountedState.useMountedState)(visible, unmountOnExit);
33
34
  const child = (0, _getChildElement.getChildElement)(children);
@@ -38,6 +39,7 @@ function createPresenceComponent(value) {
38
39
  appear,
39
40
  params
40
41
  });
42
+ const animateAtoms = (0, _useAnimateAtoms.useAnimateAtoms)();
41
43
  const isFirstMount = (0, _reactutilities.useFirstMount)();
42
44
  const isReducedMotion = (0, _useIsReducedMotion.useIsReducedMotion)();
43
45
  const handleMotionStart = (0, _reactutilities.useEventCallback)((direction)=>{
@@ -54,6 +56,11 @@ function createPresenceComponent(value) {
54
56
  onExit === null || onExit === void 0 ? void 0 : onExit();
55
57
  }
56
58
  });
59
+ const handleMotionCancel = (0, _reactutilities.useEventCallback)((direction)=>{
60
+ onMotionCancel === null || onMotionCancel === void 0 ? void 0 : onMotionCancel(null, {
61
+ direction
62
+ });
63
+ });
57
64
  (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
58
65
  // Heads up!
59
66
  // We store the params in a ref to avoid re-rendering the component when the params change.
@@ -77,7 +84,7 @@ function createPresenceComponent(value) {
77
84
  if (!forceFinishMotion) {
78
85
  handleMotionStart(direction);
79
86
  }
80
- const handle = (0, _animateAtoms.animateAtoms)(element, atoms, {
87
+ const handle = animateAtoms(element, atoms, {
81
88
  isReducedMotion: isReducedMotion()
82
89
  });
83
90
  if (forceFinishMotion) {
@@ -87,18 +94,18 @@ function createPresenceComponent(value) {
87
94
  return;
88
95
  }
89
96
  handleRef.current = handle;
90
- handle.onfinish = ()=>{
91
- handleMotionFinish(direction);
92
- };
97
+ handle.setMotionEndCallbacks(()=>handleMotionFinish(direction), ()=>handleMotionCancel(direction));
93
98
  return ()=>{
94
99
  handle.cancel();
95
100
  };
96
101
  }, // eslint-disable-next-line react-hooks/exhaustive-deps
97
102
  [
103
+ animateAtoms,
98
104
  handleRef,
99
105
  isReducedMotion,
100
106
  handleMotionFinish,
101
107
  handleMotionStart,
108
+ handleMotionCancel,
102
109
  visible
103
110
  ]);
104
111
  if (mounted) {
@@ -1 +1 @@
1
- {"version":3,"sources":["createPresenceComponent.js"],"sourcesContent":["import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { PresenceGroupChildContext } from '../contexts/PresenceGroupChildContext';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { useMountedState } from '../hooks/useMountedState';\nimport { animateAtoms } from '../utils/animateAtoms';\nimport { getChildElement } from '../utils/getChildElement';\nfunction shouldSkipAnimation(appear, isFirstMount, visible) {\n return !appear && isFirstMount && !!visible;\n}\nexport function createPresenceComponent(value) {\n const Presence = (props)=>{\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = {\n ...itemContext,\n ...props\n };\n const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, visible, unmountOnExit, ..._rest } = merged;\n const params = _rest;\n const [mounted, setMounted] = useMountedState(visible, unmountOnExit);\n const child = getChildElement(children);\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef();\n const ref = useMergedRefs(elementRef, child.ref);\n const optionsRef = React.useRef({\n appear,\n params\n });\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n const handleMotionStart = useEventCallback((direction)=>{\n onMotionStart === null || onMotionStart === void 0 ? void 0 : onMotionStart(null, {\n direction\n });\n });\n const handleMotionFinish = useEventCallback((direction)=>{\n onMotionFinish === null || onMotionFinish === void 0 ? void 0 : onMotionFinish(null, {\n direction\n });\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit === null || onExit === void 0 ? void 0 : onExit();\n }\n });\n useIsomorphicLayoutEffect(()=>{\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n optionsRef.current = {\n appear,\n params\n };\n });\n useIsomorphicLayoutEffect(()=>{\n const element = elementRef.current;\n if (!element || shouldSkipAnimation(optionsRef.current.appear, isFirstMount, visible)) {\n return;\n }\n const presenceMotion = typeof value === 'function' ? value({\n element,\n ...optionsRef.current.params\n }) : value;\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n const direction = visible ? 'enter' : 'exit';\n const forceFinishMotion = !visible && isFirstMount;\n if (!forceFinishMotion) {\n handleMotionStart(direction);\n }\n const handle = animateAtoms(element, atoms, {\n isReducedMotion: isReducedMotion()\n });\n if (forceFinishMotion) {\n // Heads up!\n // .finish() is used there to skip animation on first mount, but apply animation styles immediately\n handle.finish();\n return;\n }\n handleRef.current = handle;\n handle.onfinish = ()=>{\n handleMotionFinish(direction);\n };\n return ()=>{\n handle.cancel();\n };\n }, // Excluding `isFirstMount` from deps to prevent re-triggering the animation on subsequent renders\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n handleRef,\n isReducedMotion,\n handleMotionFinish,\n handleMotionStart,\n visible\n ]);\n if (mounted) {\n return React.cloneElement(child, {\n ref\n });\n }\n return null;\n };\n return Presence;\n}\n"],"names":["createPresenceComponent","shouldSkipAnimation","appear","isFirstMount","visible","value","Presence","props","itemContext","React","useContext","PresenceGroupChildContext","merged","children","imperativeRef","onExit","onMotionFinish","onMotionStart","unmountOnExit","_rest","params","mounted","setMounted","useMountedState","child","getChildElement","handleRef","useMotionImperativeRef","elementRef","useRef","ref","useMergedRefs","optionsRef","useFirstMount","isReducedMotion","useIsReducedMotion","handleMotionStart","useEventCallback","direction","handleMotionFinish","useIsomorphicLayoutEffect","current","element","presenceMotion","atoms","enter","exit","forceFinishMotion","handle","animateAtoms","finish","onfinish","cancel","cloneElement"],"mappings":"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"}
1
+ {"version":3,"sources":["createPresenceComponent.js"],"sourcesContent":["import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { PresenceGroupChildContext } from '../contexts/PresenceGroupChildContext';\nimport { useAnimateAtoms } from '../hooks/useAnimateAtoms';\nimport { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';\nimport { useMountedState } from '../hooks/useMountedState';\nimport { useIsReducedMotion } from '../hooks/useIsReducedMotion';\nimport { getChildElement } from '../utils/getChildElement';\nfunction shouldSkipAnimation(appear, isFirstMount, visible) {\n return !appear && isFirstMount && !!visible;\n}\nexport function createPresenceComponent(value) {\n const Presence = (props)=>{\n 'use no memo';\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = {\n ...itemContext,\n ...props\n };\n const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, onMotionCancel, visible, unmountOnExit, ..._rest } = merged;\n const params = _rest;\n const [mounted, setMounted] = useMountedState(visible, unmountOnExit);\n const child = getChildElement(children);\n const handleRef = useMotionImperativeRef(imperativeRef);\n const elementRef = React.useRef();\n const ref = useMergedRefs(elementRef, child.ref);\n const optionsRef = React.useRef({\n appear,\n params\n });\n const animateAtoms = useAnimateAtoms();\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n const handleMotionStart = useEventCallback((direction)=>{\n onMotionStart === null || onMotionStart === void 0 ? void 0 : onMotionStart(null, {\n direction\n });\n });\n const handleMotionFinish = useEventCallback((direction)=>{\n onMotionFinish === null || onMotionFinish === void 0 ? void 0 : onMotionFinish(null, {\n direction\n });\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit === null || onExit === void 0 ? void 0 : onExit();\n }\n });\n const handleMotionCancel = useEventCallback((direction)=>{\n onMotionCancel === null || onMotionCancel === void 0 ? void 0 : onMotionCancel(null, {\n direction\n });\n });\n useIsomorphicLayoutEffect(()=>{\n // Heads up!\n // We store the params in a ref to avoid re-rendering the component when the params change.\n optionsRef.current = {\n appear,\n params\n };\n });\n useIsomorphicLayoutEffect(()=>{\n const element = elementRef.current;\n if (!element || shouldSkipAnimation(optionsRef.current.appear, isFirstMount, visible)) {\n return;\n }\n const presenceMotion = typeof value === 'function' ? value({\n element,\n ...optionsRef.current.params\n }) : value;\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n const direction = visible ? 'enter' : 'exit';\n const forceFinishMotion = !visible && isFirstMount;\n if (!forceFinishMotion) {\n handleMotionStart(direction);\n }\n const handle = animateAtoms(element, atoms, {\n isReducedMotion: isReducedMotion()\n });\n if (forceFinishMotion) {\n // Heads up!\n // .finish() is used there to skip animation on first mount, but apply animation styles immediately\n handle.finish();\n return;\n }\n handleRef.current = handle;\n handle.setMotionEndCallbacks(()=>handleMotionFinish(direction), ()=>handleMotionCancel(direction));\n return ()=>{\n handle.cancel();\n };\n }, // Excluding `isFirstMount` from deps to prevent re-triggering the animation on subsequent renders\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n animateAtoms,\n handleRef,\n isReducedMotion,\n handleMotionFinish,\n handleMotionStart,\n handleMotionCancel,\n visible\n ]);\n if (mounted) {\n return React.cloneElement(child, {\n ref\n });\n }\n return null;\n };\n return Presence;\n}\n"],"names":["createPresenceComponent","shouldSkipAnimation","appear","isFirstMount","visible","value","Presence","props","itemContext","React","useContext","PresenceGroupChildContext","merged","children","imperativeRef","onExit","onMotionFinish","onMotionStart","onMotionCancel","unmountOnExit","_rest","params","mounted","setMounted","useMountedState","child","getChildElement","handleRef","useMotionImperativeRef","elementRef","useRef","ref","useMergedRefs","optionsRef","animateAtoms","useAnimateAtoms","useFirstMount","isReducedMotion","useIsReducedMotion","handleMotionStart","useEventCallback","direction","handleMotionFinish","handleMotionCancel","useIsomorphicLayoutEffect","current","element","presenceMotion","atoms","enter","exit","forceFinishMotion","handle","finish","setMotionEndCallbacks","cancel","cloneElement"],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useAnimateAtoms", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useAnimateAtoms;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
+ // Heads up! "Element." is a side-effect for minifiers, should be kept as IIFE to avoid leaking after minification.
14
+ const SUPPORTS_WEB_ANIMATIONS = /*@__PURE__*/ (()=>typeof Element.prototype.animate === 'function')();
15
+ /**
16
+ * In test environments, this hook is used to delay the execution of a callback until the next render. This is necessary
17
+ * to ensure that the callback is not executed synchronously, which would cause the test to fail.
18
+ *
19
+ * @see https://github.com/microsoft/fluentui/issues/31701
20
+ */ function useAnimateAtomsInTestEnvironment() {
21
+ const [count, setCount] = _react.useState(0);
22
+ const callbackRef = _react.useRef();
23
+ _react.useEffect(()=>{
24
+ if (count > 0) {
25
+ var _callbackRef_current;
26
+ (_callbackRef_current = callbackRef.current) === null || _callbackRef_current === void 0 ? void 0 : _callbackRef_current.call(callbackRef);
27
+ }
28
+ }, [
29
+ count
30
+ ]);
31
+ return _react.useCallback(()=>{
32
+ return {
33
+ setMotionEndCallbacks (onfinish) {
34
+ callbackRef.current = onfinish;
35
+ setCount((v)=>v + 1);
36
+ },
37
+ set playbackRate (rate){
38
+ /* no-op */ },
39
+ cancel () {
40
+ /* no-op */ },
41
+ pause () {
42
+ /* no-op */ },
43
+ play () {
44
+ /* no-op */ },
45
+ finish () {
46
+ /* no-op */ }
47
+ };
48
+ }, []);
49
+ }
50
+ function useAnimateAtoms() {
51
+ 'use no memo';
52
+ if (process.env.NODE_ENV === 'test' && !SUPPORTS_WEB_ANIMATIONS) {
53
+ // eslint-disable-next-line react-hooks/rules-of-hooks
54
+ return useAnimateAtomsInTestEnvironment();
55
+ }
56
+ // eslint-disable-next-line react-hooks/rules-of-hooks
57
+ return _react.useCallback((element, value, options)=>{
58
+ const atoms = Array.isArray(value) ? value : [
59
+ value
60
+ ];
61
+ const { isReducedMotion } = options;
62
+ const animations = atoms.map((motion)=>{
63
+ const { keyframes, ...params } = motion;
64
+ const animation = element.animate(keyframes, {
65
+ fill: 'forwards',
66
+ ...params,
67
+ ...isReducedMotion && {
68
+ duration: 1
69
+ }
70
+ });
71
+ animation.persist();
72
+ return animation;
73
+ });
74
+ return {
75
+ set playbackRate (rate){
76
+ animations.forEach((animation)=>{
77
+ animation.playbackRate = rate;
78
+ });
79
+ },
80
+ setMotionEndCallbacks (onfinish, oncancel) {
81
+ Promise.all(animations.map((animation)=>animation.finished)).then(()=>{
82
+ onfinish();
83
+ }).catch((err)=>{
84
+ var _element_ownerDocument_defaultView;
85
+ const DOMException = (_element_ownerDocument_defaultView = element.ownerDocument.defaultView) === null || _element_ownerDocument_defaultView === void 0 ? void 0 : _element_ownerDocument_defaultView.DOMException;
86
+ // Ignores "DOMException: The user aborted a request" that appears if animations are cancelled
87
+ if (DOMException && err instanceof DOMException && err.name === 'AbortError') {
88
+ oncancel();
89
+ return;
90
+ }
91
+ throw err;
92
+ });
93
+ },
94
+ cancel: ()=>{
95
+ animations.forEach((animation)=>{
96
+ animation.cancel();
97
+ });
98
+ },
99
+ pause: ()=>{
100
+ animations.forEach((animation)=>{
101
+ animation.pause();
102
+ });
103
+ },
104
+ play: ()=>{
105
+ animations.forEach((animation)=>{
106
+ animation.play();
107
+ });
108
+ },
109
+ finish: ()=>{
110
+ animations.forEach((animation)=>{
111
+ animation.finish();
112
+ });
113
+ }
114
+ };
115
+ }, []);
116
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["useAnimateAtoms.js"],"sourcesContent":["import * as React from 'react';\n// Heads up! \"Element.\" is a side-effect for minifiers, should be kept as IIFE to avoid leaking after minification.\nconst SUPPORTS_WEB_ANIMATIONS = /*@__PURE__*/ (()=>typeof Element.prototype.animate === 'function')();\n/**\n * In test environments, this hook is used to delay the execution of a callback until the next render. This is necessary\n * to ensure that the callback is not executed synchronously, which would cause the test to fail.\n *\n * @see https://github.com/microsoft/fluentui/issues/31701\n */ function useAnimateAtomsInTestEnvironment() {\n const [count, setCount] = React.useState(0);\n const callbackRef = React.useRef();\n React.useEffect(()=>{\n if (count > 0) {\n var _callbackRef_current;\n (_callbackRef_current = callbackRef.current) === null || _callbackRef_current === void 0 ? void 0 : _callbackRef_current.call(callbackRef);\n }\n }, [\n count\n ]);\n return React.useCallback(()=>{\n return {\n setMotionEndCallbacks (onfinish) {\n callbackRef.current = onfinish;\n setCount((v)=>v + 1);\n },\n set playbackRate (rate){\n /* no-op */ },\n cancel () {\n /* no-op */ },\n pause () {\n /* no-op */ },\n play () {\n /* no-op */ },\n finish () {\n /* no-op */ }\n };\n }, []);\n}\n/**\n * @internal\n */ export function useAnimateAtoms() {\n 'use no memo';\n if (process.env.NODE_ENV === 'test' && !SUPPORTS_WEB_ANIMATIONS) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useAnimateAtomsInTestEnvironment();\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return React.useCallback((element, value, options)=>{\n const atoms = Array.isArray(value) ? value : [\n value\n ];\n const { isReducedMotion } = options;\n const animations = atoms.map((motion)=>{\n const { keyframes, ...params } = motion;\n const animation = element.animate(keyframes, {\n fill: 'forwards',\n ...params,\n ...isReducedMotion && {\n duration: 1\n }\n });\n animation.persist();\n return animation;\n });\n return {\n set playbackRate (rate){\n animations.forEach((animation)=>{\n animation.playbackRate = rate;\n });\n },\n setMotionEndCallbacks (onfinish, oncancel) {\n Promise.all(animations.map((animation)=>animation.finished)).then(()=>{\n onfinish();\n }).catch((err)=>{\n var _element_ownerDocument_defaultView;\n const DOMException = (_element_ownerDocument_defaultView = element.ownerDocument.defaultView) === null || _element_ownerDocument_defaultView === void 0 ? void 0 : _element_ownerDocument_defaultView.DOMException;\n // Ignores \"DOMException: The user aborted a request\" that appears if animations are cancelled\n if (DOMException && err instanceof DOMException && err.name === 'AbortError') {\n oncancel();\n return;\n }\n throw err;\n });\n },\n cancel: ()=>{\n animations.forEach((animation)=>{\n animation.cancel();\n });\n },\n pause: ()=>{\n animations.forEach((animation)=>{\n animation.pause();\n });\n },\n play: ()=>{\n animations.forEach((animation)=>{\n animation.play();\n });\n },\n finish: ()=>{\n animations.forEach((animation)=>{\n animation.finish();\n });\n }\n };\n }, []);\n}\n"],"names":["useAnimateAtoms","SUPPORTS_WEB_ANIMATIONS","Element","prototype","animate","useAnimateAtomsInTestEnvironment","count","setCount","React","useState","callbackRef","useRef","useEffect","_callbackRef_current","current","call","useCallback","setMotionEndCallbacks","onfinish","v","playbackRate","rate","cancel","pause","play","finish","process","env","NODE_ENV","element","value","options","atoms","Array","isArray","isReducedMotion","animations","map","motion","keyframes","params","animation","fill","duration","persist","forEach","oncancel","Promise","all","finished","then","catch","err","_element_ownerDocument_defaultView","DOMException","ownerDocument","defaultView","name"],"mappings":";;;;+BAwCoBA;;;eAAAA;;;;iEAxCG;AACvB,mHAAmH;AACnH,MAAMC,0BAAwC,AAAd,WAAW,GAAI,CAAA,IAAI,OAAOC,QAAQC,SAAS,CAACC,OAAO,KAAK,UAAS;AACjG;;;;;CAKC,GAAG,SAASC;IACT,MAAM,CAACC,OAAOC,SAAS,GAAGC,OAAMC,QAAQ,CAAC;IACzC,MAAMC,cAAcF,OAAMG,MAAM;IAChCH,OAAMI,SAAS,CAAC;QACZ,IAAIN,QAAQ,GAAG;YACX,IAAIO;YACHA,CAAAA,uBAAuBH,YAAYI,OAAO,AAAD,MAAO,QAAQD,yBAAyB,KAAK,IAAI,KAAK,IAAIA,qBAAqBE,IAAI,CAACL;QAClI;IACJ,GAAG;QACCJ;KACH;IACD,OAAOE,OAAMQ,WAAW,CAAC;QACrB,OAAO;YACHC,uBAAuBC,QAAQ;gBAC3BR,YAAYI,OAAO,GAAGI;gBACtBX,SAAS,CAACY,IAAIA,IAAI;YACtB;YACA,IAAIC,cAAcC,KAAK;YACvB,SAAS,GAAG;YACZC;YACA,SAAS,GAAG;YACZC;YACA,SAAS,GAAG;YACZC;YACA,SAAS,GAAG;YACZC;YACA,SAAS,GAAG;QAChB;IACJ,GAAG,EAAE;AACT;AAGW,SAASzB;IAChB;IACA,IAAI0B,QAAQC,GAAG,CAACC,QAAQ,KAAK,UAAU,CAAC3B,yBAAyB;QAC7D,sDAAsD;QACtD,OAAOI;IACX;IACA,sDAAsD;IACtD,OAAOG,OAAMQ,WAAW,CAAC,CAACa,SAASC,OAAOC;QACtC,MAAMC,QAAQC,MAAMC,OAAO,CAACJ,SAASA,QAAQ;YACzCA;SACH;QACD,MAAM,EAAEK,eAAe,EAAE,GAAGJ;QAC5B,MAAMK,aAAaJ,MAAMK,GAAG,CAAC,CAACC;YAC1B,MAAM,EAAEC,SAAS,EAAE,GAAGC,QAAQ,GAAGF;YACjC,MAAMG,YAAYZ,QAAQzB,OAAO,CAACmC,WAAW;gBACzCG,MAAM;gBACN,GAAGF,MAAM;gBACT,GAAGL,mBAAmB;oBAClBQ,UAAU;gBACd,CAAC;YACL;YACAF,UAAUG,OAAO;YACjB,OAAOH;QACX;QACA,OAAO;YACH,IAAIrB,cAAcC,KAAK;gBACnBe,WAAWS,OAAO,CAAC,CAACJ;oBAChBA,UAAUrB,YAAY,GAAGC;gBAC7B;YACJ;YACAJ,uBAAuBC,QAAQ,EAAE4B,QAAQ;gBACrCC,QAAQC,GAAG,CAACZ,WAAWC,GAAG,CAAC,CAACI,YAAYA,UAAUQ,QAAQ,GAAGC,IAAI,CAAC;oBAC9DhC;gBACJ,GAAGiC,KAAK,CAAC,CAACC;oBACN,IAAIC;oBACJ,MAAMC,eAAe,AAACD,CAAAA,qCAAqCxB,QAAQ0B,aAAa,CAACC,WAAW,AAAD,MAAO,QAAQH,uCAAuC,KAAK,IAAI,KAAK,IAAIA,mCAAmCC,YAAY;oBAClN,8FAA8F;oBAC9F,IAAIA,gBAAgBF,eAAeE,gBAAgBF,IAAIK,IAAI,KAAK,cAAc;wBAC1EX;wBACA;oBACJ;oBACA,MAAMM;gBACV;YACJ;YACA9B,QAAQ;gBACJc,WAAWS,OAAO,CAAC,CAACJ;oBAChBA,UAAUnB,MAAM;gBACpB;YACJ;YACAC,OAAO;gBACHa,WAAWS,OAAO,CAAC,CAACJ;oBAChBA,UAAUlB,KAAK;gBACnB;YACJ;YACAC,MAAM;gBACFY,WAAWS,OAAO,CAAC,CAACJ;oBAChBA,UAAUjB,IAAI;gBAClB;YACJ;YACAC,QAAQ;gBACJW,WAAWS,OAAO,CAAC,CAACJ;oBAChBA,UAAUhB,MAAM;gBACpB;YACJ;QACJ;IACJ,GAAG,EAAE;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-motion",
3
- "version": "9.1.0",
3
+ "version": "9.2.1",
4
4
  "description": "A package with utilities & motion definitions using Web Animations API",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -25,18 +25,22 @@
25
25
  "start": "yarn storybook",
26
26
  "storybook": "yarn --cwd ../stories storybook",
27
27
  "test": "jest --passWithNoTests",
28
- "type-check": "just-scripts type-check"
28
+ "type-check": "just-scripts type-check",
29
+ "e2e": "cypress run --component",
30
+ "e2e:local": "cypress open --component",
31
+ "bundle-size": "monosize measure"
29
32
  },
30
33
  "devDependencies": {
31
34
  "@fluentui/eslint-plugin": "*",
32
35
  "@fluentui/react-conformance": "*",
33
36
  "@fluentui/react-conformance-griffel": "*",
34
37
  "@fluentui/scripts-api-extractor": "*",
35
- "@fluentui/scripts-tasks": "*"
38
+ "@fluentui/scripts-tasks": "*",
39
+ "@fluentui/scripts-cypress": "*"
36
40
  },
37
41
  "dependencies": {
38
42
  "@fluentui/react-shared-contexts": "^9.19.0",
39
- "@fluentui/react-utilities": "^9.18.10",
43
+ "@fluentui/react-utilities": "^9.18.11",
40
44
  "@swc/helpers": "^0.5.1",
41
45
  "react-is": "^17.0.2"
42
46
  },
@@ -1,74 +0,0 @@
1
- export function animateAtoms(element, value, options) {
2
- // Heads up!
3
- // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. The same is true for
4
- // older browsers that are out of browser support matrix. In these cases, the animation will be a no-op.
5
- const SUPPORTS_WEB_ANIMATIONS = typeof element.animate === 'function';
6
- const atoms = Array.isArray(value) ? value : [
7
- value
8
- ];
9
- const { isReducedMotion } = options;
10
- const animations = SUPPORTS_WEB_ANIMATIONS ? atoms.map((motion)=>{
11
- const { keyframes, ...params } = motion;
12
- const animation = element.animate(keyframes, {
13
- fill: 'forwards',
14
- ...params,
15
- ...isReducedMotion && {
16
- duration: 1
17
- }
18
- });
19
- animation.persist();
20
- return animation;
21
- }) : [];
22
- return {
23
- set playbackRate (rate){
24
- animations.forEach((animation)=>{
25
- animation.playbackRate = rate;
26
- });
27
- },
28
- set onfinish (callback){
29
- // Heads up!
30
- // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. This no-op is
31
- // necessary to avoid errors in tests.
32
- //
33
- // See https://github.com/microsoft/fluentui/issues/31593
34
- // See https://github.com/jsdom/jsdom/issues/3429
35
- if (process.env.NODE_ENV === 'test') {
36
- if (animations.length === 0) {
37
- callback();
38
- return;
39
- }
40
- }
41
- Promise.all(animations.map((animation)=>animation.finished)).then(()=>{
42
- callback();
43
- }).catch((err)=>{
44
- var _element_ownerDocument_defaultView;
45
- const DOMException = (_element_ownerDocument_defaultView = element.ownerDocument.defaultView) === null || _element_ownerDocument_defaultView === void 0 ? void 0 : _element_ownerDocument_defaultView.DOMException;
46
- // Ignores "DOMException: The user aborted a request" that appears if animations are cancelled
47
- if (DOMException && err instanceof DOMException) {
48
- return;
49
- }
50
- throw err;
51
- });
52
- },
53
- cancel: ()=>{
54
- animations.forEach((animation)=>{
55
- animation.cancel();
56
- });
57
- },
58
- pause: ()=>{
59
- animations.forEach((animation)=>{
60
- animation.pause();
61
- });
62
- },
63
- play: ()=>{
64
- animations.forEach((animation)=>{
65
- animation.play();
66
- });
67
- },
68
- finish: ()=>{
69
- animations.forEach((animation)=>{
70
- animation.finish();
71
- });
72
- }
73
- };
74
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["animateAtoms.ts"],"sourcesContent":["import type { AnimationHandle, AtomMotion } from '../types';\n\nexport function animateAtoms(\n element: HTMLElement,\n value: AtomMotion | AtomMotion[],\n options: {\n isReducedMotion: boolean;\n },\n): AnimationHandle {\n // Heads up!\n // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. The same is true for\n // older browsers that are out of browser support matrix. In these cases, the animation will be a no-op.\n const SUPPORTS_WEB_ANIMATIONS = typeof element.animate === 'function';\n\n const atoms = Array.isArray(value) ? value : [value];\n const { isReducedMotion } = options;\n\n const animations = SUPPORTS_WEB_ANIMATIONS\n ? atoms.map(motion => {\n const { keyframes, ...params } = motion;\n const animation = element.animate(keyframes, {\n fill: 'forwards',\n\n ...params,\n ...(isReducedMotion && { duration: 1 }),\n });\n\n animation.persist();\n\n return animation;\n })\n : [];\n\n return {\n set playbackRate(rate: number) {\n animations.forEach(animation => {\n animation.playbackRate = rate;\n });\n },\n set onfinish(callback: () => void) {\n // Heads up!\n // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. This no-op is\n // necessary to avoid errors in tests.\n //\n // See https://github.com/microsoft/fluentui/issues/31593\n // See https://github.com/jsdom/jsdom/issues/3429\n if (process.env.NODE_ENV === 'test') {\n if (animations.length === 0) {\n callback();\n return;\n }\n }\n\n Promise.all(animations.map(animation => animation.finished))\n .then(() => {\n callback();\n })\n .catch((err: unknown) => {\n const DOMException = element.ownerDocument.defaultView?.DOMException;\n\n // Ignores \"DOMException: The user aborted a request\" that appears if animations are cancelled\n if (DOMException && err instanceof DOMException) {\n return;\n }\n\n throw err;\n });\n },\n\n cancel: () => {\n animations.forEach(animation => {\n animation.cancel();\n });\n },\n pause: () => {\n animations.forEach(animation => {\n animation.pause();\n });\n },\n play: () => {\n animations.forEach(animation => {\n animation.play();\n });\n },\n finish: () => {\n animations.forEach(animation => {\n animation.finish();\n });\n },\n };\n}\n"],"names":["animateAtoms","element","value","options","SUPPORTS_WEB_ANIMATIONS","animate","atoms","Array","isArray","isReducedMotion","animations","map","motion","keyframes","params","animation","fill","duration","persist","playbackRate","rate","forEach","onfinish","callback","process","env","NODE_ENV","length","Promise","all","finished","then","catch","err","DOMException","ownerDocument","defaultView","cancel","pause","play","finish"],"mappings":"AAEA,OAAO,SAASA,aACdC,OAAoB,EACpBC,KAAgC,EAChCC,OAEC;IAED,YAAY;IACZ,iHAAiH;IACjH,wGAAwG;IACxG,MAAMC,0BAA0B,OAAOH,QAAQI,OAAO,KAAK;IAE3D,MAAMC,QAAQC,MAAMC,OAAO,CAACN,SAASA,QAAQ;QAACA;KAAM;IACpD,MAAM,EAAEO,eAAe,EAAE,GAAGN;IAE5B,MAAMO,aAAaN,0BACfE,MAAMK,GAAG,CAACC,CAAAA;QACR,MAAM,EAAEC,SAAS,EAAE,GAAGC,QAAQ,GAAGF;QACjC,MAAMG,YAAYd,QAAQI,OAAO,CAACQ,WAAW;YAC3CG,MAAM;YAEN,GAAGF,MAAM;YACT,GAAIL,mBAAmB;gBAAEQ,UAAU;YAAE,CAAC;QACxC;QAEAF,UAAUG,OAAO;QAEjB,OAAOH;IACT,KACA,EAAE;IAEN,OAAO;QACL,IAAII,cAAaC,KAAc;YAC7BV,WAAWW,OAAO,CAACN,CAAAA;gBACjBA,UAAUI,YAAY,GAAGC;YAC3B;QACF;QACA,IAAIE,UAASC,SAAsB;YACjC,YAAY;YACZ,0GAA0G;YAC1G,sCAAsC;YACtC,EAAE;YACF,yDAAyD;YACzD,iDAAiD;YACjD,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;gBACnC,IAAIhB,WAAWiB,MAAM,KAAK,GAAG;oBAC3BJ;oBACA;gBACF;YACF;YAEAK,QAAQC,GAAG,CAACnB,WAAWC,GAAG,CAACI,CAAAA,YAAaA,UAAUe,QAAQ,GACvDC,IAAI,CAAC;gBACJR;YACF,GACCS,KAAK,CAAC,CAACC;oBACehC;gBAArB,MAAMiC,gBAAejC,qCAAAA,QAAQkC,aAAa,CAACC,WAAW,cAAjCnC,yDAAAA,mCAAmCiC,YAAY;gBAEpE,8FAA8F;gBAC9F,IAAIA,gBAAgBD,eAAeC,cAAc;oBAC/C;gBACF;gBAEA,MAAMD;YACR;QACJ;QAEAI,QAAQ;YACN3B,WAAWW,OAAO,CAACN,CAAAA;gBACjBA,UAAUsB,MAAM;YAClB;QACF;QACAC,OAAO;YACL5B,WAAWW,OAAO,CAACN,CAAAA;gBACjBA,UAAUuB,KAAK;YACjB;QACF;QACAC,MAAM;YACJ7B,WAAWW,OAAO,CAACN,CAAAA;gBACjBA,UAAUwB,IAAI;YAChB;QACF;QACAC,QAAQ;YACN9B,WAAWW,OAAO,CAACN,CAAAA;gBACjBA,UAAUyB,MAAM;YAClB;QACF;IACF;AACF"}
@@ -1,84 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "animateAtoms", {
6
- enumerable: true,
7
- get: function() {
8
- return animateAtoms;
9
- }
10
- });
11
- function animateAtoms(element, value, options) {
12
- // Heads up!
13
- // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. The same is true for
14
- // older browsers that are out of browser support matrix. In these cases, the animation will be a no-op.
15
- const SUPPORTS_WEB_ANIMATIONS = typeof element.animate === 'function';
16
- const atoms = Array.isArray(value) ? value : [
17
- value
18
- ];
19
- const { isReducedMotion } = options;
20
- const animations = SUPPORTS_WEB_ANIMATIONS ? atoms.map((motion)=>{
21
- const { keyframes, ...params } = motion;
22
- const animation = element.animate(keyframes, {
23
- fill: 'forwards',
24
- ...params,
25
- ...isReducedMotion && {
26
- duration: 1
27
- }
28
- });
29
- animation.persist();
30
- return animation;
31
- }) : [];
32
- return {
33
- set playbackRate (rate){
34
- animations.forEach((animation)=>{
35
- animation.playbackRate = rate;
36
- });
37
- },
38
- set onfinish (callback){
39
- // Heads up!
40
- // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. This no-op is
41
- // necessary to avoid errors in tests.
42
- //
43
- // See https://github.com/microsoft/fluentui/issues/31593
44
- // See https://github.com/jsdom/jsdom/issues/3429
45
- if (process.env.NODE_ENV === 'test') {
46
- if (animations.length === 0) {
47
- callback();
48
- return;
49
- }
50
- }
51
- Promise.all(animations.map((animation)=>animation.finished)).then(()=>{
52
- callback();
53
- }).catch((err)=>{
54
- var _element_ownerDocument_defaultView;
55
- const DOMException = (_element_ownerDocument_defaultView = element.ownerDocument.defaultView) === null || _element_ownerDocument_defaultView === void 0 ? void 0 : _element_ownerDocument_defaultView.DOMException;
56
- // Ignores "DOMException: The user aborted a request" that appears if animations are cancelled
57
- if (DOMException && err instanceof DOMException) {
58
- return;
59
- }
60
- throw err;
61
- });
62
- },
63
- cancel: ()=>{
64
- animations.forEach((animation)=>{
65
- animation.cancel();
66
- });
67
- },
68
- pause: ()=>{
69
- animations.forEach((animation)=>{
70
- animation.pause();
71
- });
72
- },
73
- play: ()=>{
74
- animations.forEach((animation)=>{
75
- animation.play();
76
- });
77
- },
78
- finish: ()=>{
79
- animations.forEach((animation)=>{
80
- animation.finish();
81
- });
82
- }
83
- };
84
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["animateAtoms.js"],"sourcesContent":["export function animateAtoms(element, value, options) {\n // Heads up!\n // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. The same is true for\n // older browsers that are out of browser support matrix. In these cases, the animation will be a no-op.\n const SUPPORTS_WEB_ANIMATIONS = typeof element.animate === 'function';\n const atoms = Array.isArray(value) ? value : [\n value\n ];\n const { isReducedMotion } = options;\n const animations = SUPPORTS_WEB_ANIMATIONS ? atoms.map((motion)=>{\n const { keyframes, ...params } = motion;\n const animation = element.animate(keyframes, {\n fill: 'forwards',\n ...params,\n ...isReducedMotion && {\n duration: 1\n }\n });\n animation.persist();\n return animation;\n }) : [];\n return {\n set playbackRate (rate){\n animations.forEach((animation)=>{\n animation.playbackRate = rate;\n });\n },\n set onfinish (callback){\n // Heads up!\n // Jest uses jsdom as the default environment, which doesn't support the Web Animations API. This no-op is\n // necessary to avoid errors in tests.\n //\n // See https://github.com/microsoft/fluentui/issues/31593\n // See https://github.com/jsdom/jsdom/issues/3429\n if (process.env.NODE_ENV === 'test') {\n if (animations.length === 0) {\n callback();\n return;\n }\n }\n Promise.all(animations.map((animation)=>animation.finished)).then(()=>{\n callback();\n }).catch((err)=>{\n var _element_ownerDocument_defaultView;\n const DOMException = (_element_ownerDocument_defaultView = element.ownerDocument.defaultView) === null || _element_ownerDocument_defaultView === void 0 ? void 0 : _element_ownerDocument_defaultView.DOMException;\n // Ignores \"DOMException: The user aborted a request\" that appears if animations are cancelled\n if (DOMException && err instanceof DOMException) {\n return;\n }\n throw err;\n });\n },\n cancel: ()=>{\n animations.forEach((animation)=>{\n animation.cancel();\n });\n },\n pause: ()=>{\n animations.forEach((animation)=>{\n animation.pause();\n });\n },\n play: ()=>{\n animations.forEach((animation)=>{\n animation.play();\n });\n },\n finish: ()=>{\n animations.forEach((animation)=>{\n animation.finish();\n });\n }\n };\n}\n"],"names":["animateAtoms","element","value","options","SUPPORTS_WEB_ANIMATIONS","animate","atoms","Array","isArray","isReducedMotion","animations","map","motion","keyframes","params","animation","fill","duration","persist","playbackRate","rate","forEach","onfinish","callback","process","env","NODE_ENV","length","Promise","all","finished","then","catch","err","_element_ownerDocument_defaultView","DOMException","ownerDocument","defaultView","cancel","pause","play","finish"],"mappings":";;;;+BAAgBA;;;eAAAA;;;AAAT,SAASA,aAAaC,OAAO,EAAEC,KAAK,EAAEC,OAAO;IAChD,YAAY;IACZ,iHAAiH;IACjH,wGAAwG;IACxG,MAAMC,0BAA0B,OAAOH,QAAQI,OAAO,KAAK;IAC3D,MAAMC,QAAQC,MAAMC,OAAO,CAACN,SAASA,QAAQ;QACzCA;KACH;IACD,MAAM,EAAEO,eAAe,EAAE,GAAGN;IAC5B,MAAMO,aAAaN,0BAA0BE,MAAMK,GAAG,CAAC,CAACC;QACpD,MAAM,EAAEC,SAAS,EAAE,GAAGC,QAAQ,GAAGF;QACjC,MAAMG,YAAYd,QAAQI,OAAO,CAACQ,WAAW;YACzCG,MAAM;YACN,GAAGF,MAAM;YACT,GAAGL,mBAAmB;gBAClBQ,UAAU;YACd,CAAC;QACL;QACAF,UAAUG,OAAO;QACjB,OAAOH;IACX,KAAK,EAAE;IACP,OAAO;QACH,IAAII,cAAcC,KAAK;YACnBV,WAAWW,OAAO,CAAC,CAACN;gBAChBA,UAAUI,YAAY,GAAGC;YAC7B;QACJ;QACA,IAAIE,UAAUC,SAAS;YACnB,YAAY;YACZ,0GAA0G;YAC1G,sCAAsC;YACtC,EAAE;YACF,yDAAyD;YACzD,iDAAiD;YACjD,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;gBACjC,IAAIhB,WAAWiB,MAAM,KAAK,GAAG;oBACzBJ;oBACA;gBACJ;YACJ;YACAK,QAAQC,GAAG,CAACnB,WAAWC,GAAG,CAAC,CAACI,YAAYA,UAAUe,QAAQ,GAAGC,IAAI,CAAC;gBAC9DR;YACJ,GAAGS,KAAK,CAAC,CAACC;gBACN,IAAIC;gBACJ,MAAMC,eAAe,AAACD,CAAAA,qCAAqCjC,QAAQmC,aAAa,CAACC,WAAW,AAAD,MAAO,QAAQH,uCAAuC,KAAK,IAAI,KAAK,IAAIA,mCAAmCC,YAAY;gBAClN,8FAA8F;gBAC9F,IAAIA,gBAAgBF,eAAeE,cAAc;oBAC7C;gBACJ;gBACA,MAAMF;YACV;QACJ;QACAK,QAAQ;YACJ5B,WAAWW,OAAO,CAAC,CAACN;gBAChBA,UAAUuB,MAAM;YACpB;QACJ;QACAC,OAAO;YACH7B,WAAWW,OAAO,CAAC,CAACN;gBAChBA,UAAUwB,KAAK;YACnB;QACJ;QACAC,MAAM;YACF9B,WAAWW,OAAO,CAAC,CAACN;gBAChBA,UAAUyB,IAAI;YAClB;QACJ;QACAC,QAAQ;YACJ/B,WAAWW,OAAO,CAAC,CAACN;gBAChBA,UAAU0B,MAAM;YACpB;QACJ;IACJ;AACJ"}