@fluentui/react-motion 9.7.0 → 9.7.2
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 +22 -2
- package/lib/components/PresenceGroup.js +1 -0
- package/lib/components/PresenceGroup.js.map +1 -1
- package/lib/factories/createMotionComponent.js +6 -8
- package/lib/factories/createMotionComponent.js.map +1 -1
- package/lib/factories/createPresenceComponent.js +6 -9
- package/lib/factories/createPresenceComponent.js.map +1 -1
- package/lib/utils/useChildElement.js +48 -0
- package/lib/utils/useChildElement.js.map +1 -0
- package/lib-commonjs/components/PresenceGroup.js +1 -0
- package/lib-commonjs/components/PresenceGroup.js.map +1 -1
- package/lib-commonjs/factories/createMotionComponent.js +5 -7
- package/lib-commonjs/factories/createMotionComponent.js.map +1 -1
- package/lib-commonjs/factories/createPresenceComponent.js +5 -8
- package/lib-commonjs/factories/createPresenceComponent.js.map +1 -1
- package/lib-commonjs/utils/useChildElement.js +54 -0
- package/lib-commonjs/utils/useChildElement.js.map +1 -0
- package/package.json +4 -5
- package/lib/utils/getChildElement.js +0 -18
- package/lib/utils/getChildElement.js.map +0 -1
- package/lib-commonjs/utils/getChildElement.js +0 -29
- package/lib-commonjs/utils/getChildElement.js.map +0 -1
package/CHANGELOG.md
CHANGED
@@ -1,12 +1,32 @@
|
|
1
1
|
# Change Log - @fluentui/react-motion
|
2
2
|
|
3
|
-
This log was last generated on Wed,
|
3
|
+
This log was last generated on Wed, 16 Apr 2025 19:37:11 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.7.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.7.2)
|
8
|
+
|
9
|
+
Wed, 16 Apr 2025 19:37:11 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.7.1..@fluentui/react-motion_v9.7.2)
|
11
|
+
|
12
|
+
### Patches
|
13
|
+
|
14
|
+
- fix: improve element validation to work with React 19 ([PR #34164](https://github.com/microsoft/fluentui/pull/34164) by olfedias@microsoft.com)
|
15
|
+
- Bump @fluentui/react-utilities to v9.19.0 ([PR #34166](https://github.com/microsoft/fluentui/pull/34166) by beachball)
|
16
|
+
|
17
|
+
## [9.7.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.7.1)
|
18
|
+
|
19
|
+
Thu, 27 Mar 2025 21:12:51 GMT
|
20
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.7.0..@fluentui/react-motion_v9.7.1)
|
21
|
+
|
22
|
+
### Patches
|
23
|
+
|
24
|
+
- Bump @fluentui/react-shared-contexts to v9.23.1 ([PR #34034](https://github.com/microsoft/fluentui/pull/34034) by beachball)
|
25
|
+
- Bump @fluentui/react-utilities to v9.18.23 ([PR #34034](https://github.com/microsoft/fluentui/pull/34034) by beachball)
|
26
|
+
|
7
27
|
## [9.7.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.7.0)
|
8
28
|
|
9
|
-
Wed, 26 Mar 2025 21:46
|
29
|
+
Wed, 26 Mar 2025 21:47:46 GMT
|
10
30
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.6.10..@fluentui/react-motion_v9.7.0)
|
11
31
|
|
12
32
|
### Minor changes
|
@@ -26,6 +26,7 @@ import { PresenceGroupItemProvider } from './PresenceGroupItemProvider';
|
|
26
26
|
}, childProps.element)));
|
27
27
|
}
|
28
28
|
constructor(props, context){
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
29
30
|
super(props, context);
|
30
31
|
_define_property(this, "mounted", false);
|
31
32
|
_define_property(this, "handleExit", (childKey)=>{
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/components/PresenceGroup.tsx"],"sourcesContent":["import * as React from 'react';\
|
1
|
+
{"version":3,"sources":["../src/components/PresenceGroup.tsx"],"sourcesContent":["import * as React from 'react';\nimport { getNextChildMapping } from '../utils/groups/getNextChildMapping';\nimport { getChildMapping } from '../utils/groups/getChildMapping';\nimport type { PresenceGroupChildMapping } from '../utils/groups/types';\nimport { PresenceGroupItemProvider } from './PresenceGroupItemProvider';\n\ntype PresenceGroupProps = {\n children: React.ReactNode;\n};\n\ntype PresenceGroupState = {\n childMapping: PresenceGroupChildMapping;\n firstRender: boolean;\n};\n\n/* eslint-disable @typescript-eslint/explicit-member-accessibility */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/member-ordering */\n\nexport class PresenceGroup extends React.Component<PresenceGroupProps, PresenceGroupState> {\n private mounted: boolean = false;\n\n static getDerivedStateFromProps(\n nextProps: PresenceGroupProps,\n { childMapping: prevChildMapping, firstRender }: PresenceGroupState,\n ) {\n const nextChildMapping = getChildMapping(nextProps.children);\n\n return {\n childMapping: firstRender ? nextChildMapping : getNextChildMapping(prevChildMapping, nextChildMapping),\n firstRender: false,\n };\n }\n\n constructor(props: PresenceGroupProps, context: unknown) {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n super(props, context);\n\n this.state = {\n childMapping: {},\n firstRender: true,\n };\n }\n\n private handleExit = (childKey: string) => {\n const currentChildMapping = getChildMapping(this.props.children);\n\n if (childKey in currentChildMapping) {\n return;\n }\n\n if (this.mounted) {\n this.setState(state => {\n const childMapping = { ...state.childMapping };\n delete childMapping[childKey];\n\n return { childMapping };\n });\n }\n };\n\n componentDidMount() {\n this.mounted = true;\n }\n\n componentWillUnmount() {\n this.mounted = false;\n }\n\n render() {\n return (\n <>\n {Object.entries(this.state.childMapping).map(([childKey, childProps]) => (\n <PresenceGroupItemProvider {...childProps} childKey={childKey} key={childKey} onExit={this.handleExit}>\n {childProps.element}\n </PresenceGroupItemProvider>\n ))}\n </>\n );\n }\n}\n"],"names":["React","getNextChildMapping","getChildMapping","PresenceGroupItemProvider","PresenceGroup","Component","getDerivedStateFromProps","nextProps","childMapping","prevChildMapping","firstRender","nextChildMapping","children","componentDidMount","mounted","componentWillUnmount","render","Object","entries","state","map","childKey","childProps","key","onExit","handleExit","element","constructor","props","context","currentChildMapping","setState"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,mBAAmB,QAAQ,sCAAsC;AAC1E,SAASC,eAAe,QAAQ,kCAAkC;AAElE,SAASC,yBAAyB,QAAQ,8BAA8B;AAWxE,mEAAmE,GACnE,uDAAuD,GACvD,qDAAqD,GAErD,OAAO,MAAMC,sBAAsBJ,MAAMK,SAAS;IAGhD,OAAOC,yBACLC,SAA6B,EAC7B,EAAEC,cAAcC,gBAAgB,EAAEC,WAAW,EAAsB,EACnE;QACA,MAAMC,mBAAmBT,gBAAgBK,UAAUK,QAAQ;QAE3D,OAAO;YACLJ,cAAcE,cAAcC,mBAAmBV,oBAAoBQ,kBAAkBE;YACrFD,aAAa;QACf;IACF;IA6BAG,oBAAoB;QAClB,IAAI,CAACC,OAAO,GAAG;IACjB;IAEAC,uBAAuB;QACrB,IAAI,CAACD,OAAO,GAAG;IACjB;IAEAE,SAAS;QACP,qBACE,0CACGC,OAAOC,OAAO,CAAC,IAAI,CAACC,KAAK,CAACX,YAAY,EAAEY,GAAG,CAAC,CAAC,CAACC,UAAUC,WAAW,iBAClE,oBAACnB;gBAA2B,GAAGmB,UAAU;gBAAED,UAAUA;gBAAUE,KAAKF;gBAAUG,QAAQ,IAAI,CAACC,UAAU;eAClGH,WAAWI,OAAO;IAK7B;IA7CAC,YAAYC,KAAyB,EAAEC,OAAgB,CAAE;QACvD,4DAA4D;QAC5D,KAAK,CAACD,OAAOC;QAhBf,uBAAQf,WAAmB;QAwB3B,uBAAQW,cAAa,CAACJ;YACpB,MAAMS,sBAAsB5B,gBAAgB,IAAI,CAAC0B,KAAK,CAAChB,QAAQ;YAE/D,IAAIS,YAAYS,qBAAqB;gBACnC;YACF;YAEA,IAAI,IAAI,CAAChB,OAAO,EAAE;gBAChB,IAAI,CAACiB,QAAQ,CAACZ,CAAAA;oBACZ,MAAMX,eAAe;wBAAE,GAAGW,MAAMX,YAAY;oBAAC;oBAC7C,OAAOA,YAAY,CAACa,SAAS;oBAE7B,OAAO;wBAAEb;oBAAa;gBACxB;YACF;QACF;QArBE,IAAI,CAACW,KAAK,GAAG;YACXX,cAAc,CAAC;YACfE,aAAa;QACf;IACF;AAsCF"}
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import { useEventCallback, useIsomorphicLayoutEffect
|
1
|
+
import { useEventCallback, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
|
2
2
|
import * as React from 'react';
|
3
3
|
import { useAnimateAtoms } from '../hooks/useAnimateAtoms';
|
4
4
|
import { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';
|
5
5
|
import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
|
6
|
-
import {
|
6
|
+
import { useChildElement } from '../utils/useChildElement';
|
7
7
|
import { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';
|
8
8
|
/**
|
9
9
|
* Creates a component that will animate the children using the provided motion.
|
@@ -14,9 +14,8 @@ import { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';
|
|
14
14
|
'use no memo';
|
15
15
|
const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, onMotionCancel: onMotionCancelProp, ..._rest } = props;
|
16
16
|
const params = _rest;
|
17
|
-
const child =
|
17
|
+
const [child, childRef] = useChildElement(children);
|
18
18
|
const handleRef = useMotionImperativeRef(imperativeRef);
|
19
|
-
const elementRef = React.useRef();
|
20
19
|
const skipMotions = useMotionBehaviourContext() === 'skip';
|
21
20
|
const optionsRef = React.useRef({
|
22
21
|
skipMotions,
|
@@ -42,7 +41,7 @@ import { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';
|
|
42
41
|
};
|
43
42
|
});
|
44
43
|
useIsomorphicLayoutEffect(()=>{
|
45
|
-
const element =
|
44
|
+
const element = childRef.current;
|
46
45
|
if (element) {
|
47
46
|
const atoms = typeof value === 'function' ? value({
|
48
47
|
element,
|
@@ -63,15 +62,14 @@ import { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';
|
|
63
62
|
}
|
64
63
|
}, [
|
65
64
|
animateAtoms,
|
65
|
+
childRef,
|
66
66
|
handleRef,
|
67
67
|
isReducedMotion,
|
68
68
|
onMotionFinish,
|
69
69
|
onMotionStart,
|
70
70
|
onMotionCancel
|
71
71
|
]);
|
72
|
-
return
|
73
|
-
ref: useMergedRefs(elementRef, child.ref)
|
74
|
-
});
|
72
|
+
return child;
|
75
73
|
};
|
76
74
|
return Atom;
|
77
75
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/factories/createMotionComponent.ts"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect
|
1
|
+
{"version":3,"sources":["../src/factories/createMotionComponent.ts"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect } 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 { useChildElement } from '../utils/useChildElement';\nimport type { AtomMotion, AtomMotionFn, MotionParam, MotionImperativeRef } from '../types';\nimport { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';\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, childRef] = useChildElement(children);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const skipMotions = useMotionBehaviourContext() === 'skip';\n const optionsRef = React.useRef<{ skipMotions: boolean; params: MotionParams }>({\n skipMotions,\n params,\n });\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 optionsRef.current = { skipMotions, params };\n });\n\n useIsomorphicLayoutEffect(() => {\n const element = childRef.current;\n\n if (element) {\n const atoms = typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : value;\n\n onMotionStart();\n const handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n handleRef.current = handle;\n handle.setMotionEndCallbacks(onMotionFinish, onMotionCancel);\n\n if (optionsRef.current.skipMotions) {\n handle.finish();\n }\n\n return () => {\n handle.cancel();\n };\n }\n }, [animateAtoms, childRef, handleRef, isReducedMotion, onMotionFinish, onMotionStart, onMotionCancel]);\n\n return child;\n };\n\n return Atom;\n}\n"],"names":["useEventCallback","useIsomorphicLayoutEffect","React","useAnimateAtoms","useMotionImperativeRef","useIsReducedMotion","useChildElement","useMotionBehaviourContext","createMotionComponent","value","Atom","props","children","imperativeRef","onMotionFinish","onMotionFinishProp","onMotionStart","onMotionStartProp","onMotionCancel","onMotionCancelProp","_rest","params","child","childRef","handleRef","skipMotions","optionsRef","useRef","animateAtoms","isReducedMotion","current","element","atoms","handle","setMotionEndCallbacks","finish","cancel"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,gBAAgB,EAAEC,yBAAyB,QAAQ,4BAA4B;AACxF,YAAYC,WAAW,QAAQ;AAE/B,SAASC,eAAe,QAAQ,2BAA2B;AAC3D,SAASC,sBAAsB,QAAQ,kCAAkC;AACzE,SAASC,kBAAkB,QAAQ,8BAA8B;AACjE,SAASC,eAAe,QAAQ,2BAA2B;AAE3D,SAASC,yBAAyB,QAAQ,qCAAqC;AAqC/E;;;;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,MAAM,CAACE,OAAOC,SAAS,GAAGjB,gBAAgBM;QAE1C,MAAMY,YAAYpB,uBAAuBS;QACzC,MAAMY,cAAclB,gCAAgC;QACpD,MAAMmB,aAAaxB,MAAMyB,MAAM,CAAiD;YAC9EF;YACAJ;QACF;QAEA,MAAMO,eAAezB;QACrB,MAAM0B,kBAAkBxB;QAExB,MAAMW,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,WAAWI,OAAO,GAAG;gBAAEL;gBAAaJ;YAAO;QAC7C;QAEApB,0BAA0B;YACxB,MAAM8B,UAAUR,SAASO,OAAO;YAEhC,IAAIC,SAAS;gBACX,MAAMC,QAAQ,OAAOvB,UAAU,aAAaA,MAAM;oBAAEsB;oBAAS,GAAGL,WAAWI,OAAO,CAACT,MAAM;gBAAC,KAAKZ;gBAE/FO;gBACA,MAAMiB,SAASL,aAAaG,SAASC,OAAO;oBAAEH,iBAAiBA;gBAAkB;gBACjFL,UAAUM,OAAO,GAAGG;gBACpBA,OAAOC,qBAAqB,CAACpB,gBAAgBI;gBAE7C,IAAIQ,WAAWI,OAAO,CAACL,WAAW,EAAE;oBAClCQ,OAAOE,MAAM;gBACf;gBAEA,OAAO;oBACLF,OAAOG,MAAM;gBACf;YACF;QACF,GAAG;YAACR;YAAcL;YAAUC;YAAWK;YAAiBf;YAAgBE;YAAeE;SAAe;QAEtG,OAAOI;IACT;IAEA,OAAOZ;AACT"}
|
@@ -1,11 +1,11 @@
|
|
1
|
-
import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect
|
1
|
+
import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
|
2
2
|
import * as React from 'react';
|
3
3
|
import { PresenceGroupChildContext } from '../contexts/PresenceGroupChildContext';
|
4
4
|
import { useAnimateAtoms } from '../hooks/useAnimateAtoms';
|
5
5
|
import { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';
|
6
6
|
import { useMountedState } from '../hooks/useMountedState';
|
7
7
|
import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
|
8
|
-
import {
|
8
|
+
import { useChildElement } from '../utils/useChildElement';
|
9
9
|
import { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';
|
10
10
|
/**
|
11
11
|
* @internal A private symbol to store the motion definition on the component for variants.
|
@@ -23,10 +23,8 @@ export function createPresenceComponent(value) {
|
|
23
23
|
const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, onMotionCancel, visible, unmountOnExit, ..._rest } = merged;
|
24
24
|
const params = _rest;
|
25
25
|
const [mounted, setMounted] = useMountedState(visible, unmountOnExit);
|
26
|
-
const child =
|
26
|
+
const [child, childRef] = useChildElement(children, mounted);
|
27
27
|
const handleRef = useMotionImperativeRef(imperativeRef);
|
28
|
-
const elementRef = React.useRef();
|
29
|
-
const ref = useMergedRefs(elementRef, child.ref);
|
30
28
|
const optionsRef = React.useRef({
|
31
29
|
appear,
|
32
30
|
params,
|
@@ -64,7 +62,7 @@ export function createPresenceComponent(value) {
|
|
64
62
|
};
|
65
63
|
});
|
66
64
|
useIsomorphicLayoutEffect(()=>{
|
67
|
-
const element =
|
65
|
+
const element = childRef.current;
|
68
66
|
if (!element) {
|
69
67
|
return;
|
70
68
|
}
|
@@ -123,6 +121,7 @@ export function createPresenceComponent(value) {
|
|
123
121
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
124
122
|
[
|
125
123
|
animateAtoms,
|
124
|
+
childRef,
|
126
125
|
handleRef,
|
127
126
|
isReducedMotion,
|
128
127
|
handleMotionFinish,
|
@@ -131,9 +130,7 @@ export function createPresenceComponent(value) {
|
|
131
130
|
visible
|
132
131
|
]);
|
133
132
|
if (mounted) {
|
134
|
-
return
|
135
|
-
ref
|
136
|
-
});
|
133
|
+
return child;
|
137
134
|
}
|
138
135
|
return null;
|
139
136
|
}, {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/factories/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 {\n MotionParam,\n PresenceMotion,\n MotionImperativeRef,\n PresenceMotionFn,\n PresenceDirection,\n AnimationHandle,\n} from '../types';\nimport { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';\n\n/**\n * @internal A private symbol to store the motion definition on the component for variants.\n */\nexport const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');\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: PresenceDirection }) => 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: PresenceDirection }) => 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: PresenceDirection }) => 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\nexport type PresenceComponent<MotionParams extends Record<string, MotionParam> = {}> = {\n (props: PresenceComponentProps & MotionParams): React.ReactElement | null;\n [MOTION_DEFINITION]: PresenceMotionFn<MotionParams>;\n};\n\nconst INTERRUPTABLE_MOTION_SYMBOL = Symbol.for('interruptablePresence');\n\nexport function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: PresenceMotion | PresenceMotionFn<MotionParams>,\n): PresenceComponent<MotionParams> {\n return Object.assign(\n (props: PresenceComponentProps & MotionParams) => {\n 'use no memo';\n\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = { ...itemContext, ...props };\n const skipMotions = useMotionBehaviourContext() === 'skip';\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; skipMotions: boolean }>({\n appear,\n params,\n skipMotions,\n });\n\n const animateAtoms = useAnimateAtoms();\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n\n const handleMotionStart = useEventCallback((direction: PresenceDirection) => {\n onMotionStart?.(null, { direction });\n });\n const handleMotionFinish = useEventCallback((direction: PresenceDirection) => {\n onMotionFinish?.(null, { direction });\n\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit?.();\n }\n });\n\n const handleMotionCancel = useEventCallback((direction: PresenceDirection) => {\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, skipMotions };\n });\n\n useIsomorphicLayoutEffect(\n () => {\n const element = elementRef.current;\n\n if (!element) {\n return;\n }\n\n let handle: AnimationHandle | undefined;\n\n function cleanup() {\n if (!handle) {\n return;\n }\n\n // Heads up!\n //\n // If the animation is interruptible & is running, we don't want to cancel it as it will be reversed in\n // the next effect.\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION && handle.isRunning()) {\n return;\n }\n\n handle.cancel();\n handleRef.current = undefined;\n }\n\n const presenceMotion =\n typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : (value as PresenceMotion);\n const IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION = (\n presenceMotion as PresenceMotion & { [INTERRUPTABLE_MOTION_SYMBOL]?: boolean }\n )[INTERRUPTABLE_MOTION_SYMBOL];\n\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION) {\n handle = handleRef.current;\n\n if (handle && handle.isRunning()) {\n handle.reverse();\n\n return cleanup;\n }\n }\n\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n const direction: PresenceDirection = visible ? 'enter' : 'exit';\n\n // Heads up!\n // Initial styles are applied when the component is mounted for the first time and \"appear\" is set to \"false\" (otherwise animations are triggered)\n const applyInitialStyles = !optionsRef.current.appear && isFirstMount;\n const skipAnimationByConfig = optionsRef.current.skipMotions;\n\n if (!applyInitialStyles) {\n handleMotionStart(direction);\n }\n\n handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n if (applyInitialStyles) {\n // Heads up!\n // .finish() is used in this case to skip animation and apply animation styles immediately\n handle.finish();\n\n return cleanup;\n }\n\n handleRef.current = handle;\n handle.setMotionEndCallbacks(\n () => handleMotionFinish(direction),\n () => handleMotionCancel(direction),\n );\n\n if (skipAnimationByConfig) {\n handle.finish();\n }\n\n return cleanup;\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 // Heads up!\n // Always normalize it to a function to simplify types\n [MOTION_DEFINITION]: typeof value === 'function' ? value : () => value,\n },\n );\n}\n"],"names":["useEventCallback","useFirstMount","useIsomorphicLayoutEffect","useMergedRefs","React","PresenceGroupChildContext","useAnimateAtoms","useMotionImperativeRef","useMountedState","useIsReducedMotion","getChildElement","useMotionBehaviourContext","MOTION_DEFINITION","Symbol","INTERRUPTABLE_MOTION_SYMBOL","for","createPresenceComponent","value","Object","assign","props","itemContext","useContext","merged","skipMotions","appear","children","imperativeRef","onExit","onMotionFinish","onMotionStart","onMotionCancel","visible","unmountOnExit","_rest","params","mounted","setMounted","child","handleRef","elementRef","useRef","ref","optionsRef","animateAtoms","isFirstMount","isReducedMotion","handleMotionStart","direction","handleMotionFinish","handleMotionCancel","current","element","handle","cleanup","IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION","isRunning","cancel","undefined","presenceMotion","reverse","atoms","enter","exit","applyInitialStyles","skipAnimationByConfig","finish","setMotionEndCallbacks","cloneElement"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
1
|
+
{"version":3,"sources":["../src/factories/createPresenceComponent.ts"],"sourcesContent":["import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect } 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 { useChildElement } from '../utils/useChildElement';\nimport type {\n MotionParam,\n PresenceMotion,\n MotionImperativeRef,\n PresenceMotionFn,\n PresenceDirection,\n AnimationHandle,\n} from '../types';\nimport { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';\n\n/**\n * @internal A private symbol to store the motion definition on the component for variants.\n */\nexport const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');\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: PresenceDirection }) => 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: PresenceDirection }) => 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: PresenceDirection }) => 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\nexport type PresenceComponent<MotionParams extends Record<string, MotionParam> = {}> = {\n (props: PresenceComponentProps & MotionParams): React.ReactElement | null;\n [MOTION_DEFINITION]: PresenceMotionFn<MotionParams>;\n};\n\nconst INTERRUPTABLE_MOTION_SYMBOL = Symbol.for('interruptablePresence');\n\nexport function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: PresenceMotion | PresenceMotionFn<MotionParams>,\n): PresenceComponent<MotionParams> {\n return Object.assign(\n (props: PresenceComponentProps & MotionParams) => {\n 'use no memo';\n\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = { ...itemContext, ...props };\n const skipMotions = useMotionBehaviourContext() === 'skip';\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, childRef] = useChildElement(children, mounted);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const optionsRef = React.useRef<{ appear?: boolean; params: MotionParams; skipMotions: boolean }>({\n appear,\n params,\n skipMotions,\n });\n\n const animateAtoms = useAnimateAtoms();\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n\n const handleMotionStart = useEventCallback((direction: PresenceDirection) => {\n onMotionStart?.(null, { direction });\n });\n const handleMotionFinish = useEventCallback((direction: PresenceDirection) => {\n onMotionFinish?.(null, { direction });\n\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit?.();\n }\n });\n\n const handleMotionCancel = useEventCallback((direction: PresenceDirection) => {\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, skipMotions };\n });\n\n useIsomorphicLayoutEffect(\n () => {\n const element = childRef.current;\n\n if (!element) {\n return;\n }\n\n let handle: AnimationHandle | undefined;\n\n function cleanup() {\n if (!handle) {\n return;\n }\n\n // Heads up!\n //\n // If the animation is interruptible & is running, we don't want to cancel it as it will be reversed in\n // the next effect.\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION && handle.isRunning()) {\n return;\n }\n\n handle.cancel();\n handleRef.current = undefined;\n }\n\n const presenceMotion =\n typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : (value as PresenceMotion);\n const IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION = (\n presenceMotion as PresenceMotion & { [INTERRUPTABLE_MOTION_SYMBOL]?: boolean }\n )[INTERRUPTABLE_MOTION_SYMBOL];\n\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION) {\n handle = handleRef.current;\n\n if (handle && handle.isRunning()) {\n handle.reverse();\n\n return cleanup;\n }\n }\n\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n const direction: PresenceDirection = visible ? 'enter' : 'exit';\n\n // Heads up!\n // Initial styles are applied when the component is mounted for the first time and \"appear\" is set to \"false\" (otherwise animations are triggered)\n const applyInitialStyles = !optionsRef.current.appear && isFirstMount;\n const skipAnimationByConfig = optionsRef.current.skipMotions;\n\n if (!applyInitialStyles) {\n handleMotionStart(direction);\n }\n\n handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n if (applyInitialStyles) {\n // Heads up!\n // .finish() is used in this case to skip animation and apply animation styles immediately\n handle.finish();\n\n return cleanup;\n }\n\n handleRef.current = handle;\n handle.setMotionEndCallbacks(\n () => handleMotionFinish(direction),\n () => handleMotionCancel(direction),\n );\n\n if (skipAnimationByConfig) {\n handle.finish();\n }\n\n return cleanup;\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 childRef,\n handleRef,\n isReducedMotion,\n handleMotionFinish,\n handleMotionStart,\n handleMotionCancel,\n visible,\n ],\n );\n\n if (mounted) {\n return child;\n }\n\n return null;\n },\n {\n // Heads up!\n // Always normalize it to a function to simplify types\n [MOTION_DEFINITION]: typeof value === 'function' ? value : () => value,\n },\n );\n}\n"],"names":["useEventCallback","useFirstMount","useIsomorphicLayoutEffect","React","PresenceGroupChildContext","useAnimateAtoms","useMotionImperativeRef","useMountedState","useIsReducedMotion","useChildElement","useMotionBehaviourContext","MOTION_DEFINITION","Symbol","INTERRUPTABLE_MOTION_SYMBOL","for","createPresenceComponent","value","Object","assign","props","itemContext","useContext","merged","skipMotions","appear","children","imperativeRef","onExit","onMotionFinish","onMotionStart","onMotionCancel","visible","unmountOnExit","_rest","params","mounted","setMounted","child","childRef","handleRef","optionsRef","useRef","animateAtoms","isFirstMount","isReducedMotion","handleMotionStart","direction","handleMotionFinish","handleMotionCancel","current","element","handle","cleanup","IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION","isRunning","cancel","undefined","presenceMotion","reverse","atoms","enter","exit","applyInitialStyles","skipAnimationByConfig","finish","setMotionEndCallbacks"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import { useMergedRefs } from '@fluentui/react-utilities';
|
3
|
+
const IS_REACT_19 = React.version.startsWith('19.');
|
4
|
+
const CHILD_ERROR_MESSAGE = [
|
5
|
+
'@fluentui/react-motion: Invalid child element.',
|
6
|
+
'\n',
|
7
|
+
'Motion factories require a single child element to be passed. ',
|
8
|
+
'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().'
|
9
|
+
].join('');
|
10
|
+
/**
|
11
|
+
* A backwards-compatible way to get the ref from a React element without console errors.
|
12
|
+
*/ function getRefFromReactElement(element) {
|
13
|
+
if (IS_REACT_19) {
|
14
|
+
return element.props.ref;
|
15
|
+
}
|
16
|
+
return element.ref;
|
17
|
+
}
|
18
|
+
/**
|
19
|
+
* Validates the child and returns a cloned child element with a ref.
|
20
|
+
*
|
21
|
+
* Throws an error if the child is not a valid React element, similar to "React.Children.only".
|
22
|
+
* Logs a warning in development mode if the ref is not set as the component remains functional.
|
23
|
+
*/ export function useChildElement(children, mounted = true) {
|
24
|
+
const childRef = React.useRef(null);
|
25
|
+
React.useEffect(()=>{
|
26
|
+
if (process.env.NODE_ENV !== 'production') {
|
27
|
+
if (mounted && !childRef.current) {
|
28
|
+
// eslint-disable-next-line no-console
|
29
|
+
console.error(CHILD_ERROR_MESSAGE);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}, [
|
33
|
+
mounted
|
34
|
+
]);
|
35
|
+
try {
|
36
|
+
const child = React.Children.only(children);
|
37
|
+
if (React.isValidElement(child)) {
|
38
|
+
return [
|
39
|
+
React.cloneElement(child, {
|
40
|
+
ref: useMergedRefs(childRef, getRefFromReactElement(child))
|
41
|
+
}),
|
42
|
+
childRef
|
43
|
+
];
|
44
|
+
}
|
45
|
+
} catch {
|
46
|
+
/* empty */ }
|
47
|
+
throw new Error(CHILD_ERROR_MESSAGE);
|
48
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/utils/useChildElement.ts"],"sourcesContent":["import * as React from 'react';\nimport { useMergedRefs } from '@fluentui/react-utilities';\n\nconst IS_REACT_19 = React.version.startsWith('19.');\nconst CHILD_ERROR_MESSAGE = [\n '@fluentui/react-motion: Invalid child element.',\n '\\n',\n 'Motion factories require a single child element to be passed. ',\n 'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().',\n].join('');\n\n/**\n * A backwards-compatible way to get the ref from a React element without console errors.\n */\nfunction getRefFromReactElement<T>(element: React.ReactElement): React.Ref<T> | undefined {\n if (IS_REACT_19) {\n return element.props.ref;\n }\n\n return (element as React.ReactElement & { ref: React.Ref<T> | undefined }).ref;\n}\n\n/**\n * Validates the child and returns a cloned child element with a ref.\n *\n * Throws an error if the child is not a valid React element, similar to \"React.Children.only\".\n * Logs a warning in development mode if the ref is not set as the component remains functional.\n */\nexport function useChildElement(\n children: React.ReactElement,\n mounted: boolean = true,\n): [React.ReactElement, React.RefObject<HTMLElement>] {\n const childRef = React.useRef<HTMLElement>(null);\n\n React.useEffect(() => {\n if (process.env.NODE_ENV !== 'production') {\n if (mounted && !childRef.current) {\n // eslint-disable-next-line no-console\n console.error(CHILD_ERROR_MESSAGE);\n }\n }\n }, [mounted]);\n\n try {\n const child = React.Children.only(children) as Parameters<typeof React.isValidElement>[0];\n\n if (React.isValidElement(child)) {\n return [\n React.cloneElement(child as React.ReactElement<{ ref: React.Ref<HTMLElement> }>, {\n ref: useMergedRefs(childRef, getRefFromReactElement(child)),\n }),\n childRef,\n ];\n }\n } catch {\n /* empty */\n }\n\n throw new Error(CHILD_ERROR_MESSAGE);\n}\n"],"names":["React","useMergedRefs","IS_REACT_19","version","startsWith","CHILD_ERROR_MESSAGE","join","getRefFromReactElement","element","props","ref","useChildElement","children","mounted","childRef","useRef","useEffect","process","env","NODE_ENV","current","console","error","child","Children","only","isValidElement","cloneElement","Error"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,aAAa,QAAQ,4BAA4B;AAE1D,MAAMC,cAAcF,MAAMG,OAAO,CAACC,UAAU,CAAC;AAC7C,MAAMC,sBAAsB;IAC1B;IACA;IACA;IACA;CACD,CAACC,IAAI,CAAC;AAEP;;CAEC,GACD,SAASC,uBAA0BC,OAA2B;IAC5D,IAAIN,aAAa;QACf,OAAOM,QAAQC,KAAK,CAACC,GAAG;IAC1B;IAEA,OAAO,AAACF,QAAmEE,GAAG;AAChF;AAEA;;;;;CAKC,GACD,OAAO,SAASC,gBACdC,QAA4B,EAC5BC,UAAmB,IAAI;IAEvB,MAAMC,WAAWd,MAAMe,MAAM,CAAc;IAE3Cf,MAAMgB,SAAS,CAAC;QACd,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,IAAIN,WAAW,CAACC,SAASM,OAAO,EAAE;gBAChC,sCAAsC;gBACtCC,QAAQC,KAAK,CAACjB;YAChB;QACF;IACF,GAAG;QAACQ;KAAQ;IAEZ,IAAI;QACF,MAAMU,QAAQvB,MAAMwB,QAAQ,CAACC,IAAI,CAACb;QAElC,IAAIZ,MAAM0B,cAAc,CAACH,QAAQ;YAC/B,OAAO;gBACLvB,MAAM2B,YAAY,CAACJ,OAA8D;oBAC/Eb,KAAKT,cAAca,UAAUP,uBAAuBgB;gBACtD;gBACAT;aACD;QACH;IACF,EAAE,OAAM;IACN,SAAS,GACX;IAEA,MAAM,IAAIc,MAAMvB;AAClB"}
|
@@ -37,6 +37,7 @@ class PresenceGroup extends _react.Component {
|
|
37
37
|
}, childProps.element)));
|
38
38
|
}
|
39
39
|
constructor(props, context){
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
40
41
|
super(props, context);
|
41
42
|
_define_property._(this, "mounted", false);
|
42
43
|
_define_property._(this, "handleExit", (childKey)=>{
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/components/PresenceGroup.tsx"],"sourcesContent":["import * as React from 'react';\
|
1
|
+
{"version":3,"sources":["../src/components/PresenceGroup.tsx"],"sourcesContent":["import * as React from 'react';\nimport { getNextChildMapping } from '../utils/groups/getNextChildMapping';\nimport { getChildMapping } from '../utils/groups/getChildMapping';\nimport type { PresenceGroupChildMapping } from '../utils/groups/types';\nimport { PresenceGroupItemProvider } from './PresenceGroupItemProvider';\n\ntype PresenceGroupProps = {\n children: React.ReactNode;\n};\n\ntype PresenceGroupState = {\n childMapping: PresenceGroupChildMapping;\n firstRender: boolean;\n};\n\n/* eslint-disable @typescript-eslint/explicit-member-accessibility */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/member-ordering */\n\nexport class PresenceGroup extends React.Component<PresenceGroupProps, PresenceGroupState> {\n private mounted: boolean = false;\n\n static getDerivedStateFromProps(\n nextProps: PresenceGroupProps,\n { childMapping: prevChildMapping, firstRender }: PresenceGroupState,\n ) {\n const nextChildMapping = getChildMapping(nextProps.children);\n\n return {\n childMapping: firstRender ? nextChildMapping : getNextChildMapping(prevChildMapping, nextChildMapping),\n firstRender: false,\n };\n }\n\n constructor(props: PresenceGroupProps, context: unknown) {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n super(props, context);\n\n this.state = {\n childMapping: {},\n firstRender: true,\n };\n }\n\n private handleExit = (childKey: string) => {\n const currentChildMapping = getChildMapping(this.props.children);\n\n if (childKey in currentChildMapping) {\n return;\n }\n\n if (this.mounted) {\n this.setState(state => {\n const childMapping = { ...state.childMapping };\n delete childMapping[childKey];\n\n return { childMapping };\n });\n }\n };\n\n componentDidMount() {\n this.mounted = true;\n }\n\n componentWillUnmount() {\n this.mounted = false;\n }\n\n render() {\n return (\n <>\n {Object.entries(this.state.childMapping).map(([childKey, childProps]) => (\n <PresenceGroupItemProvider {...childProps} childKey={childKey} key={childKey} onExit={this.handleExit}>\n {childProps.element}\n </PresenceGroupItemProvider>\n ))}\n </>\n );\n }\n}\n"],"names":["PresenceGroup","React","Component","getDerivedStateFromProps","nextProps","childMapping","prevChildMapping","firstRender","nextChildMapping","getChildMapping","children","getNextChildMapping","componentDidMount","mounted","componentWillUnmount","render","Object","entries","state","map","childKey","childProps","PresenceGroupItemProvider","key","onExit","handleExit","element","constructor","props","context","currentChildMapping","setState"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAmBaA;;;eAAAA;;;;;iEAnBU;qCACa;iCACJ;2CAEU;AAenC,MAAMA,sBAAsBC,OAAMC,SAAS;IAGhD,OAAOC,yBACLC,SAA6B,EAC7B,EAAEC,cAAcC,gBAAgB,EAAEC,WAAW,EAAsB,EACnE;QACA,MAAMC,mBAAmBC,IAAAA,gCAAe,EAACL,UAAUM,QAAQ;QAE3D,OAAO;YACLL,cAAcE,cAAcC,mBAAmBG,IAAAA,wCAAmB,EAACL,kBAAkBE;YACrFD,aAAa;QACf;IACF;IA6BAK,oBAAoB;QAClB,IAAI,CAACC,OAAO,GAAG;IACjB;IAEAC,uBAAuB;QACrB,IAAI,CAACD,OAAO,GAAG;IACjB;IAEAE,SAAS;QACP,qBACE,4CACGC,OAAOC,OAAO,CAAC,IAAI,CAACC,KAAK,CAACb,YAAY,EAAEc,GAAG,CAAC,CAAC,CAACC,UAAUC,WAAW,iBAClE,qBAACC,oDAAyB;gBAAE,GAAGD,UAAU;gBAAED,UAAUA;gBAAUG,KAAKH;gBAAUI,QAAQ,IAAI,CAACC,UAAU;eAClGJ,WAAWK,OAAO;IAK7B;IA7CAC,YAAYC,KAAyB,EAAEC,OAAgB,CAAE;QACvD,4DAA4D;QAC5D,KAAK,CAACD,OAAOC;QAhBf,yBAAQhB,WAAmB;QAwB3B,yBAAQY,cAAa,CAACL;YACpB,MAAMU,sBAAsBrB,IAAAA,gCAAe,EAAC,IAAI,CAACmB,KAAK,CAAClB,QAAQ;YAE/D,IAAIU,YAAYU,qBAAqB;gBACnC;YACF;YAEA,IAAI,IAAI,CAACjB,OAAO,EAAE;gBAChB,IAAI,CAACkB,QAAQ,CAACb,CAAAA;oBACZ,MAAMb,eAAe;wBAAE,GAAGa,MAAMb,YAAY;oBAAC;oBAC7C,OAAOA,YAAY,CAACe,SAAS;oBAE7B,OAAO;wBAAEf;oBAAa;gBACxB;YACF;QACF;QArBE,IAAI,CAACa,KAAK,GAAG;YACXb,cAAc,CAAC;YACfE,aAAa;QACf;IACF;AAsCF"}
|
@@ -14,16 +14,15 @@ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
14
14
|
const _useAnimateAtoms = require("../hooks/useAnimateAtoms");
|
15
15
|
const _useMotionImperativeRef = require("../hooks/useMotionImperativeRef");
|
16
16
|
const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
|
17
|
-
const
|
17
|
+
const _useChildElement = require("../utils/useChildElement");
|
18
18
|
const _MotionBehaviourContext = require("../contexts/MotionBehaviourContext");
|
19
19
|
function createMotionComponent(value) {
|
20
20
|
const Atom = (props)=>{
|
21
21
|
'use no memo';
|
22
22
|
const { children, imperativeRef, onMotionFinish: onMotionFinishProp, onMotionStart: onMotionStartProp, onMotionCancel: onMotionCancelProp, ..._rest } = props;
|
23
23
|
const params = _rest;
|
24
|
-
const child = (0,
|
24
|
+
const [child, childRef] = (0, _useChildElement.useChildElement)(children);
|
25
25
|
const handleRef = (0, _useMotionImperativeRef.useMotionImperativeRef)(imperativeRef);
|
26
|
-
const elementRef = _react.useRef();
|
27
26
|
const skipMotions = (0, _MotionBehaviourContext.useMotionBehaviourContext)() === 'skip';
|
28
27
|
const optionsRef = _react.useRef({
|
29
28
|
skipMotions,
|
@@ -49,7 +48,7 @@ function createMotionComponent(value) {
|
|
49
48
|
};
|
50
49
|
});
|
51
50
|
(0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
|
52
|
-
const element =
|
51
|
+
const element = childRef.current;
|
53
52
|
if (element) {
|
54
53
|
const atoms = typeof value === 'function' ? value({
|
55
54
|
element,
|
@@ -70,15 +69,14 @@ function createMotionComponent(value) {
|
|
70
69
|
}
|
71
70
|
}, [
|
72
71
|
animateAtoms,
|
72
|
+
childRef,
|
73
73
|
handleRef,
|
74
74
|
isReducedMotion,
|
75
75
|
onMotionFinish,
|
76
76
|
onMotionStart,
|
77
77
|
onMotionCancel
|
78
78
|
]);
|
79
|
-
return
|
80
|
-
ref: (0, _reactutilities.useMergedRefs)(elementRef, child.ref)
|
81
|
-
});
|
79
|
+
return child;
|
82
80
|
};
|
83
81
|
return Atom;
|
84
82
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/factories/createMotionComponent.ts"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect
|
1
|
+
{"version":3,"sources":["../src/factories/createMotionComponent.ts"],"sourcesContent":["import { useEventCallback, useIsomorphicLayoutEffect } 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 { useChildElement } from '../utils/useChildElement';\nimport type { AtomMotion, AtomMotionFn, MotionParam, MotionImperativeRef } from '../types';\nimport { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';\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, childRef] = useChildElement(children);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const skipMotions = useMotionBehaviourContext() === 'skip';\n const optionsRef = React.useRef<{ skipMotions: boolean; params: MotionParams }>({\n skipMotions,\n params,\n });\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 optionsRef.current = { skipMotions, params };\n });\n\n useIsomorphicLayoutEffect(() => {\n const element = childRef.current;\n\n if (element) {\n const atoms = typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : value;\n\n onMotionStart();\n const handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n handleRef.current = handle;\n handle.setMotionEndCallbacks(onMotionFinish, onMotionCancel);\n\n if (optionsRef.current.skipMotions) {\n handle.finish();\n }\n\n return () => {\n handle.cancel();\n };\n }\n }, [animateAtoms, childRef, handleRef, isReducedMotion, onMotionFinish, onMotionStart, onMotionCancel]);\n\n return child;\n };\n\n return Atom;\n}\n"],"names":["createMotionComponent","value","Atom","props","children","imperativeRef","onMotionFinish","onMotionFinishProp","onMotionStart","onMotionStartProp","onMotionCancel","onMotionCancelProp","_rest","params","child","childRef","useChildElement","handleRef","useMotionImperativeRef","skipMotions","useMotionBehaviourContext","optionsRef","React","useRef","animateAtoms","useAnimateAtoms","isReducedMotion","useIsReducedMotion","useEventCallback","useIsomorphicLayoutEffect","current","element","atoms","handle","setMotionEndCallbacks","finish","cancel"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAkDgBA;;;eAAAA;;;;gCAlD4C;iEACrC;iCAES;wCACO;oCACJ;iCACH;wCAEU;AA0CnC,SAASA,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,MAAM,CAACE,OAAOC,SAAS,GAAGC,IAAAA,gCAAe,EAACZ;QAE1C,MAAMa,YAAYC,IAAAA,8CAAsB,EAACb;QACzC,MAAMc,cAAcC,IAAAA,iDAAyB,QAAO;QACpD,MAAMC,aAAaC,OAAMC,MAAM,CAAiD;YAC9EJ;YACAN;QACF;QAEA,MAAMW,eAAeC,IAAAA,gCAAe;QACpC,MAAMC,kBAAkBC,IAAAA,sCAAkB;QAE1C,MAAMnB,gBAAgBoB,IAAAA,gCAAgB,EAAC;YACrCnB,8BAAAA,wCAAAA,kBAAoB;QACtB;QAEA,MAAMH,iBAAiBsB,IAAAA,gCAAgB,EAAC;YACtCrB,+BAAAA,yCAAAA,mBAAqB;QACvB;QAEA,MAAMG,iBAAiBkB,IAAAA,gCAAgB,EAAC;YACtCjB,+BAAAA,yCAAAA,mBAAqB;QACvB;QAEAkB,IAAAA,yCAAyB,EAAC;YACxB,YAAY;YACZ,2FAA2F;YAC3FR,WAAWS,OAAO,GAAG;gBAAEX;gBAAaN;YAAO;QAC7C;QAEAgB,IAAAA,yCAAyB,EAAC;YACxB,MAAME,UAAUhB,SAASe,OAAO;YAEhC,IAAIC,SAAS;gBACX,MAAMC,QAAQ,OAAO/B,UAAU,aAAaA,MAAM;oBAAE8B;oBAAS,GAAGV,WAAWS,OAAO,CAACjB,MAAM;gBAAC,KAAKZ;gBAE/FO;gBACA,MAAMyB,SAAST,aAAaO,SAASC,OAAO;oBAAEN,iBAAiBA;gBAAkB;gBACjFT,UAAUa,OAAO,GAAGG;gBACpBA,OAAOC,qBAAqB,CAAC5B,gBAAgBI;gBAE7C,IAAIW,WAAWS,OAAO,CAACX,WAAW,EAAE;oBAClCc,OAAOE,MAAM;gBACf;gBAEA,OAAO;oBACLF,OAAOG,MAAM;gBACf;YACF;QACF,GAAG;YAACZ;YAAcT;YAAUE;YAAWS;YAAiBpB;YAAgBE;YAAeE;SAAe;QAEtG,OAAOI;IACT;IAEA,OAAOZ;AACT"}
|
@@ -24,7 +24,7 @@ const _useAnimateAtoms = require("../hooks/useAnimateAtoms");
|
|
24
24
|
const _useMotionImperativeRef = require("../hooks/useMotionImperativeRef");
|
25
25
|
const _useMountedState = require("../hooks/useMountedState");
|
26
26
|
const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
|
27
|
-
const
|
27
|
+
const _useChildElement = require("../utils/useChildElement");
|
28
28
|
const _MotionBehaviourContext = require("../contexts/MotionBehaviourContext");
|
29
29
|
const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');
|
30
30
|
const INTERRUPTABLE_MOTION_SYMBOL = Symbol.for('interruptablePresence');
|
@@ -40,10 +40,8 @@ function createPresenceComponent(value) {
|
|
40
40
|
const { appear, children, imperativeRef, onExit, onMotionFinish, onMotionStart, onMotionCancel, visible, unmountOnExit, ..._rest } = merged;
|
41
41
|
const params = _rest;
|
42
42
|
const [mounted, setMounted] = (0, _useMountedState.useMountedState)(visible, unmountOnExit);
|
43
|
-
const child = (0,
|
43
|
+
const [child, childRef] = (0, _useChildElement.useChildElement)(children, mounted);
|
44
44
|
const handleRef = (0, _useMotionImperativeRef.useMotionImperativeRef)(imperativeRef);
|
45
|
-
const elementRef = _react.useRef();
|
46
|
-
const ref = (0, _reactutilities.useMergedRefs)(elementRef, child.ref);
|
47
45
|
const optionsRef = _react.useRef({
|
48
46
|
appear,
|
49
47
|
params,
|
@@ -81,7 +79,7 @@ function createPresenceComponent(value) {
|
|
81
79
|
};
|
82
80
|
});
|
83
81
|
(0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
|
84
|
-
const element =
|
82
|
+
const element = childRef.current;
|
85
83
|
if (!element) {
|
86
84
|
return;
|
87
85
|
}
|
@@ -140,6 +138,7 @@ function createPresenceComponent(value) {
|
|
140
138
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
141
139
|
[
|
142
140
|
animateAtoms,
|
141
|
+
childRef,
|
143
142
|
handleRef,
|
144
143
|
isReducedMotion,
|
145
144
|
handleMotionFinish,
|
@@ -148,9 +147,7 @@ function createPresenceComponent(value) {
|
|
148
147
|
visible
|
149
148
|
]);
|
150
149
|
if (mounted) {
|
151
|
-
return
|
152
|
-
ref
|
153
|
-
});
|
150
|
+
return child;
|
154
151
|
}
|
155
152
|
return null;
|
156
153
|
}, {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/factories/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 {\n MotionParam,\n PresenceMotion,\n MotionImperativeRef,\n PresenceMotionFn,\n PresenceDirection,\n AnimationHandle,\n} from '../types';\nimport { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';\n\n/**\n * @internal A private symbol to store the motion definition on the component for variants.\n */\nexport const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');\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: PresenceDirection }) => 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: PresenceDirection }) => 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: PresenceDirection }) => 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\nexport type PresenceComponent<MotionParams extends Record<string, MotionParam> = {}> = {\n (props: PresenceComponentProps & MotionParams): React.ReactElement | null;\n [MOTION_DEFINITION]: PresenceMotionFn<MotionParams>;\n};\n\nconst INTERRUPTABLE_MOTION_SYMBOL = Symbol.for('interruptablePresence');\n\nexport function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: PresenceMotion | PresenceMotionFn<MotionParams>,\n): PresenceComponent<MotionParams> {\n return Object.assign(\n (props: PresenceComponentProps & MotionParams) => {\n 'use no memo';\n\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = { ...itemContext, ...props };\n const skipMotions = useMotionBehaviourContext() === 'skip';\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; skipMotions: boolean }>({\n appear,\n params,\n skipMotions,\n });\n\n const animateAtoms = useAnimateAtoms();\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n\n const handleMotionStart = useEventCallback((direction: PresenceDirection) => {\n onMotionStart?.(null, { direction });\n });\n const handleMotionFinish = useEventCallback((direction: PresenceDirection) => {\n onMotionFinish?.(null, { direction });\n\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit?.();\n }\n });\n\n const handleMotionCancel = useEventCallback((direction: PresenceDirection) => {\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, skipMotions };\n });\n\n useIsomorphicLayoutEffect(\n () => {\n const element = elementRef.current;\n\n if (!element) {\n return;\n }\n\n let handle: AnimationHandle | undefined;\n\n function cleanup() {\n if (!handle) {\n return;\n }\n\n // Heads up!\n //\n // If the animation is interruptible & is running, we don't want to cancel it as it will be reversed in\n // the next effect.\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION && handle.isRunning()) {\n return;\n }\n\n handle.cancel();\n handleRef.current = undefined;\n }\n\n const presenceMotion =\n typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : (value as PresenceMotion);\n const IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION = (\n presenceMotion as PresenceMotion & { [INTERRUPTABLE_MOTION_SYMBOL]?: boolean }\n )[INTERRUPTABLE_MOTION_SYMBOL];\n\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION) {\n handle = handleRef.current;\n\n if (handle && handle.isRunning()) {\n handle.reverse();\n\n return cleanup;\n }\n }\n\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n const direction: PresenceDirection = visible ? 'enter' : 'exit';\n\n // Heads up!\n // Initial styles are applied when the component is mounted for the first time and \"appear\" is set to \"false\" (otherwise animations are triggered)\n const applyInitialStyles = !optionsRef.current.appear && isFirstMount;\n const skipAnimationByConfig = optionsRef.current.skipMotions;\n\n if (!applyInitialStyles) {\n handleMotionStart(direction);\n }\n\n handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n if (applyInitialStyles) {\n // Heads up!\n // .finish() is used in this case to skip animation and apply animation styles immediately\n handle.finish();\n\n return cleanup;\n }\n\n handleRef.current = handle;\n handle.setMotionEndCallbacks(\n () => handleMotionFinish(direction),\n () => handleMotionCancel(direction),\n );\n\n if (skipAnimationByConfig) {\n handle.finish();\n }\n\n return cleanup;\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 // Heads up!\n // Always normalize it to a function to simplify types\n [MOTION_DEFINITION]: typeof value === 'function' ? value : () => value,\n },\n );\n}\n"],"names":["MOTION_DEFINITION","createPresenceComponent","Symbol","INTERRUPTABLE_MOTION_SYMBOL","for","value","Object","assign","props","itemContext","React","useContext","PresenceGroupChildContext","merged","skipMotions","useMotionBehaviourContext","appear","children","imperativeRef","onExit","onMotionFinish","onMotionStart","onMotionCancel","visible","unmountOnExit","_rest","params","mounted","setMounted","useMountedState","child","getChildElement","handleRef","useMotionImperativeRef","elementRef","useRef","ref","useMergedRefs","optionsRef","animateAtoms","useAnimateAtoms","isFirstMount","useFirstMount","isReducedMotion","useIsReducedMotion","handleMotionStart","useEventCallback","direction","handleMotionFinish","handleMotionCancel","useIsomorphicLayoutEffect","current","element","handle","cleanup","IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION","isRunning","cancel","undefined","presenceMotion","reverse","atoms","enter","exit","applyInitialStyles","skipAnimationByConfig","finish","setMotionEndCallbacks","cloneElement"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
1
|
+
{"version":3,"sources":["../src/factories/createPresenceComponent.ts"],"sourcesContent":["import { useEventCallback, useFirstMount, useIsomorphicLayoutEffect } 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 { useChildElement } from '../utils/useChildElement';\nimport type {\n MotionParam,\n PresenceMotion,\n MotionImperativeRef,\n PresenceMotionFn,\n PresenceDirection,\n AnimationHandle,\n} from '../types';\nimport { useMotionBehaviourContext } from '../contexts/MotionBehaviourContext';\n\n/**\n * @internal A private symbol to store the motion definition on the component for variants.\n */\nexport const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');\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: PresenceDirection }) => 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: PresenceDirection }) => 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: PresenceDirection }) => 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\nexport type PresenceComponent<MotionParams extends Record<string, MotionParam> = {}> = {\n (props: PresenceComponentProps & MotionParams): React.ReactElement | null;\n [MOTION_DEFINITION]: PresenceMotionFn<MotionParams>;\n};\n\nconst INTERRUPTABLE_MOTION_SYMBOL = Symbol.for('interruptablePresence');\n\nexport function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(\n value: PresenceMotion | PresenceMotionFn<MotionParams>,\n): PresenceComponent<MotionParams> {\n return Object.assign(\n (props: PresenceComponentProps & MotionParams) => {\n 'use no memo';\n\n const itemContext = React.useContext(PresenceGroupChildContext);\n const merged = { ...itemContext, ...props };\n const skipMotions = useMotionBehaviourContext() === 'skip';\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, childRef] = useChildElement(children, mounted);\n\n const handleRef = useMotionImperativeRef(imperativeRef);\n const optionsRef = React.useRef<{ appear?: boolean; params: MotionParams; skipMotions: boolean }>({\n appear,\n params,\n skipMotions,\n });\n\n const animateAtoms = useAnimateAtoms();\n const isFirstMount = useFirstMount();\n const isReducedMotion = useIsReducedMotion();\n\n const handleMotionStart = useEventCallback((direction: PresenceDirection) => {\n onMotionStart?.(null, { direction });\n });\n const handleMotionFinish = useEventCallback((direction: PresenceDirection) => {\n onMotionFinish?.(null, { direction });\n\n if (direction === 'exit' && unmountOnExit) {\n setMounted(false);\n onExit?.();\n }\n });\n\n const handleMotionCancel = useEventCallback((direction: PresenceDirection) => {\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, skipMotions };\n });\n\n useIsomorphicLayoutEffect(\n () => {\n const element = childRef.current;\n\n if (!element) {\n return;\n }\n\n let handle: AnimationHandle | undefined;\n\n function cleanup() {\n if (!handle) {\n return;\n }\n\n // Heads up!\n //\n // If the animation is interruptible & is running, we don't want to cancel it as it will be reversed in\n // the next effect.\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION && handle.isRunning()) {\n return;\n }\n\n handle.cancel();\n handleRef.current = undefined;\n }\n\n const presenceMotion =\n typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : (value as PresenceMotion);\n const IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION = (\n presenceMotion as PresenceMotion & { [INTERRUPTABLE_MOTION_SYMBOL]?: boolean }\n )[INTERRUPTABLE_MOTION_SYMBOL];\n\n if (IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION) {\n handle = handleRef.current;\n\n if (handle && handle.isRunning()) {\n handle.reverse();\n\n return cleanup;\n }\n }\n\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n const direction: PresenceDirection = visible ? 'enter' : 'exit';\n\n // Heads up!\n // Initial styles are applied when the component is mounted for the first time and \"appear\" is set to \"false\" (otherwise animations are triggered)\n const applyInitialStyles = !optionsRef.current.appear && isFirstMount;\n const skipAnimationByConfig = optionsRef.current.skipMotions;\n\n if (!applyInitialStyles) {\n handleMotionStart(direction);\n }\n\n handle = animateAtoms(element, atoms, { isReducedMotion: isReducedMotion() });\n\n if (applyInitialStyles) {\n // Heads up!\n // .finish() is used in this case to skip animation and apply animation styles immediately\n handle.finish();\n\n return cleanup;\n }\n\n handleRef.current = handle;\n handle.setMotionEndCallbacks(\n () => handleMotionFinish(direction),\n () => handleMotionCancel(direction),\n );\n\n if (skipAnimationByConfig) {\n handle.finish();\n }\n\n return cleanup;\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 childRef,\n handleRef,\n isReducedMotion,\n handleMotionFinish,\n handleMotionStart,\n handleMotionCancel,\n visible,\n ],\n );\n\n if (mounted) {\n return child;\n }\n\n return null;\n },\n {\n // Heads up!\n // Always normalize it to a function to simplify types\n [MOTION_DEFINITION]: typeof value === 'function' ? value : () => value,\n },\n );\n}\n"],"names":["MOTION_DEFINITION","createPresenceComponent","Symbol","INTERRUPTABLE_MOTION_SYMBOL","for","value","Object","assign","props","itemContext","React","useContext","PresenceGroupChildContext","merged","skipMotions","useMotionBehaviourContext","appear","children","imperativeRef","onExit","onMotionFinish","onMotionStart","onMotionCancel","visible","unmountOnExit","_rest","params","mounted","setMounted","useMountedState","child","childRef","useChildElement","handleRef","useMotionImperativeRef","optionsRef","useRef","animateAtoms","useAnimateAtoms","isFirstMount","useFirstMount","isReducedMotion","useIsReducedMotion","handleMotionStart","useEventCallback","direction","handleMotionFinish","handleMotionCancel","useIsomorphicLayoutEffect","current","element","handle","cleanup","IS_EXPERIMENTAL_INTERRUPTIBLE_MOTION","isRunning","cancel","undefined","presenceMotion","reverse","atoms","enter","exit","applyInitialStyles","skipAnimationByConfig","finish","setMotionEndCallbacks"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
Object.defineProperty(exports, "useChildElement", {
|
6
|
+
enumerable: true,
|
7
|
+
get: function() {
|
8
|
+
return useChildElement;
|
9
|
+
}
|
10
|
+
});
|
11
|
+
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
12
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
13
|
+
const _reactutilities = require("@fluentui/react-utilities");
|
14
|
+
const IS_REACT_19 = _react.version.startsWith('19.');
|
15
|
+
const CHILD_ERROR_MESSAGE = [
|
16
|
+
'@fluentui/react-motion: Invalid child element.',
|
17
|
+
'\n',
|
18
|
+
'Motion factories require a single child element to be passed. ',
|
19
|
+
'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().'
|
20
|
+
].join('');
|
21
|
+
/**
|
22
|
+
* A backwards-compatible way to get the ref from a React element without console errors.
|
23
|
+
*/ function getRefFromReactElement(element) {
|
24
|
+
if (IS_REACT_19) {
|
25
|
+
return element.props.ref;
|
26
|
+
}
|
27
|
+
return element.ref;
|
28
|
+
}
|
29
|
+
function useChildElement(children, mounted = true) {
|
30
|
+
const childRef = _react.useRef(null);
|
31
|
+
_react.useEffect(()=>{
|
32
|
+
if (process.env.NODE_ENV !== 'production') {
|
33
|
+
if (mounted && !childRef.current) {
|
34
|
+
// eslint-disable-next-line no-console
|
35
|
+
console.error(CHILD_ERROR_MESSAGE);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}, [
|
39
|
+
mounted
|
40
|
+
]);
|
41
|
+
try {
|
42
|
+
const child = _react.Children.only(children);
|
43
|
+
if (_react.isValidElement(child)) {
|
44
|
+
return [
|
45
|
+
_react.cloneElement(child, {
|
46
|
+
ref: (0, _reactutilities.useMergedRefs)(childRef, getRefFromReactElement(child))
|
47
|
+
}),
|
48
|
+
childRef
|
49
|
+
];
|
50
|
+
}
|
51
|
+
} catch {
|
52
|
+
/* empty */ }
|
53
|
+
throw new Error(CHILD_ERROR_MESSAGE);
|
54
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/utils/useChildElement.ts"],"sourcesContent":["import * as React from 'react';\nimport { useMergedRefs } from '@fluentui/react-utilities';\n\nconst IS_REACT_19 = React.version.startsWith('19.');\nconst CHILD_ERROR_MESSAGE = [\n '@fluentui/react-motion: Invalid child element.',\n '\\n',\n 'Motion factories require a single child element to be passed. ',\n 'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().',\n].join('');\n\n/**\n * A backwards-compatible way to get the ref from a React element without console errors.\n */\nfunction getRefFromReactElement<T>(element: React.ReactElement): React.Ref<T> | undefined {\n if (IS_REACT_19) {\n return element.props.ref;\n }\n\n return (element as React.ReactElement & { ref: React.Ref<T> | undefined }).ref;\n}\n\n/**\n * Validates the child and returns a cloned child element with a ref.\n *\n * Throws an error if the child is not a valid React element, similar to \"React.Children.only\".\n * Logs a warning in development mode if the ref is not set as the component remains functional.\n */\nexport function useChildElement(\n children: React.ReactElement,\n mounted: boolean = true,\n): [React.ReactElement, React.RefObject<HTMLElement>] {\n const childRef = React.useRef<HTMLElement>(null);\n\n React.useEffect(() => {\n if (process.env.NODE_ENV !== 'production') {\n if (mounted && !childRef.current) {\n // eslint-disable-next-line no-console\n console.error(CHILD_ERROR_MESSAGE);\n }\n }\n }, [mounted]);\n\n try {\n const child = React.Children.only(children) as Parameters<typeof React.isValidElement>[0];\n\n if (React.isValidElement(child)) {\n return [\n React.cloneElement(child as React.ReactElement<{ ref: React.Ref<HTMLElement> }>, {\n ref: useMergedRefs(childRef, getRefFromReactElement(child)),\n }),\n childRef,\n ];\n }\n } catch {\n /* empty */\n }\n\n throw new Error(CHILD_ERROR_MESSAGE);\n}\n"],"names":["useChildElement","IS_REACT_19","React","version","startsWith","CHILD_ERROR_MESSAGE","join","getRefFromReactElement","element","props","ref","children","mounted","childRef","useRef","useEffect","process","env","NODE_ENV","current","console","error","child","Children","only","isValidElement","cloneElement","useMergedRefs","Error"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BA4BgBA;;;eAAAA;;;;iEA5BO;gCACO;AAE9B,MAAMC,cAAcC,OAAMC,OAAO,CAACC,UAAU,CAAC;AAC7C,MAAMC,sBAAsB;IAC1B;IACA;IACA;IACA;CACD,CAACC,IAAI,CAAC;AAEP;;CAEC,GACD,SAASC,uBAA0BC,OAA2B;IAC5D,IAAIP,aAAa;QACf,OAAOO,QAAQC,KAAK,CAACC,GAAG;IAC1B;IAEA,OAAO,AAACF,QAAmEE,GAAG;AAChF;AAQO,SAASV,gBACdW,QAA4B,EAC5BC,UAAmB,IAAI;IAEvB,MAAMC,WAAWX,OAAMY,MAAM,CAAc;IAE3CZ,OAAMa,SAAS,CAAC;QACd,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,IAAIN,WAAW,CAACC,SAASM,OAAO,EAAE;gBAChC,sCAAsC;gBACtCC,QAAQC,KAAK,CAAChB;YAChB;QACF;IACF,GAAG;QAACO;KAAQ;IAEZ,IAAI;QACF,MAAMU,QAAQpB,OAAMqB,QAAQ,CAACC,IAAI,CAACb;QAElC,IAAIT,OAAMuB,cAAc,CAACH,QAAQ;YAC/B,OAAO;gBACLpB,OAAMwB,YAAY,CAACJ,OAA8D;oBAC/EZ,KAAKiB,IAAAA,6BAAa,EAACd,UAAUN,uBAAuBe;gBACtD;gBACAT;aACD;QACH;IACF,EAAE,OAAM;IACN,SAAS,GACX;IAEA,MAAM,IAAIe,MAAMvB;AAClB"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fluentui/react-motion",
|
3
|
-
"version": "9.7.
|
3
|
+
"version": "9.7.2",
|
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,10 +25,9 @@
|
|
25
25
|
"@fluentui/scripts-cypress": "*"
|
26
26
|
},
|
27
27
|
"dependencies": {
|
28
|
-
"@fluentui/react-shared-contexts": "^9.23.
|
29
|
-
"@fluentui/react-utilities": "^9.
|
30
|
-
"@swc/helpers": "^0.5.1"
|
31
|
-
"react-is": "^17.0.2"
|
28
|
+
"@fluentui/react-shared-contexts": "^9.23.1",
|
29
|
+
"@fluentui/react-utilities": "^9.19.0",
|
30
|
+
"@swc/helpers": "^0.5.1"
|
32
31
|
},
|
33
32
|
"peerDependencies": {
|
34
33
|
"@types/react": ">=16.8.0 <19.0.0",
|
@@ -1,18 +0,0 @@
|
|
1
|
-
import * as React from 'react';
|
2
|
-
import * as ReactIs from 'react-is';
|
3
|
-
export function getChildElement(children) {
|
4
|
-
try {
|
5
|
-
const child = React.Children.only(children);
|
6
|
-
if (typeof child.type === 'string' || ReactIs.isForwardRef(child)) {
|
7
|
-
return child;
|
8
|
-
}
|
9
|
-
// We don't need to do anything here: we catch the exception from React to throw a more meaningful error
|
10
|
-
// eslint-disable-next-line no-empty
|
11
|
-
} catch {}
|
12
|
-
throw new Error([
|
13
|
-
'@fluentui/react-motion: Invalid child element.',
|
14
|
-
'\n',
|
15
|
-
'Motion factories require a single child element to be passed. ',
|
16
|
-
'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().'
|
17
|
-
].join(''));
|
18
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../src/utils/getChildElement.ts"],"sourcesContent":["import * as React from 'react';\nimport * as ReactIs from 'react-is';\n\nexport function getChildElement(children: React.ReactElement) {\n try {\n const child = React.Children.only(children) as React.ReactElement & { ref: React.Ref<HTMLElement> };\n\n if (typeof child.type === 'string' || ReactIs.isForwardRef(child)) {\n return child as React.ReactElement & { ref: React.Ref<HTMLElement> };\n }\n\n // We don't need to do anything here: we catch the exception from React to throw a more meaningful error\n // eslint-disable-next-line no-empty\n } catch {}\n\n throw new Error(\n [\n '@fluentui/react-motion: Invalid child element.',\n '\\n',\n 'Motion factories require a single child element to be passed. ',\n 'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().',\n ].join(''),\n );\n}\n"],"names":["React","ReactIs","getChildElement","children","child","Children","only","type","isForwardRef","Error","join"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,YAAYC,aAAa,WAAW;AAEpC,OAAO,SAASC,gBAAgBC,QAA4B;IAC1D,IAAI;QACF,MAAMC,QAAQJ,MAAMK,QAAQ,CAACC,IAAI,CAACH;QAElC,IAAI,OAAOC,MAAMG,IAAI,KAAK,YAAYN,QAAQO,YAAY,CAACJ,QAAQ;YACjE,OAAOA;QACT;IAEA,wGAAwG;IACxG,oCAAoC;IACtC,EAAE,OAAM,CAAC;IAET,MAAM,IAAIK,MACR;QACE;QACA;QACA;QACA;KACD,CAACC,IAAI,CAAC;AAEX"}
|
@@ -1,29 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
3
|
-
value: true
|
4
|
-
});
|
5
|
-
Object.defineProperty(exports, "getChildElement", {
|
6
|
-
enumerable: true,
|
7
|
-
get: function() {
|
8
|
-
return getChildElement;
|
9
|
-
}
|
10
|
-
});
|
11
|
-
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
12
|
-
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
13
|
-
const _reactis = /*#__PURE__*/ _interop_require_wildcard._(require("react-is"));
|
14
|
-
function getChildElement(children) {
|
15
|
-
try {
|
16
|
-
const child = _react.Children.only(children);
|
17
|
-
if (typeof child.type === 'string' || _reactis.isForwardRef(child)) {
|
18
|
-
return child;
|
19
|
-
}
|
20
|
-
// We don't need to do anything here: we catch the exception from React to throw a more meaningful error
|
21
|
-
// eslint-disable-next-line no-empty
|
22
|
-
} catch {}
|
23
|
-
throw new Error([
|
24
|
-
'@fluentui/react-motion: Invalid child element.',
|
25
|
-
'\n',
|
26
|
-
'Motion factories require a single child element to be passed. ',
|
27
|
-
'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().'
|
28
|
-
].join(''));
|
29
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../src/utils/getChildElement.ts"],"sourcesContent":["import * as React from 'react';\nimport * as ReactIs from 'react-is';\n\nexport function getChildElement(children: React.ReactElement) {\n try {\n const child = React.Children.only(children) as React.ReactElement & { ref: React.Ref<HTMLElement> };\n\n if (typeof child.type === 'string' || ReactIs.isForwardRef(child)) {\n return child as React.ReactElement & { ref: React.Ref<HTMLElement> };\n }\n\n // We don't need to do anything here: we catch the exception from React to throw a more meaningful error\n // eslint-disable-next-line no-empty\n } catch {}\n\n throw new Error(\n [\n '@fluentui/react-motion: Invalid child element.',\n '\\n',\n 'Motion factories require a single child element to be passed. ',\n 'That element element should support ref forwarding i.e. it should be either an intrinsic element (e.g. div) or a component that uses React.forwardRef().',\n ].join(''),\n );\n}\n"],"names":["getChildElement","children","child","React","Children","only","type","ReactIs","isForwardRef","Error","join"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAGgBA;;;eAAAA;;;;iEAHO;mEACE;AAElB,SAASA,gBAAgBC,QAA4B;IAC1D,IAAI;QACF,MAAMC,QAAQC,OAAMC,QAAQ,CAACC,IAAI,CAACJ;QAElC,IAAI,OAAOC,MAAMI,IAAI,KAAK,YAAYC,SAAQC,YAAY,CAACN,QAAQ;YACjE,OAAOA;QACT;IAEA,wGAAwG;IACxG,oCAAoC;IACtC,EAAE,OAAM,CAAC;IAET,MAAM,IAAIO,MACR;QACE;QACA;QACA;QACA;KACD,CAACC,IAAI,CAAC;AAEX"}
|