@fluentui/react-motion-components-preview 0.15.3 → 0.15.5
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/README.md +90 -2
- package/dist/index.d.ts +2 -2
- package/lib/atoms/blur-atom.js.map +1 -1
- package/lib/atoms/fade-atom.js.map +1 -1
- package/lib/atoms/rotate-atom.js.map +1 -1
- package/lib/atoms/scale-atom.js.map +1 -1
- package/lib/atoms/slide-atom.js.map +1 -1
- package/lib/choreography/Stagger/Stagger.js.map +1 -1
- package/lib/choreography/Stagger/stagger-types.js +1 -1
- package/lib/choreography/Stagger/stagger-types.js.map +1 -1
- package/lib/choreography/Stagger/useStaggerItemsVisibility.js +1 -0
- package/lib/choreography/Stagger/useStaggerItemsVisibility.js.map +1 -1
- package/lib/choreography/Stagger/utils/motionComponentDetection.js +0 -1
- package/lib/choreography/Stagger/utils/motionComponentDetection.js.map +1 -1
- package/lib/components/Blur/Blur.js.map +1 -1
- package/lib/components/Collapse/Collapse.js.map +1 -1
- package/lib/components/Collapse/collapse-atoms.js.map +1 -1
- package/lib/components/Fade/Fade.js.map +1 -1
- package/lib/components/Rotate/Rotate.js.map +1 -1
- package/lib/components/Scale/Scale.js.map +1 -1
- package/lib/components/Slide/Slide.js.map +1 -1
- package/lib-commonjs/atoms/blur-atom.js.map +1 -1
- package/lib-commonjs/atoms/fade-atom.js.map +1 -1
- package/lib-commonjs/atoms/rotate-atom.js.map +1 -1
- package/lib-commonjs/atoms/scale-atom.js.map +1 -1
- package/lib-commonjs/atoms/slide-atom.js.map +1 -1
- package/lib-commonjs/choreography/Stagger/Stagger.js.map +1 -1
- package/lib-commonjs/choreography/Stagger/stagger-types.js +0 -2
- package/lib-commonjs/choreography/Stagger/stagger-types.js.map +1 -1
- package/lib-commonjs/choreography/Stagger/useStaggerItemsVisibility.js +1 -0
- package/lib-commonjs/choreography/Stagger/useStaggerItemsVisibility.js.map +1 -1
- package/lib-commonjs/choreography/Stagger/utils/motionComponentDetection.js +0 -2
- package/lib-commonjs/choreography/Stagger/utils/motionComponentDetection.js.map +1 -1
- package/lib-commonjs/components/Blur/Blur.js.map +1 -1
- package/lib-commonjs/components/Collapse/Collapse.js.map +1 -1
- package/lib-commonjs/components/Collapse/collapse-atoms.js.map +1 -1
- package/lib-commonjs/components/Fade/Fade.js.map +1 -1
- package/lib-commonjs/components/Rotate/Rotate.js.map +1 -1
- package/lib-commonjs/components/Scale/Scale.js.map +1 -1
- package/lib-commonjs/components/Slide/Slide.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# @fluentui/react-motion-components-preview
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Pre-built Motion Components for [Fluent UI React](https://react.fluentui.dev/)**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> ⚠️ **Preview Package**: These components are in beta and APIs may change before stable release.
|
|
6
|
+
|
|
7
|
+
Ready-to-use presence components for common UI animation patterns, built on top of `@fluentui/react-motion`.
|
|
8
|
+
|
|
9
|
+
## Components
|
|
10
|
+
|
|
11
|
+
| Component | Description |
|
|
12
|
+
| ------------ | ---------------------------------------------------------- |
|
|
13
|
+
| **Fade** | Opacity transitions for tooltips, notifications, overlays |
|
|
14
|
+
| **Scale** | Size animations for popovers, menus, emphasis |
|
|
15
|
+
| **Collapse** | Height/width expansion for accordions, expandable sections |
|
|
16
|
+
| **Slide** | Directional movement for drawers, panels, carousels |
|
|
17
|
+
| **Blur** | Focus/defocus effects for backgrounds, depth |
|
|
18
|
+
| **Rotate** | 3D rotation for card flips, reveals |
|
|
19
|
+
| **Stagger** | Choreography for sequential list animations |
|
|
20
|
+
|
|
21
|
+
Each component (except Blur and Rotate) comes with **Snappy** (150ms) and **Relaxed** (250ms) timing variants.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @fluentui/react-motion-components-preview
|
|
27
|
+
# or
|
|
28
|
+
yarn add @fluentui/react-motion-components-preview
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { Fade, Scale, Slide, Collapse } from '@fluentui/react-motion-components-preview';
|
|
35
|
+
|
|
36
|
+
// Simple fade
|
|
37
|
+
function Tooltip({ visible, children }) {
|
|
38
|
+
return (
|
|
39
|
+
<Fade visible={visible}>
|
|
40
|
+
{children}
|
|
41
|
+
</Fade>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Slide from the right
|
|
46
|
+
function Drawer({ open, children }) {
|
|
47
|
+
return (
|
|
48
|
+
<Slide visible={open} outX="20px">
|
|
49
|
+
{children}
|
|
50
|
+
</Slide>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Use timing variants
|
|
55
|
+
import { FadeSnappy, ScaleRelaxed } from '@fluentui/react-motion-components-preview';
|
|
56
|
+
|
|
57
|
+
<FadeSnappy visible={show}>Quick feedback</FadeSnappy>
|
|
58
|
+
<ScaleRelaxed visible={show}>Smooth entrance</ScaleRelaxed>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### The `.In` and `.Out` Pattern
|
|
62
|
+
|
|
63
|
+
Every presence component includes one-way sub-components:
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
// One-way enter animation (plays on mount)
|
|
67
|
+
<Fade.In>
|
|
68
|
+
<div>Fades in once</div>
|
|
69
|
+
</Fade.In>
|
|
70
|
+
|
|
71
|
+
// One-way exit animation (plays on mount)
|
|
72
|
+
<Fade.Out>
|
|
73
|
+
<div>Fades out once</div>
|
|
74
|
+
</Fade.Out>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Documentation
|
|
78
|
+
|
|
79
|
+
📚 **[Full documentation](https://react.fluentui.dev/?path=/docs/motion-components-preview-introduction--docs)**
|
|
80
|
+
|
|
81
|
+
- [Introduction](https://react.fluentui.dev/?path=/docs/motion-components-preview-introduction--docs) — Overview of all components
|
|
82
|
+
- [Fade](https://react.fluentui.dev/?path=/docs/motion-components-preview-fade--docs)
|
|
83
|
+
- [Scale](https://react.fluentui.dev/?path=/docs/motion-components-preview-scale--docs)
|
|
84
|
+
- [Collapse](https://react.fluentui.dev/?path=/docs/motion-components-preview-collapse--docs)
|
|
85
|
+
- [Slide](https://react.fluentui.dev/?path=/docs/motion-components-preview-slide--docs)
|
|
86
|
+
- [Blur](https://react.fluentui.dev/?path=/docs/motion-components-preview-blur--docs)
|
|
87
|
+
- [Rotate](https://react.fluentui.dev/?path=/docs/motion-components-preview-rotate--docs)
|
|
88
|
+
- [Stagger](https://react.fluentui.dev/?path=/docs/motion-choreography-preview-stagger--docs)
|
|
89
|
+
- [Motion Atoms](https://react.fluentui.dev/?path=/docs/motion-components-preview-atoms--docs) — Building blocks for custom components
|
|
90
|
+
|
|
91
|
+
## Related
|
|
92
|
+
|
|
93
|
+
- **[@fluentui/react-motion](https://www.npmjs.com/package/@fluentui/react-motion)** — Core motion APIs for creating custom animations
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AtomMotion } from '@fluentui/react-motion';
|
|
1
|
+
import type { AtomMotion } from '@fluentui/react-motion';
|
|
2
2
|
import { PresenceComponent } from '@fluentui/react-motion';
|
|
3
|
-
import { PresenceComponentProps } from '@fluentui/react-motion';
|
|
3
|
+
import type { PresenceComponentProps } from '@fluentui/react-motion';
|
|
4
4
|
import type { PresenceDirection } from '@fluentui/react-motion';
|
|
5
5
|
import * as React_2 from 'react';
|
|
6
6
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/blur-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/blur-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface BlurAtomParams extends BaseAtomParams {\n /** Blur radius for the out state (exited). Defaults to '10px'. */\n outRadius?: string;\n /** Blur radius for the in state (entered). Defaults to '0px'. */\n inRadius?: string;\n}\n\n/**\n * Generates a motion atom object for a blur-in or blur-out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param outRadius - Blur radius for the out state (exited) with units (e.g., '20px', '1rem'). Defaults to '10px'.\n * @param inRadius - Blur radius for the in state (entered) with units (e.g., '0px', '5px'). Defaults to '0px'.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with filter blur keyframes and the supplied duration and easing.\n */\nexport const blurAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outRadius = '10px',\n inRadius = '0px',\n}: BlurAtomParams): AtomMotion => {\n const keyframes = [{ filter: `blur(${outRadius})` }, { filter: `blur(${inRadius})` }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["motionTokens","blurAtom","direction","duration","easing","curveLinear","delay","outRadius","inRadius","keyframes","filter","reverse"],"mappings":"AACA,SAASA,YAAY,QAAQ,yBAAyB;AAUtD;;;;;;;;;CASC,GACD,OAAO,MAAMC,WAAW,CAAC,EACvBC,SAAS,EACTC,QAAQ,EACRC,SAASJ,aAAaK,WAAW,EACjCC,QAAQ,CAAC,EACTC,YAAY,MAAM,EAClBC,WAAW,KAAK,EACD;IACf,MAAMC,YAAY;QAAC;YAAEC,QAAQ,CAAC,KAAK,EAAEH,UAAU,CAAC,CAAC;QAAC;QAAG;YAAEG,QAAQ,CAAC,KAAK,EAAEF,SAAS,CAAC,CAAC;QAAC;KAAE;IACrF,IAAIN,cAAc,QAAQ;QACxBO,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAN;QACAC;QACAE;IACF;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/fade-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/fade-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface FadeAtomParams extends BaseAtomParams {\n /** Defines how values are applied before and after execution. Defaults to 'both'. */\n fill?: FillMode;\n\n /** Opacity for the out state (exited). Defaults to 0. */\n outOpacity?: number;\n\n /** Opacity for the in state (entered). Defaults to 1. */\n inOpacity?: number;\n}\n\n/**\n * Generates a motion atom object for a fade-in or fade-out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param delay - The delay before the motion starts. Defaults to 0.\n * @param outOpacity - Opacity for the out state (exited). Defaults to 0.\n * @param inOpacity - Opacity for the in state (entered). Defaults to 1.\n * @returns A motion atom object with opacity keyframes and the supplied duration and easing.\n */\nexport const fadeAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outOpacity = 0,\n inOpacity = 1,\n}: FadeAtomParams): AtomMotion => {\n const keyframes = [{ opacity: outOpacity }, { opacity: inOpacity }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n // Applying opacity backwards and forwards in time is important\n // to avoid a bug where a delayed animation is not hidden when it should be.\n fill: 'both',\n };\n};\n"],"names":["motionTokens","fadeAtom","direction","duration","easing","curveLinear","delay","outOpacity","inOpacity","keyframes","opacity","reverse","fill"],"mappings":"AACA,SAASA,YAAY,QAAQ,yBAAyB;AActD;;;;;;;;;CASC,GACD,OAAO,MAAMC,WAAW,CAAC,EACvBC,SAAS,EACTC,QAAQ,EACRC,SAASJ,aAAaK,WAAW,EACjCC,QAAQ,CAAC,EACTC,aAAa,CAAC,EACdC,YAAY,CAAC,EACE;IACf,MAAMC,YAAY;QAAC;YAAEC,SAASH;QAAW;QAAG;YAAEG,SAASF;QAAU;KAAE;IACnE,IAAIN,cAAc,QAAQ;QACxBO,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAN;QACAC;QACAE;QACA,+DAA+D;QAC/D,4EAA4E;QAC5EM,MAAM;IACR;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/rotate-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/rotate-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { RotateParams } from '../components/Rotate/rotate-types';\nimport type { BaseAtomParams } from '../types';\n\ntype Axis3D = NonNullable<RotateParams['axis']>;\n\ninterface RotateAtomParams extends BaseAtomParams {\n axis?: Axis3D;\n /** Rotation angle for the out state (exited) in degrees. Defaults to -90. */\n outAngle?: number;\n /** Rotation angle for the in state (entered) in degrees. Defaults to 0. */\n inAngle?: number;\n}\n\nconst createRotateValue = (axis: Axis3D, angle: number): string => {\n return `${axis.toLowerCase()} ${angle}deg`;\n};\n\n/**\n * Generates a motion atom object for a rotation around a single axis.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param axis - The axis of rotation: 'x', 'y', or 'z'. Defaults to 'y'.\n * @param outAngle - Rotation angle for the out state (exited) in degrees. Defaults to -90.\n * @param inAngle - Rotation angle for the in state (entered) in degrees. Defaults to 0.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with rotate keyframes and the supplied duration and easing.\n */\nexport const rotateAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n axis = 'z',\n outAngle = -90,\n inAngle = 0,\n}: RotateAtomParams): AtomMotion => {\n const keyframes = [{ rotate: createRotateValue(axis, outAngle) }, { rotate: createRotateValue(axis, inAngle) }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["motionTokens","createRotateValue","axis","angle","toLowerCase","rotateAtom","direction","duration","easing","curveLinear","delay","outAngle","inAngle","keyframes","rotate","reverse"],"mappings":"AACA,SAASA,YAAY,QAAQ,yBAAyB;AActD,MAAMC,oBAAoB,CAACC,MAAcC;IACvC,OAAO,GAAGD,KAAKE,WAAW,GAAG,CAAC,EAAED,MAAM,GAAG,CAAC;AAC5C;AAEA;;;;;;;;;;CAUC,GACD,OAAO,MAAME,aAAa,CAAC,EACzBC,SAAS,EACTC,QAAQ,EACRC,SAASR,aAAaS,WAAW,EACjCC,QAAQ,CAAC,EACTR,OAAO,GAAG,EACVS,WAAW,CAAC,EAAE,EACdC,UAAU,CAAC,EACM;IACjB,MAAMC,YAAY;QAAC;YAAEC,QAAQb,kBAAkBC,MAAMS;QAAU;QAAG;YAAEG,QAAQb,kBAAkBC,MAAMU;QAAS;KAAE;IAC/G,IAAIN,cAAc,QAAQ;QACxBO,UAAUE,OAAO;IACnB;IAEA,OAAO;QACLF;QACAN;QACAC;QACAE;IACF;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/scale-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/scale-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface ScaleAtomParams extends BaseAtomParams {\n /** Scale for the out state (exited). Defaults to 0.9. */\n outScale?: number;\n /** Scale for the in state (entered). Defaults to 1. */\n inScale?: number;\n}\n\n/**\n * Generates a motion atom object for a scale in or scale out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param outScale - Scale for the out state (exited). Defaults to 0.9.\n * @param inScale - Scale for the in state (entered). Defaults to 1.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with scale keyframes and the supplied duration and easing.\n */\nexport const scaleAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outScale = 0.9,\n inScale = 1,\n}: ScaleAtomParams): AtomMotion => {\n const keyframes = [{ scale: outScale }, { scale: inScale }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["motionTokens","scaleAtom","direction","duration","easing","curveLinear","delay","outScale","inScale","keyframes","scale","reverse"],"mappings":"AACA,SAASA,YAAY,QAAQ,yBAAyB;AAUtD;;;;;;;;;CASC,GACD,OAAO,MAAMC,YAAY,CAAC,EACxBC,SAAS,EACTC,QAAQ,EACRC,SAASJ,aAAaK,WAAW,EACjCC,QAAQ,CAAC,EACTC,WAAW,GAAG,EACdC,UAAU,CAAC,EACK;IAChB,MAAMC,YAAY;QAAC;YAAEC,OAAOH;QAAS;QAAG;YAAEG,OAAOF;QAAQ;KAAE;IAC3D,IAAIN,cAAc,QAAQ;QACxBO,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAN;QACAC;QACAE;IACF;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/slide-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/slide-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface SlideAtomParams extends BaseAtomParams {\n /** X translate for the out state (exited). Defaults to '0px'. */\n outX?: string;\n /** Y translate for the out state (exited). Defaults to '0px'. */\n outY?: string;\n /** X translate for the in state (entered). Defaults to '0px'. */\n inX?: string;\n /** Y translate for the in state (entered). Defaults to '0px'. */\n inY?: string;\n}\n\n/**\n * Generates a motion atom object for a slide-in or slide-out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param outX - X translate for the out state (exited) with units (e.g., '50px', '100%'). Defaults to '0px'.\n * @param outY - Y translate for the out state (exited) with units (e.g., '50px', '100%'). Defaults to '0px'.\n * @param inX - X translate for the in state (entered) with units (e.g., '5px', '10%'). Defaults to '0px'.\n * @param inY - Y translate for the in state (entered) with units (e.g., '5px', '10%'). Defaults to '0px'.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with translate keyframes and the supplied duration and easing.\n */\nexport const slideAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outX = '0px',\n outY = '0px',\n inX = '0px',\n inY = '0px',\n}: SlideAtomParams): AtomMotion => {\n const keyframes = [{ translate: `${outX} ${outY}` }, { translate: `${inX} ${inY}` }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["motionTokens","slideAtom","direction","duration","easing","curveLinear","delay","outX","outY","inX","inY","keyframes","translate","reverse"],"mappings":"AACA,SAASA,YAAY,QAAQ,yBAAyB;AActD;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,YAAY,CAAC,EACxBC,SAAS,EACTC,QAAQ,EACRC,SAASJ,aAAaK,WAAW,EACjCC,QAAQ,CAAC,EACTC,OAAO,KAAK,EACZC,OAAO,KAAK,EACZC,MAAM,KAAK,EACXC,MAAM,KAAK,EACK;IAChB,MAAMC,YAAY;QAAC;YAAEC,WAAW,GAAGL,KAAK,CAAC,EAAEC,MAAM;QAAC;QAAG;YAAEI,WAAW,GAAGH,IAAI,CAAC,EAAEC,KAAK;QAAC;KAAE;IACpF,IAAIR,cAAc,QAAQ;QACxBS,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAR;QACAC;QACAE;IACF;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/Stagger.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useStaggerItemsVisibility } from './useStaggerItemsVisibility';\nimport {\n DEFAULT_ITEM_DURATION,\n DEFAULT_ITEM_DELAY,\n acceptsVisibleProp,\n acceptsDelayProps,\n getStaggerChildMapping,\n} from './utils';\nimport { StaggerOneWayProps, StaggerProps, type StaggerHideMode, type StaggerDelayMode } from './stagger-types';\n\n/**\n * Shared utility to detect optimal stagger modes based on children components.\n * Consolidates the auto-detection logic used by both StaggerMain and createStaggerDirection.\n */\nconst detectStaggerModes = (\n children: React.ReactNode,\n options: {\n hideMode?: StaggerHideMode;\n delayMode?: StaggerDelayMode;\n fallbackHideMode?: StaggerHideMode;\n },\n): { hideMode: StaggerHideMode; delayMode: StaggerDelayMode } => {\n const { hideMode, delayMode, fallbackHideMode = 'visibilityStyle' } = options;\n\n const childMapping = getStaggerChildMapping(children);\n const elements = Object.values(childMapping).map(item => item.element);\n const hasVisiblePropSupport = elements.every(child => acceptsVisibleProp(child));\n const hasDelayPropSupport = elements.every(child => acceptsDelayProps(child));\n\n return {\n hideMode: hideMode ?? (hasVisiblePropSupport ? 'visibleProp' : fallbackHideMode),\n delayMode: delayMode ?? (hasDelayPropSupport ? 'delayProp' : 'timing'),\n };\n};\n\nconst StaggerOneWay: React.FC<StaggerOneWayProps> = ({\n children,\n direction,\n itemDelay = DEFAULT_ITEM_DELAY,\n itemDuration = DEFAULT_ITEM_DURATION,\n reversed = false,\n hideMode,\n delayMode = 'timing',\n onMotionFinish,\n}) => {\n const childMapping = React.useMemo(() => getStaggerChildMapping(children), [children]);\n\n // Always call hooks at the top level, regardless of delayMode\n const { itemsVisibility } = useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration,\n direction,\n reversed,\n onMotionFinish,\n hideMode,\n });\n\n // For delayProp mode, pass delay props directly to motion components\n if (delayMode === 'delayProp') {\n return (\n <>\n {Object.entries(childMapping).map(([key, { element, index }]) => {\n const staggerIndex = reversed ? Object.keys(childMapping).length - 1 - index : index;\n const delay = staggerIndex * itemDelay;\n\n // Clone element with delay prop (for enter direction) or exitDelay prop (for exit direction)\n const delayProp = direction === 'enter' ? { delay } : { exitDelay: delay };\n\n // Only set visible prop if the component supports it\n // Set visible based on direction: true for enter, false for exit\n const visibleProp = acceptsVisibleProp(element) ? { visible: direction === 'enter' } : {};\n\n return React.cloneElement(element, {\n key,\n ...visibleProp,\n ...delayProp,\n });\n })}\n </>\n );\n }\n\n // For timing mode, use the existing timing-based implementation\n\n return (\n <>\n {Object.entries(childMapping).map(([key, { element }]) => {\n if (hideMode === 'visibleProp') {\n // Use a generic record type for props to avoid `any` while still allowing unknown prop shapes.\n return React.cloneElement(element, {\n key,\n visible: itemsVisibility[key],\n } as Partial<Record<string, unknown>>);\n } else if (hideMode === 'visibilityStyle') {\n const childProps = element.props as Record<string, unknown> | undefined;\n const style = {\n ...(childProps?.style as Record<string, unknown> | undefined),\n visibility: itemsVisibility[key] ? 'visible' : 'hidden',\n };\n return React.cloneElement(element, { key, style } as Partial<Record<string, unknown>>);\n } else {\n // unmount mode\n return itemsVisibility[key] ? React.cloneElement(element, { key }) : null;\n }\n })}\n </>\n );\n};\n\n// Shared helper for StaggerIn and StaggerOut\nconst createStaggerDirection = (direction: 'enter' | 'exit') => {\n const StaggerDirection: React.FC<Omit<StaggerProps, 'visible'>> = ({ hideMode, delayMode, children, ...props }) => {\n // Auto-detect modes for better performance with motion components\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // One-way stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n return (\n <StaggerOneWay\n {...props}\n children={children}\n direction={direction}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n />\n );\n };\n\n return StaggerDirection;\n};\n\nconst StaggerIn = createStaggerDirection('enter');\nconst StaggerOut = createStaggerDirection('exit');\n\n// Main Stagger component with auto-detection or explicit modes\nconst StaggerMain: React.FC<StaggerProps> = props => {\n const { children, visible = false, hideMode, delayMode, ...rest } = props;\n\n // Auto-detect modes for bidirectional stagger\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // Bidirectional stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n const direction = visible ? 'enter' : 'exit';\n\n return (\n <StaggerOneWay\n {...rest}\n children={children}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n direction={direction}\n />\n );\n};\n\n/**\n * Stagger is a component that manages the staggered entrance and exit of its children.\n * Children are animated in sequence with configurable timing between each item.\n * Stagger can be interactively toggled between entrance and exit animations using the `visible` prop.\n *\n * @param children - React elements to animate. Elements are cloned with animation props.\n * @param visible - Controls animation direction. When `true`, the group is animating \"enter\" (items shown);\n * when `false`, the group is animating \"exit\" (items hidden). Defaults to `false`.\n * @param itemDelay - Milliseconds between each item's animation start.\n * Defaults to the package's default delay (see `DEFAULT_ITEM_DELAY`).\n * @param itemDuration - Milliseconds each item's animation lasts. Only used with `delayMode=\"timing\"`.\n * Defaults to the package's default item duration (see `DEFAULT_ITEM_DURATION`).\n * @param reversed - Whether to reverse the stagger sequence (last item animates first). Defaults to `false`.\n * @param hideMode - How children's visibility/mounting is managed. Auto-detects if not specified.\n * @param delayMode - How staggering timing is implemented. Auto-detects if not specified.\n * @param onMotionFinish - Callback invoked when the staggered animation sequence completes.\n *\n * **Auto-detection behavior:**\n * - **hideMode**: Presence components use `'visibleProp'`, DOM elements use `'visibilityStyle'`\n * - **delayMode**: Components with delay support use `'delayProp'` (most performant), others use `'timing'`\n *\n * **hideMode options:**\n * - `'visibleProp'`: Children are presence components with `visible` prop (always rendered, visibility controlled via prop)\n * - `'visibilityStyle'`: Children remain in DOM with inline style visibility: hidden/visible (preserves layout space)\n * - `'unmount'`: Children are mounted/unmounted from DOM based on visibility\n *\n * **delayMode options:**\n * - `'timing'`: Manages visibility over time using JavaScript timing\n * - `'delayProp'`: Passes delay props to motion components to use native Web Animations API delays (most performant)\n *\n * **Static variants:**\n * - `<Stagger.In>` - One-way stagger for entrance animations only (auto-detects optimal modes)\n * - `<Stagger.Out>` - One-way stagger for exit animations only (auto-detects optimal modes)\n *\n * @example\n * ```tsx\n * import { Stagger, Fade, Scale, Rotate } from '@fluentui/react-motion-components-preview';\n *\n * // Auto-detects optimal modes for presence components (delayProp + visibleProp)\n * <Stagger visible={isVisible} itemDelay={150}>\n * <Fade><div>Item 2</div></Fade>\n * <Scale><div>Item 1</div></Scale>\n * <Rotate><div>Item 3</div></Rotate>\n * </Stagger>\n *\n * // Auto-detects optimal modes for motion components (delayProp + unmount)\n * <Stagger.In itemDelay={100}>\n * <Scale.In><div>Item 1</div></Scale.In>\n * <Fade.In><div>Item 2</div></Fade.In>\n * </Stagger.In>\n *\n * // Auto-detects timing mode for DOM elements (timing + visibilityStyle)\n * <Stagger visible={isVisible} itemDelay={150} onMotionFinish={handleComplete}>\n * <div>Item 1</div>\n * <div>Item 2</div>\n * <div>Item 3</div>\n * </Stagger>\n *\n * // Override auto-detection when needed\n * <Stagger visible={isVisible} delayMode=\"timing\" hideMode=\"unmount\">\n * <CustomComponent>Item 1</CustomComponent>\n * </Stagger>\n * ```\n */\nexport const Stagger = Object.assign(StaggerMain, {\n In: StaggerIn,\n Out: StaggerOut,\n});\n"],"names":["React","useStaggerItemsVisibility","DEFAULT_ITEM_DURATION","DEFAULT_ITEM_DELAY","acceptsVisibleProp","acceptsDelayProps","getStaggerChildMapping","detectStaggerModes","children","options","hideMode","delayMode","fallbackHideMode","childMapping","elements","Object","values","map","item","element","hasVisiblePropSupport","every","child","hasDelayPropSupport","StaggerOneWay","direction","itemDelay","itemDuration","reversed","onMotionFinish","useMemo","itemsVisibility","entries","key","index","staggerIndex","keys","length","delay","delayProp","exitDelay","visibleProp","visible","cloneElement","childProps","props","style","visibility","createStaggerDirection","StaggerDirection","resolvedHideMode","resolvedDelayMode","StaggerIn","StaggerOut","StaggerMain","rest","Stagger","assign","In","Out"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/Stagger.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useStaggerItemsVisibility } from './useStaggerItemsVisibility';\nimport {\n DEFAULT_ITEM_DURATION,\n DEFAULT_ITEM_DELAY,\n acceptsVisibleProp,\n acceptsDelayProps,\n getStaggerChildMapping,\n} from './utils';\nimport type { StaggerOneWayProps, StaggerProps } from './stagger-types';\nimport { type StaggerHideMode, type StaggerDelayMode } from './stagger-types';\n\n/**\n * Shared utility to detect optimal stagger modes based on children components.\n * Consolidates the auto-detection logic used by both StaggerMain and createStaggerDirection.\n */\nconst detectStaggerModes = (\n children: React.ReactNode,\n options: {\n hideMode?: StaggerHideMode;\n delayMode?: StaggerDelayMode;\n fallbackHideMode?: StaggerHideMode;\n },\n): { hideMode: StaggerHideMode; delayMode: StaggerDelayMode } => {\n const { hideMode, delayMode, fallbackHideMode = 'visibilityStyle' } = options;\n\n const childMapping = getStaggerChildMapping(children);\n const elements = Object.values(childMapping).map(item => item.element);\n const hasVisiblePropSupport = elements.every(child => acceptsVisibleProp(child));\n const hasDelayPropSupport = elements.every(child => acceptsDelayProps(child));\n\n return {\n hideMode: hideMode ?? (hasVisiblePropSupport ? 'visibleProp' : fallbackHideMode),\n delayMode: delayMode ?? (hasDelayPropSupport ? 'delayProp' : 'timing'),\n };\n};\n\nconst StaggerOneWay: React.FC<StaggerOneWayProps> = ({\n children,\n direction,\n itemDelay = DEFAULT_ITEM_DELAY,\n itemDuration = DEFAULT_ITEM_DURATION,\n reversed = false,\n hideMode,\n delayMode = 'timing',\n onMotionFinish,\n}) => {\n const childMapping = React.useMemo(() => getStaggerChildMapping(children), [children]);\n\n // Always call hooks at the top level, regardless of delayMode\n const { itemsVisibility } = useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration,\n direction,\n reversed,\n onMotionFinish,\n hideMode,\n });\n\n // For delayProp mode, pass delay props directly to motion components\n if (delayMode === 'delayProp') {\n return (\n <>\n {Object.entries(childMapping).map(([key, { element, index }]) => {\n const staggerIndex = reversed ? Object.keys(childMapping).length - 1 - index : index;\n const delay = staggerIndex * itemDelay;\n\n // Clone element with delay prop (for enter direction) or exitDelay prop (for exit direction)\n const delayProp = direction === 'enter' ? { delay } : { exitDelay: delay };\n\n // Only set visible prop if the component supports it\n // Set visible based on direction: true for enter, false for exit\n const visibleProp = acceptsVisibleProp(element) ? { visible: direction === 'enter' } : {};\n\n return React.cloneElement(element, {\n key,\n ...visibleProp,\n ...delayProp,\n });\n })}\n </>\n );\n }\n\n // For timing mode, use the existing timing-based implementation\n\n return (\n <>\n {Object.entries(childMapping).map(([key, { element }]) => {\n if (hideMode === 'visibleProp') {\n // Use a generic record type for props to avoid `any` while still allowing unknown prop shapes.\n return React.cloneElement(element, {\n key,\n visible: itemsVisibility[key],\n } as Partial<Record<string, unknown>>);\n } else if (hideMode === 'visibilityStyle') {\n const childProps = element.props as Record<string, unknown> | undefined;\n const style = {\n ...(childProps?.style as Record<string, unknown> | undefined),\n visibility: itemsVisibility[key] ? 'visible' : 'hidden',\n };\n return React.cloneElement(element, { key, style } as Partial<Record<string, unknown>>);\n } else {\n // unmount mode\n return itemsVisibility[key] ? React.cloneElement(element, { key }) : null;\n }\n })}\n </>\n );\n};\n\n// Shared helper for StaggerIn and StaggerOut\nconst createStaggerDirection = (direction: 'enter' | 'exit') => {\n const StaggerDirection: React.FC<Omit<StaggerProps, 'visible'>> = ({ hideMode, delayMode, children, ...props }) => {\n // Auto-detect modes for better performance with motion components\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // One-way stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n return (\n <StaggerOneWay\n {...props}\n children={children}\n direction={direction}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n />\n );\n };\n\n return StaggerDirection;\n};\n\nconst StaggerIn = createStaggerDirection('enter');\nconst StaggerOut = createStaggerDirection('exit');\n\n// Main Stagger component with auto-detection or explicit modes\nconst StaggerMain: React.FC<StaggerProps> = props => {\n const { children, visible = false, hideMode, delayMode, ...rest } = props;\n\n // Auto-detect modes for bidirectional stagger\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // Bidirectional stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n const direction = visible ? 'enter' : 'exit';\n\n return (\n <StaggerOneWay\n {...rest}\n children={children}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n direction={direction}\n />\n );\n};\n\n/**\n * Stagger is a component that manages the staggered entrance and exit of its children.\n * Children are animated in sequence with configurable timing between each item.\n * Stagger can be interactively toggled between entrance and exit animations using the `visible` prop.\n *\n * @param children - React elements to animate. Elements are cloned with animation props.\n * @param visible - Controls animation direction. When `true`, the group is animating \"enter\" (items shown);\n * when `false`, the group is animating \"exit\" (items hidden). Defaults to `false`.\n * @param itemDelay - Milliseconds between each item's animation start.\n * Defaults to the package's default delay (see `DEFAULT_ITEM_DELAY`).\n * @param itemDuration - Milliseconds each item's animation lasts. Only used with `delayMode=\"timing\"`.\n * Defaults to the package's default item duration (see `DEFAULT_ITEM_DURATION`).\n * @param reversed - Whether to reverse the stagger sequence (last item animates first). Defaults to `false`.\n * @param hideMode - How children's visibility/mounting is managed. Auto-detects if not specified.\n * @param delayMode - How staggering timing is implemented. Auto-detects if not specified.\n * @param onMotionFinish - Callback invoked when the staggered animation sequence completes.\n *\n * **Auto-detection behavior:**\n * - **hideMode**: Presence components use `'visibleProp'`, DOM elements use `'visibilityStyle'`\n * - **delayMode**: Components with delay support use `'delayProp'` (most performant), others use `'timing'`\n *\n * **hideMode options:**\n * - `'visibleProp'`: Children are presence components with `visible` prop (always rendered, visibility controlled via prop)\n * - `'visibilityStyle'`: Children remain in DOM with inline style visibility: hidden/visible (preserves layout space)\n * - `'unmount'`: Children are mounted/unmounted from DOM based on visibility\n *\n * **delayMode options:**\n * - `'timing'`: Manages visibility over time using JavaScript timing\n * - `'delayProp'`: Passes delay props to motion components to use native Web Animations API delays (most performant)\n *\n * **Static variants:**\n * - `<Stagger.In>` - One-way stagger for entrance animations only (auto-detects optimal modes)\n * - `<Stagger.Out>` - One-way stagger for exit animations only (auto-detects optimal modes)\n *\n * @example\n * ```tsx\n * import { Stagger, Fade, Scale, Rotate } from '@fluentui/react-motion-components-preview';\n *\n * // Auto-detects optimal modes for presence components (delayProp + visibleProp)\n * <Stagger visible={isVisible} itemDelay={150}>\n * <Fade><div>Item 2</div></Fade>\n * <Scale><div>Item 1</div></Scale>\n * <Rotate><div>Item 3</div></Rotate>\n * </Stagger>\n *\n * // Auto-detects optimal modes for motion components (delayProp + unmount)\n * <Stagger.In itemDelay={100}>\n * <Scale.In><div>Item 1</div></Scale.In>\n * <Fade.In><div>Item 2</div></Fade.In>\n * </Stagger.In>\n *\n * // Auto-detects timing mode for DOM elements (timing + visibilityStyle)\n * <Stagger visible={isVisible} itemDelay={150} onMotionFinish={handleComplete}>\n * <div>Item 1</div>\n * <div>Item 2</div>\n * <div>Item 3</div>\n * </Stagger>\n *\n * // Override auto-detection when needed\n * <Stagger visible={isVisible} delayMode=\"timing\" hideMode=\"unmount\">\n * <CustomComponent>Item 1</CustomComponent>\n * </Stagger>\n * ```\n */\nexport const Stagger = Object.assign(StaggerMain, {\n In: StaggerIn,\n Out: StaggerOut,\n});\n"],"names":["React","useStaggerItemsVisibility","DEFAULT_ITEM_DURATION","DEFAULT_ITEM_DELAY","acceptsVisibleProp","acceptsDelayProps","getStaggerChildMapping","detectStaggerModes","children","options","hideMode","delayMode","fallbackHideMode","childMapping","elements","Object","values","map","item","element","hasVisiblePropSupport","every","child","hasDelayPropSupport","StaggerOneWay","direction","itemDelay","itemDuration","reversed","onMotionFinish","useMemo","itemsVisibility","entries","key","index","staggerIndex","keys","length","delay","delayProp","exitDelay","visibleProp","visible","cloneElement","childProps","props","style","visibility","createStaggerDirection","StaggerDirection","resolvedHideMode","resolvedDelayMode","StaggerIn","StaggerOut","StaggerMain","rest","Stagger","assign","In","Out"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export { };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/stagger-types.ts"],"sourcesContent":["import { PresenceComponentProps, PresenceDirection } from '@fluentui/react-motion';\nimport * as React from 'react';\n\n/**\n * Defines how Stagger manages its children's visibility/mounting.\n * - 'visibleProp': Children are components with a `visible` prop (e.g. motion components)\n * - 'visibilityStyle': Children remain in DOM with inline style `visibility: hidden | visible`\n * - 'unmount': Children are mounted/unmounted from DOM based on visibility\n */\nexport type StaggerHideMode = 'visibleProp' | 'visibilityStyle' | 'unmount';\n\n/**\n * Defines how Stagger implements the timing of staggered animations.\n * - 'timing': Manages visibility over time using JavaScript timing (current behavior)\n * - 'delayProp': Passes delay props to motion components to use native Web Animations API delays\n */\nexport type StaggerDelayMode = 'timing' | 'delayProp';\n\n/**\n * Props for the Stagger component that manages staggered entrance and exit animations.\n */\nexport interface StaggerProps {\n /** React elements to animate. Elements are cloned with animation props. */\n children: React.ReactNode;\n\n /**\n * Controls children animation direction. When `true`, the group is animating \"enter\" (items shown).\n * When `false`, the group is animating \"exit\" (items hidden).\n */\n visible?: PresenceComponentProps['visible'];\n\n /** Whether to reverse the stagger sequence (last item animates first). Defaults to `false`. */\n reversed?: boolean;\n\n /**\n * Milliseconds between each child's animation start.\n * Defaults to the package's default delay (see `DEFAULT_ITEM_DELAY`).\n */\n itemDelay?: number;\n\n /**\n * Milliseconds each child's animation lasts. Only used with `delayMode=\"timing\"`.\n * Defaults to the package's default duration (see `DEFAULT_ITEM_DURATION`).\n */\n itemDuration?: number;\n\n /** How children's visibility/mounting is managed. Auto-detects if not specified. */\n hideMode?: StaggerHideMode;\n\n /** How staggering timing is implemented. Defaults to 'timing'. */\n delayMode?: StaggerDelayMode;\n\n /** Callback invoked when the staggered animation sequence completes. */\n onMotionFinish?: () => void;\n}\n\nexport interface StaggerOneWayProps extends Omit<StaggerProps, 'visible' | 'hideMode' | 'delayMode'> {\n /** Animation direction: 'enter' or 'exit'. */\n direction: PresenceDirection;\n\n /** How children's visibility/mounting is managed. Required - provided by wrapper components. */\n hideMode: StaggerHideMode;\n\n /** How staggering timing is implemented. Required - provided by wrapper components. */\n delayMode: StaggerDelayMode;\n}\n"],"names":[
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/stagger-types.ts"],"sourcesContent":["import type { PresenceComponentProps, PresenceDirection } from '@fluentui/react-motion';\nimport type * as React from 'react';\n\n/**\n * Defines how Stagger manages its children's visibility/mounting.\n * - 'visibleProp': Children are components with a `visible` prop (e.g. motion components)\n * - 'visibilityStyle': Children remain in DOM with inline style `visibility: hidden | visible`\n * - 'unmount': Children are mounted/unmounted from DOM based on visibility\n */\nexport type StaggerHideMode = 'visibleProp' | 'visibilityStyle' | 'unmount';\n\n/**\n * Defines how Stagger implements the timing of staggered animations.\n * - 'timing': Manages visibility over time using JavaScript timing (current behavior)\n * - 'delayProp': Passes delay props to motion components to use native Web Animations API delays\n */\nexport type StaggerDelayMode = 'timing' | 'delayProp';\n\n/**\n * Props for the Stagger component that manages staggered entrance and exit animations.\n */\nexport interface StaggerProps {\n /** React elements to animate. Elements are cloned with animation props. */\n children: React.ReactNode;\n\n /**\n * Controls children animation direction. When `true`, the group is animating \"enter\" (items shown).\n * When `false`, the group is animating \"exit\" (items hidden).\n */\n visible?: PresenceComponentProps['visible'];\n\n /** Whether to reverse the stagger sequence (last item animates first). Defaults to `false`. */\n reversed?: boolean;\n\n /**\n * Milliseconds between each child's animation start.\n * Defaults to the package's default delay (see `DEFAULT_ITEM_DELAY`).\n */\n itemDelay?: number;\n\n /**\n * Milliseconds each child's animation lasts. Only used with `delayMode=\"timing\"`.\n * Defaults to the package's default duration (see `DEFAULT_ITEM_DURATION`).\n */\n itemDuration?: number;\n\n /** How children's visibility/mounting is managed. Auto-detects if not specified. */\n hideMode?: StaggerHideMode;\n\n /** How staggering timing is implemented. Defaults to 'timing'. */\n delayMode?: StaggerDelayMode;\n\n /** Callback invoked when the staggered animation sequence completes. */\n onMotionFinish?: () => void;\n}\n\nexport interface StaggerOneWayProps extends Omit<StaggerProps, 'visible' | 'hideMode' | 'delayMode'> {\n /** Animation direction: 'enter' or 'exit'. */\n direction: PresenceDirection;\n\n /** How children's visibility/mounting is managed. Required - provided by wrapper components. */\n hideMode: StaggerHideMode;\n\n /** How staggering timing is implemented. Required - provided by wrapper components. */\n delayMode: StaggerDelayMode;\n}\n"],"names":[],"mappings":"AAwDA,WASC"}
|
|
@@ -58,6 +58,7 @@ import { staggerItemsVisibilityAtTime, DEFAULT_ITEM_DURATION } from './utils';
|
|
|
58
58
|
});
|
|
59
59
|
// Update visibility mapping when childMapping changes
|
|
60
60
|
React.useEffect(()=>{
|
|
61
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
61
62
|
setItemsVisibility((prev)=>{
|
|
62
63
|
const next = {};
|
|
63
64
|
const targetState = direction === 'enter';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/useStaggerItemsVisibility.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useAnimationFrame, useEventCallback } from '@fluentui/react-utilities';\nimport type { StaggerProps } from './stagger-types';\nimport {\n staggerItemsVisibilityAtTime,\n type StaggerItemsVisibilityAtTimeParams,\n DEFAULT_ITEM_DURATION,\n type StaggerChildMapping,\n} from './utils';\n\nexport interface UseStaggerItemsVisibilityParams\n extends Pick<StaggerProps, 'onMotionFinish'>,\n Omit<StaggerItemsVisibilityAtTimeParams, 'elapsed' | 'itemCount'> {\n hideMode: StaggerProps['hideMode'];\n childMapping: StaggerChildMapping;\n}\n\n/**\n * Hook that tracks the visibility of a staggered sequence of items as time progresses.\n *\n * Behavior summary for all hide modes:\n * - On the first render, items are placed in their final state (enter => visible, exit => hidden)\n * and no animation runs.\n * - On subsequent renders when direction changes, items animate from the opposite state\n * to the final state over the stagger timeline.\n * - Changes to the `reversed` prop do not trigger re-animation; they only affect the order\n * during the next direction change animation.\n *\n * This hook uses child key mapping instead of item count to track individual items.\n * This allows it to correctly handle:\n * - Items being added and removed simultaneously (when count stays the same)\n * - Items being reordered\n * - Individual item identity across renders\n *\n * @param childMapping - Mapping of child keys to elements and indices\n * @param itemDelay - Milliseconds between the start of each item's animation\n * @param itemDuration - Milliseconds each item's animation lasts\n * @param direction - 'enter' (show items) or 'exit' (hide items)\n * @param reversed - Whether to reverse the stagger order (last item first)\n * @param onMotionFinish - Callback fired when the full stagger sequence completes\n * @param hideMode - How children's visibility is managed: 'visibleProp', 'visibilityStyle', or 'unmount'\n *\n * @returns An object with `itemsVisibility: Record<string, boolean>` indicating which items are currently visible by key\n */\nexport function useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration = DEFAULT_ITEM_DURATION,\n direction,\n reversed = false,\n onMotionFinish,\n hideMode = 'visibleProp',\n}: UseStaggerItemsVisibilityParams): { itemsVisibility: Record<string, boolean> } {\n const [requestAnimationFrame, cancelAnimationFrame] = useAnimationFrame();\n\n // Stabilize the callback reference to avoid re-triggering effects on every render\n const handleMotionFinish = useEventCallback(\n onMotionFinish ??\n (() => {\n return;\n }),\n );\n\n // Track animation state independently of child changes\n const [animationKey, setAnimationKey] = React.useState(0);\n const prevDirection = React.useRef(direction);\n\n // Only trigger new animation when direction actually changes, not when children change\n React.useEffect(() => {\n if (prevDirection.current !== direction) {\n setAnimationKey(prev => prev + 1);\n prevDirection.current = direction;\n }\n }, [direction]);\n\n // State: visibility mapping for all items by key\n const [itemsVisibility, setItemsVisibility] = React.useState<Record<string, boolean>>(() => {\n const initial: Record<string, boolean> = {};\n // All hide modes start in final state: visible for 'enter', hidden for 'exit'\n const initialState = direction === 'enter';\n Object.keys(childMapping).forEach(key => {\n initial[key] = initialState;\n });\n return initial;\n });\n\n // Update visibility mapping when childMapping changes\n React.useEffect(() => {\n setItemsVisibility(prev => {\n const next: Record<string, boolean> = {};\n const targetState = direction === 'enter';\n\n // Add or update items from new mapping\n Object.keys(childMapping).forEach(key => {\n if (key in prev) {\n // Existing item - preserve its visibility state\n next[key] = prev[key];\n } else {\n // New item - set to target state\n next[key] = targetState;\n }\n });\n\n // Note: Items that were in prev but not in childMapping are automatically removed\n // because we only iterate over keys in childMapping\n\n return next;\n });\n }, [childMapping, direction]);\n\n // Refs: animation timing and control\n const startTimeRef = React.useRef<number | null>(null);\n const frameRef = React.useRef<number | null>(null);\n const finishedRef = React.useRef(false);\n const isFirstRender = React.useRef(true);\n\n // Use ref to avoid re-running the animation when child mapping changes\n const childMappingRef = React.useRef(childMapping);\n\n // Update childMapping ref whenever it changes\n React.useEffect(() => {\n childMappingRef.current = childMapping;\n }, [childMapping]);\n\n // Use ref for reversed to avoid re-running animation when it changes\n const reversedRef = React.useRef(reversed);\n\n // Update reversed ref whenever it changes\n React.useEffect(() => {\n reversedRef.current = reversed;\n }, [reversed]);\n\n // ====== ANIMATION EFFECT ======\n\n React.useEffect(() => {\n let cancelled = false;\n startTimeRef.current = null;\n finishedRef.current = false;\n\n // All hide modes skip animation on first render - items are already in their final state\n if (isFirstRender.current) {\n isFirstRender.current = false;\n // Items are already in their final state from useState, no animation needed\n handleMotionFinish();\n return; // No cleanup needed for first render\n }\n\n // For animations after first render, start from the opposite of the final state\n // - Enter animation: start hidden (false), animate to visible (true)\n // - Exit animation: start visible (true), animate to hidden (false)\n const startState = direction === 'exit';\n // Use childMappingRef.current to avoid adding childMapping to dependencies\n const initialVisibility: Record<string, boolean> = {};\n Object.keys(childMappingRef.current).forEach(key => {\n initialVisibility[key] = startState;\n });\n setItemsVisibility(initialVisibility);\n\n // Animation loop: update visibility on each frame until complete\n const tick = (now: number) => {\n if (cancelled) {\n return;\n }\n if (startTimeRef.current === null) {\n startTimeRef.current = now;\n }\n const elapsed = now - (startTimeRef.current as number);\n\n const childKeys = Object.keys(childMappingRef.current);\n const itemCount = childKeys.length;\n\n const result = staggerItemsVisibilityAtTime({\n itemCount,\n elapsed,\n itemDelay,\n itemDuration,\n direction,\n reversed: reversedRef.current,\n });\n\n // Convert boolean array to keyed object\n const nextVisibility: Record<string, boolean> = {};\n childKeys.forEach((key, idx) => {\n nextVisibility[key] = result.itemsVisibility[idx];\n });\n\n setItemsVisibility(nextVisibility);\n\n if (elapsed < result.totalDuration) {\n frameRef.current = requestAnimationFrame(tick);\n } else if (!finishedRef.current) {\n finishedRef.current = true;\n handleMotionFinish();\n }\n };\n\n frameRef.current = requestAnimationFrame(tick);\n return () => {\n cancelled = true;\n if (frameRef.current) {\n cancelAnimationFrame();\n }\n };\n }, [\n animationKey,\n itemDelay,\n itemDuration,\n direction,\n requestAnimationFrame,\n cancelAnimationFrame,\n handleMotionFinish,\n ]);\n\n return { itemsVisibility };\n}\n"],"names":["React","useAnimationFrame","useEventCallback","staggerItemsVisibilityAtTime","DEFAULT_ITEM_DURATION","useStaggerItemsVisibility","childMapping","itemDelay","itemDuration","direction","reversed","onMotionFinish","hideMode","requestAnimationFrame","cancelAnimationFrame","handleMotionFinish","animationKey","setAnimationKey","useState","prevDirection","useRef","useEffect","current","prev","itemsVisibility","setItemsVisibility","initial","initialState","Object","keys","forEach","key","next","targetState","startTimeRef","frameRef","finishedRef","isFirstRender","childMappingRef","reversedRef","cancelled","startState","initialVisibility","tick","now","elapsed","childKeys","itemCount","length","result","nextVisibility","idx","totalDuration"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,iBAAiB,EAAEC,gBAAgB,QAAQ,4BAA4B;AAEhF,SACEC,4BAA4B,EAE5BC,qBAAqB,QAEhB,UAAU;AASjB;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GACD,OAAO,SAASC,0BAA0B,EACxCC,YAAY,EACZC,SAAS,EACTC,eAAeJ,qBAAqB,EACpCK,SAAS,EACTC,WAAW,KAAK,EAChBC,cAAc,EACdC,WAAW,aAAa,EACQ;IAChC,MAAM,CAACC,uBAAuBC,qBAAqB,GAAGb;IAEtD,kFAAkF;IAClF,MAAMc,qBAAqBb,iBACzBS,2BAAAA,4BAAAA,iBACG;QACC;IACF;IAGJ,uDAAuD;IACvD,MAAM,CAACK,cAAcC,gBAAgB,GAAGjB,MAAMkB,QAAQ,CAAC;IACvD,MAAMC,gBAAgBnB,MAAMoB,MAAM,CAACX;IAEnC,uFAAuF;IACvFT,MAAMqB,SAAS,CAAC;QACd,IAAIF,cAAcG,OAAO,KAAKb,WAAW;YACvCQ,gBAAgBM,CAAAA,OAAQA,OAAO;YAC/BJ,cAAcG,OAAO,GAAGb;QAC1B;IACF,GAAG;QAACA;KAAU;IAEd,iDAAiD;IACjD,MAAM,CAACe,iBAAiBC,mBAAmB,GAAGzB,MAAMkB,QAAQ,CAA0B;QACpF,MAAMQ,UAAmC,CAAC;QAC1C,8EAA8E;QAC9E,MAAMC,eAAelB,cAAc;QACnCmB,OAAOC,IAAI,CAACvB,cAAcwB,OAAO,CAACC,CAAAA;YAChCL,OAAO,CAACK,IAAI,GAAGJ;QACjB;QACA,OAAOD;IACT;IAEA,sDAAsD;IACtD1B,MAAMqB,SAAS,CAAC;QACdI,mBAAmBF,CAAAA;YACjB,MAAMS,OAAgC,CAAC;YACvC,MAAMC,cAAcxB,cAAc;YAElC,uCAAuC;YACvCmB,OAAOC,IAAI,CAACvB,cAAcwB,OAAO,CAACC,CAAAA;gBAChC,IAAIA,OAAOR,MAAM;oBACf,gDAAgD;oBAChDS,IAAI,CAACD,IAAI,GAAGR,IAAI,CAACQ,IAAI;gBACvB,OAAO;oBACL,iCAAiC;oBACjCC,IAAI,CAACD,IAAI,GAAGE;gBACd;YACF;YAEA,kFAAkF;YAClF,oDAAoD;YAEpD,OAAOD;QACT;IACF,GAAG;QAAC1B;QAAcG;KAAU;IAE5B,qCAAqC;IACrC,MAAMyB,eAAelC,MAAMoB,MAAM,CAAgB;IACjD,MAAMe,WAAWnC,MAAMoB,MAAM,CAAgB;IAC7C,MAAMgB,cAAcpC,MAAMoB,MAAM,CAAC;IACjC,MAAMiB,gBAAgBrC,MAAMoB,MAAM,CAAC;IAEnC,uEAAuE;IACvE,MAAMkB,kBAAkBtC,MAAMoB,MAAM,CAACd;IAErC,8CAA8C;IAC9CN,MAAMqB,SAAS,CAAC;QACdiB,gBAAgBhB,OAAO,GAAGhB;IAC5B,GAAG;QAACA;KAAa;IAEjB,qEAAqE;IACrE,MAAMiC,cAAcvC,MAAMoB,MAAM,CAACV;IAEjC,0CAA0C;IAC1CV,MAAMqB,SAAS,CAAC;QACdkB,YAAYjB,OAAO,GAAGZ;IACxB,GAAG;QAACA;KAAS;IAEb,iCAAiC;IAEjCV,MAAMqB,SAAS,CAAC;QACd,IAAImB,YAAY;QAChBN,aAAaZ,OAAO,GAAG;QACvBc,YAAYd,OAAO,GAAG;QAEtB,yFAAyF;QACzF,IAAIe,cAAcf,OAAO,EAAE;YACzBe,cAAcf,OAAO,GAAG;YACxB,4EAA4E;YAC5EP;YACA,QAAQ,qCAAqC;QAC/C;QAEA,gFAAgF;QAChF,qEAAqE;QACrE,oEAAoE;QACpE,MAAM0B,aAAahC,cAAc;QACjC,2EAA2E;QAC3E,MAAMiC,oBAA6C,CAAC;QACpDd,OAAOC,IAAI,CAACS,gBAAgBhB,OAAO,EAAEQ,OAAO,CAACC,CAAAA;YAC3CW,iBAAiB,CAACX,IAAI,GAAGU;QAC3B;QACAhB,mBAAmBiB;QAEnB,iEAAiE;QACjE,MAAMC,OAAO,CAACC;YACZ,IAAIJ,WAAW;gBACb;YACF;YACA,IAAIN,aAAaZ,OAAO,KAAK,MAAM;gBACjCY,aAAaZ,OAAO,GAAGsB;YACzB;YACA,MAAMC,UAAUD,MAAOV,aAAaZ,OAAO;YAE3C,MAAMwB,YAAYlB,OAAOC,IAAI,CAACS,gBAAgBhB,OAAO;YACrD,MAAMyB,YAAYD,UAAUE,MAAM;YAElC,MAAMC,SAAS9C,6BAA6B;gBAC1C4C;gBACAF;gBACAtC;gBACAC;gBACAC;gBACAC,UAAU6B,YAAYjB,OAAO;YAC/B;YAEA,wCAAwC;YACxC,MAAM4B,iBAA0C,CAAC;YACjDJ,UAAUhB,OAAO,CAAC,CAACC,KAAKoB;gBACtBD,cAAc,CAACnB,IAAI,GAAGkB,OAAOzB,eAAe,CAAC2B,IAAI;YACnD;YAEA1B,mBAAmByB;YAEnB,IAAIL,UAAUI,OAAOG,aAAa,EAAE;gBAClCjB,SAASb,OAAO,GAAGT,sBAAsB8B;YAC3C,OAAO,IAAI,CAACP,YAAYd,OAAO,EAAE;gBAC/Bc,YAAYd,OAAO,GAAG;gBACtBP;YACF;QACF;QAEAoB,SAASb,OAAO,GAAGT,sBAAsB8B;QACzC,OAAO;YACLH,YAAY;YACZ,IAAIL,SAASb,OAAO,EAAE;gBACpBR;YACF;QACF;IACF,GAAG;QACDE;QACAT;QACAC;QACAC;QACAI;QACAC;QACAC;KACD;IAED,OAAO;QAAES;IAAgB;AAC3B"}
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/useStaggerItemsVisibility.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useAnimationFrame, useEventCallback } from '@fluentui/react-utilities';\nimport type { StaggerProps } from './stagger-types';\nimport {\n staggerItemsVisibilityAtTime,\n type StaggerItemsVisibilityAtTimeParams,\n DEFAULT_ITEM_DURATION,\n type StaggerChildMapping,\n} from './utils';\n\nexport interface UseStaggerItemsVisibilityParams\n extends Pick<StaggerProps, 'onMotionFinish'>,\n Omit<StaggerItemsVisibilityAtTimeParams, 'elapsed' | 'itemCount'> {\n hideMode: StaggerProps['hideMode'];\n childMapping: StaggerChildMapping;\n}\n\n/**\n * Hook that tracks the visibility of a staggered sequence of items as time progresses.\n *\n * Behavior summary for all hide modes:\n * - On the first render, items are placed in their final state (enter => visible, exit => hidden)\n * and no animation runs.\n * - On subsequent renders when direction changes, items animate from the opposite state\n * to the final state over the stagger timeline.\n * - Changes to the `reversed` prop do not trigger re-animation; they only affect the order\n * during the next direction change animation.\n *\n * This hook uses child key mapping instead of item count to track individual items.\n * This allows it to correctly handle:\n * - Items being added and removed simultaneously (when count stays the same)\n * - Items being reordered\n * - Individual item identity across renders\n *\n * @param childMapping - Mapping of child keys to elements and indices\n * @param itemDelay - Milliseconds between the start of each item's animation\n * @param itemDuration - Milliseconds each item's animation lasts\n * @param direction - 'enter' (show items) or 'exit' (hide items)\n * @param reversed - Whether to reverse the stagger order (last item first)\n * @param onMotionFinish - Callback fired when the full stagger sequence completes\n * @param hideMode - How children's visibility is managed: 'visibleProp', 'visibilityStyle', or 'unmount'\n *\n * @returns An object with `itemsVisibility: Record<string, boolean>` indicating which items are currently visible by key\n */\nexport function useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration = DEFAULT_ITEM_DURATION,\n direction,\n reversed = false,\n onMotionFinish,\n hideMode = 'visibleProp',\n}: UseStaggerItemsVisibilityParams): { itemsVisibility: Record<string, boolean> } {\n const [requestAnimationFrame, cancelAnimationFrame] = useAnimationFrame();\n\n // Stabilize the callback reference to avoid re-triggering effects on every render\n const handleMotionFinish = useEventCallback(\n onMotionFinish ??\n (() => {\n return;\n }),\n );\n\n // Track animation state independently of child changes\n const [animationKey, setAnimationKey] = React.useState(0);\n const prevDirection = React.useRef(direction);\n\n // Only trigger new animation when direction actually changes, not when children change\n React.useEffect(() => {\n if (prevDirection.current !== direction) {\n setAnimationKey(prev => prev + 1);\n prevDirection.current = direction;\n }\n }, [direction]);\n\n // State: visibility mapping for all items by key\n const [itemsVisibility, setItemsVisibility] = React.useState<Record<string, boolean>>(() => {\n const initial: Record<string, boolean> = {};\n // All hide modes start in final state: visible for 'enter', hidden for 'exit'\n const initialState = direction === 'enter';\n Object.keys(childMapping).forEach(key => {\n initial[key] = initialState;\n });\n return initial;\n });\n\n // Update visibility mapping when childMapping changes\n React.useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setItemsVisibility(prev => {\n const next: Record<string, boolean> = {};\n const targetState = direction === 'enter';\n\n // Add or update items from new mapping\n Object.keys(childMapping).forEach(key => {\n if (key in prev) {\n // Existing item - preserve its visibility state\n next[key] = prev[key];\n } else {\n // New item - set to target state\n next[key] = targetState;\n }\n });\n\n // Note: Items that were in prev but not in childMapping are automatically removed\n // because we only iterate over keys in childMapping\n\n return next;\n });\n }, [childMapping, direction]);\n\n // Refs: animation timing and control\n const startTimeRef = React.useRef<number | null>(null);\n const frameRef = React.useRef<number | null>(null);\n const finishedRef = React.useRef(false);\n const isFirstRender = React.useRef(true);\n\n // Use ref to avoid re-running the animation when child mapping changes\n const childMappingRef = React.useRef(childMapping);\n\n // Update childMapping ref whenever it changes\n React.useEffect(() => {\n childMappingRef.current = childMapping;\n }, [childMapping]);\n\n // Use ref for reversed to avoid re-running animation when it changes\n const reversedRef = React.useRef(reversed);\n\n // Update reversed ref whenever it changes\n React.useEffect(() => {\n reversedRef.current = reversed;\n }, [reversed]);\n\n // ====== ANIMATION EFFECT ======\n\n React.useEffect(() => {\n let cancelled = false;\n startTimeRef.current = null;\n finishedRef.current = false;\n\n // All hide modes skip animation on first render - items are already in their final state\n if (isFirstRender.current) {\n isFirstRender.current = false;\n // Items are already in their final state from useState, no animation needed\n handleMotionFinish();\n return; // No cleanup needed for first render\n }\n\n // For animations after first render, start from the opposite of the final state\n // - Enter animation: start hidden (false), animate to visible (true)\n // - Exit animation: start visible (true), animate to hidden (false)\n const startState = direction === 'exit';\n // Use childMappingRef.current to avoid adding childMapping to dependencies\n const initialVisibility: Record<string, boolean> = {};\n Object.keys(childMappingRef.current).forEach(key => {\n initialVisibility[key] = startState;\n });\n setItemsVisibility(initialVisibility);\n\n // Animation loop: update visibility on each frame until complete\n const tick = (now: number) => {\n if (cancelled) {\n return;\n }\n if (startTimeRef.current === null) {\n startTimeRef.current = now;\n }\n const elapsed = now - (startTimeRef.current as number);\n\n const childKeys = Object.keys(childMappingRef.current);\n const itemCount = childKeys.length;\n\n const result = staggerItemsVisibilityAtTime({\n itemCount,\n elapsed,\n itemDelay,\n itemDuration,\n direction,\n reversed: reversedRef.current,\n });\n\n // Convert boolean array to keyed object\n const nextVisibility: Record<string, boolean> = {};\n childKeys.forEach((key, idx) => {\n nextVisibility[key] = result.itemsVisibility[idx];\n });\n\n setItemsVisibility(nextVisibility);\n\n if (elapsed < result.totalDuration) {\n frameRef.current = requestAnimationFrame(tick);\n } else if (!finishedRef.current) {\n finishedRef.current = true;\n handleMotionFinish();\n }\n };\n\n frameRef.current = requestAnimationFrame(tick);\n return () => {\n cancelled = true;\n if (frameRef.current) {\n cancelAnimationFrame();\n }\n };\n }, [\n animationKey,\n itemDelay,\n itemDuration,\n direction,\n requestAnimationFrame,\n cancelAnimationFrame,\n handleMotionFinish,\n ]);\n\n return { itemsVisibility };\n}\n"],"names":["React","useAnimationFrame","useEventCallback","staggerItemsVisibilityAtTime","DEFAULT_ITEM_DURATION","useStaggerItemsVisibility","childMapping","itemDelay","itemDuration","direction","reversed","onMotionFinish","hideMode","requestAnimationFrame","cancelAnimationFrame","handleMotionFinish","animationKey","setAnimationKey","useState","prevDirection","useRef","useEffect","current","prev","itemsVisibility","setItemsVisibility","initial","initialState","Object","keys","forEach","key","next","targetState","startTimeRef","frameRef","finishedRef","isFirstRender","childMappingRef","reversedRef","cancelled","startState","initialVisibility","tick","now","elapsed","childKeys","itemCount","length","result","nextVisibility","idx","totalDuration"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/utils/motionComponentDetection.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * Checks if a React element has all of the specified props explicitly provided.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @param props - Array of prop names to verify presence on the element\n * @returns true if all props exist on element.props, false otherwise\n *\n * @internal\n */\n\n/**\n * Checks if a React element is a motion component created by createMotionComponent.\n * Motion components are detected by the presence of the MOTION_DEFINITION symbol on the component.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the MOTION_DEFINITION symbol\n *\n * **Note:** This is a heuristic detection. Motion components may or may not support\n * specific props like `delay` or `visible` depending on their implementation.\n *\n * @internal\n */\nexport function isMotionComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the MOTION_DEFINITION symbol (internal to createMotionComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element is a presence motion component by looking for the PRESENCE_MOTION_DEFINITION symbol.\n * This symbol is added internally by createPresenceComponent and provides reliable detection.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the PRESENCE_MOTION_DEFINITION symbol\n *\n * **Presence components** (like Fade, Scale, Slide) are guaranteed to support both `visible` and `delay` props.\n *\n * @internal\n */\nexport function isPresenceComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the PRESENCE_MOTION_DEFINITION symbol (internal to createPresenceComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'PRESENCE_MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element accepts both `delay` and `exitDelay` props.\n * This uses a best-effort heuristic to detect components that support both delay props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports both delay and exitDelay props\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support both delay and exitDelay\n * - Motion components (.In/.Out variants, custom motion components) - may support both delay props\n * - Elements with explicit delay and exitDelay props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `delayMode` prop on Stagger.\n * For example, custom motion components that don't support both props should use `delayMode=\"timing\"`.\n *\n * @internal\n */\nexport function acceptsDelayProps(element: React.ReactElement): boolean {\n return isPresenceComponent(element) || isMotionComponent(element);\n}\n\n/**\n * Checks if a React element accepts a `visible` prop.\n * This uses a best-effort heuristic to detect components that support visible props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports a `visible` prop\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support visible\n * - Elements with explicit visible props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `hideMode` prop on Stagger.\n * For example, custom components that don't support visible should use `hideMode=\"visibilityStyle\"` or `hideMode=\"unmount\"`.\n *\n * @internal\n */\nexport function acceptsVisibleProp(element: React.ReactElement): boolean {\n return isPresenceComponent(element);\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/utils/motionComponentDetection.ts"],"sourcesContent":["import type * as React from 'react';\n\n/**\n * Checks if a React element has all of the specified props explicitly provided.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @param props - Array of prop names to verify presence on the element\n * @returns true if all props exist on element.props, false otherwise\n *\n * @internal\n */\n\n/**\n * Checks if a React element is a motion component created by createMotionComponent.\n * Motion components are detected by the presence of the MOTION_DEFINITION symbol on the component.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the MOTION_DEFINITION symbol\n *\n * **Note:** This is a heuristic detection. Motion components may or may not support\n * specific props like `delay` or `visible` depending on their implementation.\n *\n * @internal\n */\nexport function isMotionComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the MOTION_DEFINITION symbol (internal to createMotionComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element is a presence motion component by looking for the PRESENCE_MOTION_DEFINITION symbol.\n * This symbol is added internally by createPresenceComponent and provides reliable detection.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the PRESENCE_MOTION_DEFINITION symbol\n *\n * **Presence components** (like Fade, Scale, Slide) are guaranteed to support both `visible` and `delay` props.\n *\n * @internal\n */\nexport function isPresenceComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the PRESENCE_MOTION_DEFINITION symbol (internal to createPresenceComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'PRESENCE_MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element accepts both `delay` and `exitDelay` props.\n * This uses a best-effort heuristic to detect components that support both delay props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports both delay and exitDelay props\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support both delay and exitDelay\n * - Motion components (.In/.Out variants, custom motion components) - may support both delay props\n * - Elements with explicit delay and exitDelay props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `delayMode` prop on Stagger.\n * For example, custom motion components that don't support both props should use `delayMode=\"timing\"`.\n *\n * @internal\n */\nexport function acceptsDelayProps(element: React.ReactElement): boolean {\n return isPresenceComponent(element) || isMotionComponent(element);\n}\n\n/**\n * Checks if a React element accepts a `visible` prop.\n * This uses a best-effort heuristic to detect components that support visible props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports a `visible` prop\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support visible\n * - Elements with explicit visible props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `hideMode` prop on Stagger.\n * For example, custom components that don't support visible should use `hideMode=\"visibilityStyle\"` or `hideMode=\"unmount\"`.\n *\n * @internal\n */\nexport function acceptsVisibleProp(element: React.ReactElement): boolean {\n return isPresenceComponent(element);\n}\n"],"names":["isMotionComponent","element","type","symbols","Object","getOwnPropertySymbols","some","sym","description","isPresenceComponent","acceptsDelayProps","acceptsVisibleProp"],"mappings":"AAEA;;;;;;;;;;CAUC,GAED;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASA,kBAAkBC,OAA2B;IAC3D,IAAI,EAACA,oBAAAA,8BAAAA,QAASC,IAAI,KAAI,OAAOD,QAAQC,IAAI,KAAK,YAAY;QACxD,OAAO;IACT;IAEA,8FAA8F;IAC9F,MAAMC,UAAUC,OAAOC,qBAAqB,CAACJ,QAAQC,IAAI;IACzD,OAAOC,QAAQG,IAAI,CAACC,CAAAA,MAAOA,IAAIC,WAAW,KAAK;AACjD;AAEA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,oBAAoBR,OAA2B;IAC7D,IAAI,EAACA,oBAAAA,8BAAAA,QAASC,IAAI,KAAI,OAAOD,QAAQC,IAAI,KAAK,YAAY;QACxD,OAAO;IACT;IAEA,yGAAyG;IACzG,MAAMC,UAAUC,OAAOC,qBAAqB,CAACJ,QAAQC,IAAI;IACzD,OAAOC,QAAQG,IAAI,CAACC,CAAAA,MAAOA,IAAIC,WAAW,KAAK;AACjD;AAEA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASE,kBAAkBT,OAA2B;IAC3D,OAAOQ,oBAAoBR,YAAYD,kBAAkBC;AAC3D;AAEA;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,SAASU,mBAAmBV,OAA2B;IAC5D,OAAOQ,oBAAoBR;AAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Blur/Blur.ts"],"sourcesContent":["import { motionTokens, createPresenceComponent
|
|
1
|
+
{"version":3,"sources":["../src/components/Blur/Blur.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { blurAtom } from '../../atoms/blur-atom';\nimport type { BlurParams } from './blur-types';\n\n/**\n * Define a presence motion for blur in/out\n *\n * @param duration - Time (ms) for the enter transition (blur-in). Defaults to the `durationSlow` value (300 ms).\n * @param easing - Easing curve for the enter transition (blur-in). Defaults to the `curveDecelerateMin` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (blur-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (blur-out). Defaults to the `curveAccelerateMin` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outRadius - Blur radius for the out state (exited). Defaults to `'10px'`.\n * @param inRadius - Blur radius for the in state (entered). Defaults to `'0px'`.\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`.\n */\nconst blurPresenceFn: PresenceMotionFn<BlurParams> = ({\n duration = motionTokens.durationSlow,\n easing = motionTokens.curveDecelerateMin,\n delay = 0,\n exitDuration = duration,\n exitEasing = motionTokens.curveAccelerateMin,\n exitDelay = delay,\n outRadius = '10px',\n inRadius = '0px',\n animateOpacity = true,\n}) => {\n const enterAtoms = [blurAtom({ direction: 'enter', duration, easing, delay, outRadius, inRadius })];\n const exitAtoms = [\n blurAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outRadius,\n inRadius,\n }),\n ];\n\n // Only add fade atoms if animateOpacity is true.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies blur in/out transitions to its children. */\nexport const Blur = createPresenceComponent(blurPresenceFn);\n"],"names":["motionTokens","createPresenceComponent","fadeAtom","blurAtom","blurPresenceFn","duration","durationSlow","easing","curveDecelerateMin","delay","exitDuration","exitEasing","curveAccelerateMin","exitDelay","outRadius","inRadius","animateOpacity","enterAtoms","direction","exitAtoms","push","enter","exit","Blur"],"mappings":"AACA,SAASA,YAAY,EAAEC,uBAAuB,QAAQ,yBAAyB;AAC/E,SAASC,QAAQ,QAAQ,wBAAwB;AACjD,SAASC,QAAQ,QAAQ,wBAAwB;AAGjD;;;;;;;;;;;;CAYC,GACD,MAAMC,iBAA+C,CAAC,EACpDC,WAAWL,aAAaM,YAAY,EACpCC,SAASP,aAAaQ,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeL,QAAQ,EACvBM,aAAaX,aAAaY,kBAAkB,EAC5CC,YAAYJ,KAAK,EACjBK,YAAY,MAAM,EAClBC,WAAW,KAAK,EAChBC,iBAAiB,IAAI,EACtB;IACC,MAAMC,aAAa;QAACd,SAAS;YAAEe,WAAW;YAASb;YAAUE;YAAQE;YAAOK;YAAWC;QAAS;KAAG;IACnG,MAAMI,YAAY;QAChBhB,SAAS;YACPe,WAAW;YACXb,UAAUK;YACVH,QAAQI;YACRF,OAAOI;YACPC;YACAC;QACF;KACD;IAED,iDAAiD;IACjD,IAAIC,gBAAgB;QAClBC,WAAWG,IAAI,CAAClB,SAAS;YAAEgB,WAAW;YAASb;YAAUE;YAAQE;QAAM;QACvEU,UAAUC,IAAI,CAAClB,SAAS;YAAEgB,WAAW;YAAQb,UAAUK;YAAcH,QAAQI;YAAYF,OAAOI;QAAU;IAC5G;IAEA,OAAO;QACLQ,OAAOJ;QACPK,MAAMH;IACR;AACF;AAEA,4EAA4E,GAC5E,OAAO,MAAMI,OAAOtB,wBAAwBG,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Collapse/Collapse.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Collapse/Collapse.ts"],"sourcesContent":["import type { PresenceMotionFn, AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport type { CollapseParams } from './collapse-types';\nimport { sizeEnterAtom, sizeExitAtom, whitespaceAtom } from './collapse-atoms';\nimport { fadeAtom } from '../../atoms/fade-atom';\n\n/**\n * Define a presence motion for collapse/expand\n *\n * @param element - The element to apply the collapse motion to\n * @param duration - Time (ms) for the enter transition (expand). Defaults to the `durationNormal` value (200 ms)\n * @param easing - Easing curve for the enter transition. Defaults to the `curveEasyEaseMax` value\n * @param delay - Time (ms) to delay the entire enter transition. Defaults to 0\n * @param exitDuration - Time (ms) for the exit transition (collapse). Defaults to the `duration` param for symmetry\n * @param exitEasing - Easing curve for the exit transition. Defaults to the `easing` param for symmetry\n * @param exitDelay - Time (ms) to delay the entire exit transition. Defaults to the `delay` param for symmetry\n * @param staggerDelay - Time (ms) offset between the size and opacity animations. Defaults to 0\n * @param exitStaggerDelay - Time (ms) offset between the size and opacity animations on exit. Defaults to the `staggerDelay` param for symmetry\n * @param sizeDuration - Time (ms) for the size animation during enter. Defaults to `duration` for unified timing\n * @param opacityDuration - Time (ms) for the opacity animation during enter. Defaults to `sizeDuration` for synchronized timing\n * @param exitSizeDuration - Time (ms) for the size animation during exit. Defaults to `exitDuration` for unified timing\n * @param exitOpacityDuration - Time (ms) for the opacity animation during exit. Defaults to `exitSizeDuration` for synchronized timing\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`\n * @param orientation - The orientation of the size animation. Defaults to `'vertical'` to expand/collapse the height\n * @param outSize - Size for the out state (collapsed). Defaults to `'0px'`\n */\nconst collapsePresenceFn: PresenceMotionFn<CollapseParams> = ({\n element,\n // Primary duration controls (simple API)\n duration = motionTokens.durationNormal,\n exitDuration = duration,\n\n // Granular duration controls with smart defaults (advanced API)\n sizeDuration = duration,\n opacityDuration = sizeDuration,\n exitSizeDuration = exitDuration,\n exitOpacityDuration = exitSizeDuration,\n\n // Other timing controls\n easing = motionTokens.curveEasyEaseMax,\n delay = 0,\n exitEasing = easing,\n exitDelay = delay,\n staggerDelay = 0,\n exitStaggerDelay = staggerDelay,\n\n // Animation controls\n animateOpacity = true,\n orientation = 'vertical',\n outSize = '0px',\n}) => {\n // ----- ENTER -----\n // The enter transition is an array of up to 3 motion atoms: size, whitespace and opacity.\n // For enter: size expands first, then opacity fades in after staggerDelay\n const enterAtoms: AtomMotion[] = [\n // Apply global delay to size atom - size expansion starts first\n sizeEnterAtom({ orientation, duration: sizeDuration, easing, element, outSize, delay }),\n whitespaceAtom({ direction: 'enter', orientation, duration: sizeDuration, easing, delay }),\n ];\n // Fade in only if animateOpacity is true. Otherwise, leave opacity unaffected.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration: opacityDuration, easing, delay: delay + staggerDelay }));\n }\n\n // ----- EXIT -----\n // The exit transition is an array of up to 3 motion atoms: opacity, size and whitespace.\n // For exit: opacity fades out first, then size collapses after exitStaggerDelay\n const exitAtoms: AtomMotion[] = [];\n // Fade out only if animateOpacity is true. Otherwise, leave opacity unaffected.\n if (animateOpacity) {\n exitAtoms.push(\n fadeAtom({ direction: 'exit', duration: exitOpacityDuration, easing: exitEasing, delay: exitDelay }),\n );\n }\n\n exitAtoms.push(\n sizeExitAtom({\n orientation,\n duration: exitSizeDuration,\n easing: exitEasing,\n element,\n delay: exitDelay + exitStaggerDelay,\n outSize,\n }),\n whitespaceAtom({\n direction: 'exit',\n orientation,\n duration: exitSizeDuration,\n easing: exitEasing,\n delay: exitDelay + exitStaggerDelay, // Size/whitespace collapse after opacity finishes fading out\n }),\n );\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies collapse/expand transitions to its children. */\nexport const Collapse = createPresenceComponent(collapsePresenceFn);\n\nexport const CollapseSnappy = createPresenceComponentVariant(Collapse, {\n duration: motionTokens.durationFast,\n});\n\nexport const CollapseRelaxed = createPresenceComponentVariant(Collapse, {\n duration: motionTokens.durationSlower,\n});\n\n/** A React component that applies collapse/expand transitions with delayed fade to its children. */\nexport const CollapseDelayed = createPresenceComponentVariant(Collapse, {\n // Enter timing per motion design spec\n sizeDuration: motionTokens.durationNormal, // 200ms\n opacityDuration: motionTokens.durationSlower, // 400ms\n staggerDelay: motionTokens.durationNormal, // 200ms\n\n // Exit timing per motion design spec\n exitSizeDuration: motionTokens.durationNormal, // 200ms\n exitOpacityDuration: motionTokens.durationSlower, // 400ms\n exitStaggerDelay: motionTokens.durationSlower, // 400ms\n\n // Easing per motion design spec\n easing: motionTokens.curveEasyEase,\n exitEasing: motionTokens.curveEasyEase,\n});\n"],"names":["motionTokens","createPresenceComponent","createPresenceComponentVariant","sizeEnterAtom","sizeExitAtom","whitespaceAtom","fadeAtom","collapsePresenceFn","element","duration","durationNormal","exitDuration","sizeDuration","opacityDuration","exitSizeDuration","exitOpacityDuration","easing","curveEasyEaseMax","delay","exitEasing","exitDelay","staggerDelay","exitStaggerDelay","animateOpacity","orientation","outSize","enterAtoms","direction","push","exitAtoms","enter","exit","Collapse","CollapseSnappy","durationFast","CollapseRelaxed","durationSlower","CollapseDelayed","curveEasyEase"],"mappings":"AACA,SAASA,YAAY,EAAEC,uBAAuB,EAAEC,8BAA8B,QAAQ,yBAAyB;AAE/G,SAASC,aAAa,EAAEC,YAAY,EAAEC,cAAc,QAAQ,mBAAmB;AAC/E,SAASC,QAAQ,QAAQ,wBAAwB;AAEjD;;;;;;;;;;;;;;;;;;;CAmBC,GACD,MAAMC,qBAAuD,CAAC,EAC5DC,OAAO,EACP,yCAAyC;AACzCC,WAAWT,aAAaU,cAAc,EACtCC,eAAeF,QAAQ,EAEvB,gEAAgE;AAChEG,eAAeH,QAAQ,EACvBI,kBAAkBD,YAAY,EAC9BE,mBAAmBH,YAAY,EAC/BI,sBAAsBD,gBAAgB,EAEtC,wBAAwB;AACxBE,SAAShB,aAAaiB,gBAAgB,EACtCC,QAAQ,CAAC,EACTC,aAAaH,MAAM,EACnBI,YAAYF,KAAK,EACjBG,eAAe,CAAC,EAChBC,mBAAmBD,YAAY,EAE/B,qBAAqB;AACrBE,iBAAiB,IAAI,EACrBC,cAAc,UAAU,EACxBC,UAAU,KAAK,EAChB;IACC,oBAAoB;IACpB,0FAA0F;IAC1F,0EAA0E;IAC1E,MAAMC,aAA2B;QAC/B,gEAAgE;QAChEvB,cAAc;YAAEqB;YAAaf,UAAUG;YAAcI;YAAQR;YAASiB;YAASP;QAAM;QACrFb,eAAe;YAAEsB,WAAW;YAASH;YAAaf,UAAUG;YAAcI;YAAQE;QAAM;KACzF;IACD,+EAA+E;IAC/E,IAAIK,gBAAgB;QAClBG,WAAWE,IAAI,CAACtB,SAAS;YAAEqB,WAAW;YAASlB,UAAUI;YAAiBG;YAAQE,OAAOA,QAAQG;QAAa;IAChH;IAEA,mBAAmB;IACnB,yFAAyF;IACzF,gFAAgF;IAChF,MAAMQ,YAA0B,EAAE;IAClC,gFAAgF;IAChF,IAAIN,gBAAgB;QAClBM,UAAUD,IAAI,CACZtB,SAAS;YAAEqB,WAAW;YAAQlB,UAAUM;YAAqBC,QAAQG;YAAYD,OAAOE;QAAU;IAEtG;IAEAS,UAAUD,IAAI,CACZxB,aAAa;QACXoB;QACAf,UAAUK;QACVE,QAAQG;QACRX;QACAU,OAAOE,YAAYE;QACnBG;IACF,IACApB,eAAe;QACbsB,WAAW;QACXH;QACAf,UAAUK;QACVE,QAAQG;QACRD,OAAOE,YAAYE;IACrB;IAGF,OAAO;QACLQ,OAAOJ;QACPK,MAAMF;IACR;AACF;AAEA,gFAAgF,GAChF,OAAO,MAAMG,WAAW/B,wBAAwBM,oBAAoB;AAEpE,OAAO,MAAM0B,iBAAiB/B,+BAA+B8B,UAAU;IACrEvB,UAAUT,aAAakC,YAAY;AACrC,GAAG;AAEH,OAAO,MAAMC,kBAAkBjC,+BAA+B8B,UAAU;IACtEvB,UAAUT,aAAaoC,cAAc;AACvC,GAAG;AAEH,kGAAkG,GAClG,OAAO,MAAMC,kBAAkBnC,+BAA+B8B,UAAU;IACtE,sCAAsC;IACtCpB,cAAcZ,aAAaU,cAAc;IACzCG,iBAAiBb,aAAaoC,cAAc;IAC5Cf,cAAcrB,aAAaU,cAAc;IAEzC,qCAAqC;IACrCI,kBAAkBd,aAAaU,cAAc;IAC7CK,qBAAqBf,aAAaoC,cAAc;IAChDd,kBAAkBtB,aAAaoC,cAAc;IAE7C,gCAAgC;IAChCpB,QAAQhB,aAAasC,aAAa;IAClCnB,YAAYnB,aAAasC,aAAa;AACxC,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Collapse/collapse-atoms.ts"],"sourcesContent":["import { AtomMotion, PresenceDirection } from '@fluentui/react-motion';\nimport { CollapseOrientation } from './collapse-types';\n\n// ----- SIZE -----\n\nconst sizeValuesForOrientation = (orientation: CollapseOrientation, element: Element) => {\n const sizeName = orientation === 'horizontal' ? 'maxWidth' : 'maxHeight';\n const overflowName = orientation === 'horizontal' ? 'overflowX' : 'overflowY';\n const measuredSize = orientation === 'horizontal' ? element.scrollWidth : element.scrollHeight;\n const toSize = `${measuredSize}px`;\n return { sizeName, overflowName, toSize };\n};\n\ninterface SizeEnterAtomParams {\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n element: HTMLElement;\n /** Size for the out state (collapsed). Defaults to '0'. */\n outSize?: string;\n delay?: number;\n}\n\nexport const sizeEnterAtom = ({\n orientation,\n duration,\n easing,\n element,\n outSize = '0',\n delay = 0,\n}: SizeEnterAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n { [sizeName]: toSize, offset: 0.9999, [overflowName]: 'hidden' },\n { [sizeName]: 'unset', [overflowName]: 'unset' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\ninterface SizeExitAtomParams extends SizeEnterAtomParams {\n delay?: number;\n}\n\nexport const sizeExitAtom = ({\n orientation,\n duration,\n easing,\n element,\n delay = 0,\n outSize = '0',\n}: SizeExitAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: toSize, [overflowName]: 'hidden' },\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\n// ----- WHITESPACE -----\n\n// Whitespace animation includes padding and margin.\nconst whitespaceValuesForOrientation = (orientation: CollapseOrientation) => {\n // horizontal whitespace collapse\n if (orientation === 'horizontal') {\n return {\n paddingStart: 'paddingInlineStart',\n paddingEnd: 'paddingInlineEnd',\n marginStart: 'marginInlineStart',\n marginEnd: 'marginInlineEnd',\n };\n }\n // vertical whitespace collapse\n return {\n paddingStart: 'paddingBlockStart',\n paddingEnd: 'paddingBlockEnd',\n marginStart: 'marginBlockStart',\n marginEnd: 'marginBlockEnd',\n };\n};\n\ninterface WhitespaceAtomParams {\n direction: PresenceDirection;\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n delay?: number;\n}\n\n/**\n * A collapse animates an element's height to zero,\n but the zero height does not eliminate padding or margin in the box model.\n So here we generate keyframes to animate those whitespace properties to zero.\n */\nexport const whitespaceAtom = ({\n direction,\n orientation,\n duration,\n easing,\n delay = 0,\n}: WhitespaceAtomParams): AtomMotion => {\n const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation);\n // The keyframe with zero whitespace is at the start for enter and at the end for exit.\n const offset = direction === 'enter' ? 0 : 1;\n const keyframes = [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset }];\n\n return {\n keyframes,\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n"],"names":["sizeValuesForOrientation","orientation","element","sizeName","overflowName","measuredSize","scrollWidth","scrollHeight","toSize","sizeEnterAtom","duration","easing","outSize","delay","keyframes","offset","fill","sizeExitAtom","whitespaceValuesForOrientation","paddingStart","paddingEnd","marginStart","marginEnd","whitespaceAtom","direction"],"mappings":"AAGA,mBAAmB;AAEnB,MAAMA,2BAA2B,CAACC,aAAkCC;IAClE,MAAMC,WAAWF,gBAAgB,eAAe,aAAa;IAC7D,MAAMG,eAAeH,gBAAgB,eAAe,cAAc;IAClE,MAAMI,eAAeJ,gBAAgB,eAAeC,QAAQI,WAAW,GAAGJ,QAAQK,YAAY;IAC9F,MAAMC,SAAS,GAAGH,aAAa,EAAE,CAAC;IAClC,OAAO;QAAEF;QAAUC;QAAcI;IAAO;AAC1C;AAYA,OAAO,MAAMC,gBAAgB,CAAC,EAC5BR,WAAW,EACXS,QAAQ,EACRC,MAAM,EACNT,OAAO,EACPU,UAAU,GAAG,EACbC,QAAQ,CAAC,EACW;IACpB,MAAM,EAAEV,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLY,WAAW;YACT;gBAAE,CAACX,SAAS,EAAES;gBAAS,CAACR,aAAa,EAAE;YAAS;YAChD;gBAAE,CAACD,SAAS,EAAEK;gBAAQO,QAAQ;gBAAQ,CAACX,aAAa,EAAE;YAAS;YAC/D;gBAAE,CAACD,SAAS,EAAE;gBAAS,CAACC,aAAa,EAAE;YAAQ;SAChD;QACDM;QACAC;QACAE;QACAG,MAAM;IACR;AACF,EAAE;AAMF,OAAO,MAAMC,eAAe,CAAC,EAC3BhB,WAAW,EACXS,QAAQ,EACRC,MAAM,EACNT,OAAO,EACPW,QAAQ,CAAC,EACTD,UAAU,GAAG,EACM;IACnB,MAAM,EAAET,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLY,WAAW;YACT;gBAAE,CAACX,SAAS,EAAEK;gBAAQ,CAACJ,aAAa,EAAE;YAAS;YAC/C;gBAAE,CAACD,SAAS,EAAES;gBAAS,CAACR,aAAa,EAAE;YAAS;SACjD;QACDM;QACAC;QACAE;QACAG,MAAM;IACR;AACF,EAAE;AAEF,yBAAyB;AAEzB,oDAAoD;AACpD,MAAME,iCAAiC,CAACjB;IACtC,iCAAiC;IACjC,IAAIA,gBAAgB,cAAc;QAChC,OAAO;YACLkB,cAAc;YACdC,YAAY;YACZC,aAAa;YACbC,WAAW;QACb;IACF;IACA,+BAA+B;IAC/B,OAAO;QACLH,cAAc;QACdC,YAAY;QACZC,aAAa;QACbC,WAAW;IACb;AACF;AAUA;;;;CAIC,GACD,OAAO,MAAMC,iBAAiB,CAAC,EAC7BC,SAAS,EACTvB,WAAW,EACXS,QAAQ,EACRC,MAAM,EACNE,QAAQ,CAAC,EACY;IACrB,MAAM,EAAEM,YAAY,EAAEC,UAAU,EAAEC,WAAW,EAAEC,SAAS,EAAE,GAAGJ,+BAA+BjB;IAC5F,uFAAuF;IACvF,MAAMc,SAASS,cAAc,UAAU,IAAI;IAC3C,MAAMV,YAAY;QAAC;YAAE,CAACK,aAAa,EAAE;YAAK,CAACC,WAAW,EAAE;YAAK,CAACC,YAAY,EAAE;YAAK,CAACC,UAAU,EAAE;YAAKP;QAAO;KAAE;IAE5G,OAAO;QACLD;QACAJ;QACAC;QACAE;QACAG,MAAM;IACR;AACF,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../src/components/Collapse/collapse-atoms.ts"],"sourcesContent":["import type { AtomMotion, PresenceDirection } from '@fluentui/react-motion';\nimport type { CollapseOrientation } from './collapse-types';\n\n// ----- SIZE -----\n\nconst sizeValuesForOrientation = (orientation: CollapseOrientation, element: Element) => {\n const sizeName = orientation === 'horizontal' ? 'maxWidth' : 'maxHeight';\n const overflowName = orientation === 'horizontal' ? 'overflowX' : 'overflowY';\n const measuredSize = orientation === 'horizontal' ? element.scrollWidth : element.scrollHeight;\n const toSize = `${measuredSize}px`;\n return { sizeName, overflowName, toSize };\n};\n\ninterface SizeEnterAtomParams {\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n element: HTMLElement;\n /** Size for the out state (collapsed). Defaults to '0'. */\n outSize?: string;\n delay?: number;\n}\n\nexport const sizeEnterAtom = ({\n orientation,\n duration,\n easing,\n element,\n outSize = '0',\n delay = 0,\n}: SizeEnterAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n { [sizeName]: toSize, offset: 0.9999, [overflowName]: 'hidden' },\n { [sizeName]: 'unset', [overflowName]: 'unset' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\ninterface SizeExitAtomParams extends SizeEnterAtomParams {\n delay?: number;\n}\n\nexport const sizeExitAtom = ({\n orientation,\n duration,\n easing,\n element,\n delay = 0,\n outSize = '0',\n}: SizeExitAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: toSize, [overflowName]: 'hidden' },\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\n// ----- WHITESPACE -----\n\n// Whitespace animation includes padding and margin.\nconst whitespaceValuesForOrientation = (orientation: CollapseOrientation) => {\n // horizontal whitespace collapse\n if (orientation === 'horizontal') {\n return {\n paddingStart: 'paddingInlineStart',\n paddingEnd: 'paddingInlineEnd',\n marginStart: 'marginInlineStart',\n marginEnd: 'marginInlineEnd',\n };\n }\n // vertical whitespace collapse\n return {\n paddingStart: 'paddingBlockStart',\n paddingEnd: 'paddingBlockEnd',\n marginStart: 'marginBlockStart',\n marginEnd: 'marginBlockEnd',\n };\n};\n\ninterface WhitespaceAtomParams {\n direction: PresenceDirection;\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n delay?: number;\n}\n\n/**\n * A collapse animates an element's height to zero,\n but the zero height does not eliminate padding or margin in the box model.\n So here we generate keyframes to animate those whitespace properties to zero.\n */\nexport const whitespaceAtom = ({\n direction,\n orientation,\n duration,\n easing,\n delay = 0,\n}: WhitespaceAtomParams): AtomMotion => {\n const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation);\n // The keyframe with zero whitespace is at the start for enter and at the end for exit.\n const offset = direction === 'enter' ? 0 : 1;\n const keyframes = [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset }];\n\n return {\n keyframes,\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n"],"names":["sizeValuesForOrientation","orientation","element","sizeName","overflowName","measuredSize","scrollWidth","scrollHeight","toSize","sizeEnterAtom","duration","easing","outSize","delay","keyframes","offset","fill","sizeExitAtom","whitespaceValuesForOrientation","paddingStart","paddingEnd","marginStart","marginEnd","whitespaceAtom","direction"],"mappings":"AAGA,mBAAmB;AAEnB,MAAMA,2BAA2B,CAACC,aAAkCC;IAClE,MAAMC,WAAWF,gBAAgB,eAAe,aAAa;IAC7D,MAAMG,eAAeH,gBAAgB,eAAe,cAAc;IAClE,MAAMI,eAAeJ,gBAAgB,eAAeC,QAAQI,WAAW,GAAGJ,QAAQK,YAAY;IAC9F,MAAMC,SAAS,GAAGH,aAAa,EAAE,CAAC;IAClC,OAAO;QAAEF;QAAUC;QAAcI;IAAO;AAC1C;AAYA,OAAO,MAAMC,gBAAgB,CAAC,EAC5BR,WAAW,EACXS,QAAQ,EACRC,MAAM,EACNT,OAAO,EACPU,UAAU,GAAG,EACbC,QAAQ,CAAC,EACW;IACpB,MAAM,EAAEV,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLY,WAAW;YACT;gBAAE,CAACX,SAAS,EAAES;gBAAS,CAACR,aAAa,EAAE;YAAS;YAChD;gBAAE,CAACD,SAAS,EAAEK;gBAAQO,QAAQ;gBAAQ,CAACX,aAAa,EAAE;YAAS;YAC/D;gBAAE,CAACD,SAAS,EAAE;gBAAS,CAACC,aAAa,EAAE;YAAQ;SAChD;QACDM;QACAC;QACAE;QACAG,MAAM;IACR;AACF,EAAE;AAMF,OAAO,MAAMC,eAAe,CAAC,EAC3BhB,WAAW,EACXS,QAAQ,EACRC,MAAM,EACNT,OAAO,EACPW,QAAQ,CAAC,EACTD,UAAU,GAAG,EACM;IACnB,MAAM,EAAET,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLY,WAAW;YACT;gBAAE,CAACX,SAAS,EAAEK;gBAAQ,CAACJ,aAAa,EAAE;YAAS;YAC/C;gBAAE,CAACD,SAAS,EAAES;gBAAS,CAACR,aAAa,EAAE;YAAS;SACjD;QACDM;QACAC;QACAE;QACAG,MAAM;IACR;AACF,EAAE;AAEF,yBAAyB;AAEzB,oDAAoD;AACpD,MAAME,iCAAiC,CAACjB;IACtC,iCAAiC;IACjC,IAAIA,gBAAgB,cAAc;QAChC,OAAO;YACLkB,cAAc;YACdC,YAAY;YACZC,aAAa;YACbC,WAAW;QACb;IACF;IACA,+BAA+B;IAC/B,OAAO;QACLH,cAAc;QACdC,YAAY;QACZC,aAAa;QACbC,WAAW;IACb;AACF;AAUA;;;;CAIC,GACD,OAAO,MAAMC,iBAAiB,CAAC,EAC7BC,SAAS,EACTvB,WAAW,EACXS,QAAQ,EACRC,MAAM,EACNE,QAAQ,CAAC,EACY;IACrB,MAAM,EAAEM,YAAY,EAAEC,UAAU,EAAEC,WAAW,EAAEC,SAAS,EAAE,GAAGJ,+BAA+BjB;IAC5F,uFAAuF;IACvF,MAAMc,SAASS,cAAc,UAAU,IAAI;IAC3C,MAAMV,YAAY;QAAC;YAAE,CAACK,aAAa,EAAE;YAAK,CAACC,WAAW,EAAE;YAAK,CAACC,YAAY,EAAE;YAAK,CAACC,UAAU,EAAE;YAAKP;QAAO;KAAE;IAE5G,OAAO;QACLD;QACAJ;QACAC;QACAE;QACAG,MAAM;IACR;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Fade/Fade.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Fade/Fade.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport type { FadeParams } from './fade-types';\n\n/**\n * Define a presence motion for fade in/out\n *\n * @param duration - Time (ms) for the enter transition (fade-in). Defaults to the `durationNormal` value (200 ms).\n * @param easing - Easing curve for the enter transition (fade-in). Defaults to the `curveEasyEase` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (fade-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (fade-out). Defaults to the `easing` param for symmetry.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outOpacity - Opacity for the out state (exited). Defaults to 0.\n * @param inOpacity - Opacity for the in state (entered). Defaults to 1.\n */\nexport const fadePresenceFn: PresenceMotionFn<FadeParams> = ({\n duration = motionTokens.durationNormal,\n easing = motionTokens.curveEasyEase,\n delay = 0,\n exitDuration = duration,\n exitEasing = easing,\n exitDelay = delay,\n outOpacity = 0,\n inOpacity = 1,\n}) => {\n return {\n enter: fadeAtom({ direction: 'enter', duration, easing, delay, outOpacity, inOpacity }),\n exit: fadeAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outOpacity,\n inOpacity,\n }),\n };\n};\n\n/** A React component that applies fade in/out transitions to its children. */\nexport const Fade = createPresenceComponent(fadePresenceFn);\n\nexport const FadeSnappy = createPresenceComponentVariant(Fade, { duration: motionTokens.durationFast });\n\nexport const FadeRelaxed = createPresenceComponentVariant(Fade, { duration: motionTokens.durationGentle });\n"],"names":["motionTokens","createPresenceComponent","createPresenceComponentVariant","fadeAtom","fadePresenceFn","duration","durationNormal","easing","curveEasyEase","delay","exitDuration","exitEasing","exitDelay","outOpacity","inOpacity","enter","direction","exit","Fade","FadeSnappy","durationFast","FadeRelaxed","durationGentle"],"mappings":"AACA,SAASA,YAAY,EAAEC,uBAAuB,EAAEC,8BAA8B,QAAQ,yBAAyB;AAC/G,SAASC,QAAQ,QAAQ,wBAAwB;AAGjD;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,iBAA+C,CAAC,EAC3DC,WAAWL,aAAaM,cAAc,EACtCC,SAASP,aAAaQ,aAAa,EACnCC,QAAQ,CAAC,EACTC,eAAeL,QAAQ,EACvBM,aAAaJ,MAAM,EACnBK,YAAYH,KAAK,EACjBI,aAAa,CAAC,EACdC,YAAY,CAAC,EACd;IACC,OAAO;QACLC,OAAOZ,SAAS;YAAEa,WAAW;YAASX;YAAUE;YAAQE;YAAOI;YAAYC;QAAU;QACrFG,MAAMd,SAAS;YACba,WAAW;YACXX,UAAUK;YACVH,QAAQI;YACRF,OAAOG;YACPC;YACAC;QACF;IACF;AACF,EAAE;AAEF,4EAA4E,GAC5E,OAAO,MAAMI,OAAOjB,wBAAwBG,gBAAgB;AAE5D,OAAO,MAAMe,aAAajB,+BAA+BgB,MAAM;IAAEb,UAAUL,aAAaoB,YAAY;AAAC,GAAG;AAExG,OAAO,MAAMC,cAAcnB,+BAA+BgB,MAAM;IAAEb,UAAUL,aAAasB,cAAc;AAAC,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Rotate/Rotate.ts"],"sourcesContent":["import { AtomMotion, createPresenceComponent, motionTokens
|
|
1
|
+
{"version":3,"sources":["../src/components/Rotate/Rotate.ts"],"sourcesContent":["import type { AtomMotion, PresenceMotionFn } from '@fluentui/react-motion';\nimport { createPresenceComponent, motionTokens } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { rotateAtom } from '../../atoms/rotate-atom';\nimport type { RotateParams } from './rotate-types';\n\n/**\n * Define a presence motion for rotate in/out\n *\n * @param duration - Time (ms) for the enter transition (rotate-in). Defaults to the `durationGentle` value.\n * @param easing - Easing curve for the enter transition (rotate-in). Defaults to the `curveDecelerateMax` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (rotate-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (rotate-out). Defaults to the `curveAccelerateMax` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param axis - The axis of rotation: 'x', 'y', or 'z'. Defaults to 'z'.\n * @param outAngle - Rotation angle for the out state (exited) in degrees. Defaults to -90.\n * @param inAngle - Rotation angle for the in state (entered) in degrees. Defaults to 0.\n * @param animateOpacity - Whether to animate the opacity during the rotation. Defaults to `true`.\n */\nconst rotatePresenceFn: PresenceMotionFn<RotateParams> = ({\n duration = motionTokens.durationGentle,\n easing = motionTokens.curveDecelerateMax,\n delay = 0,\n exitDuration = duration,\n exitEasing = motionTokens.curveAccelerateMax,\n exitDelay = delay,\n axis = 'z',\n outAngle = -90,\n inAngle = 0,\n animateOpacity = true,\n}: RotateParams) => {\n const enterAtoms: AtomMotion[] = [\n rotateAtom({\n direction: 'enter',\n duration,\n easing,\n delay,\n axis,\n outAngle,\n inAngle,\n }),\n ];\n\n const exitAtoms: AtomMotion[] = [\n rotateAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n axis,\n outAngle,\n inAngle,\n }),\n ];\n\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n// Create a presence motion component to rotate an element around a single axis (x, y, or z).\nexport const Rotate = createPresenceComponent(rotatePresenceFn);\n"],"names":["createPresenceComponent","motionTokens","fadeAtom","rotateAtom","rotatePresenceFn","duration","durationGentle","easing","curveDecelerateMax","delay","exitDuration","exitEasing","curveAccelerateMax","exitDelay","axis","outAngle","inAngle","animateOpacity","enterAtoms","direction","exitAtoms","push","enter","exit","Rotate"],"mappings":"AACA,SAASA,uBAAuB,EAAEC,YAAY,QAAQ,yBAAyB;AAC/E,SAASC,QAAQ,QAAQ,wBAAwB;AACjD,SAASC,UAAU,QAAQ,0BAA0B;AAGrD;;;;;;;;;;;;;CAaC,GACD,MAAMC,mBAAmD,CAAC,EACxDC,WAAWJ,aAAaK,cAAc,EACtCC,SAASN,aAAaO,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeL,QAAQ,EACvBM,aAAaV,aAAaW,kBAAkB,EAC5CC,YAAYJ,KAAK,EACjBK,OAAO,GAAG,EACVC,WAAW,CAAC,EAAE,EACdC,UAAU,CAAC,EACXC,iBAAiB,IAAI,EACR;IACb,MAAMC,aAA2B;QAC/Bf,WAAW;YACTgB,WAAW;YACXd;YACAE;YACAE;YACAK;YACAC;YACAC;QACF;KACD;IAED,MAAMI,YAA0B;QAC9BjB,WAAW;YACTgB,WAAW;YACXd,UAAUK;YACVH,QAAQI;YACRF,OAAOI;YACPC;YACAC;YACAC;QACF;KACD;IAED,IAAIC,gBAAgB;QAClBC,WAAWG,IAAI,CAACnB,SAAS;YAAEiB,WAAW;YAASd;YAAUE;YAAQE;QAAM;QACvEW,UAAUC,IAAI,CAACnB,SAAS;YAAEiB,WAAW;YAAQd,UAAUK;YAAcH,QAAQI;YAAYF,OAAOI;QAAU;IAC5G;IAEA,OAAO;QACLS,OAAOJ;QACPK,MAAMH;IACR;AACF;AAEA,6FAA6F;AAC7F,OAAO,MAAMI,SAASxB,wBAAwBI,kBAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Scale/Scale.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Scale/Scale.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { scaleAtom } from '../../atoms/scale-atom';\nimport type { ScaleParams } from './scale-types';\n\n/**\n * Define a presence motion for scale in/out\n *\n * @param duration - Time (ms) for the enter transition (scale-in). Defaults to the `durationGentle` value (250 ms).\n * @param easing - Easing curve for the enter transition (scale-in). Defaults to the `curveDecelerateMax` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (scale-out). Defaults to the `durationNormal` value (200 ms).\n * @param exitEasing - Easing curve for the exit transition (scale-out). Defaults to the `curveAccelerateMax` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outScale - Scale for the out state (exited). Defaults to `0.9`.\n * @param inScale - Scale for the in state (entered). Defaults to `1`.\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`.\n */\nconst scalePresenceFn: PresenceMotionFn<ScaleParams> = ({\n duration = motionTokens.durationGentle,\n easing = motionTokens.curveDecelerateMax,\n delay = 0,\n exitDuration = motionTokens.durationNormal,\n exitEasing = motionTokens.curveAccelerateMax,\n exitDelay = delay,\n outScale = 0.9,\n inScale = 1,\n animateOpacity = true,\n}) => {\n const enterAtoms = [scaleAtom({ direction: 'enter', duration, easing, delay, outScale, inScale })];\n const exitAtoms = [\n scaleAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outScale,\n inScale,\n }),\n ];\n\n // Only add fade atoms if animateOpacity is true.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies scale in/out transitions to its children. */\nexport const Scale = createPresenceComponent(scalePresenceFn);\n\nexport const ScaleSnappy = createPresenceComponentVariant(Scale, {\n duration: motionTokens.durationNormal,\n exitDuration: motionTokens.durationFast,\n});\n\nexport const ScaleRelaxed = createPresenceComponentVariant(Scale, {\n duration: motionTokens.durationSlow,\n exitDuration: motionTokens.durationGentle,\n});\n"],"names":["motionTokens","createPresenceComponent","createPresenceComponentVariant","fadeAtom","scaleAtom","scalePresenceFn","duration","durationGentle","easing","curveDecelerateMax","delay","exitDuration","durationNormal","exitEasing","curveAccelerateMax","exitDelay","outScale","inScale","animateOpacity","enterAtoms","direction","exitAtoms","push","enter","exit","Scale","ScaleSnappy","durationFast","ScaleRelaxed","durationSlow"],"mappings":"AACA,SAASA,YAAY,EAAEC,uBAAuB,EAAEC,8BAA8B,QAAQ,yBAAyB;AAC/G,SAASC,QAAQ,QAAQ,wBAAwB;AACjD,SAASC,SAAS,QAAQ,yBAAyB;AAGnD;;;;;;;;;;;;CAYC,GACD,MAAMC,kBAAiD,CAAC,EACtDC,WAAWN,aAAaO,cAAc,EACtCC,SAASR,aAAaS,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeX,aAAaY,cAAc,EAC1CC,aAAab,aAAac,kBAAkB,EAC5CC,YAAYL,KAAK,EACjBM,WAAW,GAAG,EACdC,UAAU,CAAC,EACXC,iBAAiB,IAAI,EACtB;IACC,MAAMC,aAAa;QAACf,UAAU;YAAEgB,WAAW;YAASd;YAAUE;YAAQE;YAAOM;YAAUC;QAAQ;KAAG;IAClG,MAAMI,YAAY;QAChBjB,UAAU;YACRgB,WAAW;YACXd,UAAUK;YACVH,QAAQK;YACRH,OAAOK;YACPC;YACAC;QACF;KACD;IAED,iDAAiD;IACjD,IAAIC,gBAAgB;QAClBC,WAAWG,IAAI,CAACnB,SAAS;YAAEiB,WAAW;YAASd;YAAUE;YAAQE;QAAM;QACvEW,UAAUC,IAAI,CAACnB,SAAS;YAAEiB,WAAW;YAAQd,UAAUK;YAAcH,QAAQK;YAAYH,OAAOK;QAAU;IAC5G;IAEA,OAAO;QACLQ,OAAOJ;QACPK,MAAMH;IACR;AACF;AAEA,6EAA6E,GAC7E,OAAO,MAAMI,QAAQxB,wBAAwBI,iBAAiB;AAE9D,OAAO,MAAMqB,cAAcxB,+BAA+BuB,OAAO;IAC/DnB,UAAUN,aAAaY,cAAc;IACrCD,cAAcX,aAAa2B,YAAY;AACzC,GAAG;AAEH,OAAO,MAAMC,eAAe1B,+BAA+BuB,OAAO;IAChEnB,UAAUN,aAAa6B,YAAY;IACnClB,cAAcX,aAAaO,cAAc;AAC3C,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Slide/Slide.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Slide/Slide.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { slideAtom } from '../../atoms/slide-atom';\nimport type { SlideParams } from './slide-types';\n\n/**\n * Define a presence motion for slide in/out\n *\n * @param duration - Time (ms) for the enter transition (slide-in). Defaults to the `durationNormal` value (200 ms).\n * @param easing - Easing curve for the enter transition (slide-in). Defaults to the `curveDecelerateMid` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (slide-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (slide-out). Defaults to the `curveAccelerateMid` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outX - X translate for the out state (exited). Defaults to `'0px'`.\n * @param outY - Y translate for the out state (exited). Defaults to `'0px'`.\n * @param inX - X translate for the in state (entered). Defaults to `'0px'`.\n * @param inY - Y translate for the in state (entered). Defaults to `'0px'`.\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`.\n */\nconst slidePresenceFn: PresenceMotionFn<SlideParams> = ({\n duration = motionTokens.durationNormal,\n easing = motionTokens.curveDecelerateMid,\n delay = 0,\n exitDuration = duration,\n exitEasing = motionTokens.curveAccelerateMid,\n exitDelay = delay,\n outX = '0px',\n outY = '0px',\n inX = '0px',\n inY = '0px',\n animateOpacity = true,\n}: SlideParams) => {\n const enterAtoms = [slideAtom({ direction: 'enter', duration, easing, delay, outX, outY, inX, inY })];\n const exitAtoms = [\n slideAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outX,\n outY,\n inX,\n inY,\n }),\n ];\n\n // Only add fade atoms if animateOpacity is true.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies slide in/out transitions to its children. */\nexport const Slide = createPresenceComponent(slidePresenceFn);\n\nexport const SlideSnappy = createPresenceComponentVariant(Slide, {\n easing: motionTokens.curveDecelerateMax,\n exitEasing: motionTokens.curveAccelerateMax,\n});\n\nexport const SlideRelaxed = createPresenceComponentVariant(Slide, {\n duration: motionTokens.durationGentle,\n});\n"],"names":["motionTokens","createPresenceComponent","createPresenceComponentVariant","fadeAtom","slideAtom","slidePresenceFn","duration","durationNormal","easing","curveDecelerateMid","delay","exitDuration","exitEasing","curveAccelerateMid","exitDelay","outX","outY","inX","inY","animateOpacity","enterAtoms","direction","exitAtoms","push","enter","exit","Slide","SlideSnappy","curveDecelerateMax","curveAccelerateMax","SlideRelaxed","durationGentle"],"mappings":"AACA,SAASA,YAAY,EAAEC,uBAAuB,EAAEC,8BAA8B,QAAQ,yBAAyB;AAC/G,SAASC,QAAQ,QAAQ,wBAAwB;AACjD,SAASC,SAAS,QAAQ,yBAAyB;AAGnD;;;;;;;;;;;;;;CAcC,GACD,MAAMC,kBAAiD,CAAC,EACtDC,WAAWN,aAAaO,cAAc,EACtCC,SAASR,aAAaS,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeL,QAAQ,EACvBM,aAAaZ,aAAaa,kBAAkB,EAC5CC,YAAYJ,KAAK,EACjBK,OAAO,KAAK,EACZC,OAAO,KAAK,EACZC,MAAM,KAAK,EACXC,MAAM,KAAK,EACXC,iBAAiB,IAAI,EACT;IACZ,MAAMC,aAAa;QAAChB,UAAU;YAAEiB,WAAW;YAASf;YAAUE;YAAQE;YAAOK;YAAMC;YAAMC;YAAKC;QAAI;KAAG;IACrG,MAAMI,YAAY;QAChBlB,UAAU;YACRiB,WAAW;YACXf,UAAUK;YACVH,QAAQI;YACRF,OAAOI;YACPC;YACAC;YACAC;YACAC;QACF;KACD;IAED,iDAAiD;IACjD,IAAIC,gBAAgB;QAClBC,WAAWG,IAAI,CAACpB,SAAS;YAAEkB,WAAW;YAASf;YAAUE;YAAQE;QAAM;QACvEY,UAAUC,IAAI,CAACpB,SAAS;YAAEkB,WAAW;YAAQf,UAAUK;YAAcH,QAAQI;YAAYF,OAAOI;QAAU;IAC5G;IAEA,OAAO;QACLU,OAAOJ;QACPK,MAAMH;IACR;AACF;AAEA,6EAA6E,GAC7E,OAAO,MAAMI,QAAQzB,wBAAwBI,iBAAiB;AAE9D,OAAO,MAAMsB,cAAczB,+BAA+BwB,OAAO;IAC/DlB,QAAQR,aAAa4B,kBAAkB;IACvChB,YAAYZ,aAAa6B,kBAAkB;AAC7C,GAAG;AAEH,OAAO,MAAMC,eAAe5B,+BAA+BwB,OAAO;IAChEpB,UAAUN,aAAa+B,cAAc;AACvC,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/blur-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/blur-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface BlurAtomParams extends BaseAtomParams {\n /** Blur radius for the out state (exited). Defaults to '10px'. */\n outRadius?: string;\n /** Blur radius for the in state (entered). Defaults to '0px'. */\n inRadius?: string;\n}\n\n/**\n * Generates a motion atom object for a blur-in or blur-out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param outRadius - Blur radius for the out state (exited) with units (e.g., '20px', '1rem'). Defaults to '10px'.\n * @param inRadius - Blur radius for the in state (entered) with units (e.g., '0px', '5px'). Defaults to '0px'.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with filter blur keyframes and the supplied duration and easing.\n */\nexport const blurAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outRadius = '10px',\n inRadius = '0px',\n}: BlurAtomParams): AtomMotion => {\n const keyframes = [{ filter: `blur(${outRadius})` }, { filter: `blur(${inRadius})` }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["blurAtom","direction","duration","easing","motionTokens","curveLinear","delay","outRadius","inRadius","keyframes","filter","reverse"],"mappings":";;;;+BAqBaA;;;eAAAA;;;6BApBgB;AAoBtB,MAAMA,WAAW,CAAC,EACvBC,SAAS,EACTC,QAAQ,EACRC,SAASC,yBAAY,CAACC,WAAW,EACjCC,QAAQ,CAAC,EACTC,YAAY,MAAM,EAClBC,WAAW,KAAK,EACD;IACf,MAAMC,YAAY;QAAC;YAAEC,QAAQ,CAAC,KAAK,EAAEH,UAAU,CAAC,CAAC;QAAC;QAAG;YAAEG,QAAQ,CAAC,KAAK,EAAEF,SAAS,CAAC,CAAC;QAAC;KAAE;IACrF,IAAIP,cAAc,QAAQ;QACxBQ,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAP;QACAC;QACAG;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/fade-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/fade-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface FadeAtomParams extends BaseAtomParams {\n /** Defines how values are applied before and after execution. Defaults to 'both'. */\n fill?: FillMode;\n\n /** Opacity for the out state (exited). Defaults to 0. */\n outOpacity?: number;\n\n /** Opacity for the in state (entered). Defaults to 1. */\n inOpacity?: number;\n}\n\n/**\n * Generates a motion atom object for a fade-in or fade-out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param delay - The delay before the motion starts. Defaults to 0.\n * @param outOpacity - Opacity for the out state (exited). Defaults to 0.\n * @param inOpacity - Opacity for the in state (entered). Defaults to 1.\n * @returns A motion atom object with opacity keyframes and the supplied duration and easing.\n */\nexport const fadeAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outOpacity = 0,\n inOpacity = 1,\n}: FadeAtomParams): AtomMotion => {\n const keyframes = [{ opacity: outOpacity }, { opacity: inOpacity }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n // Applying opacity backwards and forwards in time is important\n // to avoid a bug where a delayed animation is not hidden when it should be.\n fill: 'both',\n };\n};\n"],"names":["fadeAtom","direction","duration","easing","motionTokens","curveLinear","delay","outOpacity","inOpacity","keyframes","opacity","reverse","fill"],"mappings":";;;;+BAyBaA;;;eAAAA;;;6BAxBgB;AAwBtB,MAAMA,WAAW,CAAC,EACvBC,SAAS,EACTC,QAAQ,EACRC,SAASC,yBAAY,CAACC,WAAW,EACjCC,QAAQ,CAAC,EACTC,aAAa,CAAC,EACdC,YAAY,CAAC,EACE;IACf,MAAMC,YAAY;QAAC;YAAEC,SAASH;QAAW;QAAG;YAAEG,SAASF;QAAU;KAAE;IACnE,IAAIP,cAAc,QAAQ;QACxBQ,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAP;QACAC;QACAG;QACA,+DAA+D;QAC/D,4EAA4E;QAC5EM,MAAM;IACR;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/rotate-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/rotate-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { RotateParams } from '../components/Rotate/rotate-types';\nimport type { BaseAtomParams } from '../types';\n\ntype Axis3D = NonNullable<RotateParams['axis']>;\n\ninterface RotateAtomParams extends BaseAtomParams {\n axis?: Axis3D;\n /** Rotation angle for the out state (exited) in degrees. Defaults to -90. */\n outAngle?: number;\n /** Rotation angle for the in state (entered) in degrees. Defaults to 0. */\n inAngle?: number;\n}\n\nconst createRotateValue = (axis: Axis3D, angle: number): string => {\n return `${axis.toLowerCase()} ${angle}deg`;\n};\n\n/**\n * Generates a motion atom object for a rotation around a single axis.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param axis - The axis of rotation: 'x', 'y', or 'z'. Defaults to 'y'.\n * @param outAngle - Rotation angle for the out state (exited) in degrees. Defaults to -90.\n * @param inAngle - Rotation angle for the in state (entered) in degrees. Defaults to 0.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with rotate keyframes and the supplied duration and easing.\n */\nexport const rotateAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n axis = 'z',\n outAngle = -90,\n inAngle = 0,\n}: RotateAtomParams): AtomMotion => {\n const keyframes = [{ rotate: createRotateValue(axis, outAngle) }, { rotate: createRotateValue(axis, inAngle) }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["rotateAtom","createRotateValue","axis","angle","toLowerCase","direction","duration","easing","motionTokens","curveLinear","delay","outAngle","inAngle","keyframes","rotate","reverse"],"mappings":";;;;+BA8BaA;;;eAAAA;;;6BA7BgB;AAc7B,MAAMC,oBAAoB,CAACC,MAAcC;IACvC,OAAO,GAAGD,KAAKE,WAAW,GAAG,CAAC,EAAED,MAAM,GAAG,CAAC;AAC5C;AAaO,MAAMH,aAAa,CAAC,EACzBK,SAAS,EACTC,QAAQ,EACRC,SAASC,yBAAY,CAACC,WAAW,EACjCC,QAAQ,CAAC,EACTR,OAAO,GAAG,EACVS,WAAW,CAAC,EAAE,EACdC,UAAU,CAAC,EACM;IACjB,MAAMC,YAAY;QAAC;YAAEC,QAAQb,kBAAkBC,MAAMS;QAAU;QAAG;YAAEG,QAAQb,kBAAkBC,MAAMU;QAAS;KAAE;IAC/G,IAAIP,cAAc,QAAQ;QACxBQ,UAAUE,OAAO;IACnB;IAEA,OAAO;QACLF;QACAP;QACAC;QACAG;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/scale-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/scale-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface ScaleAtomParams extends BaseAtomParams {\n /** Scale for the out state (exited). Defaults to 0.9. */\n outScale?: number;\n /** Scale for the in state (entered). Defaults to 1. */\n inScale?: number;\n}\n\n/**\n * Generates a motion atom object for a scale in or scale out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param outScale - Scale for the out state (exited). Defaults to 0.9.\n * @param inScale - Scale for the in state (entered). Defaults to 1.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with scale keyframes and the supplied duration and easing.\n */\nexport const scaleAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outScale = 0.9,\n inScale = 1,\n}: ScaleAtomParams): AtomMotion => {\n const keyframes = [{ scale: outScale }, { scale: inScale }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["scaleAtom","direction","duration","easing","motionTokens","curveLinear","delay","outScale","inScale","keyframes","scale","reverse"],"mappings":";;;;+BAqBaA;;;eAAAA;;;6BApBgB;AAoBtB,MAAMA,YAAY,CAAC,EACxBC,SAAS,EACTC,QAAQ,EACRC,SAASC,yBAAY,CAACC,WAAW,EACjCC,QAAQ,CAAC,EACTC,WAAW,GAAG,EACdC,UAAU,CAAC,EACK;IAChB,MAAMC,YAAY;QAAC;YAAEC,OAAOH;QAAS;QAAG;YAAEG,OAAOF;QAAQ;KAAE;IAC3D,IAAIP,cAAc,QAAQ;QACxBQ,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAP;QACAC;QACAG;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/slide-atom.ts"],"sourcesContent":["import { AtomMotion
|
|
1
|
+
{"version":3,"sources":["../src/atoms/slide-atom.ts"],"sourcesContent":["import type { AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens } from '@fluentui/react-motion';\nimport type { BaseAtomParams } from '../types';\n\ninterface SlideAtomParams extends BaseAtomParams {\n /** X translate for the out state (exited). Defaults to '0px'. */\n outX?: string;\n /** Y translate for the out state (exited). Defaults to '0px'. */\n outY?: string;\n /** X translate for the in state (entered). Defaults to '0px'. */\n inX?: string;\n /** Y translate for the in state (entered). Defaults to '0px'. */\n inY?: string;\n}\n\n/**\n * Generates a motion atom object for a slide-in or slide-out.\n * @param direction - The functional direction of the motion: 'enter' or 'exit'.\n * @param duration - The duration of the motion in milliseconds.\n * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.\n * @param outX - X translate for the out state (exited) with units (e.g., '50px', '100%'). Defaults to '0px'.\n * @param outY - Y translate for the out state (exited) with units (e.g., '50px', '100%'). Defaults to '0px'.\n * @param inX - X translate for the in state (entered) with units (e.g., '5px', '10%'). Defaults to '0px'.\n * @param inY - Y translate for the in state (entered) with units (e.g., '5px', '10%'). Defaults to '0px'.\n * @param delay - Time (ms) to delay the animation. Defaults to 0.\n * @returns A motion atom object with translate keyframes and the supplied duration and easing.\n */\nexport const slideAtom = ({\n direction,\n duration,\n easing = motionTokens.curveLinear,\n delay = 0,\n outX = '0px',\n outY = '0px',\n inX = '0px',\n inY = '0px',\n}: SlideAtomParams): AtomMotion => {\n const keyframes = [{ translate: `${outX} ${outY}` }, { translate: `${inX} ${inY}` }];\n if (direction === 'exit') {\n keyframes.reverse();\n }\n return {\n keyframes,\n duration,\n easing,\n delay,\n };\n};\n"],"names":["slideAtom","direction","duration","easing","motionTokens","curveLinear","delay","outX","outY","inX","inY","keyframes","translate","reverse"],"mappings":";;;;+BA2BaA;;;eAAAA;;;6BA1BgB;AA0BtB,MAAMA,YAAY,CAAC,EACxBC,SAAS,EACTC,QAAQ,EACRC,SAASC,yBAAY,CAACC,WAAW,EACjCC,QAAQ,CAAC,EACTC,OAAO,KAAK,EACZC,OAAO,KAAK,EACZC,MAAM,KAAK,EACXC,MAAM,KAAK,EACK;IAChB,MAAMC,YAAY;QAAC;YAAEC,WAAW,GAAGL,KAAK,CAAC,EAAEC,MAAM;QAAC;QAAG;YAAEI,WAAW,GAAGH,IAAI,CAAC,EAAEC,KAAK;QAAC;KAAE;IACpF,IAAIT,cAAc,QAAQ;QACxBU,UAAUE,OAAO;IACnB;IACA,OAAO;QACLF;QACAT;QACAC;QACAG;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/Stagger.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useStaggerItemsVisibility } from './useStaggerItemsVisibility';\nimport {\n DEFAULT_ITEM_DURATION,\n DEFAULT_ITEM_DELAY,\n acceptsVisibleProp,\n acceptsDelayProps,\n getStaggerChildMapping,\n} from './utils';\nimport { StaggerOneWayProps, StaggerProps, type StaggerHideMode, type StaggerDelayMode } from './stagger-types';\n\n/**\n * Shared utility to detect optimal stagger modes based on children components.\n * Consolidates the auto-detection logic used by both StaggerMain and createStaggerDirection.\n */\nconst detectStaggerModes = (\n children: React.ReactNode,\n options: {\n hideMode?: StaggerHideMode;\n delayMode?: StaggerDelayMode;\n fallbackHideMode?: StaggerHideMode;\n },\n): { hideMode: StaggerHideMode; delayMode: StaggerDelayMode } => {\n const { hideMode, delayMode, fallbackHideMode = 'visibilityStyle' } = options;\n\n const childMapping = getStaggerChildMapping(children);\n const elements = Object.values(childMapping).map(item => item.element);\n const hasVisiblePropSupport = elements.every(child => acceptsVisibleProp(child));\n const hasDelayPropSupport = elements.every(child => acceptsDelayProps(child));\n\n return {\n hideMode: hideMode ?? (hasVisiblePropSupport ? 'visibleProp' : fallbackHideMode),\n delayMode: delayMode ?? (hasDelayPropSupport ? 'delayProp' : 'timing'),\n };\n};\n\nconst StaggerOneWay: React.FC<StaggerOneWayProps> = ({\n children,\n direction,\n itemDelay = DEFAULT_ITEM_DELAY,\n itemDuration = DEFAULT_ITEM_DURATION,\n reversed = false,\n hideMode,\n delayMode = 'timing',\n onMotionFinish,\n}) => {\n const childMapping = React.useMemo(() => getStaggerChildMapping(children), [children]);\n\n // Always call hooks at the top level, regardless of delayMode\n const { itemsVisibility } = useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration,\n direction,\n reversed,\n onMotionFinish,\n hideMode,\n });\n\n // For delayProp mode, pass delay props directly to motion components\n if (delayMode === 'delayProp') {\n return (\n <>\n {Object.entries(childMapping).map(([key, { element, index }]) => {\n const staggerIndex = reversed ? Object.keys(childMapping).length - 1 - index : index;\n const delay = staggerIndex * itemDelay;\n\n // Clone element with delay prop (for enter direction) or exitDelay prop (for exit direction)\n const delayProp = direction === 'enter' ? { delay } : { exitDelay: delay };\n\n // Only set visible prop if the component supports it\n // Set visible based on direction: true for enter, false for exit\n const visibleProp = acceptsVisibleProp(element) ? { visible: direction === 'enter' } : {};\n\n return React.cloneElement(element, {\n key,\n ...visibleProp,\n ...delayProp,\n });\n })}\n </>\n );\n }\n\n // For timing mode, use the existing timing-based implementation\n\n return (\n <>\n {Object.entries(childMapping).map(([key, { element }]) => {\n if (hideMode === 'visibleProp') {\n // Use a generic record type for props to avoid `any` while still allowing unknown prop shapes.\n return React.cloneElement(element, {\n key,\n visible: itemsVisibility[key],\n } as Partial<Record<string, unknown>>);\n } else if (hideMode === 'visibilityStyle') {\n const childProps = element.props as Record<string, unknown> | undefined;\n const style = {\n ...(childProps?.style as Record<string, unknown> | undefined),\n visibility: itemsVisibility[key] ? 'visible' : 'hidden',\n };\n return React.cloneElement(element, { key, style } as Partial<Record<string, unknown>>);\n } else {\n // unmount mode\n return itemsVisibility[key] ? React.cloneElement(element, { key }) : null;\n }\n })}\n </>\n );\n};\n\n// Shared helper for StaggerIn and StaggerOut\nconst createStaggerDirection = (direction: 'enter' | 'exit') => {\n const StaggerDirection: React.FC<Omit<StaggerProps, 'visible'>> = ({ hideMode, delayMode, children, ...props }) => {\n // Auto-detect modes for better performance with motion components\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // One-way stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n return (\n <StaggerOneWay\n {...props}\n children={children}\n direction={direction}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n />\n );\n };\n\n return StaggerDirection;\n};\n\nconst StaggerIn = createStaggerDirection('enter');\nconst StaggerOut = createStaggerDirection('exit');\n\n// Main Stagger component with auto-detection or explicit modes\nconst StaggerMain: React.FC<StaggerProps> = props => {\n const { children, visible = false, hideMode, delayMode, ...rest } = props;\n\n // Auto-detect modes for bidirectional stagger\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // Bidirectional stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n const direction = visible ? 'enter' : 'exit';\n\n return (\n <StaggerOneWay\n {...rest}\n children={children}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n direction={direction}\n />\n );\n};\n\n/**\n * Stagger is a component that manages the staggered entrance and exit of its children.\n * Children are animated in sequence with configurable timing between each item.\n * Stagger can be interactively toggled between entrance and exit animations using the `visible` prop.\n *\n * @param children - React elements to animate. Elements are cloned with animation props.\n * @param visible - Controls animation direction. When `true`, the group is animating \"enter\" (items shown);\n * when `false`, the group is animating \"exit\" (items hidden). Defaults to `false`.\n * @param itemDelay - Milliseconds between each item's animation start.\n * Defaults to the package's default delay (see `DEFAULT_ITEM_DELAY`).\n * @param itemDuration - Milliseconds each item's animation lasts. Only used with `delayMode=\"timing\"`.\n * Defaults to the package's default item duration (see `DEFAULT_ITEM_DURATION`).\n * @param reversed - Whether to reverse the stagger sequence (last item animates first). Defaults to `false`.\n * @param hideMode - How children's visibility/mounting is managed. Auto-detects if not specified.\n * @param delayMode - How staggering timing is implemented. Auto-detects if not specified.\n * @param onMotionFinish - Callback invoked when the staggered animation sequence completes.\n *\n * **Auto-detection behavior:**\n * - **hideMode**: Presence components use `'visibleProp'`, DOM elements use `'visibilityStyle'`\n * - **delayMode**: Components with delay support use `'delayProp'` (most performant), others use `'timing'`\n *\n * **hideMode options:**\n * - `'visibleProp'`: Children are presence components with `visible` prop (always rendered, visibility controlled via prop)\n * - `'visibilityStyle'`: Children remain in DOM with inline style visibility: hidden/visible (preserves layout space)\n * - `'unmount'`: Children are mounted/unmounted from DOM based on visibility\n *\n * **delayMode options:**\n * - `'timing'`: Manages visibility over time using JavaScript timing\n * - `'delayProp'`: Passes delay props to motion components to use native Web Animations API delays (most performant)\n *\n * **Static variants:**\n * - `<Stagger.In>` - One-way stagger for entrance animations only (auto-detects optimal modes)\n * - `<Stagger.Out>` - One-way stagger for exit animations only (auto-detects optimal modes)\n *\n * @example\n * ```tsx\n * import { Stagger, Fade, Scale, Rotate } from '@fluentui/react-motion-components-preview';\n *\n * // Auto-detects optimal modes for presence components (delayProp + visibleProp)\n * <Stagger visible={isVisible} itemDelay={150}>\n * <Fade><div>Item 2</div></Fade>\n * <Scale><div>Item 1</div></Scale>\n * <Rotate><div>Item 3</div></Rotate>\n * </Stagger>\n *\n * // Auto-detects optimal modes for motion components (delayProp + unmount)\n * <Stagger.In itemDelay={100}>\n * <Scale.In><div>Item 1</div></Scale.In>\n * <Fade.In><div>Item 2</div></Fade.In>\n * </Stagger.In>\n *\n * // Auto-detects timing mode for DOM elements (timing + visibilityStyle)\n * <Stagger visible={isVisible} itemDelay={150} onMotionFinish={handleComplete}>\n * <div>Item 1</div>\n * <div>Item 2</div>\n * <div>Item 3</div>\n * </Stagger>\n *\n * // Override auto-detection when needed\n * <Stagger visible={isVisible} delayMode=\"timing\" hideMode=\"unmount\">\n * <CustomComponent>Item 1</CustomComponent>\n * </Stagger>\n * ```\n */\nexport const Stagger = Object.assign(StaggerMain, {\n In: StaggerIn,\n Out: StaggerOut,\n});\n"],"names":["Stagger","detectStaggerModes","children","options","hideMode","delayMode","fallbackHideMode","childMapping","getStaggerChildMapping","elements","Object","values","map","item","element","hasVisiblePropSupport","every","child","acceptsVisibleProp","hasDelayPropSupport","acceptsDelayProps","StaggerOneWay","direction","itemDelay","DEFAULT_ITEM_DELAY","itemDuration","DEFAULT_ITEM_DURATION","reversed","onMotionFinish","React","useMemo","itemsVisibility","useStaggerItemsVisibility","entries","key","index","staggerIndex","keys","length","delay","delayProp","exitDelay","visibleProp","visible","cloneElement","childProps","props","style","visibility","createStaggerDirection","StaggerDirection","resolvedHideMode","resolvedDelayMode","StaggerIn","StaggerOut","StaggerMain","rest","assign","In","Out"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/Stagger.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useStaggerItemsVisibility } from './useStaggerItemsVisibility';\nimport {\n DEFAULT_ITEM_DURATION,\n DEFAULT_ITEM_DELAY,\n acceptsVisibleProp,\n acceptsDelayProps,\n getStaggerChildMapping,\n} from './utils';\nimport type { StaggerOneWayProps, StaggerProps } from './stagger-types';\nimport { type StaggerHideMode, type StaggerDelayMode } from './stagger-types';\n\n/**\n * Shared utility to detect optimal stagger modes based on children components.\n * Consolidates the auto-detection logic used by both StaggerMain and createStaggerDirection.\n */\nconst detectStaggerModes = (\n children: React.ReactNode,\n options: {\n hideMode?: StaggerHideMode;\n delayMode?: StaggerDelayMode;\n fallbackHideMode?: StaggerHideMode;\n },\n): { hideMode: StaggerHideMode; delayMode: StaggerDelayMode } => {\n const { hideMode, delayMode, fallbackHideMode = 'visibilityStyle' } = options;\n\n const childMapping = getStaggerChildMapping(children);\n const elements = Object.values(childMapping).map(item => item.element);\n const hasVisiblePropSupport = elements.every(child => acceptsVisibleProp(child));\n const hasDelayPropSupport = elements.every(child => acceptsDelayProps(child));\n\n return {\n hideMode: hideMode ?? (hasVisiblePropSupport ? 'visibleProp' : fallbackHideMode),\n delayMode: delayMode ?? (hasDelayPropSupport ? 'delayProp' : 'timing'),\n };\n};\n\nconst StaggerOneWay: React.FC<StaggerOneWayProps> = ({\n children,\n direction,\n itemDelay = DEFAULT_ITEM_DELAY,\n itemDuration = DEFAULT_ITEM_DURATION,\n reversed = false,\n hideMode,\n delayMode = 'timing',\n onMotionFinish,\n}) => {\n const childMapping = React.useMemo(() => getStaggerChildMapping(children), [children]);\n\n // Always call hooks at the top level, regardless of delayMode\n const { itemsVisibility } = useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration,\n direction,\n reversed,\n onMotionFinish,\n hideMode,\n });\n\n // For delayProp mode, pass delay props directly to motion components\n if (delayMode === 'delayProp') {\n return (\n <>\n {Object.entries(childMapping).map(([key, { element, index }]) => {\n const staggerIndex = reversed ? Object.keys(childMapping).length - 1 - index : index;\n const delay = staggerIndex * itemDelay;\n\n // Clone element with delay prop (for enter direction) or exitDelay prop (for exit direction)\n const delayProp = direction === 'enter' ? { delay } : { exitDelay: delay };\n\n // Only set visible prop if the component supports it\n // Set visible based on direction: true for enter, false for exit\n const visibleProp = acceptsVisibleProp(element) ? { visible: direction === 'enter' } : {};\n\n return React.cloneElement(element, {\n key,\n ...visibleProp,\n ...delayProp,\n });\n })}\n </>\n );\n }\n\n // For timing mode, use the existing timing-based implementation\n\n return (\n <>\n {Object.entries(childMapping).map(([key, { element }]) => {\n if (hideMode === 'visibleProp') {\n // Use a generic record type for props to avoid `any` while still allowing unknown prop shapes.\n return React.cloneElement(element, {\n key,\n visible: itemsVisibility[key],\n } as Partial<Record<string, unknown>>);\n } else if (hideMode === 'visibilityStyle') {\n const childProps = element.props as Record<string, unknown> | undefined;\n const style = {\n ...(childProps?.style as Record<string, unknown> | undefined),\n visibility: itemsVisibility[key] ? 'visible' : 'hidden',\n };\n return React.cloneElement(element, { key, style } as Partial<Record<string, unknown>>);\n } else {\n // unmount mode\n return itemsVisibility[key] ? React.cloneElement(element, { key }) : null;\n }\n })}\n </>\n );\n};\n\n// Shared helper for StaggerIn and StaggerOut\nconst createStaggerDirection = (direction: 'enter' | 'exit') => {\n const StaggerDirection: React.FC<Omit<StaggerProps, 'visible'>> = ({ hideMode, delayMode, children, ...props }) => {\n // Auto-detect modes for better performance with motion components\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // One-way stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n return (\n <StaggerOneWay\n {...props}\n children={children}\n direction={direction}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n />\n );\n };\n\n return StaggerDirection;\n};\n\nconst StaggerIn = createStaggerDirection('enter');\nconst StaggerOut = createStaggerDirection('exit');\n\n// Main Stagger component with auto-detection or explicit modes\nconst StaggerMain: React.FC<StaggerProps> = props => {\n const { children, visible = false, hideMode, delayMode, ...rest } = props;\n\n // Auto-detect modes for bidirectional stagger\n const { hideMode: resolvedHideMode, delayMode: resolvedDelayMode } = detectStaggerModes(children, {\n hideMode,\n delayMode,\n // Bidirectional stagger falls back to visibilityStyle if it doesn't detect visibleProp support\n fallbackHideMode: 'visibilityStyle',\n });\n\n const direction = visible ? 'enter' : 'exit';\n\n return (\n <StaggerOneWay\n {...rest}\n children={children}\n hideMode={resolvedHideMode}\n delayMode={resolvedDelayMode}\n direction={direction}\n />\n );\n};\n\n/**\n * Stagger is a component that manages the staggered entrance and exit of its children.\n * Children are animated in sequence with configurable timing between each item.\n * Stagger can be interactively toggled between entrance and exit animations using the `visible` prop.\n *\n * @param children - React elements to animate. Elements are cloned with animation props.\n * @param visible - Controls animation direction. When `true`, the group is animating \"enter\" (items shown);\n * when `false`, the group is animating \"exit\" (items hidden). Defaults to `false`.\n * @param itemDelay - Milliseconds between each item's animation start.\n * Defaults to the package's default delay (see `DEFAULT_ITEM_DELAY`).\n * @param itemDuration - Milliseconds each item's animation lasts. Only used with `delayMode=\"timing\"`.\n * Defaults to the package's default item duration (see `DEFAULT_ITEM_DURATION`).\n * @param reversed - Whether to reverse the stagger sequence (last item animates first). Defaults to `false`.\n * @param hideMode - How children's visibility/mounting is managed. Auto-detects if not specified.\n * @param delayMode - How staggering timing is implemented. Auto-detects if not specified.\n * @param onMotionFinish - Callback invoked when the staggered animation sequence completes.\n *\n * **Auto-detection behavior:**\n * - **hideMode**: Presence components use `'visibleProp'`, DOM elements use `'visibilityStyle'`\n * - **delayMode**: Components with delay support use `'delayProp'` (most performant), others use `'timing'`\n *\n * **hideMode options:**\n * - `'visibleProp'`: Children are presence components with `visible` prop (always rendered, visibility controlled via prop)\n * - `'visibilityStyle'`: Children remain in DOM with inline style visibility: hidden/visible (preserves layout space)\n * - `'unmount'`: Children are mounted/unmounted from DOM based on visibility\n *\n * **delayMode options:**\n * - `'timing'`: Manages visibility over time using JavaScript timing\n * - `'delayProp'`: Passes delay props to motion components to use native Web Animations API delays (most performant)\n *\n * **Static variants:**\n * - `<Stagger.In>` - One-way stagger for entrance animations only (auto-detects optimal modes)\n * - `<Stagger.Out>` - One-way stagger for exit animations only (auto-detects optimal modes)\n *\n * @example\n * ```tsx\n * import { Stagger, Fade, Scale, Rotate } from '@fluentui/react-motion-components-preview';\n *\n * // Auto-detects optimal modes for presence components (delayProp + visibleProp)\n * <Stagger visible={isVisible} itemDelay={150}>\n * <Fade><div>Item 2</div></Fade>\n * <Scale><div>Item 1</div></Scale>\n * <Rotate><div>Item 3</div></Rotate>\n * </Stagger>\n *\n * // Auto-detects optimal modes for motion components (delayProp + unmount)\n * <Stagger.In itemDelay={100}>\n * <Scale.In><div>Item 1</div></Scale.In>\n * <Fade.In><div>Item 2</div></Fade.In>\n * </Stagger.In>\n *\n * // Auto-detects timing mode for DOM elements (timing + visibilityStyle)\n * <Stagger visible={isVisible} itemDelay={150} onMotionFinish={handleComplete}>\n * <div>Item 1</div>\n * <div>Item 2</div>\n * <div>Item 3</div>\n * </Stagger>\n *\n * // Override auto-detection when needed\n * <Stagger visible={isVisible} delayMode=\"timing\" hideMode=\"unmount\">\n * <CustomComponent>Item 1</CustomComponent>\n * </Stagger>\n * ```\n */\nexport const Stagger = Object.assign(StaggerMain, {\n In: StaggerIn,\n Out: StaggerOut,\n});\n"],"names":["Stagger","detectStaggerModes","children","options","hideMode","delayMode","fallbackHideMode","childMapping","getStaggerChildMapping","elements","Object","values","map","item","element","hasVisiblePropSupport","every","child","acceptsVisibleProp","hasDelayPropSupport","acceptsDelayProps","StaggerOneWay","direction","itemDelay","DEFAULT_ITEM_DELAY","itemDuration","DEFAULT_ITEM_DURATION","reversed","onMotionFinish","React","useMemo","itemsVisibility","useStaggerItemsVisibility","entries","key","index","staggerIndex","keys","length","delay","delayProp","exitDelay","visibleProp","visible","cloneElement","childProps","props","style","visibility","createStaggerDirection","StaggerDirection","resolvedHideMode","resolvedDelayMode","StaggerIn","StaggerOut","StaggerMain","rest","assign","In","Out"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
|
@@ -43,6 +43,7 @@ function useStaggerItemsVisibility({ childMapping, itemDelay, itemDuration = _ut
|
|
|
43
43
|
});
|
|
44
44
|
// Update visibility mapping when childMapping changes
|
|
45
45
|
_react.useEffect(()=>{
|
|
46
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
46
47
|
setItemsVisibility((prev)=>{
|
|
47
48
|
const next = {};
|
|
48
49
|
const targetState = direction === 'enter';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/useStaggerItemsVisibility.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useAnimationFrame, useEventCallback } from '@fluentui/react-utilities';\nimport type { StaggerProps } from './stagger-types';\nimport {\n staggerItemsVisibilityAtTime,\n type StaggerItemsVisibilityAtTimeParams,\n DEFAULT_ITEM_DURATION,\n type StaggerChildMapping,\n} from './utils';\n\nexport interface UseStaggerItemsVisibilityParams\n extends Pick<StaggerProps, 'onMotionFinish'>,\n Omit<StaggerItemsVisibilityAtTimeParams, 'elapsed' | 'itemCount'> {\n hideMode: StaggerProps['hideMode'];\n childMapping: StaggerChildMapping;\n}\n\n/**\n * Hook that tracks the visibility of a staggered sequence of items as time progresses.\n *\n * Behavior summary for all hide modes:\n * - On the first render, items are placed in their final state (enter => visible, exit => hidden)\n * and no animation runs.\n * - On subsequent renders when direction changes, items animate from the opposite state\n * to the final state over the stagger timeline.\n * - Changes to the `reversed` prop do not trigger re-animation; they only affect the order\n * during the next direction change animation.\n *\n * This hook uses child key mapping instead of item count to track individual items.\n * This allows it to correctly handle:\n * - Items being added and removed simultaneously (when count stays the same)\n * - Items being reordered\n * - Individual item identity across renders\n *\n * @param childMapping - Mapping of child keys to elements and indices\n * @param itemDelay - Milliseconds between the start of each item's animation\n * @param itemDuration - Milliseconds each item's animation lasts\n * @param direction - 'enter' (show items) or 'exit' (hide items)\n * @param reversed - Whether to reverse the stagger order (last item first)\n * @param onMotionFinish - Callback fired when the full stagger sequence completes\n * @param hideMode - How children's visibility is managed: 'visibleProp', 'visibilityStyle', or 'unmount'\n *\n * @returns An object with `itemsVisibility: Record<string, boolean>` indicating which items are currently visible by key\n */\nexport function useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration = DEFAULT_ITEM_DURATION,\n direction,\n reversed = false,\n onMotionFinish,\n hideMode = 'visibleProp',\n}: UseStaggerItemsVisibilityParams): { itemsVisibility: Record<string, boolean> } {\n const [requestAnimationFrame, cancelAnimationFrame] = useAnimationFrame();\n\n // Stabilize the callback reference to avoid re-triggering effects on every render\n const handleMotionFinish = useEventCallback(\n onMotionFinish ??\n (() => {\n return;\n }),\n );\n\n // Track animation state independently of child changes\n const [animationKey, setAnimationKey] = React.useState(0);\n const prevDirection = React.useRef(direction);\n\n // Only trigger new animation when direction actually changes, not when children change\n React.useEffect(() => {\n if (prevDirection.current !== direction) {\n setAnimationKey(prev => prev + 1);\n prevDirection.current = direction;\n }\n }, [direction]);\n\n // State: visibility mapping for all items by key\n const [itemsVisibility, setItemsVisibility] = React.useState<Record<string, boolean>>(() => {\n const initial: Record<string, boolean> = {};\n // All hide modes start in final state: visible for 'enter', hidden for 'exit'\n const initialState = direction === 'enter';\n Object.keys(childMapping).forEach(key => {\n initial[key] = initialState;\n });\n return initial;\n });\n\n // Update visibility mapping when childMapping changes\n React.useEffect(() => {\n setItemsVisibility(prev => {\n const next: Record<string, boolean> = {};\n const targetState = direction === 'enter';\n\n // Add or update items from new mapping\n Object.keys(childMapping).forEach(key => {\n if (key in prev) {\n // Existing item - preserve its visibility state\n next[key] = prev[key];\n } else {\n // New item - set to target state\n next[key] = targetState;\n }\n });\n\n // Note: Items that were in prev but not in childMapping are automatically removed\n // because we only iterate over keys in childMapping\n\n return next;\n });\n }, [childMapping, direction]);\n\n // Refs: animation timing and control\n const startTimeRef = React.useRef<number | null>(null);\n const frameRef = React.useRef<number | null>(null);\n const finishedRef = React.useRef(false);\n const isFirstRender = React.useRef(true);\n\n // Use ref to avoid re-running the animation when child mapping changes\n const childMappingRef = React.useRef(childMapping);\n\n // Update childMapping ref whenever it changes\n React.useEffect(() => {\n childMappingRef.current = childMapping;\n }, [childMapping]);\n\n // Use ref for reversed to avoid re-running animation when it changes\n const reversedRef = React.useRef(reversed);\n\n // Update reversed ref whenever it changes\n React.useEffect(() => {\n reversedRef.current = reversed;\n }, [reversed]);\n\n // ====== ANIMATION EFFECT ======\n\n React.useEffect(() => {\n let cancelled = false;\n startTimeRef.current = null;\n finishedRef.current = false;\n\n // All hide modes skip animation on first render - items are already in their final state\n if (isFirstRender.current) {\n isFirstRender.current = false;\n // Items are already in their final state from useState, no animation needed\n handleMotionFinish();\n return; // No cleanup needed for first render\n }\n\n // For animations after first render, start from the opposite of the final state\n // - Enter animation: start hidden (false), animate to visible (true)\n // - Exit animation: start visible (true), animate to hidden (false)\n const startState = direction === 'exit';\n // Use childMappingRef.current to avoid adding childMapping to dependencies\n const initialVisibility: Record<string, boolean> = {};\n Object.keys(childMappingRef.current).forEach(key => {\n initialVisibility[key] = startState;\n });\n setItemsVisibility(initialVisibility);\n\n // Animation loop: update visibility on each frame until complete\n const tick = (now: number) => {\n if (cancelled) {\n return;\n }\n if (startTimeRef.current === null) {\n startTimeRef.current = now;\n }\n const elapsed = now - (startTimeRef.current as number);\n\n const childKeys = Object.keys(childMappingRef.current);\n const itemCount = childKeys.length;\n\n const result = staggerItemsVisibilityAtTime({\n itemCount,\n elapsed,\n itemDelay,\n itemDuration,\n direction,\n reversed: reversedRef.current,\n });\n\n // Convert boolean array to keyed object\n const nextVisibility: Record<string, boolean> = {};\n childKeys.forEach((key, idx) => {\n nextVisibility[key] = result.itemsVisibility[idx];\n });\n\n setItemsVisibility(nextVisibility);\n\n if (elapsed < result.totalDuration) {\n frameRef.current = requestAnimationFrame(tick);\n } else if (!finishedRef.current) {\n finishedRef.current = true;\n handleMotionFinish();\n }\n };\n\n frameRef.current = requestAnimationFrame(tick);\n return () => {\n cancelled = true;\n if (frameRef.current) {\n cancelAnimationFrame();\n }\n };\n }, [\n animationKey,\n itemDelay,\n itemDuration,\n direction,\n requestAnimationFrame,\n cancelAnimationFrame,\n handleMotionFinish,\n ]);\n\n return { itemsVisibility };\n}\n"],"names":["useStaggerItemsVisibility","childMapping","itemDelay","itemDuration","DEFAULT_ITEM_DURATION","direction","reversed","onMotionFinish","hideMode","requestAnimationFrame","cancelAnimationFrame","useAnimationFrame","handleMotionFinish","useEventCallback","animationKey","setAnimationKey","React","useState","prevDirection","useRef","useEffect","current","prev","itemsVisibility","setItemsVisibility","initial","initialState","Object","keys","forEach","key","next","targetState","startTimeRef","frameRef","finishedRef","isFirstRender","childMappingRef","reversedRef","cancelled","startState","initialVisibility","tick","now","elapsed","childKeys","itemCount","length","result","staggerItemsVisibilityAtTime","nextVisibility","idx","totalDuration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/useStaggerItemsVisibility.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useAnimationFrame, useEventCallback } from '@fluentui/react-utilities';\nimport type { StaggerProps } from './stagger-types';\nimport {\n staggerItemsVisibilityAtTime,\n type StaggerItemsVisibilityAtTimeParams,\n DEFAULT_ITEM_DURATION,\n type StaggerChildMapping,\n} from './utils';\n\nexport interface UseStaggerItemsVisibilityParams\n extends Pick<StaggerProps, 'onMotionFinish'>,\n Omit<StaggerItemsVisibilityAtTimeParams, 'elapsed' | 'itemCount'> {\n hideMode: StaggerProps['hideMode'];\n childMapping: StaggerChildMapping;\n}\n\n/**\n * Hook that tracks the visibility of a staggered sequence of items as time progresses.\n *\n * Behavior summary for all hide modes:\n * - On the first render, items are placed in their final state (enter => visible, exit => hidden)\n * and no animation runs.\n * - On subsequent renders when direction changes, items animate from the opposite state\n * to the final state over the stagger timeline.\n * - Changes to the `reversed` prop do not trigger re-animation; they only affect the order\n * during the next direction change animation.\n *\n * This hook uses child key mapping instead of item count to track individual items.\n * This allows it to correctly handle:\n * - Items being added and removed simultaneously (when count stays the same)\n * - Items being reordered\n * - Individual item identity across renders\n *\n * @param childMapping - Mapping of child keys to elements and indices\n * @param itemDelay - Milliseconds between the start of each item's animation\n * @param itemDuration - Milliseconds each item's animation lasts\n * @param direction - 'enter' (show items) or 'exit' (hide items)\n * @param reversed - Whether to reverse the stagger order (last item first)\n * @param onMotionFinish - Callback fired when the full stagger sequence completes\n * @param hideMode - How children's visibility is managed: 'visibleProp', 'visibilityStyle', or 'unmount'\n *\n * @returns An object with `itemsVisibility: Record<string, boolean>` indicating which items are currently visible by key\n */\nexport function useStaggerItemsVisibility({\n childMapping,\n itemDelay,\n itemDuration = DEFAULT_ITEM_DURATION,\n direction,\n reversed = false,\n onMotionFinish,\n hideMode = 'visibleProp',\n}: UseStaggerItemsVisibilityParams): { itemsVisibility: Record<string, boolean> } {\n const [requestAnimationFrame, cancelAnimationFrame] = useAnimationFrame();\n\n // Stabilize the callback reference to avoid re-triggering effects on every render\n const handleMotionFinish = useEventCallback(\n onMotionFinish ??\n (() => {\n return;\n }),\n );\n\n // Track animation state independently of child changes\n const [animationKey, setAnimationKey] = React.useState(0);\n const prevDirection = React.useRef(direction);\n\n // Only trigger new animation when direction actually changes, not when children change\n React.useEffect(() => {\n if (prevDirection.current !== direction) {\n setAnimationKey(prev => prev + 1);\n prevDirection.current = direction;\n }\n }, [direction]);\n\n // State: visibility mapping for all items by key\n const [itemsVisibility, setItemsVisibility] = React.useState<Record<string, boolean>>(() => {\n const initial: Record<string, boolean> = {};\n // All hide modes start in final state: visible for 'enter', hidden for 'exit'\n const initialState = direction === 'enter';\n Object.keys(childMapping).forEach(key => {\n initial[key] = initialState;\n });\n return initial;\n });\n\n // Update visibility mapping when childMapping changes\n React.useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setItemsVisibility(prev => {\n const next: Record<string, boolean> = {};\n const targetState = direction === 'enter';\n\n // Add or update items from new mapping\n Object.keys(childMapping).forEach(key => {\n if (key in prev) {\n // Existing item - preserve its visibility state\n next[key] = prev[key];\n } else {\n // New item - set to target state\n next[key] = targetState;\n }\n });\n\n // Note: Items that were in prev but not in childMapping are automatically removed\n // because we only iterate over keys in childMapping\n\n return next;\n });\n }, [childMapping, direction]);\n\n // Refs: animation timing and control\n const startTimeRef = React.useRef<number | null>(null);\n const frameRef = React.useRef<number | null>(null);\n const finishedRef = React.useRef(false);\n const isFirstRender = React.useRef(true);\n\n // Use ref to avoid re-running the animation when child mapping changes\n const childMappingRef = React.useRef(childMapping);\n\n // Update childMapping ref whenever it changes\n React.useEffect(() => {\n childMappingRef.current = childMapping;\n }, [childMapping]);\n\n // Use ref for reversed to avoid re-running animation when it changes\n const reversedRef = React.useRef(reversed);\n\n // Update reversed ref whenever it changes\n React.useEffect(() => {\n reversedRef.current = reversed;\n }, [reversed]);\n\n // ====== ANIMATION EFFECT ======\n\n React.useEffect(() => {\n let cancelled = false;\n startTimeRef.current = null;\n finishedRef.current = false;\n\n // All hide modes skip animation on first render - items are already in their final state\n if (isFirstRender.current) {\n isFirstRender.current = false;\n // Items are already in their final state from useState, no animation needed\n handleMotionFinish();\n return; // No cleanup needed for first render\n }\n\n // For animations after first render, start from the opposite of the final state\n // - Enter animation: start hidden (false), animate to visible (true)\n // - Exit animation: start visible (true), animate to hidden (false)\n const startState = direction === 'exit';\n // Use childMappingRef.current to avoid adding childMapping to dependencies\n const initialVisibility: Record<string, boolean> = {};\n Object.keys(childMappingRef.current).forEach(key => {\n initialVisibility[key] = startState;\n });\n setItemsVisibility(initialVisibility);\n\n // Animation loop: update visibility on each frame until complete\n const tick = (now: number) => {\n if (cancelled) {\n return;\n }\n if (startTimeRef.current === null) {\n startTimeRef.current = now;\n }\n const elapsed = now - (startTimeRef.current as number);\n\n const childKeys = Object.keys(childMappingRef.current);\n const itemCount = childKeys.length;\n\n const result = staggerItemsVisibilityAtTime({\n itemCount,\n elapsed,\n itemDelay,\n itemDuration,\n direction,\n reversed: reversedRef.current,\n });\n\n // Convert boolean array to keyed object\n const nextVisibility: Record<string, boolean> = {};\n childKeys.forEach((key, idx) => {\n nextVisibility[key] = result.itemsVisibility[idx];\n });\n\n setItemsVisibility(nextVisibility);\n\n if (elapsed < result.totalDuration) {\n frameRef.current = requestAnimationFrame(tick);\n } else if (!finishedRef.current) {\n finishedRef.current = true;\n handleMotionFinish();\n }\n };\n\n frameRef.current = requestAnimationFrame(tick);\n return () => {\n cancelled = true;\n if (frameRef.current) {\n cancelAnimationFrame();\n }\n };\n }, [\n animationKey,\n itemDelay,\n itemDuration,\n direction,\n requestAnimationFrame,\n cancelAnimationFrame,\n handleMotionFinish,\n ]);\n\n return { itemsVisibility };\n}\n"],"names":["useStaggerItemsVisibility","childMapping","itemDelay","itemDuration","DEFAULT_ITEM_DURATION","direction","reversed","onMotionFinish","hideMode","requestAnimationFrame","cancelAnimationFrame","useAnimationFrame","handleMotionFinish","useEventCallback","animationKey","setAnimationKey","React","useState","prevDirection","useRef","useEffect","current","prev","itemsVisibility","setItemsVisibility","initial","initialState","Object","keys","forEach","key","next","targetState","startTimeRef","frameRef","finishedRef","isFirstRender","childMappingRef","reversedRef","cancelled","startState","initialVisibility","tick","now","elapsed","childKeys","itemCount","length","result","staggerItemsVisibilityAtTime","nextVisibility","idx","totalDuration"],"mappings":"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"}
|
|
@@ -22,8 +22,6 @@ _export(exports, {
|
|
|
22
22
|
return isPresenceComponent;
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
|
-
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
|
26
|
-
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
27
25
|
function isMotionComponent(element) {
|
|
28
26
|
if (!(element === null || element === void 0 ? void 0 : element.type) || typeof element.type !== 'function') {
|
|
29
27
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/choreography/Stagger/utils/motionComponentDetection.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * Checks if a React element has all of the specified props explicitly provided.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @param props - Array of prop names to verify presence on the element\n * @returns true if all props exist on element.props, false otherwise\n *\n * @internal\n */\n\n/**\n * Checks if a React element is a motion component created by createMotionComponent.\n * Motion components are detected by the presence of the MOTION_DEFINITION symbol on the component.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the MOTION_DEFINITION symbol\n *\n * **Note:** This is a heuristic detection. Motion components may or may not support\n * specific props like `delay` or `visible` depending on their implementation.\n *\n * @internal\n */\nexport function isMotionComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the MOTION_DEFINITION symbol (internal to createMotionComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element is a presence motion component by looking for the PRESENCE_MOTION_DEFINITION symbol.\n * This symbol is added internally by createPresenceComponent and provides reliable detection.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the PRESENCE_MOTION_DEFINITION symbol\n *\n * **Presence components** (like Fade, Scale, Slide) are guaranteed to support both `visible` and `delay` props.\n *\n * @internal\n */\nexport function isPresenceComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the PRESENCE_MOTION_DEFINITION symbol (internal to createPresenceComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'PRESENCE_MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element accepts both `delay` and `exitDelay` props.\n * This uses a best-effort heuristic to detect components that support both delay props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports both delay and exitDelay props\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support both delay and exitDelay\n * - Motion components (.In/.Out variants, custom motion components) - may support both delay props\n * - Elements with explicit delay and exitDelay props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `delayMode` prop on Stagger.\n * For example, custom motion components that don't support both props should use `delayMode=\"timing\"`.\n *\n * @internal\n */\nexport function acceptsDelayProps(element: React.ReactElement): boolean {\n return isPresenceComponent(element) || isMotionComponent(element);\n}\n\n/**\n * Checks if a React element accepts a `visible` prop.\n * This uses a best-effort heuristic to detect components that support visible props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports a `visible` prop\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support visible\n * - Elements with explicit visible props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `hideMode` prop on Stagger.\n * For example, custom components that don't support visible should use `hideMode=\"visibilityStyle\"` or `hideMode=\"unmount\"`.\n *\n * @internal\n */\nexport function acceptsVisibleProp(element: React.ReactElement): boolean {\n return isPresenceComponent(element);\n}\n"],"names":["acceptsDelayProps","acceptsVisibleProp","isMotionComponent","isPresenceComponent","element","type","symbols","Object","getOwnPropertySymbols","some","sym","description"],"mappings":";;;;;;;;;;;IAgFgBA,iBAAiB;eAAjBA;;IAsBAC,kBAAkB;eAAlBA;;IA1EAC,iBAAiB;eAAjBA;;IAuBAC,mBAAmB;eAAnBA
|
|
1
|
+
{"version":3,"sources":["../src/choreography/Stagger/utils/motionComponentDetection.ts"],"sourcesContent":["import type * as React from 'react';\n\n/**\n * Checks if a React element has all of the specified props explicitly provided.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @param props - Array of prop names to verify presence on the element\n * @returns true if all props exist on element.props, false otherwise\n *\n * @internal\n */\n\n/**\n * Checks if a React element is a motion component created by createMotionComponent.\n * Motion components are detected by the presence of the MOTION_DEFINITION symbol on the component.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the MOTION_DEFINITION symbol\n *\n * **Note:** This is a heuristic detection. Motion components may or may not support\n * specific props like `delay` or `visible` depending on their implementation.\n *\n * @internal\n */\nexport function isMotionComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the MOTION_DEFINITION symbol (internal to createMotionComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element is a presence motion component by looking for the PRESENCE_MOTION_DEFINITION symbol.\n * This symbol is added internally by createPresenceComponent and provides reliable detection.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element's type contains the PRESENCE_MOTION_DEFINITION symbol\n *\n * **Presence components** (like Fade, Scale, Slide) are guaranteed to support both `visible` and `delay` props.\n *\n * @internal\n */\nexport function isPresenceComponent(element: React.ReactElement): boolean {\n if (!element?.type || typeof element.type !== 'function') {\n return false;\n }\n\n // Check if the component has the PRESENCE_MOTION_DEFINITION symbol (internal to createPresenceComponent)\n const symbols = Object.getOwnPropertySymbols(element.type);\n return symbols.some(sym => sym.description === 'PRESENCE_MOTION_DEFINITION');\n}\n\n/**\n * Checks if a React element accepts both `delay` and `exitDelay` props.\n * This uses a best-effort heuristic to detect components that support both delay props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports both delay and exitDelay props\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support both delay and exitDelay\n * - Motion components (.In/.Out variants, custom motion components) - may support both delay props\n * - Elements with explicit delay and exitDelay props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `delayMode` prop on Stagger.\n * For example, custom motion components that don't support both props should use `delayMode=\"timing\"`.\n *\n * @internal\n */\nexport function acceptsDelayProps(element: React.ReactElement): boolean {\n return isPresenceComponent(element) || isMotionComponent(element);\n}\n\n/**\n * Checks if a React element accepts a `visible` prop.\n * This uses a best-effort heuristic to detect components that support visible props.\n *\n * - Exported for testing purposes\n *\n * @param element - React element to inspect\n * @returns true when the element likely supports a `visible` prop\n *\n * **Auto-detection includes:**\n * - Presence components (Fade, Scale, etc.) - guaranteed to support visible\n * - Elements with explicit visible props already set\n *\n * **When to override:** If auto-detection is incorrect, use explicit `hideMode` prop on Stagger.\n * For example, custom components that don't support visible should use `hideMode=\"visibilityStyle\"` or `hideMode=\"unmount\"`.\n *\n * @internal\n */\nexport function acceptsVisibleProp(element: React.ReactElement): boolean {\n return isPresenceComponent(element);\n}\n"],"names":["acceptsDelayProps","acceptsVisibleProp","isMotionComponent","isPresenceComponent","element","type","symbols","Object","getOwnPropertySymbols","some","sym","description"],"mappings":";;;;;;;;;;;IAgFgBA,iBAAiB;eAAjBA;;IAsBAC,kBAAkB;eAAlBA;;IA1EAC,iBAAiB;eAAjBA;;IAuBAC,mBAAmB;eAAnBA;;;AAvBT,SAASD,kBAAkBE,OAA2B;IAC3D,IAAI,EAACA,oBAAAA,8BAAAA,QAASC,IAAI,KAAI,OAAOD,QAAQC,IAAI,KAAK,YAAY;QACxD,OAAO;IACT;IAEA,8FAA8F;IAC9F,MAAMC,UAAUC,OAAOC,qBAAqB,CAACJ,QAAQC,IAAI;IACzD,OAAOC,QAAQG,IAAI,CAACC,CAAAA,MAAOA,IAAIC,WAAW,KAAK;AACjD;AAeO,SAASR,oBAAoBC,OAA2B;IAC7D,IAAI,EAACA,oBAAAA,8BAAAA,QAASC,IAAI,KAAI,OAAOD,QAAQC,IAAI,KAAK,YAAY;QACxD,OAAO;IACT;IAEA,yGAAyG;IACzG,MAAMC,UAAUC,OAAOC,qBAAqB,CAACJ,QAAQC,IAAI;IACzD,OAAOC,QAAQG,IAAI,CAACC,CAAAA,MAAOA,IAAIC,WAAW,KAAK;AACjD;AAqBO,SAASX,kBAAkBI,OAA2B;IAC3D,OAAOD,oBAAoBC,YAAYF,kBAAkBE;AAC3D;AAoBO,SAASH,mBAAmBG,OAA2B;IAC5D,OAAOD,oBAAoBC;AAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Blur/Blur.ts"],"sourcesContent":["import { motionTokens, createPresenceComponent
|
|
1
|
+
{"version":3,"sources":["../src/components/Blur/Blur.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { blurAtom } from '../../atoms/blur-atom';\nimport type { BlurParams } from './blur-types';\n\n/**\n * Define a presence motion for blur in/out\n *\n * @param duration - Time (ms) for the enter transition (blur-in). Defaults to the `durationSlow` value (300 ms).\n * @param easing - Easing curve for the enter transition (blur-in). Defaults to the `curveDecelerateMin` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (blur-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (blur-out). Defaults to the `curveAccelerateMin` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outRadius - Blur radius for the out state (exited). Defaults to `'10px'`.\n * @param inRadius - Blur radius for the in state (entered). Defaults to `'0px'`.\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`.\n */\nconst blurPresenceFn: PresenceMotionFn<BlurParams> = ({\n duration = motionTokens.durationSlow,\n easing = motionTokens.curveDecelerateMin,\n delay = 0,\n exitDuration = duration,\n exitEasing = motionTokens.curveAccelerateMin,\n exitDelay = delay,\n outRadius = '10px',\n inRadius = '0px',\n animateOpacity = true,\n}) => {\n const enterAtoms = [blurAtom({ direction: 'enter', duration, easing, delay, outRadius, inRadius })];\n const exitAtoms = [\n blurAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outRadius,\n inRadius,\n }),\n ];\n\n // Only add fade atoms if animateOpacity is true.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies blur in/out transitions to its children. */\nexport const Blur = createPresenceComponent(blurPresenceFn);\n"],"names":["Blur","blurPresenceFn","duration","motionTokens","durationSlow","easing","curveDecelerateMin","delay","exitDuration","exitEasing","curveAccelerateMin","exitDelay","outRadius","inRadius","animateOpacity","enterAtoms","blurAtom","direction","exitAtoms","push","fadeAtom","enter","exit","createPresenceComponent"],"mappings":";;;;+BAuDaA;;;eAAAA;;;6BAtDyC;0BAC7B;0BACA;AAGzB;;;;;;;;;;;;CAYC,GACD,MAAMC,iBAA+C,CAAC,EACpDC,WAAWC,yBAAY,CAACC,YAAY,EACpCC,SAASF,yBAAY,CAACG,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeN,QAAQ,EACvBO,aAAaN,yBAAY,CAACO,kBAAkB,EAC5CC,YAAYJ,KAAK,EACjBK,YAAY,MAAM,EAClBC,WAAW,KAAK,EAChBC,iBAAiB,IAAI,EACtB;IACC,MAAMC,aAAa;QAACC,IAAAA,kBAAQ,EAAC;YAAEC,WAAW;YAASf;YAAUG;YAAQE;YAAOK;YAAWC;QAAS;KAAG;IACnG,MAAMK,YAAY;QAChBF,IAAAA,kBAAQ,EAAC;YACPC,WAAW;YACXf,UAAUM;YACVH,QAAQI;YACRF,OAAOI;YACPC;YACAC;QACF;KACD;IAED,iDAAiD;IACjD,IAAIC,gBAAgB;QAClBC,WAAWI,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAASf;YAAUG;YAAQE;QAAM;QACvEW,UAAUC,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAAQf,UAAUM;YAAcH,QAAQI;YAAYF,OAAOI;QAAU;IAC5G;IAEA,OAAO;QACLU,OAAON;QACPO,MAAMJ;IACR;AACF;AAGO,MAAMlB,OAAOuB,IAAAA,oCAAuB,EAACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Collapse/Collapse.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Collapse/Collapse.ts"],"sourcesContent":["import type { PresenceMotionFn, AtomMotion } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport type { CollapseParams } from './collapse-types';\nimport { sizeEnterAtom, sizeExitAtom, whitespaceAtom } from './collapse-atoms';\nimport { fadeAtom } from '../../atoms/fade-atom';\n\n/**\n * Define a presence motion for collapse/expand\n *\n * @param element - The element to apply the collapse motion to\n * @param duration - Time (ms) for the enter transition (expand). Defaults to the `durationNormal` value (200 ms)\n * @param easing - Easing curve for the enter transition. Defaults to the `curveEasyEaseMax` value\n * @param delay - Time (ms) to delay the entire enter transition. Defaults to 0\n * @param exitDuration - Time (ms) for the exit transition (collapse). Defaults to the `duration` param for symmetry\n * @param exitEasing - Easing curve for the exit transition. Defaults to the `easing` param for symmetry\n * @param exitDelay - Time (ms) to delay the entire exit transition. Defaults to the `delay` param for symmetry\n * @param staggerDelay - Time (ms) offset between the size and opacity animations. Defaults to 0\n * @param exitStaggerDelay - Time (ms) offset between the size and opacity animations on exit. Defaults to the `staggerDelay` param for symmetry\n * @param sizeDuration - Time (ms) for the size animation during enter. Defaults to `duration` for unified timing\n * @param opacityDuration - Time (ms) for the opacity animation during enter. Defaults to `sizeDuration` for synchronized timing\n * @param exitSizeDuration - Time (ms) for the size animation during exit. Defaults to `exitDuration` for unified timing\n * @param exitOpacityDuration - Time (ms) for the opacity animation during exit. Defaults to `exitSizeDuration` for synchronized timing\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`\n * @param orientation - The orientation of the size animation. Defaults to `'vertical'` to expand/collapse the height\n * @param outSize - Size for the out state (collapsed). Defaults to `'0px'`\n */\nconst collapsePresenceFn: PresenceMotionFn<CollapseParams> = ({\n element,\n // Primary duration controls (simple API)\n duration = motionTokens.durationNormal,\n exitDuration = duration,\n\n // Granular duration controls with smart defaults (advanced API)\n sizeDuration = duration,\n opacityDuration = sizeDuration,\n exitSizeDuration = exitDuration,\n exitOpacityDuration = exitSizeDuration,\n\n // Other timing controls\n easing = motionTokens.curveEasyEaseMax,\n delay = 0,\n exitEasing = easing,\n exitDelay = delay,\n staggerDelay = 0,\n exitStaggerDelay = staggerDelay,\n\n // Animation controls\n animateOpacity = true,\n orientation = 'vertical',\n outSize = '0px',\n}) => {\n // ----- ENTER -----\n // The enter transition is an array of up to 3 motion atoms: size, whitespace and opacity.\n // For enter: size expands first, then opacity fades in after staggerDelay\n const enterAtoms: AtomMotion[] = [\n // Apply global delay to size atom - size expansion starts first\n sizeEnterAtom({ orientation, duration: sizeDuration, easing, element, outSize, delay }),\n whitespaceAtom({ direction: 'enter', orientation, duration: sizeDuration, easing, delay }),\n ];\n // Fade in only if animateOpacity is true. Otherwise, leave opacity unaffected.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration: opacityDuration, easing, delay: delay + staggerDelay }));\n }\n\n // ----- EXIT -----\n // The exit transition is an array of up to 3 motion atoms: opacity, size and whitespace.\n // For exit: opacity fades out first, then size collapses after exitStaggerDelay\n const exitAtoms: AtomMotion[] = [];\n // Fade out only if animateOpacity is true. Otherwise, leave opacity unaffected.\n if (animateOpacity) {\n exitAtoms.push(\n fadeAtom({ direction: 'exit', duration: exitOpacityDuration, easing: exitEasing, delay: exitDelay }),\n );\n }\n\n exitAtoms.push(\n sizeExitAtom({\n orientation,\n duration: exitSizeDuration,\n easing: exitEasing,\n element,\n delay: exitDelay + exitStaggerDelay,\n outSize,\n }),\n whitespaceAtom({\n direction: 'exit',\n orientation,\n duration: exitSizeDuration,\n easing: exitEasing,\n delay: exitDelay + exitStaggerDelay, // Size/whitespace collapse after opacity finishes fading out\n }),\n );\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies collapse/expand transitions to its children. */\nexport const Collapse = createPresenceComponent(collapsePresenceFn);\n\nexport const CollapseSnappy = createPresenceComponentVariant(Collapse, {\n duration: motionTokens.durationFast,\n});\n\nexport const CollapseRelaxed = createPresenceComponentVariant(Collapse, {\n duration: motionTokens.durationSlower,\n});\n\n/** A React component that applies collapse/expand transitions with delayed fade to its children. */\nexport const CollapseDelayed = createPresenceComponentVariant(Collapse, {\n // Enter timing per motion design spec\n sizeDuration: motionTokens.durationNormal, // 200ms\n opacityDuration: motionTokens.durationSlower, // 400ms\n staggerDelay: motionTokens.durationNormal, // 200ms\n\n // Exit timing per motion design spec\n exitSizeDuration: motionTokens.durationNormal, // 200ms\n exitOpacityDuration: motionTokens.durationSlower, // 400ms\n exitStaggerDelay: motionTokens.durationSlower, // 400ms\n\n // Easing per motion design spec\n easing: motionTokens.curveEasyEase,\n exitEasing: motionTokens.curveEasyEase,\n});\n"],"names":["Collapse","CollapseDelayed","CollapseRelaxed","CollapseSnappy","collapsePresenceFn","element","duration","motionTokens","durationNormal","exitDuration","sizeDuration","opacityDuration","exitSizeDuration","exitOpacityDuration","easing","curveEasyEaseMax","delay","exitEasing","exitDelay","staggerDelay","exitStaggerDelay","animateOpacity","orientation","outSize","enterAtoms","sizeEnterAtom","whitespaceAtom","direction","push","fadeAtom","exitAtoms","sizeExitAtom","enter","exit","createPresenceComponent","createPresenceComponentVariant","durationFast","durationSlower","curveEasyEase"],"mappings":";;;;;;;;;;;IAoGaA,QAAQ;eAARA;;IAWAC,eAAe;eAAfA;;IALAC,eAAe;eAAfA;;IAJAC,cAAc;eAAdA;;;6BArGyE;+BAE1B;0BACnC;AAEzB;;;;;;;;;;;;;;;;;;;CAmBC,GACD,MAAMC,qBAAuD,CAAC,EAC5DC,OAAO,EACP,yCAAyC;AACzCC,WAAWC,yBAAY,CAACC,cAAc,EACtCC,eAAeH,QAAQ,EAEvB,gEAAgE;AAChEI,eAAeJ,QAAQ,EACvBK,kBAAkBD,YAAY,EAC9BE,mBAAmBH,YAAY,EAC/BI,sBAAsBD,gBAAgB,EAEtC,wBAAwB;AACxBE,SAASP,yBAAY,CAACQ,gBAAgB,EACtCC,QAAQ,CAAC,EACTC,aAAaH,MAAM,EACnBI,YAAYF,KAAK,EACjBG,eAAe,CAAC,EAChBC,mBAAmBD,YAAY,EAE/B,qBAAqB;AACrBE,iBAAiB,IAAI,EACrBC,cAAc,UAAU,EACxBC,UAAU,KAAK,EAChB;IACC,oBAAoB;IACpB,0FAA0F;IAC1F,0EAA0E;IAC1E,MAAMC,aAA2B;QAC/B,gEAAgE;QAChEC,IAAAA,4BAAa,EAAC;YAAEH;YAAahB,UAAUI;YAAcI;YAAQT;YAASkB;YAASP;QAAM;QACrFU,IAAAA,6BAAc,EAAC;YAAEC,WAAW;YAASL;YAAahB,UAAUI;YAAcI;YAAQE;QAAM;KACzF;IACD,+EAA+E;IAC/E,IAAIK,gBAAgB;QAClBG,WAAWI,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEF,WAAW;YAASrB,UAAUK;YAAiBG;YAAQE,OAAOA,QAAQG;QAAa;IAChH;IAEA,mBAAmB;IACnB,yFAAyF;IACzF,gFAAgF;IAChF,MAAMW,YAA0B,EAAE;IAClC,gFAAgF;IAChF,IAAIT,gBAAgB;QAClBS,UAAUF,IAAI,CACZC,IAAAA,kBAAQ,EAAC;YAAEF,WAAW;YAAQrB,UAAUO;YAAqBC,QAAQG;YAAYD,OAAOE;QAAU;IAEtG;IAEAY,UAAUF,IAAI,CACZG,IAAAA,2BAAY,EAAC;QACXT;QACAhB,UAAUM;QACVE,QAAQG;QACRZ;QACAW,OAAOE,YAAYE;QACnBG;IACF,IACAG,IAAAA,6BAAc,EAAC;QACbC,WAAW;QACXL;QACAhB,UAAUM;QACVE,QAAQG;QACRD,OAAOE,YAAYE;IACrB;IAGF,OAAO;QACLY,OAAOR;QACPS,MAAMH;IACR;AACF;AAGO,MAAM9B,WAAWkC,IAAAA,oCAAuB,EAAC9B;AAEzC,MAAMD,iBAAiBgC,IAAAA,2CAA8B,EAACnC,UAAU;IACrEM,UAAUC,yBAAY,CAAC6B,YAAY;AACrC;AAEO,MAAMlC,kBAAkBiC,IAAAA,2CAA8B,EAACnC,UAAU;IACtEM,UAAUC,yBAAY,CAAC8B,cAAc;AACvC;AAGO,MAAMpC,kBAAkBkC,IAAAA,2CAA8B,EAACnC,UAAU;IACtE,sCAAsC;IACtCU,cAAcH,yBAAY,CAACC,cAAc;IACzCG,iBAAiBJ,yBAAY,CAAC8B,cAAc;IAC5ClB,cAAcZ,yBAAY,CAACC,cAAc;IAEzC,qCAAqC;IACrCI,kBAAkBL,yBAAY,CAACC,cAAc;IAC7CK,qBAAqBN,yBAAY,CAAC8B,cAAc;IAChDjB,kBAAkBb,yBAAY,CAAC8B,cAAc;IAE7C,gCAAgC;IAChCvB,QAAQP,yBAAY,CAAC+B,aAAa;IAClCrB,YAAYV,yBAAY,CAAC+B,aAAa;AACxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Collapse/collapse-atoms.ts"],"sourcesContent":["import { AtomMotion, PresenceDirection } from '@fluentui/react-motion';\nimport { CollapseOrientation } from './collapse-types';\n\n// ----- SIZE -----\n\nconst sizeValuesForOrientation = (orientation: CollapseOrientation, element: Element) => {\n const sizeName = orientation === 'horizontal' ? 'maxWidth' : 'maxHeight';\n const overflowName = orientation === 'horizontal' ? 'overflowX' : 'overflowY';\n const measuredSize = orientation === 'horizontal' ? element.scrollWidth : element.scrollHeight;\n const toSize = `${measuredSize}px`;\n return { sizeName, overflowName, toSize };\n};\n\ninterface SizeEnterAtomParams {\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n element: HTMLElement;\n /** Size for the out state (collapsed). Defaults to '0'. */\n outSize?: string;\n delay?: number;\n}\n\nexport const sizeEnterAtom = ({\n orientation,\n duration,\n easing,\n element,\n outSize = '0',\n delay = 0,\n}: SizeEnterAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n { [sizeName]: toSize, offset: 0.9999, [overflowName]: 'hidden' },\n { [sizeName]: 'unset', [overflowName]: 'unset' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\ninterface SizeExitAtomParams extends SizeEnterAtomParams {\n delay?: number;\n}\n\nexport const sizeExitAtom = ({\n orientation,\n duration,\n easing,\n element,\n delay = 0,\n outSize = '0',\n}: SizeExitAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: toSize, [overflowName]: 'hidden' },\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\n// ----- WHITESPACE -----\n\n// Whitespace animation includes padding and margin.\nconst whitespaceValuesForOrientation = (orientation: CollapseOrientation) => {\n // horizontal whitespace collapse\n if (orientation === 'horizontal') {\n return {\n paddingStart: 'paddingInlineStart',\n paddingEnd: 'paddingInlineEnd',\n marginStart: 'marginInlineStart',\n marginEnd: 'marginInlineEnd',\n };\n }\n // vertical whitespace collapse\n return {\n paddingStart: 'paddingBlockStart',\n paddingEnd: 'paddingBlockEnd',\n marginStart: 'marginBlockStart',\n marginEnd: 'marginBlockEnd',\n };\n};\n\ninterface WhitespaceAtomParams {\n direction: PresenceDirection;\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n delay?: number;\n}\n\n/**\n * A collapse animates an element's height to zero,\n but the zero height does not eliminate padding or margin in the box model.\n So here we generate keyframes to animate those whitespace properties to zero.\n */\nexport const whitespaceAtom = ({\n direction,\n orientation,\n duration,\n easing,\n delay = 0,\n}: WhitespaceAtomParams): AtomMotion => {\n const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation);\n // The keyframe with zero whitespace is at the start for enter and at the end for exit.\n const offset = direction === 'enter' ? 0 : 1;\n const keyframes = [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset }];\n\n return {\n keyframes,\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n"],"names":["sizeEnterAtom","sizeExitAtom","whitespaceAtom","sizeValuesForOrientation","orientation","element","sizeName","overflowName","measuredSize","scrollWidth","scrollHeight","toSize","duration","easing","outSize","delay","keyframes","offset","fill","whitespaceValuesForOrientation","paddingStart","paddingEnd","marginStart","marginEnd","direction"],"mappings":";;;;;;;;;;;IAuBaA,aAAa;eAAbA;;IA2BAC,YAAY;eAAZA;;IAyDAC,cAAc;eAAdA;;;AAxGb,mBAAmB;AAEnB,MAAMC,2BAA2B,CAACC,aAAkCC;IAClE,MAAMC,WAAWF,gBAAgB,eAAe,aAAa;IAC7D,MAAMG,eAAeH,gBAAgB,eAAe,cAAc;IAClE,MAAMI,eAAeJ,gBAAgB,eAAeC,QAAQI,WAAW,GAAGJ,QAAQK,YAAY;IAC9F,MAAMC,SAAS,GAAGH,aAAa,EAAE,CAAC;IAClC,OAAO;QAAEF;QAAUC;QAAcI;IAAO;AAC1C;AAYO,MAAMX,gBAAgB,CAAC,EAC5BI,WAAW,EACXQ,QAAQ,EACRC,MAAM,EACNR,OAAO,EACPS,UAAU,GAAG,EACbC,QAAQ,CAAC,EACW;IACpB,MAAM,EAAET,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLW,WAAW;YACT;gBAAE,CAACV,SAAS,EAAEQ;gBAAS,CAACP,aAAa,EAAE;YAAS;YAChD;gBAAE,CAACD,SAAS,EAAEK;gBAAQM,QAAQ;gBAAQ,CAACV,aAAa,EAAE;YAAS;YAC/D;gBAAE,CAACD,SAAS,EAAE;gBAAS,CAACC,aAAa,EAAE;YAAQ;SAChD;QACDK;QACAC;QACAE;QACAG,MAAM;IACR;AACF;AAMO,MAAMjB,eAAe,CAAC,EAC3BG,WAAW,EACXQ,QAAQ,EACRC,MAAM,EACNR,OAAO,EACPU,QAAQ,CAAC,EACTD,UAAU,GAAG,EACM;IACnB,MAAM,EAAER,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLW,WAAW;YACT;gBAAE,CAACV,SAAS,EAAEK;gBAAQ,CAACJ,aAAa,EAAE;YAAS;YAC/C;gBAAE,CAACD,SAAS,EAAEQ;gBAAS,CAACP,aAAa,EAAE;YAAS;SACjD;QACDK;QACAC;QACAE;QACAG,MAAM;IACR;AACF;AAEA,yBAAyB;AAEzB,oDAAoD;AACpD,MAAMC,iCAAiC,CAACf;IACtC,iCAAiC;IACjC,IAAIA,gBAAgB,cAAc;QAChC,OAAO;YACLgB,cAAc;YACdC,YAAY;YACZC,aAAa;YACbC,WAAW;QACb;IACF;IACA,+BAA+B;IAC/B,OAAO;QACLH,cAAc;QACdC,YAAY;QACZC,aAAa;QACbC,WAAW;IACb;AACF;AAeO,MAAMrB,iBAAiB,CAAC,EAC7BsB,SAAS,EACTpB,WAAW,EACXQ,QAAQ,EACRC,MAAM,EACNE,QAAQ,CAAC,EACY;IACrB,MAAM,EAAEK,YAAY,EAAEC,UAAU,EAAEC,WAAW,EAAEC,SAAS,EAAE,GAAGJ,+BAA+Bf;IAC5F,uFAAuF;IACvF,MAAMa,SAASO,cAAc,UAAU,IAAI;IAC3C,MAAMR,YAAY;QAAC;YAAE,CAACI,aAAa,EAAE;YAAK,CAACC,WAAW,EAAE;YAAK,CAACC,YAAY,EAAE;YAAK,CAACC,UAAU,EAAE;YAAKN;QAAO;KAAE;IAE5G,OAAO;QACLD;QACAJ;QACAC;QACAE;QACAG,MAAM;IACR;AACF"}
|
|
1
|
+
{"version":3,"sources":["../src/components/Collapse/collapse-atoms.ts"],"sourcesContent":["import type { AtomMotion, PresenceDirection } from '@fluentui/react-motion';\nimport type { CollapseOrientation } from './collapse-types';\n\n// ----- SIZE -----\n\nconst sizeValuesForOrientation = (orientation: CollapseOrientation, element: Element) => {\n const sizeName = orientation === 'horizontal' ? 'maxWidth' : 'maxHeight';\n const overflowName = orientation === 'horizontal' ? 'overflowX' : 'overflowY';\n const measuredSize = orientation === 'horizontal' ? element.scrollWidth : element.scrollHeight;\n const toSize = `${measuredSize}px`;\n return { sizeName, overflowName, toSize };\n};\n\ninterface SizeEnterAtomParams {\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n element: HTMLElement;\n /** Size for the out state (collapsed). Defaults to '0'. */\n outSize?: string;\n delay?: number;\n}\n\nexport const sizeEnterAtom = ({\n orientation,\n duration,\n easing,\n element,\n outSize = '0',\n delay = 0,\n}: SizeEnterAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n { [sizeName]: toSize, offset: 0.9999, [overflowName]: 'hidden' },\n { [sizeName]: 'unset', [overflowName]: 'unset' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\ninterface SizeExitAtomParams extends SizeEnterAtomParams {\n delay?: number;\n}\n\nexport const sizeExitAtom = ({\n orientation,\n duration,\n easing,\n element,\n delay = 0,\n outSize = '0',\n}: SizeExitAtomParams): AtomMotion => {\n const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);\n\n return {\n keyframes: [\n { [sizeName]: toSize, [overflowName]: 'hidden' },\n { [sizeName]: outSize, [overflowName]: 'hidden' },\n ],\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n\n// ----- WHITESPACE -----\n\n// Whitespace animation includes padding and margin.\nconst whitespaceValuesForOrientation = (orientation: CollapseOrientation) => {\n // horizontal whitespace collapse\n if (orientation === 'horizontal') {\n return {\n paddingStart: 'paddingInlineStart',\n paddingEnd: 'paddingInlineEnd',\n marginStart: 'marginInlineStart',\n marginEnd: 'marginInlineEnd',\n };\n }\n // vertical whitespace collapse\n return {\n paddingStart: 'paddingBlockStart',\n paddingEnd: 'paddingBlockEnd',\n marginStart: 'marginBlockStart',\n marginEnd: 'marginBlockEnd',\n };\n};\n\ninterface WhitespaceAtomParams {\n direction: PresenceDirection;\n orientation: CollapseOrientation;\n duration: number;\n easing: string;\n delay?: number;\n}\n\n/**\n * A collapse animates an element's height to zero,\n but the zero height does not eliminate padding or margin in the box model.\n So here we generate keyframes to animate those whitespace properties to zero.\n */\nexport const whitespaceAtom = ({\n direction,\n orientation,\n duration,\n easing,\n delay = 0,\n}: WhitespaceAtomParams): AtomMotion => {\n const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation);\n // The keyframe with zero whitespace is at the start for enter and at the end for exit.\n const offset = direction === 'enter' ? 0 : 1;\n const keyframes = [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset }];\n\n return {\n keyframes,\n duration,\n easing,\n delay,\n fill: 'both',\n };\n};\n"],"names":["sizeEnterAtom","sizeExitAtom","whitespaceAtom","sizeValuesForOrientation","orientation","element","sizeName","overflowName","measuredSize","scrollWidth","scrollHeight","toSize","duration","easing","outSize","delay","keyframes","offset","fill","whitespaceValuesForOrientation","paddingStart","paddingEnd","marginStart","marginEnd","direction"],"mappings":";;;;;;;;;;;IAuBaA,aAAa;eAAbA;;IA2BAC,YAAY;eAAZA;;IAyDAC,cAAc;eAAdA;;;AAxGb,mBAAmB;AAEnB,MAAMC,2BAA2B,CAACC,aAAkCC;IAClE,MAAMC,WAAWF,gBAAgB,eAAe,aAAa;IAC7D,MAAMG,eAAeH,gBAAgB,eAAe,cAAc;IAClE,MAAMI,eAAeJ,gBAAgB,eAAeC,QAAQI,WAAW,GAAGJ,QAAQK,YAAY;IAC9F,MAAMC,SAAS,GAAGH,aAAa,EAAE,CAAC;IAClC,OAAO;QAAEF;QAAUC;QAAcI;IAAO;AAC1C;AAYO,MAAMX,gBAAgB,CAAC,EAC5BI,WAAW,EACXQ,QAAQ,EACRC,MAAM,EACNR,OAAO,EACPS,UAAU,GAAG,EACbC,QAAQ,CAAC,EACW;IACpB,MAAM,EAAET,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLW,WAAW;YACT;gBAAE,CAACV,SAAS,EAAEQ;gBAAS,CAACP,aAAa,EAAE;YAAS;YAChD;gBAAE,CAACD,SAAS,EAAEK;gBAAQM,QAAQ;gBAAQ,CAACV,aAAa,EAAE;YAAS;YAC/D;gBAAE,CAACD,SAAS,EAAE;gBAAS,CAACC,aAAa,EAAE;YAAQ;SAChD;QACDK;QACAC;QACAE;QACAG,MAAM;IACR;AACF;AAMO,MAAMjB,eAAe,CAAC,EAC3BG,WAAW,EACXQ,QAAQ,EACRC,MAAM,EACNR,OAAO,EACPU,QAAQ,CAAC,EACTD,UAAU,GAAG,EACM;IACnB,MAAM,EAAER,QAAQ,EAAEC,YAAY,EAAEI,MAAM,EAAE,GAAGR,yBAAyBC,aAAaC;IAEjF,OAAO;QACLW,WAAW;YACT;gBAAE,CAACV,SAAS,EAAEK;gBAAQ,CAACJ,aAAa,EAAE;YAAS;YAC/C;gBAAE,CAACD,SAAS,EAAEQ;gBAAS,CAACP,aAAa,EAAE;YAAS;SACjD;QACDK;QACAC;QACAE;QACAG,MAAM;IACR;AACF;AAEA,yBAAyB;AAEzB,oDAAoD;AACpD,MAAMC,iCAAiC,CAACf;IACtC,iCAAiC;IACjC,IAAIA,gBAAgB,cAAc;QAChC,OAAO;YACLgB,cAAc;YACdC,YAAY;YACZC,aAAa;YACbC,WAAW;QACb;IACF;IACA,+BAA+B;IAC/B,OAAO;QACLH,cAAc;QACdC,YAAY;QACZC,aAAa;QACbC,WAAW;IACb;AACF;AAeO,MAAMrB,iBAAiB,CAAC,EAC7BsB,SAAS,EACTpB,WAAW,EACXQ,QAAQ,EACRC,MAAM,EACNE,QAAQ,CAAC,EACY;IACrB,MAAM,EAAEK,YAAY,EAAEC,UAAU,EAAEC,WAAW,EAAEC,SAAS,EAAE,GAAGJ,+BAA+Bf;IAC5F,uFAAuF;IACvF,MAAMa,SAASO,cAAc,UAAU,IAAI;IAC3C,MAAMR,YAAY;QAAC;YAAE,CAACI,aAAa,EAAE;YAAK,CAACC,WAAW,EAAE;YAAK,CAACC,YAAY,EAAE;YAAK,CAACC,UAAU,EAAE;YAAKN;QAAO;KAAE;IAE5G,OAAO;QACLD;QACAJ;QACAC;QACAE;QACAG,MAAM;IACR;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Fade/Fade.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Fade/Fade.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport type { FadeParams } from './fade-types';\n\n/**\n * Define a presence motion for fade in/out\n *\n * @param duration - Time (ms) for the enter transition (fade-in). Defaults to the `durationNormal` value (200 ms).\n * @param easing - Easing curve for the enter transition (fade-in). Defaults to the `curveEasyEase` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (fade-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (fade-out). Defaults to the `easing` param for symmetry.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outOpacity - Opacity for the out state (exited). Defaults to 0.\n * @param inOpacity - Opacity for the in state (entered). Defaults to 1.\n */\nexport const fadePresenceFn: PresenceMotionFn<FadeParams> = ({\n duration = motionTokens.durationNormal,\n easing = motionTokens.curveEasyEase,\n delay = 0,\n exitDuration = duration,\n exitEasing = easing,\n exitDelay = delay,\n outOpacity = 0,\n inOpacity = 1,\n}) => {\n return {\n enter: fadeAtom({ direction: 'enter', duration, easing, delay, outOpacity, inOpacity }),\n exit: fadeAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outOpacity,\n inOpacity,\n }),\n };\n};\n\n/** A React component that applies fade in/out transitions to its children. */\nexport const Fade = createPresenceComponent(fadePresenceFn);\n\nexport const FadeSnappy = createPresenceComponentVariant(Fade, { duration: motionTokens.durationFast });\n\nexport const FadeRelaxed = createPresenceComponentVariant(Fade, { duration: motionTokens.durationGentle });\n"],"names":["Fade","FadeRelaxed","FadeSnappy","fadePresenceFn","duration","motionTokens","durationNormal","easing","curveEasyEase","delay","exitDuration","exitEasing","exitDelay","outOpacity","inOpacity","enter","fadeAtom","direction","exit","createPresenceComponent","createPresenceComponentVariant","durationFast","durationGentle"],"mappings":";;;;;;;;;;;IAyCaA,IAAI;eAAJA;;IAIAC,WAAW;eAAXA;;IAFAC,UAAU;eAAVA;;IA1BAC,cAAc;eAAdA;;;6BAhByE;0BAC7D;AAelB,MAAMA,iBAA+C,CAAC,EAC3DC,WAAWC,yBAAY,CAACC,cAAc,EACtCC,SAASF,yBAAY,CAACG,aAAa,EACnCC,QAAQ,CAAC,EACTC,eAAeN,QAAQ,EACvBO,aAAaJ,MAAM,EACnBK,YAAYH,KAAK,EACjBI,aAAa,CAAC,EACdC,YAAY,CAAC,EACd;IACC,OAAO;QACLC,OAAOC,IAAAA,kBAAQ,EAAC;YAAEC,WAAW;YAASb;YAAUG;YAAQE;YAAOI;YAAYC;QAAU;QACrFI,MAAMF,IAAAA,kBAAQ,EAAC;YACbC,WAAW;YACXb,UAAUM;YACVH,QAAQI;YACRF,OAAOG;YACPC;YACAC;QACF;IACF;AACF;AAGO,MAAMd,OAAOmB,IAAAA,oCAAuB,EAAChB;AAErC,MAAMD,aAAakB,IAAAA,2CAA8B,EAACpB,MAAM;IAAEI,UAAUC,yBAAY,CAACgB,YAAY;AAAC;AAE9F,MAAMpB,cAAcmB,IAAAA,2CAA8B,EAACpB,MAAM;IAAEI,UAAUC,yBAAY,CAACiB,cAAc;AAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Rotate/Rotate.ts"],"sourcesContent":["import { AtomMotion, createPresenceComponent, motionTokens
|
|
1
|
+
{"version":3,"sources":["../src/components/Rotate/Rotate.ts"],"sourcesContent":["import type { AtomMotion, PresenceMotionFn } from '@fluentui/react-motion';\nimport { createPresenceComponent, motionTokens } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { rotateAtom } from '../../atoms/rotate-atom';\nimport type { RotateParams } from './rotate-types';\n\n/**\n * Define a presence motion for rotate in/out\n *\n * @param duration - Time (ms) for the enter transition (rotate-in). Defaults to the `durationGentle` value.\n * @param easing - Easing curve for the enter transition (rotate-in). Defaults to the `curveDecelerateMax` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (rotate-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (rotate-out). Defaults to the `curveAccelerateMax` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param axis - The axis of rotation: 'x', 'y', or 'z'. Defaults to 'z'.\n * @param outAngle - Rotation angle for the out state (exited) in degrees. Defaults to -90.\n * @param inAngle - Rotation angle for the in state (entered) in degrees. Defaults to 0.\n * @param animateOpacity - Whether to animate the opacity during the rotation. Defaults to `true`.\n */\nconst rotatePresenceFn: PresenceMotionFn<RotateParams> = ({\n duration = motionTokens.durationGentle,\n easing = motionTokens.curveDecelerateMax,\n delay = 0,\n exitDuration = duration,\n exitEasing = motionTokens.curveAccelerateMax,\n exitDelay = delay,\n axis = 'z',\n outAngle = -90,\n inAngle = 0,\n animateOpacity = true,\n}: RotateParams) => {\n const enterAtoms: AtomMotion[] = [\n rotateAtom({\n direction: 'enter',\n duration,\n easing,\n delay,\n axis,\n outAngle,\n inAngle,\n }),\n ];\n\n const exitAtoms: AtomMotion[] = [\n rotateAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n axis,\n outAngle,\n inAngle,\n }),\n ];\n\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n// Create a presence motion component to rotate an element around a single axis (x, y, or z).\nexport const Rotate = createPresenceComponent(rotatePresenceFn);\n"],"names":["Rotate","rotatePresenceFn","duration","motionTokens","durationGentle","easing","curveDecelerateMax","delay","exitDuration","exitEasing","curveAccelerateMax","exitDelay","axis","outAngle","inAngle","animateOpacity","enterAtoms","rotateAtom","direction","exitAtoms","push","fadeAtom","enter","exit","createPresenceComponent"],"mappings":";;;;+BAoEaA;;;eAAAA;;;6BAnEyC;0BAC7B;4BACE;AAG3B;;;;;;;;;;;;;CAaC,GACD,MAAMC,mBAAmD,CAAC,EACxDC,WAAWC,yBAAY,CAACC,cAAc,EACtCC,SAASF,yBAAY,CAACG,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeN,QAAQ,EACvBO,aAAaN,yBAAY,CAACO,kBAAkB,EAC5CC,YAAYJ,KAAK,EACjBK,OAAO,GAAG,EACVC,WAAW,CAAC,EAAE,EACdC,UAAU,CAAC,EACXC,iBAAiB,IAAI,EACR;IACb,MAAMC,aAA2B;QAC/BC,IAAAA,sBAAU,EAAC;YACTC,WAAW;YACXhB;YACAG;YACAE;YACAK;YACAC;YACAC;QACF;KACD;IAED,MAAMK,YAA0B;QAC9BF,IAAAA,sBAAU,EAAC;YACTC,WAAW;YACXhB,UAAUM;YACVH,QAAQI;YACRF,OAAOI;YACPC;YACAC;YACAC;QACF;KACD;IAED,IAAIC,gBAAgB;QAClBC,WAAWI,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAAShB;YAAUG;YAAQE;QAAM;QACvEY,UAAUC,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAAQhB,UAAUM;YAAcH,QAAQI;YAAYF,OAAOI;QAAU;IAC5G;IAEA,OAAO;QACLW,OAAON;QACPO,MAAMJ;IACR;AACF;AAGO,MAAMnB,SAASwB,IAAAA,oCAAuB,EAACvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Scale/Scale.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Scale/Scale.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { scaleAtom } from '../../atoms/scale-atom';\nimport type { ScaleParams } from './scale-types';\n\n/**\n * Define a presence motion for scale in/out\n *\n * @param duration - Time (ms) for the enter transition (scale-in). Defaults to the `durationGentle` value (250 ms).\n * @param easing - Easing curve for the enter transition (scale-in). Defaults to the `curveDecelerateMax` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (scale-out). Defaults to the `durationNormal` value (200 ms).\n * @param exitEasing - Easing curve for the exit transition (scale-out). Defaults to the `curveAccelerateMax` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outScale - Scale for the out state (exited). Defaults to `0.9`.\n * @param inScale - Scale for the in state (entered). Defaults to `1`.\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`.\n */\nconst scalePresenceFn: PresenceMotionFn<ScaleParams> = ({\n duration = motionTokens.durationGentle,\n easing = motionTokens.curveDecelerateMax,\n delay = 0,\n exitDuration = motionTokens.durationNormal,\n exitEasing = motionTokens.curveAccelerateMax,\n exitDelay = delay,\n outScale = 0.9,\n inScale = 1,\n animateOpacity = true,\n}) => {\n const enterAtoms = [scaleAtom({ direction: 'enter', duration, easing, delay, outScale, inScale })];\n const exitAtoms = [\n scaleAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outScale,\n inScale,\n }),\n ];\n\n // Only add fade atoms if animateOpacity is true.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies scale in/out transitions to its children. */\nexport const Scale = createPresenceComponent(scalePresenceFn);\n\nexport const ScaleSnappy = createPresenceComponentVariant(Scale, {\n duration: motionTokens.durationNormal,\n exitDuration: motionTokens.durationFast,\n});\n\nexport const ScaleRelaxed = createPresenceComponentVariant(Scale, {\n duration: motionTokens.durationSlow,\n exitDuration: motionTokens.durationGentle,\n});\n"],"names":["Scale","ScaleRelaxed","ScaleSnappy","scalePresenceFn","duration","motionTokens","durationGentle","easing","curveDecelerateMax","delay","exitDuration","durationNormal","exitEasing","curveAccelerateMax","exitDelay","outScale","inScale","animateOpacity","enterAtoms","scaleAtom","direction","exitAtoms","push","fadeAtom","enter","exit","createPresenceComponent","createPresenceComponentVariant","durationFast","durationSlow"],"mappings":";;;;;;;;;;;IAuDaA,KAAK;eAALA;;IAOAC,YAAY;eAAZA;;IALAC,WAAW;eAAXA;;;6BAxDyE;0BAC7D;2BACC;AAG1B;;;;;;;;;;;;CAYC,GACD,MAAMC,kBAAiD,CAAC,EACtDC,WAAWC,yBAAY,CAACC,cAAc,EACtCC,SAASF,yBAAY,CAACG,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeL,yBAAY,CAACM,cAAc,EAC1CC,aAAaP,yBAAY,CAACQ,kBAAkB,EAC5CC,YAAYL,KAAK,EACjBM,WAAW,GAAG,EACdC,UAAU,CAAC,EACXC,iBAAiB,IAAI,EACtB;IACC,MAAMC,aAAa;QAACC,IAAAA,oBAAS,EAAC;YAAEC,WAAW;YAAShB;YAAUG;YAAQE;YAAOM;YAAUC;QAAQ;KAAG;IAClG,MAAMK,YAAY;QAChBF,IAAAA,oBAAS,EAAC;YACRC,WAAW;YACXhB,UAAUM;YACVH,QAAQK;YACRH,OAAOK;YACPC;YACAC;QACF;KACD;IAED,iDAAiD;IACjD,IAAIC,gBAAgB;QAClBC,WAAWI,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAAShB;YAAUG;YAAQE;QAAM;QACvEY,UAAUC,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAAQhB,UAAUM;YAAcH,QAAQK;YAAYH,OAAOK;QAAU;IAC5G;IAEA,OAAO;QACLU,OAAON;QACPO,MAAMJ;IACR;AACF;AAGO,MAAMrB,QAAQ0B,IAAAA,oCAAuB,EAACvB;AAEtC,MAAMD,cAAcyB,IAAAA,2CAA8B,EAAC3B,OAAO;IAC/DI,UAAUC,yBAAY,CAACM,cAAc;IACrCD,cAAcL,yBAAY,CAACuB,YAAY;AACzC;AAEO,MAAM3B,eAAe0B,IAAAA,2CAA8B,EAAC3B,OAAO;IAChEI,UAAUC,yBAAY,CAACwB,YAAY;IACnCnB,cAAcL,yBAAY,CAACC,cAAc;AAC3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Slide/Slide.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/components/Slide/Slide.ts"],"sourcesContent":["import type { PresenceMotionFn } from '@fluentui/react-motion';\nimport { motionTokens, createPresenceComponent, createPresenceComponentVariant } from '@fluentui/react-motion';\nimport { fadeAtom } from '../../atoms/fade-atom';\nimport { slideAtom } from '../../atoms/slide-atom';\nimport type { SlideParams } from './slide-types';\n\n/**\n * Define a presence motion for slide in/out\n *\n * @param duration - Time (ms) for the enter transition (slide-in). Defaults to the `durationNormal` value (200 ms).\n * @param easing - Easing curve for the enter transition (slide-in). Defaults to the `curveDecelerateMid` value.\n * @param delay - Time (ms) to delay the enter transition. Defaults to 0.\n * @param exitDuration - Time (ms) for the exit transition (slide-out). Defaults to the `duration` param for symmetry.\n * @param exitEasing - Easing curve for the exit transition (slide-out). Defaults to the `curveAccelerateMid` value.\n * @param exitDelay - Time (ms) to delay the exit transition. Defaults to the `delay` param for symmetry.\n * @param outX - X translate for the out state (exited). Defaults to `'0px'`.\n * @param outY - Y translate for the out state (exited). Defaults to `'0px'`.\n * @param inX - X translate for the in state (entered). Defaults to `'0px'`.\n * @param inY - Y translate for the in state (entered). Defaults to `'0px'`.\n * @param animateOpacity - Whether to animate the opacity. Defaults to `true`.\n */\nconst slidePresenceFn: PresenceMotionFn<SlideParams> = ({\n duration = motionTokens.durationNormal,\n easing = motionTokens.curveDecelerateMid,\n delay = 0,\n exitDuration = duration,\n exitEasing = motionTokens.curveAccelerateMid,\n exitDelay = delay,\n outX = '0px',\n outY = '0px',\n inX = '0px',\n inY = '0px',\n animateOpacity = true,\n}: SlideParams) => {\n const enterAtoms = [slideAtom({ direction: 'enter', duration, easing, delay, outX, outY, inX, inY })];\n const exitAtoms = [\n slideAtom({\n direction: 'exit',\n duration: exitDuration,\n easing: exitEasing,\n delay: exitDelay,\n outX,\n outY,\n inX,\n inY,\n }),\n ];\n\n // Only add fade atoms if animateOpacity is true.\n if (animateOpacity) {\n enterAtoms.push(fadeAtom({ direction: 'enter', duration, easing, delay }));\n exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing, delay: exitDelay }));\n }\n\n return {\n enter: enterAtoms,\n exit: exitAtoms,\n };\n};\n\n/** A React component that applies slide in/out transitions to its children. */\nexport const Slide = createPresenceComponent(slidePresenceFn);\n\nexport const SlideSnappy = createPresenceComponentVariant(Slide, {\n easing: motionTokens.curveDecelerateMax,\n exitEasing: motionTokens.curveAccelerateMax,\n});\n\nexport const SlideRelaxed = createPresenceComponentVariant(Slide, {\n duration: motionTokens.durationGentle,\n});\n"],"names":["Slide","SlideRelaxed","SlideSnappy","slidePresenceFn","duration","motionTokens","durationNormal","easing","curveDecelerateMid","delay","exitDuration","exitEasing","curveAccelerateMid","exitDelay","outX","outY","inX","inY","animateOpacity","enterAtoms","slideAtom","direction","exitAtoms","push","fadeAtom","enter","exit","createPresenceComponent","createPresenceComponentVariant","curveDecelerateMax","curveAccelerateMax","durationGentle"],"mappings":";;;;;;;;;;;IA6DaA,KAAK;eAALA;;IAOAC,YAAY;eAAZA;;IALAC,WAAW;eAAXA;;;6BA9DyE;0BAC7D;2BACC;AAG1B;;;;;;;;;;;;;;CAcC,GACD,MAAMC,kBAAiD,CAAC,EACtDC,WAAWC,yBAAY,CAACC,cAAc,EACtCC,SAASF,yBAAY,CAACG,kBAAkB,EACxCC,QAAQ,CAAC,EACTC,eAAeN,QAAQ,EACvBO,aAAaN,yBAAY,CAACO,kBAAkB,EAC5CC,YAAYJ,KAAK,EACjBK,OAAO,KAAK,EACZC,OAAO,KAAK,EACZC,MAAM,KAAK,EACXC,MAAM,KAAK,EACXC,iBAAiB,IAAI,EACT;IACZ,MAAMC,aAAa;QAACC,IAAAA,oBAAS,EAAC;YAAEC,WAAW;YAASjB;YAAUG;YAAQE;YAAOK;YAAMC;YAAMC;YAAKC;QAAI;KAAG;IACrG,MAAMK,YAAY;QAChBF,IAAAA,oBAAS,EAAC;YACRC,WAAW;YACXjB,UAAUM;YACVH,QAAQI;YACRF,OAAOI;YACPC;YACAC;YACAC;YACAC;QACF;KACD;IAED,iDAAiD;IACjD,IAAIC,gBAAgB;QAClBC,WAAWI,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAASjB;YAAUG;YAAQE;QAAM;QACvEa,UAAUC,IAAI,CAACC,IAAAA,kBAAQ,EAAC;YAAEH,WAAW;YAAQjB,UAAUM;YAAcH,QAAQI;YAAYF,OAAOI;QAAU;IAC5G;IAEA,OAAO;QACLY,OAAON;QACPO,MAAMJ;IACR;AACF;AAGO,MAAMtB,QAAQ2B,IAAAA,oCAAuB,EAACxB;AAEtC,MAAMD,cAAc0B,IAAAA,2CAA8B,EAAC5B,OAAO;IAC/DO,QAAQF,yBAAY,CAACwB,kBAAkB;IACvClB,YAAYN,yBAAY,CAACyB,kBAAkB;AAC7C;AAEO,MAAM7B,eAAe2B,IAAAA,2CAA8B,EAAC5B,OAAO;IAChEI,UAAUC,yBAAY,CAAC0B,cAAc;AACvC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui/react-motion-components-preview",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.5",
|
|
4
4
|
"description": "A preview package for Fluent UI motion components, providing a collection of components",
|
|
5
5
|
"main": "lib-commonjs/index.js",
|
|
6
6
|
"module": "lib/index.js",
|