@aphrody/m3-motion 3.3.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +243 -243
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,243 +1,243 @@
|
|
|
1
|
-
# @aphrody/m3-motion
|
|
2
|
-
|
|
3
|
-
High-fidelity React animation components for Material Design 3 (M3) motion specifications, powered by [Motion](https://motion.dev/) (formerly Framer Motion).
|
|
4
|
-
|
|
5
|
-
This package implements the core Material Design 3 motion patterns—including **Container Transform**, **Shared Axis**, **Fade Through**, **Collapse**, and **Fade**—using Google's official spring, easing, and duration tokens.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
bun add @aphrody/m3-motion motion
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Ensure you have `react` (>= 18.0.0) and `motion` (>= 12.0.0) installed in your project.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 1. Container Transform (`M3ContainerTransform`)
|
|
20
|
-
|
|
21
|
-
The container transform pattern transitions one UI element to another (e.g., morphing a small Card component into a full-page Detail view).
|
|
22
|
-
|
|
23
|
-
### Key Features
|
|
24
|
-
* **Aspect Ratio Preservation**: Automatically prevents layout distortion (skewing/stretching) of children during container morphs using layout-position correction.
|
|
25
|
-
* **Spec-Compliant Cross-Fade**: Fades out the starting content early (0% to 30% of transition) and delays the fade-in of target content (20% to 100% of transition) to avoid messy intermediate states.
|
|
26
|
-
* **Pointer Event Management**: Prevents inactive, hidden content from intercepting pointer interactions.
|
|
27
|
-
* **Flexibility**: Supports both the **Single-Container Toggle** approach (re-rendering within the same container) and the **Two-Container Shared Layout** approach (different source/target elements linked via `layoutId`).
|
|
28
|
-
|
|
29
|
-
### Sub-Components
|
|
30
|
-
* `M3ContainerTransform`: Parent morphing container.
|
|
31
|
-
* `M3ContainerTransformStart`: Wrapper for starting content (e.g., collapsed card details).
|
|
32
|
-
* `M3ContainerTransformEnd`: Wrapper for ending content (e.g., expanded page details).
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
### Code Examples
|
|
37
|
-
|
|
38
|
-
#### Single-Container Toggle Approach
|
|
39
|
-
Best when morphing a single component instance in place using state.
|
|
40
|
-
|
|
41
|
-
```tsx
|
|
42
|
-
import React, { useState } from "react";
|
|
43
|
-
import {
|
|
44
|
-
M3ContainerTransform,
|
|
45
|
-
M3ContainerTransformStart,
|
|
46
|
-
M3ContainerTransformEnd
|
|
47
|
-
} from "@aphrody/m3-motion";
|
|
48
|
-
|
|
49
|
-
export const MorphingCard = () => {
|
|
50
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<M3ContainerTransform
|
|
54
|
-
isExpanded={isExpanded}
|
|
55
|
-
speed="default"
|
|
56
|
-
style={{
|
|
57
|
-
width: isExpanded ? 500 : 250,
|
|
58
|
-
height: isExpanded ? 400 : 150,
|
|
59
|
-
borderRadius: isExpanded ? 28 : 16,
|
|
60
|
-
backgroundColor: "var(--md-sys-color-surface-container)",
|
|
61
|
-
cursor: "pointer"
|
|
62
|
-
}}
|
|
63
|
-
onClick={() => setIsExpanded(!isExpanded)}
|
|
64
|
-
>
|
|
65
|
-
{/* Start state (collapsed content) */}
|
|
66
|
-
<M3ContainerTransformStart>
|
|
67
|
-
<div style={{ padding: 16 }}>
|
|
68
|
-
<h3>Collapsed Card</h3>
|
|
69
|
-
<p>Click me to expand...</p>
|
|
70
|
-
</div>
|
|
71
|
-
</M3ContainerTransformStart>
|
|
72
|
-
|
|
73
|
-
{/* End state (expanded detail content) */}
|
|
74
|
-
<M3ContainerTransformEnd>
|
|
75
|
-
<div style={{ padding: 24 }}>
|
|
76
|
-
<h2>Detailed View</h2>
|
|
77
|
-
<p>This is the expanded content showing the full detail surface.</p>
|
|
78
|
-
<button onClick={(e) => { e.stopPropagation(); setIsExpanded(false); }}>
|
|
79
|
-
Close
|
|
80
|
-
</button>
|
|
81
|
-
</div>
|
|
82
|
-
</M3ContainerTransformEnd>
|
|
83
|
-
</M3ContainerTransform>
|
|
84
|
-
);
|
|
85
|
-
};
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
#### Two-Container Shared Layout Approach (linked via `layoutId`)
|
|
89
|
-
Best for page/route transitions or separate DOM elements. Wrap the conditional render in `<AnimatePresence>` to enable the exit fade-out transition.
|
|
90
|
-
|
|
91
|
-
```tsx
|
|
92
|
-
import React, { useState } from "react";
|
|
93
|
-
import { AnimatePresence } from "motion/react";
|
|
94
|
-
import {
|
|
95
|
-
M3ContainerTransform,
|
|
96
|
-
M3ContainerTransformStart,
|
|
97
|
-
M3ContainerTransformEnd
|
|
98
|
-
} from "@aphrody/m3-motion";
|
|
99
|
-
|
|
100
|
-
export const ListView = () => {
|
|
101
|
-
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<div>
|
|
105
|
-
{/* List of items */}
|
|
106
|
-
{!selectedId && (
|
|
107
|
-
<div className="grid">
|
|
108
|
-
<M3ContainerTransform
|
|
109
|
-
layoutId="card-item-1"
|
|
110
|
-
onClick={() => setSelectedId("1")}
|
|
111
|
-
style={{ borderRadius: 16, background: "#eee", width: 200, height: 120 }}
|
|
112
|
-
>
|
|
113
|
-
<M3ContainerTransformStart>
|
|
114
|
-
<div style={{ padding: 12 }}>Card Content 1</div>
|
|
115
|
-
</M3ContainerTransformStart>
|
|
116
|
-
</M3ContainerTransform>
|
|
117
|
-
</div>
|
|
118
|
-
)}
|
|
119
|
-
|
|
120
|
-
{/* Expanded detail page */}
|
|
121
|
-
<AnimatePresence>
|
|
122
|
-
{selectedId === "1" && (
|
|
123
|
-
<div className="backdrop">
|
|
124
|
-
<M3ContainerTransform
|
|
125
|
-
layoutId="card-item-1"
|
|
126
|
-
style={{ borderRadius: 24, background: "#fff", width: 600, height: 450 }}
|
|
127
|
-
>
|
|
128
|
-
<M3ContainerTransformEnd>
|
|
129
|
-
<div style={{ padding: 24 }}>
|
|
130
|
-
<h2>Expanded Title 1</h2>
|
|
131
|
-
<p>Long detail text...</p>
|
|
132
|
-
<button onClick={() => setSelectedId(null)}>Back to List</button>
|
|
133
|
-
</div>
|
|
134
|
-
</M3ContainerTransformEnd>
|
|
135
|
-
</M3ContainerTransform>
|
|
136
|
-
</div>
|
|
137
|
-
)}
|
|
138
|
-
</AnimatePresence>
|
|
139
|
-
</div>
|
|
140
|
-
);
|
|
141
|
-
};
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## 2. Shared Axis (`M3SharedAxis`)
|
|
147
|
-
|
|
148
|
-
Used for transitions between UI elements that have a spatial or navigational relationship (e.g., page stepper, tab switching, or dialog overlays). Supports `x`, `y`, and `z` axes.
|
|
149
|
-
|
|
150
|
-
* Default enter duration: **300ms** (`medium2`) with `emphasizedDecelerate` ease.
|
|
151
|
-
* Default exit duration: **200ms** (`short4`) with `emphasizedAccelerate` ease.
|
|
152
|
-
|
|
153
|
-
### Code Example
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
import React, { useState } from "react";
|
|
157
|
-
import { M3SharedAxis } from "@aphrody/m3-motion";
|
|
158
|
-
|
|
159
|
-
export const StepWizard = () => {
|
|
160
|
-
const [step, setStep] = useState(0);
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<div>
|
|
164
|
-
<M3SharedAxis
|
|
165
|
-
stateKey={step}
|
|
166
|
-
axis="x"
|
|
167
|
-
forward={step > 0}
|
|
168
|
-
style={{ padding: 20 }}
|
|
169
|
-
>
|
|
170
|
-
{step === 0 && <div>Step 1: Enter details</div>}
|
|
171
|
-
{step === 1 && <div>Step 2: Review options</div>}
|
|
172
|
-
{step === 2 && <div>Step 3: Confirm purchase</div>}
|
|
173
|
-
</M3SharedAxis>
|
|
174
|
-
|
|
175
|
-
<button onClick={() => setStep(prev => Math.max(0, prev - 1))}>Back</button>
|
|
176
|
-
<button onClick={() => setStep(prev => Math.min(2, prev + 1))}>Next</button>
|
|
177
|
-
</div>
|
|
178
|
-
);
|
|
179
|
-
};
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## 3. Fade Through (`M3FadeThrough`)
|
|
185
|
-
|
|
186
|
-
Used for transitions between primary views that do not have a strong spatial relationship (e.g., bottom navigation switching, settings screens).
|
|
187
|
-
|
|
188
|
-
* Default exit duration (fade-out): **90ms** with `emphasizedAccelerate` ease.
|
|
189
|
-
* Default enter duration (fade-in & scale-up from 92%): **210ms** with `emphasizedDecelerate` ease.
|
|
190
|
-
|
|
191
|
-
### Code Example
|
|
192
|
-
|
|
193
|
-
```tsx
|
|
194
|
-
import React, { useState } from "react";
|
|
195
|
-
import { M3FadeThrough } from "@aphrody/m3-motion";
|
|
196
|
-
|
|
197
|
-
export const AppNavigation = () => {
|
|
198
|
-
const [currentTab, setCurrentTab] = useState("home");
|
|
199
|
-
|
|
200
|
-
return (
|
|
201
|
-
<div>
|
|
202
|
-
<M3FadeThrough stateKey={currentTab} style={{ height: 400 }}>
|
|
203
|
-
{currentTab === "home" && <div>Home View Content</div>}
|
|
204
|
-
{currentTab === "search" && <div>Search Page Content</div>}
|
|
205
|
-
{currentTab === "profile" && <div>User Profile Settings</div>}
|
|
206
|
-
</M3FadeThrough>
|
|
207
|
-
|
|
208
|
-
<nav>
|
|
209
|
-
<button onClick={() => setCurrentTab("home")}>Home</button>
|
|
210
|
-
<button onClick={() => setCurrentTab("search")}>Search</button>
|
|
211
|
-
<button onClick={() => setCurrentTab("profile")}>Profile</button>
|
|
212
|
-
</nav>
|
|
213
|
-
</div>
|
|
214
|
-
);
|
|
215
|
-
};
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## 4. Duration and Easing Presets
|
|
221
|
-
|
|
222
|
-
Developers have direct access to official Material Design 3 timings and curves:
|
|
223
|
-
|
|
224
|
-
```tsx
|
|
225
|
-
import { m3Easings, m3Durations, m3Springs } from "@aphrody/m3-motion";
|
|
226
|
-
|
|
227
|
-
// Custom animation example using M3 tokens
|
|
228
|
-
const myCustomTransition = {
|
|
229
|
-
ease: m3Easings.emphasizedDecelerate,
|
|
230
|
-
duration: m3Durations.medium4, // 400ms
|
|
231
|
-
};
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Motion Presets Summary
|
|
235
|
-
* **`m3Easings`**: Bezier curves for `emphasized` (approx), `emphasizedDecelerate` (enter), `emphasizedAccelerate` (exit), `standard`, `standardDecelerate`, and `standardAccelerate`.
|
|
236
|
-
* **`m3Durations`**: Timing scales from `short1` (50ms) to `extraLong4` (1000ms).
|
|
237
|
-
* **`m3Springs`**: Hand-tuned spring constants (`fast`, `default`, `slow`) split into `spatial` (bouncy) and `effects` (critically damped).
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## License
|
|
242
|
-
|
|
243
|
-
Apache-2.0
|
|
1
|
+
# @aphrody/m3-motion
|
|
2
|
+
|
|
3
|
+
High-fidelity React animation components for Material Design 3 (M3) motion specifications, powered by [Motion](https://motion.dev/) (formerly Framer Motion).
|
|
4
|
+
|
|
5
|
+
This package implements the core Material Design 3 motion patterns—including **Container Transform**, **Shared Axis**, **Fade Through**, **Collapse**, and **Fade**—using Google's official spring, easing, and duration tokens.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add @aphrody/m3-motion motion
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Ensure you have `react` (>= 18.0.0) and `motion` (>= 12.0.0) installed in your project.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. Container Transform (`M3ContainerTransform`)
|
|
20
|
+
|
|
21
|
+
The container transform pattern transitions one UI element to another (e.g., morphing a small Card component into a full-page Detail view).
|
|
22
|
+
|
|
23
|
+
### Key Features
|
|
24
|
+
* **Aspect Ratio Preservation**: Automatically prevents layout distortion (skewing/stretching) of children during container morphs using layout-position correction.
|
|
25
|
+
* **Spec-Compliant Cross-Fade**: Fades out the starting content early (0% to 30% of transition) and delays the fade-in of target content (20% to 100% of transition) to avoid messy intermediate states.
|
|
26
|
+
* **Pointer Event Management**: Prevents inactive, hidden content from intercepting pointer interactions.
|
|
27
|
+
* **Flexibility**: Supports both the **Single-Container Toggle** approach (re-rendering within the same container) and the **Two-Container Shared Layout** approach (different source/target elements linked via `layoutId`).
|
|
28
|
+
|
|
29
|
+
### Sub-Components
|
|
30
|
+
* `M3ContainerTransform`: Parent morphing container.
|
|
31
|
+
* `M3ContainerTransformStart`: Wrapper for starting content (e.g., collapsed card details).
|
|
32
|
+
* `M3ContainerTransformEnd`: Wrapper for ending content (e.g., expanded page details).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### Code Examples
|
|
37
|
+
|
|
38
|
+
#### Single-Container Toggle Approach
|
|
39
|
+
Best when morphing a single component instance in place using state.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import React, { useState } from "react";
|
|
43
|
+
import {
|
|
44
|
+
M3ContainerTransform,
|
|
45
|
+
M3ContainerTransformStart,
|
|
46
|
+
M3ContainerTransformEnd
|
|
47
|
+
} from "@aphrody/m3-motion";
|
|
48
|
+
|
|
49
|
+
export const MorphingCard = () => {
|
|
50
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<M3ContainerTransform
|
|
54
|
+
isExpanded={isExpanded}
|
|
55
|
+
speed="default"
|
|
56
|
+
style={{
|
|
57
|
+
width: isExpanded ? 500 : 250,
|
|
58
|
+
height: isExpanded ? 400 : 150,
|
|
59
|
+
borderRadius: isExpanded ? 28 : 16,
|
|
60
|
+
backgroundColor: "var(--md-sys-color-surface-container)",
|
|
61
|
+
cursor: "pointer"
|
|
62
|
+
}}
|
|
63
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
64
|
+
>
|
|
65
|
+
{/* Start state (collapsed content) */}
|
|
66
|
+
<M3ContainerTransformStart>
|
|
67
|
+
<div style={{ padding: 16 }}>
|
|
68
|
+
<h3>Collapsed Card</h3>
|
|
69
|
+
<p>Click me to expand...</p>
|
|
70
|
+
</div>
|
|
71
|
+
</M3ContainerTransformStart>
|
|
72
|
+
|
|
73
|
+
{/* End state (expanded detail content) */}
|
|
74
|
+
<M3ContainerTransformEnd>
|
|
75
|
+
<div style={{ padding: 24 }}>
|
|
76
|
+
<h2>Detailed View</h2>
|
|
77
|
+
<p>This is the expanded content showing the full detail surface.</p>
|
|
78
|
+
<button onClick={(e) => { e.stopPropagation(); setIsExpanded(false); }}>
|
|
79
|
+
Close
|
|
80
|
+
</button>
|
|
81
|
+
</div>
|
|
82
|
+
</M3ContainerTransformEnd>
|
|
83
|
+
</M3ContainerTransform>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Two-Container Shared Layout Approach (linked via `layoutId`)
|
|
89
|
+
Best for page/route transitions or separate DOM elements. Wrap the conditional render in `<AnimatePresence>` to enable the exit fade-out transition.
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import React, { useState } from "react";
|
|
93
|
+
import { AnimatePresence } from "motion/react";
|
|
94
|
+
import {
|
|
95
|
+
M3ContainerTransform,
|
|
96
|
+
M3ContainerTransformStart,
|
|
97
|
+
M3ContainerTransformEnd
|
|
98
|
+
} from "@aphrody/m3-motion";
|
|
99
|
+
|
|
100
|
+
export const ListView = () => {
|
|
101
|
+
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<div>
|
|
105
|
+
{/* List of items */}
|
|
106
|
+
{!selectedId && (
|
|
107
|
+
<div className="grid">
|
|
108
|
+
<M3ContainerTransform
|
|
109
|
+
layoutId="card-item-1"
|
|
110
|
+
onClick={() => setSelectedId("1")}
|
|
111
|
+
style={{ borderRadius: 16, background: "#eee", width: 200, height: 120 }}
|
|
112
|
+
>
|
|
113
|
+
<M3ContainerTransformStart>
|
|
114
|
+
<div style={{ padding: 12 }}>Card Content 1</div>
|
|
115
|
+
</M3ContainerTransformStart>
|
|
116
|
+
</M3ContainerTransform>
|
|
117
|
+
</div>
|
|
118
|
+
)}
|
|
119
|
+
|
|
120
|
+
{/* Expanded detail page */}
|
|
121
|
+
<AnimatePresence>
|
|
122
|
+
{selectedId === "1" && (
|
|
123
|
+
<div className="backdrop">
|
|
124
|
+
<M3ContainerTransform
|
|
125
|
+
layoutId="card-item-1"
|
|
126
|
+
style={{ borderRadius: 24, background: "#fff", width: 600, height: 450 }}
|
|
127
|
+
>
|
|
128
|
+
<M3ContainerTransformEnd>
|
|
129
|
+
<div style={{ padding: 24 }}>
|
|
130
|
+
<h2>Expanded Title 1</h2>
|
|
131
|
+
<p>Long detail text...</p>
|
|
132
|
+
<button onClick={() => setSelectedId(null)}>Back to List</button>
|
|
133
|
+
</div>
|
|
134
|
+
</M3ContainerTransformEnd>
|
|
135
|
+
</M3ContainerTransform>
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
</AnimatePresence>
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 2. Shared Axis (`M3SharedAxis`)
|
|
147
|
+
|
|
148
|
+
Used for transitions between UI elements that have a spatial or navigational relationship (e.g., page stepper, tab switching, or dialog overlays). Supports `x`, `y`, and `z` axes.
|
|
149
|
+
|
|
150
|
+
* Default enter duration: **300ms** (`medium2`) with `emphasizedDecelerate` ease.
|
|
151
|
+
* Default exit duration: **200ms** (`short4`) with `emphasizedAccelerate` ease.
|
|
152
|
+
|
|
153
|
+
### Code Example
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
import React, { useState } from "react";
|
|
157
|
+
import { M3SharedAxis } from "@aphrody/m3-motion";
|
|
158
|
+
|
|
159
|
+
export const StepWizard = () => {
|
|
160
|
+
const [step, setStep] = useState(0);
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div>
|
|
164
|
+
<M3SharedAxis
|
|
165
|
+
stateKey={step}
|
|
166
|
+
axis="x"
|
|
167
|
+
forward={step > 0}
|
|
168
|
+
style={{ padding: 20 }}
|
|
169
|
+
>
|
|
170
|
+
{step === 0 && <div>Step 1: Enter details</div>}
|
|
171
|
+
{step === 1 && <div>Step 2: Review options</div>}
|
|
172
|
+
{step === 2 && <div>Step 3: Confirm purchase</div>}
|
|
173
|
+
</M3SharedAxis>
|
|
174
|
+
|
|
175
|
+
<button onClick={() => setStep(prev => Math.max(0, prev - 1))}>Back</button>
|
|
176
|
+
<button onClick={() => setStep(prev => Math.min(2, prev + 1))}>Next</button>
|
|
177
|
+
</div>
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 3. Fade Through (`M3FadeThrough`)
|
|
185
|
+
|
|
186
|
+
Used for transitions between primary views that do not have a strong spatial relationship (e.g., bottom navigation switching, settings screens).
|
|
187
|
+
|
|
188
|
+
* Default exit duration (fade-out): **90ms** with `emphasizedAccelerate` ease.
|
|
189
|
+
* Default enter duration (fade-in & scale-up from 92%): **210ms** with `emphasizedDecelerate` ease.
|
|
190
|
+
|
|
191
|
+
### Code Example
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import React, { useState } from "react";
|
|
195
|
+
import { M3FadeThrough } from "@aphrody/m3-motion";
|
|
196
|
+
|
|
197
|
+
export const AppNavigation = () => {
|
|
198
|
+
const [currentTab, setCurrentTab] = useState("home");
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<div>
|
|
202
|
+
<M3FadeThrough stateKey={currentTab} style={{ height: 400 }}>
|
|
203
|
+
{currentTab === "home" && <div>Home View Content</div>}
|
|
204
|
+
{currentTab === "search" && <div>Search Page Content</div>}
|
|
205
|
+
{currentTab === "profile" && <div>User Profile Settings</div>}
|
|
206
|
+
</M3FadeThrough>
|
|
207
|
+
|
|
208
|
+
<nav>
|
|
209
|
+
<button onClick={() => setCurrentTab("home")}>Home</button>
|
|
210
|
+
<button onClick={() => setCurrentTab("search")}>Search</button>
|
|
211
|
+
<button onClick={() => setCurrentTab("profile")}>Profile</button>
|
|
212
|
+
</nav>
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
};
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 4. Duration and Easing Presets
|
|
221
|
+
|
|
222
|
+
Developers have direct access to official Material Design 3 timings and curves:
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
import { m3Easings, m3Durations, m3Springs } from "@aphrody/m3-motion";
|
|
226
|
+
|
|
227
|
+
// Custom animation example using M3 tokens
|
|
228
|
+
const myCustomTransition = {
|
|
229
|
+
ease: m3Easings.emphasizedDecelerate,
|
|
230
|
+
duration: m3Durations.medium4, // 400ms
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Motion Presets Summary
|
|
235
|
+
* **`m3Easings`**: Bezier curves for `emphasized` (approx), `emphasizedDecelerate` (enter), `emphasizedAccelerate` (exit), `standard`, `standardDecelerate`, and `standardAccelerate`.
|
|
236
|
+
* **`m3Durations`**: Timing scales from `short1` (50ms) to `extraLong4` (1000ms).
|
|
237
|
+
* **`m3Springs`**: Hand-tuned spring constants (`fast`, `default`, `slow`) split into `spatial` (bouncy) and `effects` (critically damped).
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
Apache-2.0
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/springs.ts","../src/easings.ts","../src/spring-interpolation.ts","../src/components/M3Fade.tsx","../src/components/M3SharedAxis.tsx","../src/components/M3FadeThrough.tsx","../src/components/M3Collapse.tsx","../src/components/M3ContainerTransform.tsx","../src/components/M3Transition.tsx","../src/components/M3ListStagger.tsx","../src/hooks/useM3Animate.ts"],"names":["x1","y1","x2","y2","React","React2","jsx","motion","AnimatePresence","React4","React6","React7"],"mappings":"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","file":"index.js","sourcesContent":["import type { Transition } from \"motion/react\";\r\n\r\n/**\r\n * Material Design 3 Spring Transition Presets.\r\n * Driven by physical stiffness, damping, and mass.\r\n *\r\n * Category Guide:\r\n * - Spatial: Used for movement (x/y positions, width/height, scale, borders). Includes overshoot (bounce).\r\n * - Effects: Used for color changes, opacities, and gradients. Critically damped (no overshoot).\r\n */\r\nexport const m3Springs = {\r\n fast: {\r\n spatial: {\r\n type: \"spring\",\r\n stiffness: 400,\r\n damping: 24,\r\n mass: 0.8,\r\n } as Transition,\r\n effects: {\r\n type: \"spring\",\r\n stiffness: 350,\r\n damping: 37,\r\n mass: 0.8,\r\n } as Transition,\r\n },\r\n default: {\r\n spatial: {\r\n type: \"spring\",\r\n stiffness: 220,\r\n damping: 17,\r\n mass: 1.0,\r\n } as Transition,\r\n effects: {\r\n type: \"spring\",\r\n stiffness: 180,\r\n damping: 26,\r\n mass: 1.0,\r\n } as Transition,\r\n },\r\n slow: {\r\n spatial: {\r\n type: \"spring\",\r\n stiffness: 80,\r\n damping: 12,\r\n mass: 1.2,\r\n } as Transition,\r\n effects: {\r\n type: \"spring\",\r\n stiffness: 70,\r\n damping: 16,\r\n mass: 1.2,\r\n } as Transition,\r\n },\r\n} as const;\r\n","/**\r\n * Material Design 3 Easing Presets.\r\n * Represented as cubic-bezier array coordinates [x1, y1, x2, y2].\r\n *\r\n * Source of truth: packages/material-web/tokens/versions/v0_192/_md-sys-motion.scss\r\n * and docs/01-md3-spec-foundations.md §7.1\r\n *\r\n * Note on `emphasized`: the full M3 emphasized path is a 2-segment spline\r\n * (not expressible as a single cubic-bezier). The token file maps\r\n * easing-emphasized to cubic-bezier(0.2, 0, 0, 1) — identical to standard —\r\n * because that is the closest single-bezier approximation used in web\r\n * implementations. Use emphasizedDecelerate / emphasizedAccelerate for\r\n * enter/exit transitions respectively (recommended practice per spec §7.1).\r\n */\r\nexport const m3Easings = {\r\n /** Closest single-bezier approximation. Use emphasizedDecelerate/Accelerate for transitions. */\r\n emphasized: [0.2, 0.0, 0.0, 1.0],\r\n emphasizedDecelerate: [0.05, 0.7, 0.1, 1.0],\r\n emphasizedAccelerate: [0.3, 0.0, 0.8, 0.15],\r\n standard: [0.2, 0.0, 0.0, 1.0],\r\n standardDecelerate: [0.0, 0.0, 0.0, 1.0],\r\n standardAccelerate: [0.3, 0.0, 1.0, 1.0],\r\n linear: [0.0, 0.0, 1.0, 1.0],\r\n /** Legacy (M2 default) — kept for migration compatibility. */\r\n legacy: [0.4, 0.0, 0.2, 1.0],\r\n legacyDecelerate: [0.0, 0.0, 0.2, 1.0],\r\n legacyAccelerate: [0.4, 0.0, 1.0, 1.0],\r\n} as const;\r\n\r\nexport type M3EasingKey = keyof typeof m3Easings;\r\nexport type M3EasingValue = (typeof m3Easings)[M3EasingKey];\r\n\r\n/**\r\n * Material Design 3 Duration Presets (in seconds, compatible with Motion duration option).\r\n *\r\n * Canonical values from _md-sys-motion.scss:\r\n * short1=50ms, short2=100ms, short3=150ms, short4=200ms\r\n * medium1=250ms, medium2=300ms, medium3=350ms, medium4=400ms\r\n * long1=450ms, long2=500ms, long3=550ms, long4=600ms\r\n * extraLong1=700ms, extraLong2=800ms, extraLong3=900ms, extraLong4=1000ms\r\n */\r\nexport const m3Durations = {\r\n short1: 0.05,\r\n short2: 0.1,\r\n short3: 0.15,\r\n short4: 0.2,\r\n medium1: 0.25,\r\n medium2: 0.3,\r\n medium3: 0.35,\r\n medium4: 0.4,\r\n long1: 0.45,\r\n long2: 0.5,\r\n long3: 0.55,\r\n long4: 0.6,\r\n extraLong1: 0.7,\r\n extraLong2: 0.8,\r\n extraLong3: 0.9,\r\n extraLong4: 1.0,\r\n} as const;\r\n\r\nexport type M3DurationKey = keyof typeof m3Durations;\r\nexport type M3DurationValue = (typeof m3Durations)[M3DurationKey];\r\n","// SPDX-License-Identifier: Apache-2.0\r\n\r\n/**\r\n * Physical spring interpolation for the Web platform (M3 Expressive, Phase 3.1).\r\n *\r\n * The React components in this package drive springs through `motion/react`,\r\n * which runs a per-frame numerical integrator. Lit components from\r\n * `@material/web` live inside a Shadow DOM and have no access to Motion, so\r\n * they can only animate through CSS transitions (a single `cubic-bezier`) or\r\n * the Web Animations API (`element.animate(keyframes, options)`).\r\n *\r\n * This module is the bridge: it turns the same physical spring parameters\r\n * (`stiffness` / `damping` / `mass`) used by {@link m3Springs} into:\r\n *\r\n * 1. a settle-time estimate in milliseconds ({@link springDurationMs}),\r\n * 2. a single `cubic-bezier(...)` CSS easing approximation\r\n * ({@link springToCssEasing}), and\r\n * 3. an exact sampling of the analytical damped-spring solution as WAAPI\r\n * keyframes ({@link springToWaapiKeyframes}), which — unlike a\r\n * cubic-bezier — preserves overshoot/bounce.\r\n *\r\n * All functions are pure, deterministic and SSR-safe: there is no DOM access\r\n * at module load or call time. `Keyframe` is referenced only as a DOM lib\r\n * type. The maths handle the three damping regimes (under-, critically- and\r\n * over-damped) without dividing by zero.\r\n *\r\n * Physical model (mass-spring-damper, m x'' + c x' + k x = 0):\r\n * - natural angular frequency w0 = sqrt(k / m)\r\n * - damping ratio zeta = c / (2 * sqrt(k * m))\r\n * - damped angular frequency wd = w0 * sqrt(1 - zeta^2) (under-damped)\r\n *\r\n * Here `k` = stiffness, `c` = damping, `m` = mass.\r\n */\r\n\r\n/** Physical parameters of a mass-spring-damper system. */\r\nexport interface SpringParams {\r\n /** Spring stiffness `k` (> 0). Higher = snappier. */\r\n stiffness: number;\r\n /** Damping coefficient `c` (>= 0). Higher = less / no bounce. */\r\n damping: number;\r\n /** Mass `m` (> 0). Defaults to 1. Higher = slower, heavier feel. */\r\n mass?: number;\r\n}\r\n\r\n/** One sample of the analytical spring solution, progress-normalised. */\r\nexport interface SpringSample {\r\n /** Timeline position in [0, 1]. */\r\n offset: number;\r\n /**\r\n * Animated value at this offset. With `from`/`to` defaults (0 -> 1) this\r\n * is the normalised progress and may exceed 1 (overshoot) for\r\n * under-damped springs — that is the whole point of WAAPI sampling.\r\n */\r\n value: number;\r\n}\r\n\r\n/** Result bundle for WAAPI consumption. */\r\nexport interface SpringWaapi {\r\n /** Progress-normalised samples (always present, easy to remap). */\r\n samples: SpringSample[];\r\n /**\r\n * Ready-to-use `Keyframe[]`. Empty `{ offset }`-only objects unless a\r\n * property mapper is supplied via {@link springToWaapiKeyframes} options;\r\n * use {@link springKeyframesForProperty} to project `samples` onto a CSS\r\n * property such as `transform` or `opacity`.\r\n */\r\n keyframes: Keyframe[];\r\n /** WAAPI `KeyframeEffectOptions`-compatible timing. */\r\n options: { duration: number; easing: string };\r\n}\r\n\r\nconst MIN_DURATION_MS = 50;\r\nconst MAX_DURATION_MS = 2000;\r\n/** Envelope threshold for \"settled\": within 0.5% of the rest position. */\r\nconst SETTLE_THRESHOLD = 0.005;\r\nconst DEFAULT_MASS = 1;\r\nconst DEFAULT_STEPS = 60;\r\n\r\n/** Clamp helper (deterministic, NaN-safe via the final fallback). */\r\nfunction clamp(value: number, min: number, max: number): number {\r\n if (value < min) return min;\r\n if (value > max) return max;\r\n return value;\r\n}\r\n\r\n/**\r\n * Normalise raw params: enforce a positive mass/stiffness and a non-negative\r\n * damping so the downstream maths never produce NaN/Infinity.\r\n */\r\nfunction normalize(params: SpringParams): { k: number; c: number; m: number } {\r\n const m = params.mass != null && params.mass > 0 ? params.mass : DEFAULT_MASS;\r\n const k = params.stiffness > 0 ? params.stiffness : 1;\r\n const c = params.damping >= 0 ? params.damping : 0;\r\n return { k, c, m };\r\n}\r\n\r\n/** Natural angular frequency `w0 = sqrt(k / m)`. */\r\nfunction naturalFrequency(k: number, m: number): number {\r\n return Math.sqrt(k / m);\r\n}\r\n\r\n/** Damping ratio `zeta = c / (2 * sqrt(k * m))`. */\r\nfunction dampingRatio(k: number, c: number, m: number): number {\r\n const denom = 2 * Math.sqrt(k * m);\r\n return denom > 0 ? c / denom : 0;\r\n}\r\n\r\n/**\r\n * Estimate the spring settle time in milliseconds.\r\n *\r\n * The motion decays under the exponential envelope `exp(-zeta * w0 * t)`. The\r\n * system is considered settled once that envelope drops below\r\n * {@link SETTLE_THRESHOLD} (0.5%):\r\n *\r\n * exp(-zeta * w0 * t) = threshold\r\n * => t = -ln(threshold) / (zeta * w0)\r\n *\r\n * For over-damped systems (`zeta > 1`) the slow real root dominates the decay,\r\n * so we use the smaller-magnitude pole `s = w0 * (zeta - sqrt(zeta^2 - 1))`\r\n * instead of `zeta * w0`, which would otherwise badly under-estimate the tail.\r\n *\r\n * The result is clamped to a sensible UI range\r\n * [{@link MIN_DURATION_MS}, {@link MAX_DURATION_MS}].\r\n */\r\nexport function springDurationMs(params: SpringParams): number {\r\n const { k, c, m } = normalize(params);\r\n const w0 = naturalFrequency(k, m);\r\n const zeta = dampingRatio(k, c, m);\r\n\r\n // Effective decay rate (1/s). For under/critically-damped this is zeta*w0;\r\n // for over-damped the dominant (slowest) pole governs the tail.\r\n let decayRate: number;\r\n if (zeta > 1) {\r\n const root = Math.sqrt(zeta * zeta - 1);\r\n decayRate = w0 * (zeta - root);\r\n } else {\r\n decayRate = zeta * w0;\r\n }\r\n\r\n if (!(decayRate > 0) || !Number.isFinite(decayRate)) {\r\n // Undamped or degenerate: cap at the maximum.\r\n return MAX_DURATION_MS;\r\n }\r\n\r\n const settleSeconds = -Math.log(SETTLE_THRESHOLD) / decayRate;\r\n const settleMs = settleSeconds * 1000;\r\n return clamp(settleMs, MIN_DURATION_MS, MAX_DURATION_MS);\r\n}\r\n\r\n/**\r\n * Approximate a spring with a single CSS `cubic-bezier(x1,y1,x2,y2)` easing.\r\n *\r\n * LIMITATION: a cubic-bezier easing is monotonic in time and its output is\r\n * conceptually clamped to [0, 1] by the CSS engine for most properties, so it\r\n * **cannot represent overshoot/bounce**. For bouncy (under-damped) spatial\r\n * springs we therefore fall back to an expressive M3 decelerate curve\r\n * (`cubic-bezier(0.05, 0.7, 0.1, 1)` = `emphasizedDecelerate`) which reads as\r\n * a lively settle without the impossible overshoot. Use\r\n * {@link springToWaapiKeyframes} when real bounce is required.\r\n *\r\n * Control points are derived from the damping ratio `zeta`:\r\n * - low zeta (bouncy) -> sharper attack, snappier feel\r\n * - high zeta (smooth) -> gentle ease-out, closer to standard decelerate\r\n *\r\n * The mapping is deterministic and the control points are bounded to valid\r\n * cubic-bezier ranges (x in [0, 1]; y unbounded by spec but kept in [0, 1]).\r\n */\r\nexport function springToCssEasing(params: SpringParams): string {\r\n const { k, c, m } = normalize(params);\r\n const zeta = dampingRatio(k, c, m);\r\n\r\n // Bouncy springs (visibly under-damped) overshoot, which a cubic-bezier\r\n // cannot express -> fall back to an expressive M3 decelerate.\r\n if (zeta < 0.85) {\r\n const [x1, y1, x2, y2] = [0.05, 0.7, 0.1, 1.0];\r\n return `cubic-bezier(${x1}, ${y1}, ${x2}, ${y2})`;\r\n }\r\n\r\n // For near-critical / over-damped springs we synthesise a decelerate\r\n // curve whose attack sharpens as zeta drops toward 1. Map zeta in\r\n // [0.85, ~2+] onto an interpolation factor t in [1, 0] (clamped), where\r\n // t=1 is the sharpest valid attack and t=0 a soft standard ease-out.\r\n const t = clamp((zeta - 0.85) / (1.6 - 0.85), 0, 1);\r\n\r\n // Endpoints of the interpolation:\r\n // sharp (t = 0): emphasized-ish decelerate, vivid attack\r\n // smooth (t = 1): standard decelerate, gentle\r\n const x1 = lerp(0.1, 0.0, t);\r\n const y1 = lerp(0.65, 0.0, t);\r\n const x2 = lerp(0.2, 0.0, t);\r\n const y2 = 1.0;\r\n\r\n return `cubic-bezier(${round(x1)}, ${round(y1)}, ${round(x2)}, ${round(y2)})`;\r\n}\r\n\r\nfunction lerp(a: number, b: number, t: number): number {\r\n return a + (b - a) * t;\r\n}\r\n\r\nfunction round(n: number): number {\r\n return Math.round(n * 1000) / 1000;\r\n}\r\n\r\n/**\r\n * Evaluate the analytical position of a unit-step damped spring at time `t`\r\n * (seconds), starting at rest at 0 and settling to 1.\r\n *\r\n * Closed-form solutions of `m x'' + c x' + k x = k` with `x(0)=0`, `x'(0)=0`:\r\n *\r\n * - Under-damped (zeta < 1):\r\n * x(t) = 1 - e^{-zeta w0 t} ( cos(wd t) + (zeta w0 / wd) sin(wd t) )\r\n * with wd = w0 sqrt(1 - zeta^2)\r\n * - Critically damped (zeta == 1):\r\n * x(t) = 1 - e^{-w0 t} (1 + w0 t)\r\n * - Over-damped (zeta > 1):\r\n * with poles s1,2 = -w0 (zeta -/+ sqrt(zeta^2 - 1)),\r\n * x(t) = 1 - ( s2 e^{s1 t} - s1 e^{s2 t} ) / (s2 - s1)\r\n *\r\n * The under-damped branch is the only one that can return values > 1\r\n * (overshoot). The `wd` divide is guarded: it is only used when\r\n * `1 - zeta^2 > 0`, so there is no division by zero at the regime boundaries.\r\n */\r\nfunction springPosition(t: number, w0: number, zeta: number): number {\r\n if (t <= 0) return 0;\r\n\r\n if (zeta < 1 - 1e-6) {\r\n // Under-damped.\r\n const wd = w0 * Math.sqrt(1 - zeta * zeta);\r\n const envelope = Math.exp(-zeta * w0 * t);\r\n const osc = Math.cos(wd * t) + ((zeta * w0) / wd) * Math.sin(wd * t);\r\n return 1 - envelope * osc;\r\n }\r\n\r\n if (zeta <= 1 + 1e-6) {\r\n // Critically damped (treat the boundary band as critical for stability).\r\n const envelope = Math.exp(-w0 * t);\r\n return 1 - envelope * (1 + w0 * t);\r\n }\r\n\r\n // Over-damped: two distinct real poles.\r\n const root = Math.sqrt(zeta * zeta - 1);\r\n const s1 = -w0 * (zeta - root);\r\n const s2 = -w0 * (zeta + root);\r\n const e1 = Math.exp(s1 * t);\r\n const e2 = Math.exp(s2 * t);\r\n return 1 - (s2 * e1 - s1 * e2) / (s2 - s1);\r\n}\r\n\r\n/**\r\n * Sample the analytical damped-spring solution into WAAPI-ready data.\r\n *\r\n * Returns {@link SpringWaapi} containing:\r\n * - `samples`: `{ offset, value }[]` of the progress curve (value in `from`\r\n * -> `to` units; may overshoot past `to` for under-damped springs),\r\n * - `keyframes`: `Keyframe[]` carrying only `offset` unless `opts.property`\r\n * is given (see below),\r\n * - `options`: `{ duration, easing: \"linear\" }` — easing is `linear`\r\n * because the spring shape is fully baked into the per-frame samples.\r\n *\r\n * Options:\r\n * - `steps` : number of samples (default {@link DEFAULT_STEPS}, min 2).\r\n * - `from`/`to` : start/end values (defaults 0 -> 1).\r\n * - `property` + `unit`/`format` : project samples onto a CSS property so the\r\n * returned `keyframes` are directly consumable by `element.animate`.\r\n *\r\n * Examples:\r\n * springToWaapiKeyframes(p, { property: \"transform\", format: (v) => `translateX(${v}px)`, from: 100, to: 0 })\r\n * springToWaapiKeyframes(p, { property: \"opacity\" })\r\n *\r\n * The first sample is exactly `{ offset: 0, value: from }`; the last is\r\n * `{ offset: 1, value: to }` (snapped to the rest position so the animation\r\n * always finishes precisely on target, even though the analytical value at the\r\n * truncated settle time may differ by the sub-threshold tail).\r\n */\r\nexport function springToWaapiKeyframes(\r\n params: SpringParams,\r\n opts?: {\r\n steps?: number;\r\n from?: number;\r\n to?: number;\r\n /** CSS property name to emit on each keyframe (e.g. \"transform\"). */\r\n property?: string;\r\n /** Format a numeric value into the property string (overrides `unit`). */\r\n format?: (value: number) => string;\r\n /** Unit suffix when `format` is absent (e.g. \"px\", \"%\"). */\r\n unit?: string;\r\n },\r\n): SpringWaapi {\r\n const { k, c, m } = normalize(params);\r\n const w0 = naturalFrequency(k, m);\r\n const zeta = dampingRatio(k, c, m);\r\n\r\n const steps = Math.max(2, Math.floor(opts?.steps ?? DEFAULT_STEPS));\r\n const from = opts?.from ?? 0;\r\n const to = opts?.to ?? 1;\r\n const span = to - from;\r\n\r\n const duration = springDurationMs(params);\r\n const durationSeconds = duration / 1000;\r\n\r\n const samples: SpringSample[] = [];\r\n for (let i = 0; i < steps; i++) {\r\n const offset = i / (steps - 1);\r\n let value: number;\r\n if (i === 0) {\r\n value = from;\r\n } else if (i === steps - 1) {\r\n // Snap the final frame exactly to the target.\r\n value = to;\r\n } else {\r\n const t = offset * durationSeconds;\r\n const progress = springPosition(t, w0, zeta);\r\n value = from + span * progress;\r\n }\r\n samples.push({ offset, value });\r\n }\r\n\r\n const keyframes = opts?.property\r\n ? buildKeyframes(samples, opts.property, opts.format, opts.unit)\r\n : samples.map((s) => ({ offset: s.offset }) as Keyframe);\r\n\r\n return {\r\n samples,\r\n keyframes,\r\n // Easing is linear: the spring's shape is encoded in the samples\r\n // themselves, so the browser must interpolate them at constant rate.\r\n options: { duration, easing: \"linear\" },\r\n };\r\n}\r\n\r\n/**\r\n * Project spring {@link SpringSample}s onto a CSS property, returning\r\n * `Keyframe[]` ready for `element.animate`.\r\n *\r\n * @param samples output of {@link springToWaapiKeyframes}.\r\n * @param property CSS property name, e.g. \"transform\" or \"opacity\".\r\n * @param format optional formatter (value -> CSS string); overrides `unit`.\r\n * @param unit unit suffix used when no `format` is given (default \"\").\r\n */\r\nexport function springKeyframesForProperty(\r\n samples: readonly SpringSample[],\r\n property: string,\r\n format?: (value: number) => string,\r\n unit?: string,\r\n): Keyframe[] {\r\n return buildKeyframes(samples, property, format, unit);\r\n}\r\n\r\nfunction buildKeyframes(\r\n samples: readonly SpringSample[],\r\n property: string,\r\n format?: (value: number) => string,\r\n unit?: string,\r\n): Keyframe[] {\r\n const suffix = unit ?? \"\";\r\n return samples.map((s) => {\r\n const css = format ? format(s.value) : `${s.value}${suffix}`;\r\n // `Keyframe` indexes string property names, so a dynamic key is valid.\r\n return { offset: s.offset, [property]: css } as Keyframe;\r\n });\r\n}\r\n\r\n/**\r\n * Spring preset shape as authored in {@link m3Springs} (a Motion `Transition`\r\n * augmented with the physical fields). Kept minimal so we depend only on the\r\n * numeric fields, not on the full Motion type.\r\n */\r\nexport interface SpringPresetLike {\r\n stiffness?: number;\r\n damping?: number;\r\n mass?: number;\r\n}\r\n\r\n/**\r\n * Extract {@link SpringParams} from an {@link m3Springs} entry (or any\r\n * compatible preset object) for reuse on the Lit / WAAPI side.\r\n *\r\n * Missing fields fall back to the `default.spatial` M3 preset values so the\r\n * result is always a usable, finite spring.\r\n *\r\n * @example\r\n * springFromPreset(m3Springs.default.spatial) // { stiffness: 220, damping: 17, mass: 1 }\r\n */\r\nexport function springFromPreset(preset: SpringPresetLike): SpringParams {\r\n return {\r\n stiffness: preset.stiffness != null && preset.stiffness > 0 ? preset.stiffness : 220,\r\n damping: preset.damping != null && preset.damping >= 0 ? preset.damping : 17,\r\n mass: preset.mass != null && preset.mass > 0 ? preset.mass : DEFAULT_MASS,\r\n };\r\n}\r\n","import * as React from \"react\";\r\nimport { motion, AnimatePresence } from \"motion/react\";\r\nimport type { HTMLMotionProps } from \"motion/react\";\r\nimport { m3Easings, m3Durations } from \"../easings.js\";\r\n\r\nexport interface M3FadeProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * If true, the component will transition in. If false, it will transition out.\r\n * If omitted, the component behaves as a standard motion element meant to be unmounted/mounted\r\n * by an external <AnimatePresence>.\r\n */\r\n in?: boolean;\r\n /**\r\n * If true, animate the transition on initial mount.\r\n * @default true\r\n */\r\n appear?: boolean;\r\n}\r\n\r\n/**\r\n * M3Fade transition component.\r\n * Fades elements in/out using Material 3 standard decelerate/accelerate curves.\r\n */\r\nexport const M3Fade = React.forwardRef<HTMLDivElement, M3FadeProps>(\r\n ({ in: inProp, appear = true, children, ...props }, ref) => {\r\n const variants = {\r\n initial: { opacity: 0 },\r\n animate: {\r\n opacity: 1,\r\n transition: {\r\n ease: m3Easings.emphasizedDecelerate,\r\n duration: m3Durations.medium2,\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n transition: {\r\n ease: m3Easings.emphasizedAccelerate,\r\n duration: m3Durations.short4,\r\n },\r\n },\r\n };\r\n\r\n const content = (\r\n <motion.div\r\n ref={ref}\r\n variants={variants}\r\n initial={appear ? \"initial\" : false}\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n style={{ willChange: \"opacity\" }}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n );\r\n\r\n if (inProp !== undefined) {\r\n return <AnimatePresence>{inProp ? content : null}</AnimatePresence>;\r\n }\r\n\r\n return content;\r\n },\r\n);\r\n\r\nM3Fade.displayName = \"M3Fade\";\r\n","import * as React from \"react\";\r\nimport { motion, AnimatePresence } from \"motion/react\";\r\nimport type { HTMLMotionProps, Transition, Variants } from \"motion/react\";\r\nimport { m3Easings, m3Durations } from \"../easings.js\";\r\n\r\nexport interface M3SharedAxisProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * If true, the component will transition in. If false, it will transition out.\r\n * If omitted, the component behaves as a standard motion element meant to be unmounted/mounted\r\n * by an external <AnimatePresence>.\r\n */\r\n in?: boolean;\r\n /**\r\n * Axis of translation.\r\n * @default \"x\"\r\n */\r\n axis?: \"x\" | \"y\" | \"z\";\r\n /**\r\n * Direction of navigation. If true, slides forward/up/zoom-in. If false, slides backward/down/zoom-out.\r\n * @default true\r\n */\r\n forward?: boolean;\r\n /**\r\n * If true, animate the transition on initial mount.\r\n * @default true\r\n */\r\n appear?: boolean;\r\n /**\r\n * Custom transition for the shared axis animation.\r\n */\r\n transition?: Transition;\r\n}\r\n\r\n/**\r\n * M3SharedAxis transition component.\r\n * Implements the Material 3 Shared Axis motion pattern (X, Y, Z axes).\r\n */\r\nexport const M3SharedAxis = React.forwardRef<HTMLDivElement, M3SharedAxisProps>(\r\n ({ in: inProp, axis = \"x\", forward = true, appear = true, transition: customTransition, variants: customVariants, children, ...props }, ref) => {\r\n // Offset values according to M3 specifications (usually 30px translation or ~8% scale change)\r\n const translateOffset = 30;\r\n const scaleOffset = 0.08;\r\n\r\n const defaultVariants: Variants = {\r\n initial: {\r\n opacity: 0,\r\n x: axis === \"x\" ? (forward ? translateOffset : -translateOffset) : 0,\r\n y: axis === \"y\" ? (forward ? translateOffset : -translateOffset) : 0,\r\n scale: axis === \"z\" ? (forward ? 1 - scaleOffset : 1 + scaleOffset) : 1,\r\n },\r\n animate: {\r\n opacity: 1,\r\n x: 0,\r\n y: 0,\r\n scale: 1,\r\n transition: customTransition || {\r\n x: { ease: m3Easings.emphasizedDecelerate, duration: m3Durations.medium2 },\r\n y: { ease: m3Easings.emphasizedDecelerate, duration: m3Durations.medium2 },\r\n scale: { ease: m3Easings.emphasizedDecelerate, duration: m3Durations.medium2 },\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n x: axis === \"x\" ? (forward ? -translateOffset : translateOffset) : 0,\r\n y: axis === \"y\" ? (forward ? -translateOffset : translateOffset) : 0,\r\n scale: axis === \"z\" ? (forward ? 1 + scaleOffset : 1 - scaleOffset) : 1,\r\n transition: customTransition || {\r\n x: { ease: m3Easings.emphasizedAccelerate, duration: m3Durations.short4 },\r\n y: { ease: m3Easings.emphasizedAccelerate, duration: m3Durations.short4 },\r\n scale: { ease: m3Easings.emphasizedAccelerate, duration: m3Durations.short4 },\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\r\n },\r\n },\r\n };\r\n\r\n const resolvedVariants = customVariants || defaultVariants;\r\n\r\n const content = (\r\n <motion.div\r\n ref={ref}\r\n variants={resolvedVariants}\r\n initial={appear ? \"initial\" : false}\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n style={{ willChange: \"opacity, transform\" }}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n );\r\n\r\n if (inProp !== undefined) {\r\n return <AnimatePresence mode=\"wait\">{inProp ? content : null}</AnimatePresence>;\r\n }\r\n\r\n return content;\r\n },\r\n);\r\n\r\nM3SharedAxis.displayName = \"M3SharedAxis\";\r\n\r\n","import * as React from \"react\";\r\nimport { motion, AnimatePresence } from \"motion/react\";\r\nimport type { HTMLMotionProps, Transition, Variants } from \"motion/react\";\r\nimport { m3Easings } from \"../easings.js\";\r\n\r\nexport interface M3FadeThroughProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * Unique key representing the active view/content. Changing this key triggers the transition.\r\n */\r\n stateKey: React.Key;\r\n /**\r\n * Custom transition for the fade through animation.\r\n */\r\n transition?: Transition;\r\n}\r\n\r\n/**\r\n * M3FadeThrough transition component.\r\n * Implements the Material 3 Fade Through navigation pattern.\r\n * The outgoing element fades out over 90ms, followed by the incoming element fading in and scaling up over 210ms.\r\n */\r\nexport const M3FadeThrough: React.FC<M3FadeThroughProps> = ({ stateKey, transition: customTransition, variants: customVariants, children, ...props }) => {\r\n const defaultVariants: Variants = {\r\n initial: {\r\n opacity: 0,\r\n scale: 0.92,\r\n },\r\n animate: {\r\n opacity: 1,\r\n scale: 1,\r\n transition: customTransition || {\r\n opacity: {\r\n ease: m3Easings.emphasizedDecelerate,\r\n duration: 0.21,\r\n },\r\n scale: {\r\n ease: m3Easings.emphasizedDecelerate,\r\n duration: 0.21,\r\n },\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n transition: customTransition || {\r\n opacity: {\r\n ease: m3Easings.emphasizedAccelerate,\r\n duration: 0.09,\r\n },\r\n },\r\n },\r\n };\r\n\r\n const resolvedVariants = customVariants || defaultVariants;\r\n\r\n return (\r\n <AnimatePresence mode=\"wait\">\r\n <motion.div\r\n key={stateKey}\r\n variants={resolvedVariants}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n style={{ willChange: \"opacity, transform\" }}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n </AnimatePresence>\r\n );\r\n};\r\n\r\nM3FadeThrough.displayName = \"M3FadeThrough\";\r\n\r\n","import * as React from \"react\";\r\nimport { motion, AnimatePresence } from \"motion/react\";\r\nimport type { HTMLMotionProps } from \"motion/react\";\r\nimport { m3Easings, m3Durations } from \"../easings.js\";\r\n\r\nexport interface M3CollapseProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * If true, the component expands. If false, it collapses.\r\n * If omitted, the component behaves as a standard motion element meant to be unmounted/mounted\r\n * by an external <AnimatePresence>.\r\n */\r\n in?: boolean;\r\n /**\r\n * If true, animate the transition on initial mount.\r\n * @default false\r\n */\r\n appear?: boolean;\r\n}\r\n\r\n/**\r\n * M3Collapse transition component.\r\n * Animates the height and opacity of its children, perfect for accordions, menus, or disclosures.\r\n */\r\nexport const M3Collapse = React.forwardRef<HTMLDivElement, M3CollapseProps>(\r\n ({ in: inProp, appear = false, children, ...props }, ref) => {\r\n const variants = {\r\n initial: { height: 0, opacity: 0 },\r\n animate: {\r\n height: \"auto\",\r\n opacity: 1,\r\n transition: {\r\n height: {\r\n ease: m3Easings.emphasized,\r\n duration: m3Durations.medium4,\r\n },\r\n opacity: {\r\n ease: m3Easings.standard,\r\n duration: m3Durations.medium2,\r\n },\r\n },\r\n },\r\n exit: {\r\n height: 0,\r\n opacity: 0,\r\n transition: {\r\n height: {\r\n ease: m3Easings.emphasized,\r\n duration: m3Durations.medium4,\r\n },\r\n opacity: {\r\n ease: m3Easings.standard,\r\n duration: m3Durations.medium2,\r\n },\r\n },\r\n },\r\n };\r\n\r\n const content = (\r\n <motion.div\r\n ref={ref}\r\n variants={variants}\r\n initial={appear ? \"initial\" : false}\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n style={{ overflow: \"hidden\", willChange: \"height, opacity\" }}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n );\r\n\r\n if (inProp !== undefined) {\r\n return <AnimatePresence initial={appear}>{inProp ? content : null}</AnimatePresence>;\r\n }\r\n\r\n return content;\r\n },\r\n);\r\n\r\nM3Collapse.displayName = \"M3Collapse\";\r\n","import * as React from \"react\";\r\nimport { motion } from \"motion/react\";\r\nimport type { HTMLMotionProps, Transition, MotionStyle } from \"motion/react\";\r\nimport { m3Springs } from \"../springs.js\";\r\nimport { m3Easings } from \"../easings.js\";\r\n\r\nexport interface M3ContainerTransformProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * Shared identifier linking the starting container (e.g., card) and ending container (e.g., detail page).\r\n */\r\n layoutId?: string;\r\n /**\r\n * Speed preset to use for the morphing animation.\r\n * @default \"default\"\r\n */\r\n speed?: \"fast\" | \"default\" | \"slow\";\r\n /**\r\n * If true, renders the expanded container state.\r\n * @default false\r\n */\r\n isExpanded?: boolean;\r\n}\r\n\r\nexport interface M3ContainerTransformContextValue {\r\n isExpanded: boolean;\r\n speed: \"fast\" | \"default\" | \"slow\";\r\n}\r\n\r\nexport const M3ContainerTransformContext = React.createContext<M3ContainerTransformContextValue | null>(null);\r\n\r\n/**\r\n * Helper function to generate spec-compliant cross-fade timings.\r\n */\r\nfunction getDefaultTransition(isActive: boolean, speed: \"fast\" | \"default\" | \"slow\"): Transition {\r\n if (speed === \"fast\") {\r\n return isActive\r\n ? { delay: 0.05, duration: 0.15, ease: m3Easings.emphasizedDecelerate }\r\n : { duration: 0.08, ease: m3Easings.emphasizedAccelerate };\r\n }\r\n if (speed === \"slow\") {\r\n return isActive\r\n ? { delay: 0.2, duration: 0.6, ease: m3Easings.emphasizedDecelerate }\r\n : { duration: 0.25, ease: m3Easings.emphasizedAccelerate };\r\n }\r\n // Default speed\r\n return isActive\r\n ? { delay: 0.1, duration: 0.35, ease: m3Easings.emphasizedDecelerate }\r\n : { duration: 0.15, ease: m3Easings.emphasizedAccelerate };\r\n}\r\n\r\n/**\r\n * M3ContainerTransform component.\r\n * Implements the Material 3 Container Transform motion pattern using shared element transitions.\r\n * Use the same layoutId on both source and target containers to morph them smoothly.\r\n */\r\nexport const M3ContainerTransform = React.forwardRef<HTMLDivElement, M3ContainerTransformProps>(\r\n ({ layoutId, speed = \"default\", isExpanded = false, children, transition, style, ...props }, ref) => {\r\n // Select the M3 spatial spring configuration based on speed\r\n const springConfig = m3Springs[speed].spatial;\r\n\r\n const contextValue = React.useMemo(\r\n () => ({ isExpanded, speed }),\r\n [isExpanded, speed]\r\n );\r\n\r\n return (\r\n <M3ContainerTransformContext.Provider value={contextValue}>\r\n <motion.div\r\n ref={ref}\r\n layoutId={layoutId}\r\n layout\r\n transition={transition || springConfig}\r\n style={{\r\n willChange: \"transform, border-radius\",\r\n overflow: \"hidden\",\r\n ...style,\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n </M3ContainerTransformContext.Provider>\r\n );\r\n },\r\n);\r\n\r\nM3ContainerTransform.displayName = \"M3ContainerTransform\";\r\n\r\nexport interface M3ContainerTransformStartProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * Overrides the active state. By default, active when isExpanded is false.\r\n */\r\n active?: boolean;\r\n}\r\n\r\n/**\r\n * M3ContainerTransformStart component.\r\n * Represents the starting content (e.g., Card content) inside M3ContainerTransform.\r\n * Prevents aspect ratio distortion and fades out during the container transform morph.\r\n */\r\nexport const M3ContainerTransformStart = React.forwardRef<HTMLDivElement, M3ContainerTransformStartProps>(\r\n ({ active, children, style, transition, layout = \"position\", ...props }, ref) => {\r\n const context = React.useContext(M3ContainerTransformContext);\r\n const isActive = active ?? (context ? !context.isExpanded : true);\r\n const speed = context?.speed ?? \"default\";\r\n\r\n const baseStyle: MotionStyle = {\r\n width: \"100%\",\r\n height: \"100%\",\r\n boxSizing: \"border-box\",\r\n pointerEvents: isActive ? \"auto\" : \"none\",\r\n ...(!isActive && {\r\n position: \"absolute\",\r\n top: 0,\r\n left: 0,\r\n }),\r\n ...style,\r\n };\r\n\r\n const resolvedTransition = transition || getDefaultTransition(isActive, speed);\r\n\r\n return (\r\n <motion.div\r\n ref={ref}\r\n layout={layout}\r\n animate={{ opacity: isActive ? 1 : 0 }}\r\n transition={resolvedTransition}\r\n style={baseStyle}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n );\r\n },\r\n);\r\n\r\nM3ContainerTransformStart.displayName = \"M3ContainerTransformStart\";\r\n\r\nexport interface M3ContainerTransformEndProps extends HTMLMotionProps<\"div\"> {\r\n /**\r\n * Overrides the active state. By default, active when isExpanded is true.\r\n */\r\n active?: boolean;\r\n}\r\n\r\n/**\r\n * M3ContainerTransformEnd component.\r\n * Represents the target content (e.g., Detail page content) inside M3ContainerTransform.\r\n * Prevents aspect ratio distortion and fades in during the container transform morph.\r\n */\r\nexport const M3ContainerTransformEnd = React.forwardRef<HTMLDivElement, M3ContainerTransformEndProps>(\r\n ({ active, children, style, transition, layout = \"position\", ...props }, ref) => {\r\n const context = React.useContext(M3ContainerTransformContext);\r\n const isActive = active ?? (context ? context.isExpanded : true);\r\n const speed = context?.speed ?? \"default\";\r\n\r\n const baseStyle: MotionStyle = {\r\n width: \"100%\",\r\n height: \"100%\",\r\n boxSizing: \"border-box\",\r\n pointerEvents: isActive ? \"auto\" : \"none\",\r\n ...(!isActive && {\r\n position: \"absolute\",\r\n top: 0,\r\n left: 0,\r\n }),\r\n ...style,\r\n };\r\n\r\n const resolvedTransition = transition || getDefaultTransition(isActive, speed);\r\n\r\n return (\r\n <motion.div\r\n ref={ref}\r\n layout={layout}\r\n initial={{ opacity: 0 }}\r\n animate={{ opacity: isActive ? 1 : 0 }}\r\n transition={resolvedTransition}\r\n style={baseStyle}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n );\r\n },\r\n);\r\n\r\nM3ContainerTransformEnd.displayName = \"M3ContainerTransformEnd\";\r\n\r\n","\"use client\";\r\nimport * as React from \"react\";\r\nimport { AnimatePresence, motion } from \"motion/react\";\r\nimport type { HTMLMotionProps, MotionStyle, Transition, Variants } from \"motion/react\";\r\nimport { m3Easings, m3Durations } from \"../easings.js\";\r\n\r\nexport type M3TransitionPattern =\r\n | \"fade\"\r\n | \"fade-through\"\r\n | \"shared-axis-x\"\r\n | \"shared-axis-y\"\r\n | \"shared-axis-z\"\r\n | \"collapse\";\r\n\r\nexport interface M3TransitionProps extends Omit<HTMLMotionProps<\"div\">, \"variants\" | \"style\"> {\r\n style?: MotionStyle;\r\n /**\r\n * Unique key representing the active view/content. Changing this key triggers the transition.\r\n */\r\n stateKey: React.Key;\r\n /**\r\n * Which M3 transition pattern to apply.\r\n * @default \"fade\"\r\n */\r\n pattern?: M3TransitionPattern;\r\n /**\r\n * Direction of navigation for shared-axis-* patterns.\r\n * @default true\r\n */\r\n forward?: boolean;\r\n /**\r\n * Custom variants — overrides the pattern defaults entirely.\r\n */\r\n variants?: Variants;\r\n /**\r\n * AnimatePresence mode.\r\n * @default \"wait\"\r\n */\r\n mode?: \"wait\" | \"sync\" | \"popLayout\";\r\n}\r\n\r\nconst OFFSET = 30;\r\nconst SCALE_OFFSET = 0.08;\r\n\r\nfunction buildVariants(pattern: M3TransitionPattern, forward: boolean): Variants {\r\n const enterTransition: Transition = {\r\n ease: m3Easings.emphasizedDecelerate,\r\n duration: m3Durations.medium2,\r\n };\r\n const exitTransition: Transition = {\r\n ease: m3Easings.emphasizedAccelerate,\r\n duration: m3Durations.short4,\r\n };\r\n\r\n switch (pattern) {\r\n case \"fade-through\":\r\n return {\r\n initial: { opacity: 0, scale: 0.92 },\r\n animate: {\r\n opacity: 1,\r\n scale: 1,\r\n transition: {\r\n opacity: { ease: m3Easings.emphasizedDecelerate, duration: 0.21 },\r\n scale: { ease: m3Easings.emphasizedDecelerate, duration: 0.21 },\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n transition: { opacity: { ease: m3Easings.emphasizedAccelerate, duration: 0.09 } },\r\n },\r\n };\r\n case \"shared-axis-x\":\r\n return {\r\n initial: { opacity: 0, x: forward ? OFFSET : -OFFSET },\r\n animate: {\r\n opacity: 1,\r\n x: 0,\r\n transition: {\r\n x: enterTransition,\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n x: forward ? -OFFSET : OFFSET,\r\n transition: {\r\n x: exitTransition,\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\r\n },\r\n },\r\n };\r\n case \"shared-axis-y\":\r\n return {\r\n initial: { opacity: 0, y: forward ? OFFSET : -OFFSET },\r\n animate: {\r\n opacity: 1,\r\n y: 0,\r\n transition: {\r\n y: enterTransition,\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n y: forward ? -OFFSET : OFFSET,\r\n transition: {\r\n y: exitTransition,\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\r\n },\r\n },\r\n };\r\n case \"shared-axis-z\":\r\n return {\r\n initial: { opacity: 0, scale: forward ? 1 - SCALE_OFFSET : 1 + SCALE_OFFSET },\r\n animate: {\r\n opacity: 1,\r\n scale: 1,\r\n transition: {\r\n scale: enterTransition,\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n scale: forward ? 1 + SCALE_OFFSET : 1 - SCALE_OFFSET,\r\n transition: {\r\n scale: exitTransition,\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\r\n },\r\n },\r\n };\r\n case \"collapse\":\r\n return {\r\n initial: { height: 0, opacity: 0 },\r\n animate: {\r\n height: \"auto\",\r\n opacity: 1,\r\n transition: {\r\n height: { ease: m3Easings.emphasized, duration: m3Durations.medium4 },\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\r\n },\r\n },\r\n exit: {\r\n height: 0,\r\n opacity: 0,\r\n transition: {\r\n height: { ease: m3Easings.emphasized, duration: m3Durations.medium4 },\r\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\r\n },\r\n },\r\n };\r\n case \"fade\":\r\n default:\r\n return {\r\n initial: { opacity: 0 },\r\n animate: { opacity: 1, transition: enterTransition },\r\n exit: { opacity: 0, transition: exitTransition },\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * M3Transition — generic Material 3 transition wrapper.\r\n * Supports all standard M3 patterns via the `pattern` prop.\r\n * The `stateKey` prop drives AnimatePresence re-mounts.\r\n */\r\nexport const M3Transition = React.forwardRef<HTMLDivElement, M3TransitionProps>(\r\n (\r\n {\r\n stateKey,\r\n pattern = \"fade\",\r\n forward = true,\r\n mode = \"wait\",\r\n variants,\r\n children,\r\n style,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const resolvedVariants = variants ?? buildVariants(pattern, forward);\r\n const baseStyle: MotionStyle =\r\n pattern === \"collapse\" ? { overflow: \"hidden\" } : { willChange: \"opacity, transform\" };\r\n const resolvedStyle: MotionStyle = { ...baseStyle, ...style };\r\n\r\n return (\r\n <AnimatePresence mode={mode}>\r\n <motion.div\r\n key={stateKey}\r\n ref={ref}\r\n variants={resolvedVariants}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n style={resolvedStyle}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n </AnimatePresence>\r\n );\r\n },\r\n);\r\n\r\nM3Transition.displayName = \"M3Transition\";\r\n","\"use client\";\r\nimport * as React from \"react\";\r\nimport { AnimatePresence, motion } from \"motion/react\";\r\nimport type { HTMLMotionProps, Variants } from \"motion/react\";\r\nimport { m3Easings, m3Durations } from \"../easings.js\";\r\n\r\nexport interface M3ListStaggerProps {\r\n /**\r\n * Delay between each child item entering the scene (seconds).\r\n * @default 0.05\r\n */\r\n staggerDelay?: number;\r\n /**\r\n * Delay before the stagger sequence starts (seconds).\r\n * @default 0\r\n */\r\n delayChildren?: number;\r\n /**\r\n * If true, items animate on initial render.\r\n * @default true\r\n */\r\n appear?: boolean;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport interface M3ListStaggerItemProps extends HTMLMotionProps<\"div\"> {\r\n children?: React.ReactNode;\r\n}\r\n\r\nconst containerVariants: Variants = {\r\n hidden: {},\r\n visible: (_custom: { staggerDelay: number; delayChildren: number }) => ({\r\n transition: {\r\n staggerChildren: _custom.staggerDelay,\r\n delayChildren: _custom.delayChildren,\r\n },\r\n }),\r\n exit: {},\r\n};\r\n\r\nconst itemVariants: Variants = {\r\n hidden: { opacity: 0, y: 8 },\r\n visible: {\r\n opacity: 1,\r\n y: 0,\r\n transition: {\r\n ease: m3Easings.emphasizedDecelerate,\r\n duration: m3Durations.medium2,\r\n },\r\n },\r\n exit: {\r\n opacity: 0,\r\n y: 4,\r\n transition: {\r\n ease: m3Easings.emphasizedAccelerate,\r\n duration: m3Durations.short3,\r\n },\r\n },\r\n};\r\n\r\n/**\r\n * M3ListStagger — stagger container for list-item enter/exit animations.\r\n *\r\n * Usage:\r\n * <M3ListStagger>\r\n * {items.map(item => <M3ListStaggerItem key={item.id}>{item.label}</M3ListStaggerItem>)}\r\n * </M3ListStagger>\r\n */\r\nexport const M3ListStagger = React.forwardRef<HTMLDivElement, M3ListStaggerProps>(\r\n ({ staggerDelay = 0.05, delayChildren = 0, appear = true, children, className, style }, ref) => {\r\n return (\r\n <AnimatePresence>\r\n <motion.div\r\n ref={ref}\r\n className={className}\r\n style={style}\r\n variants={containerVariants}\r\n initial={appear ? \"hidden\" : false}\r\n animate=\"visible\"\r\n exit=\"exit\"\r\n custom={{ staggerDelay, delayChildren }}\r\n >\r\n {children}\r\n </motion.div>\r\n </AnimatePresence>\r\n );\r\n },\r\n);\r\n\r\nM3ListStagger.displayName = \"M3ListStagger\";\r\n\r\n/**\r\n * M3ListStaggerItem — a single animated item inside M3ListStagger.\r\n * Must be a direct or indirect descendant of M3ListStagger to inherit variants.\r\n */\r\nexport const M3ListStaggerItem = React.forwardRef<HTMLDivElement, M3ListStaggerItemProps>(\r\n ({ children, style, ...props }, ref) => {\r\n return (\r\n <motion.div\r\n ref={ref}\r\n variants={itemVariants}\r\n style={{ willChange: \"opacity, transform\", ...style }}\r\n {...props}\r\n >\r\n {children}\r\n </motion.div>\r\n );\r\n },\r\n);\r\n\r\nM3ListStaggerItem.displayName = \"M3ListStaggerItem\";\r\n","import { useAnimate } from \"motion/react\";\r\nimport type {\r\n AnimationScope,\r\n AnimationPlaybackControlsWithThen,\r\n AnimationSequence,\r\n SequenceOptions,\r\n ElementOrSelector,\r\n DOMKeyframesDefinition,\r\n AnimationOptions,\r\n MotionValue,\r\n UnresolvedValueKeyframe,\r\n ValueAnimationTransition,\r\n ObjectTarget,\r\n} from \"motion/react\";\r\nimport { m3Easings, m3Durations } from \"../easings.js\";\r\n\r\n/**\r\n * Overloaded type for the scoped animate function returned by useM3Animate.\r\n * Mirrors the overload set of the underlying motion animate, adding M3 defaults.\r\n */\r\nexport interface M3AnimateFn {\r\n (sequence: AnimationSequence, options?: SequenceOptions): AnimationPlaybackControlsWithThen;\r\n (\r\n value: string | MotionValue<string>,\r\n keyframes: string | UnresolvedValueKeyframe<string>[],\r\n options?: ValueAnimationTransition<string>,\r\n ): AnimationPlaybackControlsWithThen;\r\n (\r\n value: number | MotionValue<number>,\r\n keyframes: number | UnresolvedValueKeyframe<number>[],\r\n options?: ValueAnimationTransition<number>,\r\n ): AnimationPlaybackControlsWithThen;\r\n <V extends string | number>(\r\n value: V | MotionValue<V>,\r\n keyframes: V | UnresolvedValueKeyframe<V>[],\r\n options?: ValueAnimationTransition<V>,\r\n ): AnimationPlaybackControlsWithThen;\r\n (\r\n element: ElementOrSelector,\r\n keyframes: DOMKeyframesDefinition,\r\n options?: AnimationOptions,\r\n ): AnimationPlaybackControlsWithThen;\r\n <O extends object>(\r\n object: O | O[],\r\n keyframes: ObjectTarget<O>,\r\n options?: AnimationOptions,\r\n ): AnimationPlaybackControlsWithThen;\r\n}\r\n\r\n/**\r\n * A custom hook wrapping motion's `useAnimate` that injects Material 3 motion defaults\r\n * (emphasized easing and medium2 duration) for all imperative DOM animations.\r\n *\r\n * SSR-safe: useAnimate creates refs; no DOM access occurs at module or render time.\r\n */\r\nexport function useM3Animate<T extends Element = HTMLElement>(): [AnimationScope<T>, M3AnimateFn] {\r\n const [scope, animate] = useAnimate<T>();\r\n\r\n const m3Animate: M3AnimateFn = (\r\n elementOrSelector: unknown,\r\n keyframes?: unknown,\r\n options?: unknown,\r\n ) => {\r\n if (Array.isArray(elementOrSelector)) {\r\n // Sequence overload\r\n return (animate as CallableFunction)(\r\n elementOrSelector,\r\n keyframes as SequenceOptions,\r\n ) as AnimationPlaybackControlsWithThen;\r\n }\r\n\r\n if (\r\n typeof elementOrSelector === \"string\" ||\r\n elementOrSelector instanceof Element ||\r\n (typeof elementOrSelector === \"object\" &&\r\n elementOrSelector !== null &&\r\n \"current\" in elementOrSelector) ||\r\n typeof elementOrSelector === \"number\" ||\r\n (typeof elementOrSelector === \"object\" &&\r\n elementOrSelector !== null &&\r\n \"get\" in elementOrSelector)\r\n ) {\r\n return (animate as CallableFunction)(elementOrSelector, keyframes, {\r\n ease: m3Easings.emphasized,\r\n duration: m3Durations.medium2,\r\n ...(typeof options === \"object\" && options !== null ? options : {}),\r\n }) as AnimationPlaybackControlsWithThen;\r\n }\r\n\r\n return (animate as CallableFunction)(elementOrSelector, keyframes, {\r\n ease: m3Easings.emphasized,\r\n duration: m3Durations.medium2,\r\n ...(typeof options === \"object\" && options !== null ? options : {}),\r\n }) as AnimationPlaybackControlsWithThen;\r\n };\r\n\r\n return [scope, m3Animate];\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/springs.ts","../src/easings.ts","../src/spring-interpolation.ts","../src/components/M3Fade.tsx","../src/components/M3SharedAxis.tsx","../src/components/M3FadeThrough.tsx","../src/components/M3Collapse.tsx","../src/components/M3ContainerTransform.tsx","../src/components/M3Transition.tsx","../src/components/M3ListStagger.tsx","../src/hooks/useM3Animate.ts"],"names":["x1","y1","x2","y2","React","React2","jsx","motion","AnimatePresence","React4","React6","React7"],"mappings":"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","file":"index.js","sourcesContent":["import type { Transition } from \"motion/react\";\n\n/**\n * Material Design 3 Spring Transition Presets.\n * Driven by physical stiffness, damping, and mass.\n *\n * Category Guide:\n * - Spatial: Used for movement (x/y positions, width/height, scale, borders). Includes overshoot (bounce).\n * - Effects: Used for color changes, opacities, and gradients. Critically damped (no overshoot).\n */\nexport const m3Springs = {\n fast: {\n spatial: {\n type: \"spring\",\n stiffness: 400,\n damping: 24,\n mass: 0.8,\n } as Transition,\n effects: {\n type: \"spring\",\n stiffness: 350,\n damping: 37,\n mass: 0.8,\n } as Transition,\n },\n default: {\n spatial: {\n type: \"spring\",\n stiffness: 220,\n damping: 17,\n mass: 1.0,\n } as Transition,\n effects: {\n type: \"spring\",\n stiffness: 180,\n damping: 26,\n mass: 1.0,\n } as Transition,\n },\n slow: {\n spatial: {\n type: \"spring\",\n stiffness: 80,\n damping: 12,\n mass: 1.2,\n } as Transition,\n effects: {\n type: \"spring\",\n stiffness: 70,\n damping: 16,\n mass: 1.2,\n } as Transition,\n },\n} as const;\n","/**\n * Material Design 3 Easing Presets.\n * Represented as cubic-bezier array coordinates [x1, y1, x2, y2].\n *\n * Source of truth: packages/material-web/tokens/versions/v0_192/_md-sys-motion.scss\n * and docs/01-md3-spec-foundations.md §7.1\n *\n * Note on `emphasized`: the full M3 emphasized path is a 2-segment spline\n * (not expressible as a single cubic-bezier). The token file maps\n * easing-emphasized to cubic-bezier(0.2, 0, 0, 1) — identical to standard —\n * because that is the closest single-bezier approximation used in web\n * implementations. Use emphasizedDecelerate / emphasizedAccelerate for\n * enter/exit transitions respectively (recommended practice per spec §7.1).\n */\nexport const m3Easings = {\n /** Closest single-bezier approximation. Use emphasizedDecelerate/Accelerate for transitions. */\n emphasized: [0.2, 0.0, 0.0, 1.0],\n emphasizedDecelerate: [0.05, 0.7, 0.1, 1.0],\n emphasizedAccelerate: [0.3, 0.0, 0.8, 0.15],\n standard: [0.2, 0.0, 0.0, 1.0],\n standardDecelerate: [0.0, 0.0, 0.0, 1.0],\n standardAccelerate: [0.3, 0.0, 1.0, 1.0],\n linear: [0.0, 0.0, 1.0, 1.0],\n /** Legacy (M2 default) — kept for migration compatibility. */\n legacy: [0.4, 0.0, 0.2, 1.0],\n legacyDecelerate: [0.0, 0.0, 0.2, 1.0],\n legacyAccelerate: [0.4, 0.0, 1.0, 1.0],\n} as const;\n\nexport type M3EasingKey = keyof typeof m3Easings;\nexport type M3EasingValue = (typeof m3Easings)[M3EasingKey];\n\n/**\n * Material Design 3 Duration Presets (in seconds, compatible with Motion duration option).\n *\n * Canonical values from _md-sys-motion.scss:\n * short1=50ms, short2=100ms, short3=150ms, short4=200ms\n * medium1=250ms, medium2=300ms, medium3=350ms, medium4=400ms\n * long1=450ms, long2=500ms, long3=550ms, long4=600ms\n * extraLong1=700ms, extraLong2=800ms, extraLong3=900ms, extraLong4=1000ms\n */\nexport const m3Durations = {\n short1: 0.05,\n short2: 0.1,\n short3: 0.15,\n short4: 0.2,\n medium1: 0.25,\n medium2: 0.3,\n medium3: 0.35,\n medium4: 0.4,\n long1: 0.45,\n long2: 0.5,\n long3: 0.55,\n long4: 0.6,\n extraLong1: 0.7,\n extraLong2: 0.8,\n extraLong3: 0.9,\n extraLong4: 1.0,\n} as const;\n\nexport type M3DurationKey = keyof typeof m3Durations;\nexport type M3DurationValue = (typeof m3Durations)[M3DurationKey];\n","// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Physical spring interpolation for the Web platform (M3 Expressive, Phase 3.1).\n *\n * The React components in this package drive springs through `motion/react`,\n * which runs a per-frame numerical integrator. Lit components from\n * `@material/web` live inside a Shadow DOM and have no access to Motion, so\n * they can only animate through CSS transitions (a single `cubic-bezier`) or\n * the Web Animations API (`element.animate(keyframes, options)`).\n *\n * This module is the bridge: it turns the same physical spring parameters\n * (`stiffness` / `damping` / `mass`) used by {@link m3Springs} into:\n *\n * 1. a settle-time estimate in milliseconds ({@link springDurationMs}),\n * 2. a single `cubic-bezier(...)` CSS easing approximation\n * ({@link springToCssEasing}), and\n * 3. an exact sampling of the analytical damped-spring solution as WAAPI\n * keyframes ({@link springToWaapiKeyframes}), which — unlike a\n * cubic-bezier — preserves overshoot/bounce.\n *\n * All functions are pure, deterministic and SSR-safe: there is no DOM access\n * at module load or call time. `Keyframe` is referenced only as a DOM lib\n * type. The maths handle the three damping regimes (under-, critically- and\n * over-damped) without dividing by zero.\n *\n * Physical model (mass-spring-damper, m x'' + c x' + k x = 0):\n * - natural angular frequency w0 = sqrt(k / m)\n * - damping ratio zeta = c / (2 * sqrt(k * m))\n * - damped angular frequency wd = w0 * sqrt(1 - zeta^2) (under-damped)\n *\n * Here `k` = stiffness, `c` = damping, `m` = mass.\n */\n\n/** Physical parameters of a mass-spring-damper system. */\nexport interface SpringParams {\n /** Spring stiffness `k` (> 0). Higher = snappier. */\n stiffness: number;\n /** Damping coefficient `c` (>= 0). Higher = less / no bounce. */\n damping: number;\n /** Mass `m` (> 0). Defaults to 1. Higher = slower, heavier feel. */\n mass?: number;\n}\n\n/** One sample of the analytical spring solution, progress-normalised. */\nexport interface SpringSample {\n /** Timeline position in [0, 1]. */\n offset: number;\n /**\n * Animated value at this offset. With `from`/`to` defaults (0 -> 1) this\n * is the normalised progress and may exceed 1 (overshoot) for\n * under-damped springs — that is the whole point of WAAPI sampling.\n */\n value: number;\n}\n\n/** Result bundle for WAAPI consumption. */\nexport interface SpringWaapi {\n /** Progress-normalised samples (always present, easy to remap). */\n samples: SpringSample[];\n /**\n * Ready-to-use `Keyframe[]`. Empty `{ offset }`-only objects unless a\n * property mapper is supplied via {@link springToWaapiKeyframes} options;\n * use {@link springKeyframesForProperty} to project `samples` onto a CSS\n * property such as `transform` or `opacity`.\n */\n keyframes: Keyframe[];\n /** WAAPI `KeyframeEffectOptions`-compatible timing. */\n options: { duration: number; easing: string };\n}\n\nconst MIN_DURATION_MS = 50;\nconst MAX_DURATION_MS = 2000;\n/** Envelope threshold for \"settled\": within 0.5% of the rest position. */\nconst SETTLE_THRESHOLD = 0.005;\nconst DEFAULT_MASS = 1;\nconst DEFAULT_STEPS = 60;\n\n/** Clamp helper (deterministic, NaN-safe via the final fallback). */\nfunction clamp(value: number, min: number, max: number): number {\n if (value < min) return min;\n if (value > max) return max;\n return value;\n}\n\n/**\n * Normalise raw params: enforce a positive mass/stiffness and a non-negative\n * damping so the downstream maths never produce NaN/Infinity.\n */\nfunction normalize(params: SpringParams): { k: number; c: number; m: number } {\n const m = params.mass != null && params.mass > 0 ? params.mass : DEFAULT_MASS;\n const k = params.stiffness > 0 ? params.stiffness : 1;\n const c = params.damping >= 0 ? params.damping : 0;\n return { k, c, m };\n}\n\n/** Natural angular frequency `w0 = sqrt(k / m)`. */\nfunction naturalFrequency(k: number, m: number): number {\n return Math.sqrt(k / m);\n}\n\n/** Damping ratio `zeta = c / (2 * sqrt(k * m))`. */\nfunction dampingRatio(k: number, c: number, m: number): number {\n const denom = 2 * Math.sqrt(k * m);\n return denom > 0 ? c / denom : 0;\n}\n\n/**\n * Estimate the spring settle time in milliseconds.\n *\n * The motion decays under the exponential envelope `exp(-zeta * w0 * t)`. The\n * system is considered settled once that envelope drops below\n * {@link SETTLE_THRESHOLD} (0.5%):\n *\n * exp(-zeta * w0 * t) = threshold\n * => t = -ln(threshold) / (zeta * w0)\n *\n * For over-damped systems (`zeta > 1`) the slow real root dominates the decay,\n * so we use the smaller-magnitude pole `s = w0 * (zeta - sqrt(zeta^2 - 1))`\n * instead of `zeta * w0`, which would otherwise badly under-estimate the tail.\n *\n * The result is clamped to a sensible UI range\n * [{@link MIN_DURATION_MS}, {@link MAX_DURATION_MS}].\n */\nexport function springDurationMs(params: SpringParams): number {\n const { k, c, m } = normalize(params);\n const w0 = naturalFrequency(k, m);\n const zeta = dampingRatio(k, c, m);\n\n // Effective decay rate (1/s). For under/critically-damped this is zeta*w0;\n // for over-damped the dominant (slowest) pole governs the tail.\n let decayRate: number;\n if (zeta > 1) {\n const root = Math.sqrt(zeta * zeta - 1);\n decayRate = w0 * (zeta - root);\n } else {\n decayRate = zeta * w0;\n }\n\n if (!(decayRate > 0) || !Number.isFinite(decayRate)) {\n // Undamped or degenerate: cap at the maximum.\n return MAX_DURATION_MS;\n }\n\n const settleSeconds = -Math.log(SETTLE_THRESHOLD) / decayRate;\n const settleMs = settleSeconds * 1000;\n return clamp(settleMs, MIN_DURATION_MS, MAX_DURATION_MS);\n}\n\n/**\n * Approximate a spring with a single CSS `cubic-bezier(x1,y1,x2,y2)` easing.\n *\n * LIMITATION: a cubic-bezier easing is monotonic in time and its output is\n * conceptually clamped to [0, 1] by the CSS engine for most properties, so it\n * **cannot represent overshoot/bounce**. For bouncy (under-damped) spatial\n * springs we therefore fall back to an expressive M3 decelerate curve\n * (`cubic-bezier(0.05, 0.7, 0.1, 1)` = `emphasizedDecelerate`) which reads as\n * a lively settle without the impossible overshoot. Use\n * {@link springToWaapiKeyframes} when real bounce is required.\n *\n * Control points are derived from the damping ratio `zeta`:\n * - low zeta (bouncy) -> sharper attack, snappier feel\n * - high zeta (smooth) -> gentle ease-out, closer to standard decelerate\n *\n * The mapping is deterministic and the control points are bounded to valid\n * cubic-bezier ranges (x in [0, 1]; y unbounded by spec but kept in [0, 1]).\n */\nexport function springToCssEasing(params: SpringParams): string {\n const { k, c, m } = normalize(params);\n const zeta = dampingRatio(k, c, m);\n\n // Bouncy springs (visibly under-damped) overshoot, which a cubic-bezier\n // cannot express -> fall back to an expressive M3 decelerate.\n if (zeta < 0.85) {\n const [x1, y1, x2, y2] = [0.05, 0.7, 0.1, 1.0];\n return `cubic-bezier(${x1}, ${y1}, ${x2}, ${y2})`;\n }\n\n // For near-critical / over-damped springs we synthesise a decelerate\n // curve whose attack sharpens as zeta drops toward 1. Map zeta in\n // [0.85, ~2+] onto an interpolation factor t in [1, 0] (clamped), where\n // t=1 is the sharpest valid attack and t=0 a soft standard ease-out.\n const t = clamp((zeta - 0.85) / (1.6 - 0.85), 0, 1);\n\n // Endpoints of the interpolation:\n // sharp (t = 0): emphasized-ish decelerate, vivid attack\n // smooth (t = 1): standard decelerate, gentle\n const x1 = lerp(0.1, 0.0, t);\n const y1 = lerp(0.65, 0.0, t);\n const x2 = lerp(0.2, 0.0, t);\n const y2 = 1.0;\n\n return `cubic-bezier(${round(x1)}, ${round(y1)}, ${round(x2)}, ${round(y2)})`;\n}\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction round(n: number): number {\n return Math.round(n * 1000) / 1000;\n}\n\n/**\n * Evaluate the analytical position of a unit-step damped spring at time `t`\n * (seconds), starting at rest at 0 and settling to 1.\n *\n * Closed-form solutions of `m x'' + c x' + k x = k` with `x(0)=0`, `x'(0)=0`:\n *\n * - Under-damped (zeta < 1):\n * x(t) = 1 - e^{-zeta w0 t} ( cos(wd t) + (zeta w0 / wd) sin(wd t) )\n * with wd = w0 sqrt(1 - zeta^2)\n * - Critically damped (zeta == 1):\n * x(t) = 1 - e^{-w0 t} (1 + w0 t)\n * - Over-damped (zeta > 1):\n * with poles s1,2 = -w0 (zeta -/+ sqrt(zeta^2 - 1)),\n * x(t) = 1 - ( s2 e^{s1 t} - s1 e^{s2 t} ) / (s2 - s1)\n *\n * The under-damped branch is the only one that can return values > 1\n * (overshoot). The `wd` divide is guarded: it is only used when\n * `1 - zeta^2 > 0`, so there is no division by zero at the regime boundaries.\n */\nfunction springPosition(t: number, w0: number, zeta: number): number {\n if (t <= 0) return 0;\n\n if (zeta < 1 - 1e-6) {\n // Under-damped.\n const wd = w0 * Math.sqrt(1 - zeta * zeta);\n const envelope = Math.exp(-zeta * w0 * t);\n const osc = Math.cos(wd * t) + ((zeta * w0) / wd) * Math.sin(wd * t);\n return 1 - envelope * osc;\n }\n\n if (zeta <= 1 + 1e-6) {\n // Critically damped (treat the boundary band as critical for stability).\n const envelope = Math.exp(-w0 * t);\n return 1 - envelope * (1 + w0 * t);\n }\n\n // Over-damped: two distinct real poles.\n const root = Math.sqrt(zeta * zeta - 1);\n const s1 = -w0 * (zeta - root);\n const s2 = -w0 * (zeta + root);\n const e1 = Math.exp(s1 * t);\n const e2 = Math.exp(s2 * t);\n return 1 - (s2 * e1 - s1 * e2) / (s2 - s1);\n}\n\n/**\n * Sample the analytical damped-spring solution into WAAPI-ready data.\n *\n * Returns {@link SpringWaapi} containing:\n * - `samples`: `{ offset, value }[]` of the progress curve (value in `from`\n * -> `to` units; may overshoot past `to` for under-damped springs),\n * - `keyframes`: `Keyframe[]` carrying only `offset` unless `opts.property`\n * is given (see below),\n * - `options`: `{ duration, easing: \"linear\" }` — easing is `linear`\n * because the spring shape is fully baked into the per-frame samples.\n *\n * Options:\n * - `steps` : number of samples (default {@link DEFAULT_STEPS}, min 2).\n * - `from`/`to` : start/end values (defaults 0 -> 1).\n * - `property` + `unit`/`format` : project samples onto a CSS property so the\n * returned `keyframes` are directly consumable by `element.animate`.\n *\n * Examples:\n * springToWaapiKeyframes(p, { property: \"transform\", format: (v) => `translateX(${v}px)`, from: 100, to: 0 })\n * springToWaapiKeyframes(p, { property: \"opacity\" })\n *\n * The first sample is exactly `{ offset: 0, value: from }`; the last is\n * `{ offset: 1, value: to }` (snapped to the rest position so the animation\n * always finishes precisely on target, even though the analytical value at the\n * truncated settle time may differ by the sub-threshold tail).\n */\nexport function springToWaapiKeyframes(\n params: SpringParams,\n opts?: {\n steps?: number;\n from?: number;\n to?: number;\n /** CSS property name to emit on each keyframe (e.g. \"transform\"). */\n property?: string;\n /** Format a numeric value into the property string (overrides `unit`). */\n format?: (value: number) => string;\n /** Unit suffix when `format` is absent (e.g. \"px\", \"%\"). */\n unit?: string;\n },\n): SpringWaapi {\n const { k, c, m } = normalize(params);\n const w0 = naturalFrequency(k, m);\n const zeta = dampingRatio(k, c, m);\n\n const steps = Math.max(2, Math.floor(opts?.steps ?? DEFAULT_STEPS));\n const from = opts?.from ?? 0;\n const to = opts?.to ?? 1;\n const span = to - from;\n\n const duration = springDurationMs(params);\n const durationSeconds = duration / 1000;\n\n const samples: SpringSample[] = [];\n for (let i = 0; i < steps; i++) {\n const offset = i / (steps - 1);\n let value: number;\n if (i === 0) {\n value = from;\n } else if (i === steps - 1) {\n // Snap the final frame exactly to the target.\n value = to;\n } else {\n const t = offset * durationSeconds;\n const progress = springPosition(t, w0, zeta);\n value = from + span * progress;\n }\n samples.push({ offset, value });\n }\n\n const keyframes = opts?.property\n ? buildKeyframes(samples, opts.property, opts.format, opts.unit)\n : samples.map((s) => ({ offset: s.offset }) as Keyframe);\n\n return {\n samples,\n keyframes,\n // Easing is linear: the spring's shape is encoded in the samples\n // themselves, so the browser must interpolate them at constant rate.\n options: { duration, easing: \"linear\" },\n };\n}\n\n/**\n * Project spring {@link SpringSample}s onto a CSS property, returning\n * `Keyframe[]` ready for `element.animate`.\n *\n * @param samples output of {@link springToWaapiKeyframes}.\n * @param property CSS property name, e.g. \"transform\" or \"opacity\".\n * @param format optional formatter (value -> CSS string); overrides `unit`.\n * @param unit unit suffix used when no `format` is given (default \"\").\n */\nexport function springKeyframesForProperty(\n samples: readonly SpringSample[],\n property: string,\n format?: (value: number) => string,\n unit?: string,\n): Keyframe[] {\n return buildKeyframes(samples, property, format, unit);\n}\n\nfunction buildKeyframes(\n samples: readonly SpringSample[],\n property: string,\n format?: (value: number) => string,\n unit?: string,\n): Keyframe[] {\n const suffix = unit ?? \"\";\n return samples.map((s) => {\n const css = format ? format(s.value) : `${s.value}${suffix}`;\n // `Keyframe` indexes string property names, so a dynamic key is valid.\n return { offset: s.offset, [property]: css } as Keyframe;\n });\n}\n\n/**\n * Spring preset shape as authored in {@link m3Springs} (a Motion `Transition`\n * augmented with the physical fields). Kept minimal so we depend only on the\n * numeric fields, not on the full Motion type.\n */\nexport interface SpringPresetLike {\n stiffness?: number;\n damping?: number;\n mass?: number;\n}\n\n/**\n * Extract {@link SpringParams} from an {@link m3Springs} entry (or any\n * compatible preset object) for reuse on the Lit / WAAPI side.\n *\n * Missing fields fall back to the `default.spatial` M3 preset values so the\n * result is always a usable, finite spring.\n *\n * @example\n * springFromPreset(m3Springs.default.spatial) // { stiffness: 220, damping: 17, mass: 1 }\n */\nexport function springFromPreset(preset: SpringPresetLike): SpringParams {\n return {\n stiffness: preset.stiffness != null && preset.stiffness > 0 ? preset.stiffness : 220,\n damping: preset.damping != null && preset.damping >= 0 ? preset.damping : 17,\n mass: preset.mass != null && preset.mass > 0 ? preset.mass : DEFAULT_MASS,\n };\n}\n","import * as React from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { HTMLMotionProps } from \"motion/react\";\nimport { m3Easings, m3Durations } from \"../easings.js\";\n\nexport interface M3FadeProps extends HTMLMotionProps<\"div\"> {\n /**\n * If true, the component will transition in. If false, it will transition out.\n * If omitted, the component behaves as a standard motion element meant to be unmounted/mounted\n * by an external <AnimatePresence>.\n */\n in?: boolean;\n /**\n * If true, animate the transition on initial mount.\n * @default true\n */\n appear?: boolean;\n}\n\n/**\n * M3Fade transition component.\n * Fades elements in/out using Material 3 standard decelerate/accelerate curves.\n */\nexport const M3Fade = React.forwardRef<HTMLDivElement, M3FadeProps>(\n ({ in: inProp, appear = true, children, ...props }, ref) => {\n const variants = {\n initial: { opacity: 0 },\n animate: {\n opacity: 1,\n transition: {\n ease: m3Easings.emphasizedDecelerate,\n duration: m3Durations.medium2,\n },\n },\n exit: {\n opacity: 0,\n transition: {\n ease: m3Easings.emphasizedAccelerate,\n duration: m3Durations.short4,\n },\n },\n };\n\n const content = (\n <motion.div\n ref={ref}\n variants={variants}\n initial={appear ? \"initial\" : false}\n animate=\"animate\"\n exit=\"exit\"\n style={{ willChange: \"opacity\" }}\n {...props}\n >\n {children}\n </motion.div>\n );\n\n if (inProp !== undefined) {\n return <AnimatePresence>{inProp ? content : null}</AnimatePresence>;\n }\n\n return content;\n },\n);\n\nM3Fade.displayName = \"M3Fade\";\n","import * as React from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { HTMLMotionProps, Transition, Variants } from \"motion/react\";\nimport { m3Easings, m3Durations } from \"../easings.js\";\n\nexport interface M3SharedAxisProps extends HTMLMotionProps<\"div\"> {\n /**\n * If true, the component will transition in. If false, it will transition out.\n * If omitted, the component behaves as a standard motion element meant to be unmounted/mounted\n * by an external <AnimatePresence>.\n */\n in?: boolean;\n /**\n * Axis of translation.\n * @default \"x\"\n */\n axis?: \"x\" | \"y\" | \"z\";\n /**\n * Direction of navigation. If true, slides forward/up/zoom-in. If false, slides backward/down/zoom-out.\n * @default true\n */\n forward?: boolean;\n /**\n * If true, animate the transition on initial mount.\n * @default true\n */\n appear?: boolean;\n /**\n * Custom transition for the shared axis animation.\n */\n transition?: Transition;\n}\n\n/**\n * M3SharedAxis transition component.\n * Implements the Material 3 Shared Axis motion pattern (X, Y, Z axes).\n */\nexport const M3SharedAxis = React.forwardRef<HTMLDivElement, M3SharedAxisProps>(\n ({ in: inProp, axis = \"x\", forward = true, appear = true, transition: customTransition, variants: customVariants, children, ...props }, ref) => {\n // Offset values according to M3 specifications (usually 30px translation or ~8% scale change)\n const translateOffset = 30;\n const scaleOffset = 0.08;\n\n const defaultVariants: Variants = {\n initial: {\n opacity: 0,\n x: axis === \"x\" ? (forward ? translateOffset : -translateOffset) : 0,\n y: axis === \"y\" ? (forward ? translateOffset : -translateOffset) : 0,\n scale: axis === \"z\" ? (forward ? 1 - scaleOffset : 1 + scaleOffset) : 1,\n },\n animate: {\n opacity: 1,\n x: 0,\n y: 0,\n scale: 1,\n transition: customTransition || {\n x: { ease: m3Easings.emphasizedDecelerate, duration: m3Durations.medium2 },\n y: { ease: m3Easings.emphasizedDecelerate, duration: m3Durations.medium2 },\n scale: { ease: m3Easings.emphasizedDecelerate, duration: m3Durations.medium2 },\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\n },\n },\n exit: {\n opacity: 0,\n x: axis === \"x\" ? (forward ? -translateOffset : translateOffset) : 0,\n y: axis === \"y\" ? (forward ? -translateOffset : translateOffset) : 0,\n scale: axis === \"z\" ? (forward ? 1 + scaleOffset : 1 - scaleOffset) : 1,\n transition: customTransition || {\n x: { ease: m3Easings.emphasizedAccelerate, duration: m3Durations.short4 },\n y: { ease: m3Easings.emphasizedAccelerate, duration: m3Durations.short4 },\n scale: { ease: m3Easings.emphasizedAccelerate, duration: m3Durations.short4 },\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\n },\n },\n };\n\n const resolvedVariants = customVariants || defaultVariants;\n\n const content = (\n <motion.div\n ref={ref}\n variants={resolvedVariants}\n initial={appear ? \"initial\" : false}\n animate=\"animate\"\n exit=\"exit\"\n style={{ willChange: \"opacity, transform\" }}\n {...props}\n >\n {children}\n </motion.div>\n );\n\n if (inProp !== undefined) {\n return <AnimatePresence mode=\"wait\">{inProp ? content : null}</AnimatePresence>;\n }\n\n return content;\n },\n);\n\nM3SharedAxis.displayName = \"M3SharedAxis\";\n\n","import * as React from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { HTMLMotionProps, Transition, Variants } from \"motion/react\";\nimport { m3Easings } from \"../easings.js\";\n\nexport interface M3FadeThroughProps extends HTMLMotionProps<\"div\"> {\n /**\n * Unique key representing the active view/content. Changing this key triggers the transition.\n */\n stateKey: React.Key;\n /**\n * Custom transition for the fade through animation.\n */\n transition?: Transition;\n}\n\n/**\n * M3FadeThrough transition component.\n * Implements the Material 3 Fade Through navigation pattern.\n * The outgoing element fades out over 90ms, followed by the incoming element fading in and scaling up over 210ms.\n */\nexport const M3FadeThrough: React.FC<M3FadeThroughProps> = ({ stateKey, transition: customTransition, variants: customVariants, children, ...props }) => {\n const defaultVariants: Variants = {\n initial: {\n opacity: 0,\n scale: 0.92,\n },\n animate: {\n opacity: 1,\n scale: 1,\n transition: customTransition || {\n opacity: {\n ease: m3Easings.emphasizedDecelerate,\n duration: 0.21,\n },\n scale: {\n ease: m3Easings.emphasizedDecelerate,\n duration: 0.21,\n },\n },\n },\n exit: {\n opacity: 0,\n transition: customTransition || {\n opacity: {\n ease: m3Easings.emphasizedAccelerate,\n duration: 0.09,\n },\n },\n },\n };\n\n const resolvedVariants = customVariants || defaultVariants;\n\n return (\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={stateKey}\n variants={resolvedVariants}\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n style={{ willChange: \"opacity, transform\" }}\n {...props}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n );\n};\n\nM3FadeThrough.displayName = \"M3FadeThrough\";\n\n","import * as React from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { HTMLMotionProps } from \"motion/react\";\nimport { m3Easings, m3Durations } from \"../easings.js\";\n\nexport interface M3CollapseProps extends HTMLMotionProps<\"div\"> {\n /**\n * If true, the component expands. If false, it collapses.\n * If omitted, the component behaves as a standard motion element meant to be unmounted/mounted\n * by an external <AnimatePresence>.\n */\n in?: boolean;\n /**\n * If true, animate the transition on initial mount.\n * @default false\n */\n appear?: boolean;\n}\n\n/**\n * M3Collapse transition component.\n * Animates the height and opacity of its children, perfect for accordions, menus, or disclosures.\n */\nexport const M3Collapse = React.forwardRef<HTMLDivElement, M3CollapseProps>(\n ({ in: inProp, appear = false, children, ...props }, ref) => {\n const variants = {\n initial: { height: 0, opacity: 0 },\n animate: {\n height: \"auto\",\n opacity: 1,\n transition: {\n height: {\n ease: m3Easings.emphasized,\n duration: m3Durations.medium4,\n },\n opacity: {\n ease: m3Easings.standard,\n duration: m3Durations.medium2,\n },\n },\n },\n exit: {\n height: 0,\n opacity: 0,\n transition: {\n height: {\n ease: m3Easings.emphasized,\n duration: m3Durations.medium4,\n },\n opacity: {\n ease: m3Easings.standard,\n duration: m3Durations.medium2,\n },\n },\n },\n };\n\n const content = (\n <motion.div\n ref={ref}\n variants={variants}\n initial={appear ? \"initial\" : false}\n animate=\"animate\"\n exit=\"exit\"\n style={{ overflow: \"hidden\", willChange: \"height, opacity\" }}\n {...props}\n >\n {children}\n </motion.div>\n );\n\n if (inProp !== undefined) {\n return <AnimatePresence initial={appear}>{inProp ? content : null}</AnimatePresence>;\n }\n\n return content;\n },\n);\n\nM3Collapse.displayName = \"M3Collapse\";\n","import * as React from \"react\";\nimport { motion } from \"motion/react\";\nimport type { HTMLMotionProps, Transition, MotionStyle } from \"motion/react\";\nimport { m3Springs } from \"../springs.js\";\nimport { m3Easings } from \"../easings.js\";\n\nexport interface M3ContainerTransformProps extends HTMLMotionProps<\"div\"> {\n /**\n * Shared identifier linking the starting container (e.g., card) and ending container (e.g., detail page).\n */\n layoutId?: string;\n /**\n * Speed preset to use for the morphing animation.\n * @default \"default\"\n */\n speed?: \"fast\" | \"default\" | \"slow\";\n /**\n * If true, renders the expanded container state.\n * @default false\n */\n isExpanded?: boolean;\n}\n\nexport interface M3ContainerTransformContextValue {\n isExpanded: boolean;\n speed: \"fast\" | \"default\" | \"slow\";\n}\n\nexport const M3ContainerTransformContext = React.createContext<M3ContainerTransformContextValue | null>(null);\n\n/**\n * Helper function to generate spec-compliant cross-fade timings.\n */\nfunction getDefaultTransition(isActive: boolean, speed: \"fast\" | \"default\" | \"slow\"): Transition {\n if (speed === \"fast\") {\n return isActive\n ? { delay: 0.05, duration: 0.15, ease: m3Easings.emphasizedDecelerate }\n : { duration: 0.08, ease: m3Easings.emphasizedAccelerate };\n }\n if (speed === \"slow\") {\n return isActive\n ? { delay: 0.2, duration: 0.6, ease: m3Easings.emphasizedDecelerate }\n : { duration: 0.25, ease: m3Easings.emphasizedAccelerate };\n }\n // Default speed\n return isActive\n ? { delay: 0.1, duration: 0.35, ease: m3Easings.emphasizedDecelerate }\n : { duration: 0.15, ease: m3Easings.emphasizedAccelerate };\n}\n\n/**\n * M3ContainerTransform component.\n * Implements the Material 3 Container Transform motion pattern using shared element transitions.\n * Use the same layoutId on both source and target containers to morph them smoothly.\n */\nexport const M3ContainerTransform = React.forwardRef<HTMLDivElement, M3ContainerTransformProps>(\n ({ layoutId, speed = \"default\", isExpanded = false, children, transition, style, ...props }, ref) => {\n // Select the M3 spatial spring configuration based on speed\n const springConfig = m3Springs[speed].spatial;\n\n const contextValue = React.useMemo(\n () => ({ isExpanded, speed }),\n [isExpanded, speed]\n );\n\n return (\n <M3ContainerTransformContext.Provider value={contextValue}>\n <motion.div\n ref={ref}\n layoutId={layoutId}\n layout\n transition={transition || springConfig}\n style={{\n willChange: \"transform, border-radius\",\n overflow: \"hidden\",\n ...style,\n }}\n {...props}\n >\n {children}\n </motion.div>\n </M3ContainerTransformContext.Provider>\n );\n },\n);\n\nM3ContainerTransform.displayName = \"M3ContainerTransform\";\n\nexport interface M3ContainerTransformStartProps extends HTMLMotionProps<\"div\"> {\n /**\n * Overrides the active state. By default, active when isExpanded is false.\n */\n active?: boolean;\n}\n\n/**\n * M3ContainerTransformStart component.\n * Represents the starting content (e.g., Card content) inside M3ContainerTransform.\n * Prevents aspect ratio distortion and fades out during the container transform morph.\n */\nexport const M3ContainerTransformStart = React.forwardRef<HTMLDivElement, M3ContainerTransformStartProps>(\n ({ active, children, style, transition, layout = \"position\", ...props }, ref) => {\n const context = React.useContext(M3ContainerTransformContext);\n const isActive = active ?? (context ? !context.isExpanded : true);\n const speed = context?.speed ?? \"default\";\n\n const baseStyle: MotionStyle = {\n width: \"100%\",\n height: \"100%\",\n boxSizing: \"border-box\",\n pointerEvents: isActive ? \"auto\" : \"none\",\n ...(!isActive && {\n position: \"absolute\",\n top: 0,\n left: 0,\n }),\n ...style,\n };\n\n const resolvedTransition = transition || getDefaultTransition(isActive, speed);\n\n return (\n <motion.div\n ref={ref}\n layout={layout}\n animate={{ opacity: isActive ? 1 : 0 }}\n transition={resolvedTransition}\n style={baseStyle}\n {...props}\n >\n {children}\n </motion.div>\n );\n },\n);\n\nM3ContainerTransformStart.displayName = \"M3ContainerTransformStart\";\n\nexport interface M3ContainerTransformEndProps extends HTMLMotionProps<\"div\"> {\n /**\n * Overrides the active state. By default, active when isExpanded is true.\n */\n active?: boolean;\n}\n\n/**\n * M3ContainerTransformEnd component.\n * Represents the target content (e.g., Detail page content) inside M3ContainerTransform.\n * Prevents aspect ratio distortion and fades in during the container transform morph.\n */\nexport const M3ContainerTransformEnd = React.forwardRef<HTMLDivElement, M3ContainerTransformEndProps>(\n ({ active, children, style, transition, layout = \"position\", ...props }, ref) => {\n const context = React.useContext(M3ContainerTransformContext);\n const isActive = active ?? (context ? context.isExpanded : true);\n const speed = context?.speed ?? \"default\";\n\n const baseStyle: MotionStyle = {\n width: \"100%\",\n height: \"100%\",\n boxSizing: \"border-box\",\n pointerEvents: isActive ? \"auto\" : \"none\",\n ...(!isActive && {\n position: \"absolute\",\n top: 0,\n left: 0,\n }),\n ...style,\n };\n\n const resolvedTransition = transition || getDefaultTransition(isActive, speed);\n\n return (\n <motion.div\n ref={ref}\n layout={layout}\n initial={{ opacity: 0 }}\n animate={{ opacity: isActive ? 1 : 0 }}\n transition={resolvedTransition}\n style={baseStyle}\n {...props}\n >\n {children}\n </motion.div>\n );\n },\n);\n\nM3ContainerTransformEnd.displayName = \"M3ContainerTransformEnd\";\n\n","\"use client\";\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport type { HTMLMotionProps, MotionStyle, Transition, Variants } from \"motion/react\";\nimport { m3Easings, m3Durations } from \"../easings.js\";\n\nexport type M3TransitionPattern =\n | \"fade\"\n | \"fade-through\"\n | \"shared-axis-x\"\n | \"shared-axis-y\"\n | \"shared-axis-z\"\n | \"collapse\";\n\nexport interface M3TransitionProps extends Omit<HTMLMotionProps<\"div\">, \"variants\" | \"style\"> {\n style?: MotionStyle;\n /**\n * Unique key representing the active view/content. Changing this key triggers the transition.\n */\n stateKey: React.Key;\n /**\n * Which M3 transition pattern to apply.\n * @default \"fade\"\n */\n pattern?: M3TransitionPattern;\n /**\n * Direction of navigation for shared-axis-* patterns.\n * @default true\n */\n forward?: boolean;\n /**\n * Custom variants — overrides the pattern defaults entirely.\n */\n variants?: Variants;\n /**\n * AnimatePresence mode.\n * @default \"wait\"\n */\n mode?: \"wait\" | \"sync\" | \"popLayout\";\n}\n\nconst OFFSET = 30;\nconst SCALE_OFFSET = 0.08;\n\nfunction buildVariants(pattern: M3TransitionPattern, forward: boolean): Variants {\n const enterTransition: Transition = {\n ease: m3Easings.emphasizedDecelerate,\n duration: m3Durations.medium2,\n };\n const exitTransition: Transition = {\n ease: m3Easings.emphasizedAccelerate,\n duration: m3Durations.short4,\n };\n\n switch (pattern) {\n case \"fade-through\":\n return {\n initial: { opacity: 0, scale: 0.92 },\n animate: {\n opacity: 1,\n scale: 1,\n transition: {\n opacity: { ease: m3Easings.emphasizedDecelerate, duration: 0.21 },\n scale: { ease: m3Easings.emphasizedDecelerate, duration: 0.21 },\n },\n },\n exit: {\n opacity: 0,\n transition: { opacity: { ease: m3Easings.emphasizedAccelerate, duration: 0.09 } },\n },\n };\n case \"shared-axis-x\":\n return {\n initial: { opacity: 0, x: forward ? OFFSET : -OFFSET },\n animate: {\n opacity: 1,\n x: 0,\n transition: {\n x: enterTransition,\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\n },\n },\n exit: {\n opacity: 0,\n x: forward ? -OFFSET : OFFSET,\n transition: {\n x: exitTransition,\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\n },\n },\n };\n case \"shared-axis-y\":\n return {\n initial: { opacity: 0, y: forward ? OFFSET : -OFFSET },\n animate: {\n opacity: 1,\n y: 0,\n transition: {\n y: enterTransition,\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\n },\n },\n exit: {\n opacity: 0,\n y: forward ? -OFFSET : OFFSET,\n transition: {\n y: exitTransition,\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\n },\n },\n };\n case \"shared-axis-z\":\n return {\n initial: { opacity: 0, scale: forward ? 1 - SCALE_OFFSET : 1 + SCALE_OFFSET },\n animate: {\n opacity: 1,\n scale: 1,\n transition: {\n scale: enterTransition,\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\n },\n },\n exit: {\n opacity: 0,\n scale: forward ? 1 + SCALE_OFFSET : 1 - SCALE_OFFSET,\n transition: {\n scale: exitTransition,\n opacity: { ease: m3Easings.standard, duration: m3Durations.short4 },\n },\n },\n };\n case \"collapse\":\n return {\n initial: { height: 0, opacity: 0 },\n animate: {\n height: \"auto\",\n opacity: 1,\n transition: {\n height: { ease: m3Easings.emphasized, duration: m3Durations.medium4 },\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\n },\n },\n exit: {\n height: 0,\n opacity: 0,\n transition: {\n height: { ease: m3Easings.emphasized, duration: m3Durations.medium4 },\n opacity: { ease: m3Easings.standard, duration: m3Durations.medium2 },\n },\n },\n };\n case \"fade\":\n default:\n return {\n initial: { opacity: 0 },\n animate: { opacity: 1, transition: enterTransition },\n exit: { opacity: 0, transition: exitTransition },\n };\n }\n}\n\n/**\n * M3Transition — generic Material 3 transition wrapper.\n * Supports all standard M3 patterns via the `pattern` prop.\n * The `stateKey` prop drives AnimatePresence re-mounts.\n */\nexport const M3Transition = React.forwardRef<HTMLDivElement, M3TransitionProps>(\n (\n {\n stateKey,\n pattern = \"fade\",\n forward = true,\n mode = \"wait\",\n variants,\n children,\n style,\n ...props\n },\n ref,\n ) => {\n const resolvedVariants = variants ?? buildVariants(pattern, forward);\n const baseStyle: MotionStyle =\n pattern === \"collapse\" ? { overflow: \"hidden\" } : { willChange: \"opacity, transform\" };\n const resolvedStyle: MotionStyle = { ...baseStyle, ...style };\n\n return (\n <AnimatePresence mode={mode}>\n <motion.div\n key={stateKey}\n ref={ref}\n variants={resolvedVariants}\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n style={resolvedStyle}\n {...props}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n );\n },\n);\n\nM3Transition.displayName = \"M3Transition\";\n","\"use client\";\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport type { HTMLMotionProps, Variants } from \"motion/react\";\nimport { m3Easings, m3Durations } from \"../easings.js\";\n\nexport interface M3ListStaggerProps {\n /**\n * Delay between each child item entering the scene (seconds).\n * @default 0.05\n */\n staggerDelay?: number;\n /**\n * Delay before the stagger sequence starts (seconds).\n * @default 0\n */\n delayChildren?: number;\n /**\n * If true, items animate on initial render.\n * @default true\n */\n appear?: boolean;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n}\n\nexport interface M3ListStaggerItemProps extends HTMLMotionProps<\"div\"> {\n children?: React.ReactNode;\n}\n\nconst containerVariants: Variants = {\n hidden: {},\n visible: (_custom: { staggerDelay: number; delayChildren: number }) => ({\n transition: {\n staggerChildren: _custom.staggerDelay,\n delayChildren: _custom.delayChildren,\n },\n }),\n exit: {},\n};\n\nconst itemVariants: Variants = {\n hidden: { opacity: 0, y: 8 },\n visible: {\n opacity: 1,\n y: 0,\n transition: {\n ease: m3Easings.emphasizedDecelerate,\n duration: m3Durations.medium2,\n },\n },\n exit: {\n opacity: 0,\n y: 4,\n transition: {\n ease: m3Easings.emphasizedAccelerate,\n duration: m3Durations.short3,\n },\n },\n};\n\n/**\n * M3ListStagger — stagger container for list-item enter/exit animations.\n *\n * Usage:\n * <M3ListStagger>\n * {items.map(item => <M3ListStaggerItem key={item.id}>{item.label}</M3ListStaggerItem>)}\n * </M3ListStagger>\n */\nexport const M3ListStagger = React.forwardRef<HTMLDivElement, M3ListStaggerProps>(\n ({ staggerDelay = 0.05, delayChildren = 0, appear = true, children, className, style }, ref) => {\n return (\n <AnimatePresence>\n <motion.div\n ref={ref}\n className={className}\n style={style}\n variants={containerVariants}\n initial={appear ? \"hidden\" : false}\n animate=\"visible\"\n exit=\"exit\"\n custom={{ staggerDelay, delayChildren }}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n );\n },\n);\n\nM3ListStagger.displayName = \"M3ListStagger\";\n\n/**\n * M3ListStaggerItem — a single animated item inside M3ListStagger.\n * Must be a direct or indirect descendant of M3ListStagger to inherit variants.\n */\nexport const M3ListStaggerItem = React.forwardRef<HTMLDivElement, M3ListStaggerItemProps>(\n ({ children, style, ...props }, ref) => {\n return (\n <motion.div\n ref={ref}\n variants={itemVariants}\n style={{ willChange: \"opacity, transform\", ...style }}\n {...props}\n >\n {children}\n </motion.div>\n );\n },\n);\n\nM3ListStaggerItem.displayName = \"M3ListStaggerItem\";\n","import { useAnimate } from \"motion/react\";\nimport type {\n AnimationScope,\n AnimationPlaybackControlsWithThen,\n AnimationSequence,\n SequenceOptions,\n ElementOrSelector,\n DOMKeyframesDefinition,\n AnimationOptions,\n MotionValue,\n UnresolvedValueKeyframe,\n ValueAnimationTransition,\n ObjectTarget,\n} from \"motion/react\";\nimport { m3Easings, m3Durations } from \"../easings.js\";\n\n/**\n * Overloaded type for the scoped animate function returned by useM3Animate.\n * Mirrors the overload set of the underlying motion animate, adding M3 defaults.\n */\nexport interface M3AnimateFn {\n (sequence: AnimationSequence, options?: SequenceOptions): AnimationPlaybackControlsWithThen;\n (\n value: string | MotionValue<string>,\n keyframes: string | UnresolvedValueKeyframe<string>[],\n options?: ValueAnimationTransition<string>,\n ): AnimationPlaybackControlsWithThen;\n (\n value: number | MotionValue<number>,\n keyframes: number | UnresolvedValueKeyframe<number>[],\n options?: ValueAnimationTransition<number>,\n ): AnimationPlaybackControlsWithThen;\n <V extends string | number>(\n value: V | MotionValue<V>,\n keyframes: V | UnresolvedValueKeyframe<V>[],\n options?: ValueAnimationTransition<V>,\n ): AnimationPlaybackControlsWithThen;\n (\n element: ElementOrSelector,\n keyframes: DOMKeyframesDefinition,\n options?: AnimationOptions,\n ): AnimationPlaybackControlsWithThen;\n <O extends object>(\n object: O | O[],\n keyframes: ObjectTarget<O>,\n options?: AnimationOptions,\n ): AnimationPlaybackControlsWithThen;\n}\n\n/**\n * A custom hook wrapping motion's `useAnimate` that injects Material 3 motion defaults\n * (emphasized easing and medium2 duration) for all imperative DOM animations.\n *\n * SSR-safe: useAnimate creates refs; no DOM access occurs at module or render time.\n */\nexport function useM3Animate<T extends Element = HTMLElement>(): [AnimationScope<T>, M3AnimateFn] {\n const [scope, animate] = useAnimate<T>();\n\n const m3Animate: M3AnimateFn = (\n elementOrSelector: unknown,\n keyframes?: unknown,\n options?: unknown,\n ) => {\n if (Array.isArray(elementOrSelector)) {\n // Sequence overload\n return (animate as CallableFunction)(\n elementOrSelector,\n keyframes as SequenceOptions,\n ) as AnimationPlaybackControlsWithThen;\n }\n\n if (\n typeof elementOrSelector === \"string\" ||\n elementOrSelector instanceof Element ||\n (typeof elementOrSelector === \"object\" &&\n elementOrSelector !== null &&\n \"current\" in elementOrSelector) ||\n typeof elementOrSelector === \"number\" ||\n (typeof elementOrSelector === \"object\" &&\n elementOrSelector !== null &&\n \"get\" in elementOrSelector)\n ) {\n return (animate as CallableFunction)(elementOrSelector, keyframes, {\n ease: m3Easings.emphasized,\n duration: m3Durations.medium2,\n ...(typeof options === \"object\" && options !== null ? options : {}),\n }) as AnimationPlaybackControlsWithThen;\n }\n\n return (animate as CallableFunction)(elementOrSelector, keyframes, {\n ease: m3Easings.emphasized,\n duration: m3Durations.medium2,\n ...(typeof options === \"object\" && options !== null ? options : {}),\n }) as AnimationPlaybackControlsWithThen;\n };\n\n return [scope, m3Animate];\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aphrody/m3-motion",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "Material 3 animation plugin powered by Motion (formerly Framer Motion)",
|
|
5
5
|
"homepage": "https://github.com/aphrody-code/material-web/tree/main/packages/m3-motion#readme",
|
|
6
6
|
"bugs": {
|