@fluentui/react-motion 9.2.2 → 9.3.0
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 +18 -2
- package/dist/index.d.ts +48 -8
- package/lib/factories/createPresenceComponent.js +9 -3
- package/lib/factories/createPresenceComponent.js.map +1 -1
- package/lib/factories/createPresenceComponentVariant.js +23 -0
- package/lib/factories/createPresenceComponentVariant.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib-commonjs/factories/createPresenceComponent.js +18 -6
- package/lib-commonjs/factories/createPresenceComponent.js.map +1 -1
- package/lib-commonjs/factories/createPresenceComponentVariant.js +39 -0
- package/lib-commonjs/factories/createPresenceComponentVariant.js.map +1 -0
- package/lib-commonjs/index.js +4 -0
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/types.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
@@ -1,12 +1,28 @@
|
|
1
1
|
# Change Log - @fluentui/react-motion
|
2
2
|
|
3
|
-
This log was last generated on
|
3
|
+
This log was last generated on Mon, 15 Jul 2024 17:20:19 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.3.0)
|
8
|
+
|
9
|
+
Mon, 15 Jul 2024 17:20:19 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.2.2..@fluentui/react-motion_v9.3.0)
|
11
|
+
|
12
|
+
### Minor changes
|
13
|
+
|
14
|
+
- feat(motion): add PresenceDirection type ([PR #31958](https://github.com/microsoft/fluentui/pull/31958) by olfedias@microsoft.com)
|
15
|
+
- Bump @fluentui/react-shared-contexts to v9.19.1 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
16
|
+
- Bump @fluentui/react-utilities to v9.18.12 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
17
|
+
|
18
|
+
### Patches
|
19
|
+
|
20
|
+
- fix: revert incorectly set npm versions in all packages ([PR #31937](https://github.com/microsoft/fluentui/pull/31937) by martinhochel@microsoft.com)
|
21
|
+
- feat: add createPresenceComponentVariant() ([PR #31943](https://github.com/microsoft/fluentui/pull/31943) by olfedias@microsoft.com)
|
22
|
+
|
7
23
|
## [9.2.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-motion_v9.2.2)
|
8
24
|
|
9
|
-
Thu, 04 Jul 2024 15:
|
25
|
+
Thu, 04 Jul 2024 15:14:35 GMT
|
10
26
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-motion_v9.2.1..@fluentui/react-motion_v9.2.2)
|
11
27
|
|
12
28
|
### Patches
|
package/dist/index.d.ts
CHANGED
@@ -15,7 +15,9 @@ export declare type AtomMotionFn<MotionParams extends Record<string, MotionParam
|
|
15
15
|
*/
|
16
16
|
export declare function createMotionComponent<MotionParams extends Record<string, MotionParam> = {}>(value: AtomMotion | AtomMotion[] | AtomMotionFn<MotionParams>): React_2.FC<MotionComponentProps & MotionParams>;
|
17
17
|
|
18
|
-
export declare function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(value: PresenceMotion | PresenceMotionFn<MotionParams>):
|
18
|
+
export declare function createPresenceComponent<MotionParams extends Record<string, MotionParam> = {}>(value: PresenceMotion | PresenceMotionFn<MotionParams>): PresenceComponent<MotionParams>;
|
19
|
+
|
20
|
+
export declare function createPresenceComponentVariant<MotionParams extends Record<string, MotionParam> = {}>(component: PresenceComponent<MotionParams>, override: PresenceOverride): PresenceComponent<MotionParams>;
|
19
21
|
|
20
22
|
export declare const curves: {
|
21
23
|
readonly curveAccelerateMax: "cubic-bezier(0.9,0.1,1,0.2)";
|
@@ -40,6 +42,11 @@ export declare const durations: {
|
|
40
42
|
readonly durationUltraSlow: 500;
|
41
43
|
};
|
42
44
|
|
45
|
+
/**
|
46
|
+
* @internal A private symbol to store the motion definition on the component for variants.
|
47
|
+
*/
|
48
|
+
declare const MOTION_DEFINITION: unique symbol;
|
49
|
+
|
43
50
|
export declare type MotionComponentProps = {
|
44
51
|
children: React_2.ReactElement;
|
45
52
|
/** Provides imperative controls for the animation. */
|
@@ -103,6 +110,11 @@ export declare const motionTokens: {
|
|
103
110
|
durationUltraSlow: 500;
|
104
111
|
};
|
105
112
|
|
113
|
+
export declare type PresenceComponent<MotionParams extends Record<string, MotionParam> = {}> = {
|
114
|
+
(props: PresenceComponentProps & MotionParams): React_2.ReactElement | null;
|
115
|
+
[MOTION_DEFINITION]: PresenceMotionFn<MotionParams>;
|
116
|
+
};
|
117
|
+
|
106
118
|
export declare type PresenceComponentProps = {
|
107
119
|
/**
|
108
120
|
* By default, the child component won't execute the "enter" motion when it initially mounts, regardless of the value
|
@@ -120,7 +132,7 @@ export declare type PresenceComponentProps = {
|
|
120
132
|
* triggered once all animations have finished with "null" instead of an event object to avoid ambiguity.
|
121
133
|
*/
|
122
134
|
onMotionFinish?: (ev: null, data: {
|
123
|
-
direction:
|
135
|
+
direction: PresenceDirection;
|
124
136
|
}) => void;
|
125
137
|
/**
|
126
138
|
* Callback that is called when the whole motion is cancelled. When a motion is cancelled it does not
|
@@ -130,7 +142,7 @@ export declare type PresenceComponentProps = {
|
|
130
142
|
* triggered once all animations have finished with "null" instead of an event object to avoid ambiguity.
|
131
143
|
*/
|
132
144
|
onMotionCancel?: (ev: null, data: {
|
133
|
-
direction:
|
145
|
+
direction: PresenceDirection;
|
134
146
|
}) => void;
|
135
147
|
/**
|
136
148
|
* Callback that is called when the whole motion starts.
|
@@ -140,7 +152,7 @@ export declare type PresenceComponentProps = {
|
|
140
152
|
* so the callback is triggered with "null".
|
141
153
|
*/
|
142
154
|
onMotionStart?: (ev: null, data: {
|
143
|
-
direction:
|
155
|
+
direction: PresenceDirection;
|
144
156
|
}) => void;
|
145
157
|
/** Defines whether a component is visible; triggers the "enter" or "exit" motions. */
|
146
158
|
visible?: boolean;
|
@@ -151,6 +163,8 @@ export declare type PresenceComponentProps = {
|
|
151
163
|
unmountOnExit?: boolean;
|
152
164
|
};
|
153
165
|
|
166
|
+
export declare type PresenceDirection = 'enter' | 'exit';
|
167
|
+
|
154
168
|
export declare class PresenceGroup extends React_2.Component<PresenceGroupProps, PresenceGroupState> {
|
155
169
|
private mounted;
|
156
170
|
static getDerivedStateFromProps(nextProps: PresenceGroupProps, { childMapping: prevChildMapping, firstRender }: PresenceGroupState): {
|
@@ -182,13 +196,39 @@ declare type PresenceGroupState = {
|
|
182
196
|
firstRender: boolean;
|
183
197
|
};
|
184
198
|
|
185
|
-
export declare type PresenceMotion =
|
186
|
-
enter: AtomMotion | AtomMotion[];
|
187
|
-
exit: AtomMotion | AtomMotion[];
|
188
|
-
};
|
199
|
+
export declare type PresenceMotion = Record<PresenceDirection, AtomMotion | AtomMotion[]>;
|
189
200
|
|
190
201
|
export declare type PresenceMotionFn<MotionParams extends Record<string, MotionParam> = {}> = (params: {
|
191
202
|
element: HTMLElement;
|
192
203
|
} & MotionParams) => PresenceMotion;
|
193
204
|
|
205
|
+
/**
|
206
|
+
* @internal
|
207
|
+
*
|
208
|
+
* Override properties for presence transitions.
|
209
|
+
*
|
210
|
+
* @example <caption>Override duration for all transitions</caption>
|
211
|
+
* ```
|
212
|
+
* const override: PresenceOverride = {
|
213
|
+
* all: { duration: 1000 },
|
214
|
+
* };
|
215
|
+
* ```
|
216
|
+
*
|
217
|
+
* @example <caption>Override easing for exit transition</caption>
|
218
|
+
* ```
|
219
|
+
* const override: PresenceOverride = {
|
220
|
+
* exit: { easing: 'ease-out' },
|
221
|
+
* };
|
222
|
+
* ```
|
223
|
+
*/
|
224
|
+
declare type PresenceOverride = Partial<Record<PresenceDirection | 'all', Partial<PresenceOverrideFields>>>;
|
225
|
+
|
226
|
+
/**
|
227
|
+
* @internal
|
228
|
+
*/
|
229
|
+
declare type PresenceOverrideFields = {
|
230
|
+
duration: KeyframeEffectOptions['duration'];
|
231
|
+
easing: KeyframeEffectOptions['easing'];
|
232
|
+
};
|
233
|
+
|
194
234
|
export { }
|
@@ -6,11 +6,14 @@ import { useMotionImperativeRef } from '../hooks/useMotionImperativeRef';
|
|
6
6
|
import { useMountedState } from '../hooks/useMountedState';
|
7
7
|
import { useIsReducedMotion } from '../hooks/useIsReducedMotion';
|
8
8
|
import { getChildElement } from '../utils/getChildElement';
|
9
|
+
/**
|
10
|
+
* @internal A private symbol to store the motion definition on the component for variants.
|
11
|
+
*/ export const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');
|
9
12
|
function shouldSkipAnimation(appear, isFirstMount, visible) {
|
10
13
|
return !appear && isFirstMount && !!visible;
|
11
14
|
}
|
12
15
|
export function createPresenceComponent(value) {
|
13
|
-
|
16
|
+
return Object.assign((props)=>{
|
14
17
|
'use no memo';
|
15
18
|
const itemContext = React.useContext(PresenceGroupChildContext);
|
16
19
|
const merged = {
|
@@ -104,6 +107,9 @@ export function createPresenceComponent(value) {
|
|
104
107
|
});
|
105
108
|
}
|
106
109
|
return null;
|
107
|
-
}
|
108
|
-
|
110
|
+
}, {
|
111
|
+
// Heads up!
|
112
|
+
// Always normalize it to a function to simplify types
|
113
|
+
[MOTION_DEFINITION]: typeof value === 'function' ? value : ()=>value
|
114
|
+
});
|
109
115
|
}
|
@@ -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 { 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"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","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, PresenceDirection } from '../types';\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\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): 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\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: 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 };\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 =\n typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : (value as PresenceMotion);\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n\n const direction: PresenceDirection = 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 // 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","MOTION_DEFINITION","Symbol","shouldSkipAnimation","appear","isFirstMount","visible","createPresenceComponent","value","Object","assign","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"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { MOTION_DEFINITION, createPresenceComponent } from './createPresenceComponent';
|
2
|
+
/**
|
3
|
+
* @internal
|
4
|
+
*/ export function overridePresenceMotion(presenceMotion, override) {
|
5
|
+
return (...args)=>{
|
6
|
+
const { enter, exit } = presenceMotion(...args);
|
7
|
+
return {
|
8
|
+
enter: {
|
9
|
+
...enter,
|
10
|
+
...override.all,
|
11
|
+
...override.enter
|
12
|
+
},
|
13
|
+
exit: {
|
14
|
+
...exit,
|
15
|
+
...override.all,
|
16
|
+
...override.exit
|
17
|
+
}
|
18
|
+
};
|
19
|
+
};
|
20
|
+
}
|
21
|
+
export function createPresenceComponentVariant(component, override) {
|
22
|
+
return createPresenceComponent(overridePresenceMotion(component[MOTION_DEFINITION], override));
|
23
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["createPresenceComponentVariant.ts"],"sourcesContent":["import type { MotionParam, PresenceDirection, PresenceMotionFn } from '../types';\nimport { MOTION_DEFINITION, createPresenceComponent, PresenceComponent } from './createPresenceComponent';\n\n/**\n * @internal\n */\ntype PresenceOverrideFields = {\n duration: KeyframeEffectOptions['duration'];\n easing: KeyframeEffectOptions['easing'];\n};\n\n/**\n * @internal\n *\n * Override properties for presence transitions.\n *\n * @example <caption>Override duration for all transitions</caption>\n * ```\n * const override: PresenceOverride = {\n * all: { duration: 1000 },\n * };\n * ```\n *\n * @example <caption>Override easing for exit transition</caption>\n * ```\n * const override: PresenceOverride = {\n * exit: { easing: 'ease-out' },\n * };\n * ```\n */\ntype PresenceOverride = Partial<Record<PresenceDirection | 'all', Partial<PresenceOverrideFields>>>;\n\n/**\n * @internal\n */\nexport function overridePresenceMotion<MotionParams extends Record<string, MotionParam> = {}>(\n presenceMotion: PresenceMotionFn<MotionParams>,\n override: PresenceOverride,\n): PresenceMotionFn<MotionParams> {\n return (...args: Parameters<PresenceMotionFn<MotionParams>>) => {\n const { enter, exit } = presenceMotion(...args);\n\n return {\n enter: { ...enter, ...override.all, ...override.enter },\n exit: { ...exit, ...override.all, ...override.exit },\n };\n };\n}\n\nexport function createPresenceComponentVariant<MotionParams extends Record<string, MotionParam> = {}>(\n component: PresenceComponent<MotionParams>,\n override: PresenceOverride,\n): PresenceComponent<MotionParams> {\n return createPresenceComponent(overridePresenceMotion(component[MOTION_DEFINITION], override));\n}\n"],"names":["MOTION_DEFINITION","createPresenceComponent","overridePresenceMotion","presenceMotion","override","args","enter","exit","all","createPresenceComponentVariant","component"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;","mappings":"AACA,SAASA,iBAAiB,EAAEC,uBAAuB,QAA2B,4BAA4B;AA+B1G;;CAEC,GACD,OAAO,SAASC,uBACdC,cAA8C,EAC9CC,QAA0B;IAE1B,OAAO,CAAC,GAAGC;QACT,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGJ,kBAAkBE;QAE1C,OAAO;YACLC,OAAO;gBAAE,GAAGA,KAAK;gBAAE,GAAGF,SAASI,GAAG;gBAAE,GAAGJ,SAASE,KAAK;YAAC;YACtDC,MAAM;gBAAE,GAAGA,IAAI;gBAAE,GAAGH,SAASI,GAAG;gBAAE,GAAGJ,SAASG,IAAI;YAAC;QACrD;IACF;AACF;AAEA,OAAO,SAASE,+BACdC,SAA0C,EAC1CN,QAA0B;IAE1B,OAAOH,wBAAwBC,uBAAuBQ,SAAS,CAACV,kBAAkB,EAAEI;AACtF"}
|
package/lib/index.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
export { motionTokens, durations, curves } from './motions/motionTokens';
|
2
2
|
export { createMotionComponent } from './factories/createMotionComponent';
|
3
3
|
export { createPresenceComponent } from './factories/createPresenceComponent';
|
4
|
+
export { createPresenceComponentVariant } from './factories/createPresenceComponentVariant';
|
4
5
|
export { PresenceGroup } from './components/PresenceGroup';
|
package/lib/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export { motionTokens, durations, curves } from './motions/motionTokens';\n\nexport { createMotionComponent, type MotionComponentProps } from './factories/createMotionComponent';\nexport {
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export { motionTokens, durations, curves } from './motions/motionTokens';\n\nexport { createMotionComponent, type MotionComponentProps } from './factories/createMotionComponent';\nexport {\n createPresenceComponent,\n type PresenceComponentProps,\n type PresenceComponent,\n} from './factories/createPresenceComponent';\nexport { createPresenceComponentVariant } from './factories/createPresenceComponentVariant';\n\nexport { PresenceGroup } from './components/PresenceGroup';\n\nexport type {\n AtomMotion,\n AtomMotionFn,\n PresenceMotion,\n PresenceMotionFn,\n PresenceDirection,\n MotionImperativeRef,\n} from './types';\n"],"names":["motionTokens","durations","curves","createMotionComponent","createPresenceComponent","createPresenceComponentVariant","PresenceGroup"],"rangeMappings":";;;;","mappings":"AAAA,SAASA,YAAY,EAAEC,SAAS,EAAEC,MAAM,QAAQ,yBAAyB;AAEzE,SAASC,qBAAqB,QAAmC,oCAAoC;AACrG,SACEC,uBAAuB,QAGlB,sCAAsC;AAC7C,SAASC,8BAA8B,QAAQ,6CAA6C;AAE5F,SAASC,aAAa,QAAQ,6BAA6B"}
|
package/lib/types.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["types.ts"],"sourcesContent":["export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions;\n\nexport type
|
1
|
+
{"version":3,"sources":["types.ts"],"sourcesContent":["export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions;\n\nexport type PresenceDirection = 'enter' | 'exit';\n\nexport type PresenceMotion = Record<PresenceDirection, AtomMotion | AtomMotion[]>;\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[];\n\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":[],"rangeMappings":"","mappings":"AA4BA,WAME"}
|
@@ -2,9 +2,17 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
3
3
|
value: true
|
4
4
|
});
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
function _export(target, all) {
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
7
|
+
enumerable: true,
|
8
|
+
get: all[name]
|
9
|
+
});
|
10
|
+
}
|
11
|
+
_export(exports, {
|
12
|
+
MOTION_DEFINITION: function() {
|
13
|
+
return MOTION_DEFINITION;
|
14
|
+
},
|
15
|
+
createPresenceComponent: function() {
|
8
16
|
return createPresenceComponent;
|
9
17
|
}
|
10
18
|
});
|
@@ -17,11 +25,12 @@ const _useMotionImperativeRef = require("../hooks/useMotionImperativeRef");
|
|
17
25
|
const _useMountedState = require("../hooks/useMountedState");
|
18
26
|
const _useIsReducedMotion = require("../hooks/useIsReducedMotion");
|
19
27
|
const _getChildElement = require("../utils/getChildElement");
|
28
|
+
const MOTION_DEFINITION = Symbol('MOTION_DEFINITION');
|
20
29
|
function shouldSkipAnimation(appear, isFirstMount, visible) {
|
21
30
|
return !appear && isFirstMount && !!visible;
|
22
31
|
}
|
23
32
|
function createPresenceComponent(value) {
|
24
|
-
|
33
|
+
return Object.assign((props)=>{
|
25
34
|
'use no memo';
|
26
35
|
const itemContext = _react.useContext(_PresenceGroupChildContext.PresenceGroupChildContext);
|
27
36
|
const merged = {
|
@@ -114,6 +123,9 @@ function createPresenceComponent(value) {
|
|
114
123
|
});
|
115
124
|
}
|
116
125
|
return null;
|
117
|
-
}
|
118
|
-
|
126
|
+
}, {
|
127
|
+
// Heads up!
|
128
|
+
// Always normalize it to a function to simplify types
|
129
|
+
[MOTION_DEFINITION]: typeof value === 'function' ? value : ()=>value
|
130
|
+
});
|
119
131
|
}
|
@@ -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 { 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":["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"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","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, PresenceDirection } from '../types';\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\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): 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\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: 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 };\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 =\n typeof value === 'function' ? value({ element, ...optionsRef.current.params }) : (value as PresenceMotion);\n const atoms = visible ? presenceMotion.enter : presenceMotion.exit;\n\n const direction: PresenceDirection = 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 // 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","shouldSkipAnimation","appear","isFirstMount","visible","value","Object","assign","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"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAcaA,iBAAAA;eAAAA;;IA+DGC,uBAAAA;eAAAA;;;;gCA7E0E;iEACnE;2CAEmB;iCACV;wCACO;iCACP;oCACG;iCACH;AAMzB,MAAMD,oBAAoBE,OAAO;AA2DxC,SAASC,oBAAoBC,MAA2B,EAAEC,YAAqB,EAAEC,OAA4B;IAC3G,OAAO,CAACF,UAAUC,gBAAgB,CAAC,CAACC;AACtC;AAEO,SAASL,wBACdM,KAAsD;IAEtD,OAAOC,OAAOC,MAAM,CAClB,CAACC;QACC;QAEA,MAAMC,cAAcC,OAAMC,UAAU,CAACC,oDAAAA;QACrC,MAAMC,SAAS;YAAE,GAAGJ,WAAW;YAAE,GAAGD,KAAK;QAAC;QAE1C,MAAM,EACJN,MAAM,EACNY,QAAQ,EACRC,aAAa,EACbC,MAAM,EACNC,cAAc,EACdC,aAAa,EACbC,cAAc,EACdf,OAAO,EACPgB,aAAa,EACb,GAAGC,OACJ,GAAGR;QACJ,MAAMS,SAASD;QAEf,MAAM,CAACE,SAASC,WAAW,GAAGC,IAAAA,gCAAAA,EAAgBrB,SAASgB;QACvD,MAAMM,QAAQC,IAAAA,gCAAAA,EAAgBb;QAE9B,MAAMc,YAAYC,IAAAA,8CAAAA,EAAuBd;QACzC,MAAMe,aAAapB,OAAMqB,MAAM;QAC/B,MAAMC,MAAMC,IAAAA,6BAAAA,EAAcH,YAAYJ,MAAMM,GAAG;QAC/C,MAAME,aAAaxB,OAAMqB,MAAM,CAA6C;YAAE7B;YAAQoB;QAAO;QAE7F,MAAMa,eAAeC,IAAAA,gCAAAA;QACrB,MAAMjC,eAAekC,IAAAA,6BAAAA;QACrB,MAAMC,kBAAkBC,IAAAA,sCAAAA;QAExB,MAAMC,oBAAoBC,IAAAA,gCAAAA,EAAiB,CAACC;YAC1CxB,kBAAAA,QAAAA,kBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,cAAgB,MAAM;gBAAEwB;YAAU;QACpC;QACA,MAAMC,qBAAqBF,IAAAA,gCAAAA,EAAiB,CAACC;YAC3CzB,mBAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAiB,MAAM;gBAAEyB;YAAU;YAEnC,IAAIA,cAAc,UAAUtB,eAAe;gBACzCI,WAAW;gBACXR,WAAAA,QAAAA,WAAAA,KAAAA,IAAAA,KAAAA,IAAAA;YACF;QACF;QAEA,MAAM4B,qBAAqBH,IAAAA,gCAAAA,EAAiB,CAACC;YAC3CvB,mBAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAiB,MAAM;gBAAEuB;YAAU;QACrC;QAEAG,IAAAA,yCAAAA,EAA0B;YACxB,YAAY;YACZ,2FAA2F;YAC3FX,WAAWY,OAAO,GAAG;gBAAE5C;gBAAQoB;YAAO;QACxC;QAEAuB,IAAAA,yCAAAA,EACE;YACE,MAAME,UAAUjB,WAAWgB,OAAO;YAElC,IAAI,CAACC,WAAW9C,oBAAoBiC,WAAWY,OAAO,CAAC5C,MAAM,EAAEC,cAAcC,UAAU;gBACrF;YACF;YAEA,MAAM4C,iBACJ,OAAO3C,UAAU,aAAaA,MAAM;gBAAE0C;gBAAS,GAAGb,WAAWY,OAAO,CAACxB,MAAM;YAAC,KAAMjB;YACpF,MAAM4C,QAAQ7C,UAAU4C,eAAeE,KAAK,GAAGF,eAAeG,IAAI;YAElE,MAAMT,YAA+BtC,UAAU,UAAU;YACzD,MAAMgD,oBAAoB,CAAChD,WAAWD;YAEtC,IAAI,CAACiD,mBAAmB;gBACtBZ,kBAAkBE;YACpB;YAEA,MAAMW,SAASlB,aAAaY,SAASE,OAAO;gBAAEX,iBAAiBA;YAAkB;YAEjF,IAAIc,mBAAmB;gBACrB,YAAY;gBACZ,mGAAmG;gBACnGC,OAAOC,MAAM;gBACb;YACF;YAEA1B,UAAUkB,OAAO,GAAGO;YACpBA,OAAOE,qBAAqB,CAC1B,IAAMZ,mBAAmBD,YACzB,IAAME,mBAAmBF;YAG3B,OAAO;gBACLW,OAAOG,MAAM;YACf;QACF,GAEA,uDAAuD;QACvD;YAACrB;YAAcP;YAAWU;YAAiBK;YAAoBH;YAAmBI;YAAoBxC;SAAQ;QAGhH,IAAImB,SAAS;YACX,qBAAOb,OAAM+C,YAAY,CAAC/B,OAAO;gBAAEM;YAAI;QACzC;QAEA,OAAO;IACT,GACA;QACE,YAAY;QACZ,sDAAsD;QACtD,CAAClC,kBAAkB,EAAE,OAAOO,UAAU,aAAaA,QAAQ,IAAMA;IACnE;AAEJ"}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
function _export(target, all) {
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
7
|
+
enumerable: true,
|
8
|
+
get: all[name]
|
9
|
+
});
|
10
|
+
}
|
11
|
+
_export(exports, {
|
12
|
+
createPresenceComponentVariant: function() {
|
13
|
+
return createPresenceComponentVariant;
|
14
|
+
},
|
15
|
+
overridePresenceMotion: function() {
|
16
|
+
return overridePresenceMotion;
|
17
|
+
}
|
18
|
+
});
|
19
|
+
const _createPresenceComponent = require("./createPresenceComponent");
|
20
|
+
function overridePresenceMotion(presenceMotion, override) {
|
21
|
+
return (...args)=>{
|
22
|
+
const { enter, exit } = presenceMotion(...args);
|
23
|
+
return {
|
24
|
+
enter: {
|
25
|
+
...enter,
|
26
|
+
...override.all,
|
27
|
+
...override.enter
|
28
|
+
},
|
29
|
+
exit: {
|
30
|
+
...exit,
|
31
|
+
...override.all,
|
32
|
+
...override.exit
|
33
|
+
}
|
34
|
+
};
|
35
|
+
};
|
36
|
+
}
|
37
|
+
function createPresenceComponentVariant(component, override) {
|
38
|
+
return (0, _createPresenceComponent.createPresenceComponent)(overridePresenceMotion(component[_createPresenceComponent.MOTION_DEFINITION], override));
|
39
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["createPresenceComponentVariant.ts"],"sourcesContent":["import type { MotionParam, PresenceDirection, PresenceMotionFn } from '../types';\nimport { MOTION_DEFINITION, createPresenceComponent, PresenceComponent } from './createPresenceComponent';\n\n/**\n * @internal\n */\ntype PresenceOverrideFields = {\n duration: KeyframeEffectOptions['duration'];\n easing: KeyframeEffectOptions['easing'];\n};\n\n/**\n * @internal\n *\n * Override properties for presence transitions.\n *\n * @example <caption>Override duration for all transitions</caption>\n * ```\n * const override: PresenceOverride = {\n * all: { duration: 1000 },\n * };\n * ```\n *\n * @example <caption>Override easing for exit transition</caption>\n * ```\n * const override: PresenceOverride = {\n * exit: { easing: 'ease-out' },\n * };\n * ```\n */\ntype PresenceOverride = Partial<Record<PresenceDirection | 'all', Partial<PresenceOverrideFields>>>;\n\n/**\n * @internal\n */\nexport function overridePresenceMotion<MotionParams extends Record<string, MotionParam> = {}>(\n presenceMotion: PresenceMotionFn<MotionParams>,\n override: PresenceOverride,\n): PresenceMotionFn<MotionParams> {\n return (...args: Parameters<PresenceMotionFn<MotionParams>>) => {\n const { enter, exit } = presenceMotion(...args);\n\n return {\n enter: { ...enter, ...override.all, ...override.enter },\n exit: { ...exit, ...override.all, ...override.exit },\n };\n };\n}\n\nexport function createPresenceComponentVariant<MotionParams extends Record<string, MotionParam> = {}>(\n component: PresenceComponent<MotionParams>,\n override: PresenceOverride,\n): PresenceComponent<MotionParams> {\n return createPresenceComponent(overridePresenceMotion(component[MOTION_DEFINITION], override));\n}\n"],"names":["createPresenceComponentVariant","overridePresenceMotion","presenceMotion","override","args","enter","exit","all","component","createPresenceComponent","MOTION_DEFINITION"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAiDgBA,8BAAAA;eAAAA;;IAdAC,sBAAAA;eAAAA;;;yCAlC8D;AAkCvE,SAASA,uBACdC,cAA8C,EAC9CC,QAA0B;IAE1B,OAAO,CAAC,GAAGC;QACT,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGJ,kBAAkBE;QAE1C,OAAO;YACLC,OAAO;gBAAE,GAAGA,KAAK;gBAAE,GAAGF,SAASI,GAAG;gBAAE,GAAGJ,SAASE,KAAK;YAAC;YACtDC,MAAM;gBAAE,GAAGA,IAAI;gBAAE,GAAGH,SAASI,GAAG;gBAAE,GAAGJ,SAASG,IAAI;YAAC;QACrD;IACF;AACF;AAEO,SAASN,+BACdQ,SAA0C,EAC1CL,QAA0B;IAE1B,OAAOM,IAAAA,gDAAAA,EAAwBR,uBAAuBO,SAAS,CAACE,0CAAAA,CAAkB,EAAEP;AACtF"}
|
package/lib-commonjs/index.js
CHANGED
@@ -18,6 +18,9 @@ _export(exports, {
|
|
18
18
|
createPresenceComponent: function() {
|
19
19
|
return _createPresenceComponent.createPresenceComponent;
|
20
20
|
},
|
21
|
+
createPresenceComponentVariant: function() {
|
22
|
+
return _createPresenceComponentVariant.createPresenceComponentVariant;
|
23
|
+
},
|
21
24
|
curves: function() {
|
22
25
|
return _motionTokens.curves;
|
23
26
|
},
|
@@ -31,4 +34,5 @@ _export(exports, {
|
|
31
34
|
const _motionTokens = require("./motions/motionTokens");
|
32
35
|
const _createMotionComponent = require("./factories/createMotionComponent");
|
33
36
|
const _createPresenceComponent = require("./factories/createPresenceComponent");
|
37
|
+
const _createPresenceComponentVariant = require("./factories/createPresenceComponentVariant");
|
34
38
|
const _PresenceGroup = require("./components/PresenceGroup");
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export { motionTokens, durations, curves } from './motions/motionTokens';\n\nexport { createMotionComponent, type MotionComponentProps } from './factories/createMotionComponent';\nexport {
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export { motionTokens, durations, curves } from './motions/motionTokens';\n\nexport { createMotionComponent, type MotionComponentProps } from './factories/createMotionComponent';\nexport {\n createPresenceComponent,\n type PresenceComponentProps,\n type PresenceComponent,\n} from './factories/createPresenceComponent';\nexport { createPresenceComponentVariant } from './factories/createPresenceComponentVariant';\n\nexport { PresenceGroup } from './components/PresenceGroup';\n\nexport type {\n AtomMotion,\n AtomMotionFn,\n PresenceMotion,\n PresenceMotionFn,\n PresenceDirection,\n MotionImperativeRef,\n} from './types';\n"],"names":["PresenceGroup","createMotionComponent","createPresenceComponent","createPresenceComponentVariant","curves","durations","motionTokens"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAUSA,aAAa;eAAbA,4BAAa;;IARbC,qBAAqB;eAArBA,4CAAqB;;IAE5BC,uBAAuB;eAAvBA,gDAAuB;;IAIhBC,8BAA8B;eAA9BA,8DAA8B;;IARLC,MAAM;eAANA,oBAAM;;IAAjBC,SAAS;eAATA,uBAAS;;IAAvBC,YAAY;eAAZA,0BAAY;;;8BAA2B;uCAEiB;yCAK1D;gDACwC;+BAEjB"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["types.ts"],"sourcesContent":["export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions;\n\nexport type
|
1
|
+
{"version":3,"sources":["types.ts"],"sourcesContent":["export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions;\n\nexport type PresenceDirection = 'enter' | 'exit';\n\nexport type PresenceMotion = Record<PresenceDirection, AtomMotion | AtomMotion[]>;\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[];\n\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":[],"rangeMappings":"","mappings":""}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fluentui/react-motion",
|
3
|
-
"version": "9.
|
3
|
+
"version": "9.3.0",
|
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",
|
@@ -39,15 +39,15 @@
|
|
39
39
|
"@fluentui/scripts-cypress": "*"
|
40
40
|
},
|
41
41
|
"dependencies": {
|
42
|
-
"@fluentui/react-shared-contexts": "^9.19.
|
43
|
-
"@fluentui/react-utilities": "^9.18.
|
42
|
+
"@fluentui/react-shared-contexts": "^9.19.1",
|
43
|
+
"@fluentui/react-utilities": "^9.18.12",
|
44
44
|
"@swc/helpers": "^0.5.1",
|
45
45
|
"react-is": "^17.0.2"
|
46
46
|
},
|
47
47
|
"peerDependencies": {
|
48
48
|
"@types/react": ">=16.8.0 <19.0.0",
|
49
49
|
"@types/react-dom": ">=16.8.0 <19.0.0",
|
50
|
-
"react": ">=16.
|
50
|
+
"react": ">=16.14.0 <19.0.0",
|
51
51
|
"react-dom": ">=16.8.0 <19.0.0"
|
52
52
|
},
|
53
53
|
"exports": {
|