@enact-ui/animate 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api-schema.json +206 -0
- package/dist/components/CountUp.d.ts +84 -0
- package/dist/components/CountUp.d.ts.map +1 -0
- package/dist/components/CountUp.js +68 -0
- package/dist/components/CountUp.js.map +1 -0
- package/dist/components/MotionDiv.d.ts +159 -0
- package/dist/components/MotionDiv.d.ts.map +1 -0
- package/dist/components/MotionDiv.js +162 -0
- package/dist/components/MotionDiv.js.map +1 -0
- package/dist/components/StaggerContainer.d.ts +136 -0
- package/dist/components/StaggerContainer.d.ts.map +1 -0
- package/dist/components/StaggerContainer.js +166 -0
- package/dist/components/StaggerContainer.js.map +1 -0
- package/dist/hooks/use-component-animation.d.ts +156 -0
- package/dist/hooks/use-component-animation.d.ts.map +1 -0
- package/dist/hooks/use-component-animation.js +231 -0
- package/dist/hooks/use-component-animation.js.map +1 -0
- package/dist/hooks/use-count-up.d.ts +111 -0
- package/dist/hooks/use-count-up.d.ts.map +1 -0
- package/dist/hooks/use-count-up.js +246 -0
- package/dist/hooks/use-count-up.js.map +1 -0
- package/dist/hooks/use-draw-path.d.ts +96 -0
- package/dist/hooks/use-draw-path.d.ts.map +1 -0
- package/dist/hooks/use-draw-path.js +227 -0
- package/dist/hooks/use-draw-path.js.map +1 -0
- package/dist/hooks/use-motion-preset.d.ts.map +1 -1
- package/dist/hooks/use-motion-preset.js +17 -16
- package/dist/hooks/use-motion-preset.js.map +1 -1
- package/dist/hooks/use-stagger.d.ts +174 -0
- package/dist/hooks/use-stagger.d.ts.map +1 -0
- package/dist/hooks/use-stagger.js +256 -0
- package/dist/hooks/use-stagger.js.map +1 -0
- package/dist/index.d.ts +17 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2442 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2335 -25
- package/dist/index.mjs.map +1 -1
- package/dist/presets/component-presets.d.ts +246 -0
- package/dist/presets/component-presets.d.ts.map +1 -0
- package/dist/presets/component-presets.js +472 -0
- package/dist/presets/component-presets.js.map +1 -0
- package/dist/presets/micro-interactions.d.ts +451 -0
- package/dist/presets/micro-interactions.d.ts.map +1 -0
- package/dist/presets/micro-interactions.js +856 -0
- package/dist/presets/micro-interactions.js.map +1 -0
- package/dist/presets/motion-presets.d.ts.map +1 -1
- package/dist/presets/motion-presets.js +0 -1
- package/dist/presets/motion-presets.js.map +1 -1
- package/dist/presets/motion-styles.d.ts +186 -0
- package/dist/presets/motion-styles.d.ts.map +1 -0
- package/dist/presets/motion-styles.js +204 -0
- package/dist/presets/motion-styles.js.map +1 -0
- package/dist/presets/stagger-presets.d.ts +378 -0
- package/dist/presets/stagger-presets.d.ts.map +1 -0
- package/dist/presets/stagger-presets.js +582 -0
- package/dist/presets/stagger-presets.js.map +1 -0
- package/dist/showcase/motion-presets.demo.d.ts +25 -0
- package/dist/showcase/motion-presets.demo.d.ts.map +1 -0
- package/dist/showcase/motion-presets.demo.js +96 -0
- package/dist/showcase/motion-presets.demo.js.map +1 -0
- package/dist/showcase/motion-presets.story.d.ts +37 -0
- package/dist/showcase/motion-presets.story.d.ts.map +1 -0
- package/dist/showcase/motion-presets.story.js +151 -0
- package/dist/showcase/motion-presets.story.js.map +1 -0
- package/dist/utils/easing.d.ts +294 -0
- package/dist/utils/easing.d.ts.map +1 -0
- package/dist/utils/easing.js +265 -0
- package/dist/utils/easing.js.map +1 -0
- package/dist/utils/reduced-motion.d.ts +322 -0
- package/dist/utils/reduced-motion.d.ts.map +1 -0
- package/dist/utils/reduced-motion.js +362 -0
- package/dist/utils/reduced-motion.js.map +1 -0
- package/dist/utils/select-preset.d.ts +186 -0
- package/dist/utils/select-preset.d.ts.map +1 -0
- package/dist/utils/select-preset.js +320 -0
- package/dist/utils/select-preset.js.map +1 -0
- package/dist/utils/spring-configs.d.ts +187 -0
- package/dist/utils/spring-configs.d.ts.map +1 -0
- package/dist/utils/spring-configs.js +169 -0
- package/dist/utils/spring-configs.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
// Copyright (c) 2026 Amsterdam Data Labs
|
|
2
|
+
"use client";
|
|
3
|
+
/**
|
|
4
|
+
* Reduced Motion Utilities
|
|
5
|
+
*
|
|
6
|
+
* @ai-hint This module provides utilities for handling the `prefers-reduced-motion`
|
|
7
|
+
* media query. Use these utilities to ensure animations are accessible and respect
|
|
8
|
+
* user preferences for reduced motion.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { useEffect, useState } from "react";
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// =============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Media query string for detecting reduced motion preference.
|
|
18
|
+
*
|
|
19
|
+
* @ai-hint Use this constant when you need to directly query the media feature
|
|
20
|
+
* outside of the provided hooks.
|
|
21
|
+
*/
|
|
22
|
+
export const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
23
|
+
/**
|
|
24
|
+
* Default transition for reduced motion mode.
|
|
25
|
+
* Provides instant transitions without animation.
|
|
26
|
+
*
|
|
27
|
+
* @ai-hint This transition effectively disables animation while still
|
|
28
|
+
* allowing the final state to be applied immediately.
|
|
29
|
+
*/
|
|
30
|
+
export const INSTANT_TRANSITION = {
|
|
31
|
+
duration: 0,
|
|
32
|
+
delay: 0,
|
|
33
|
+
};
|
|
34
|
+
// =============================================================================
|
|
35
|
+
// Hooks
|
|
36
|
+
// =============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Hook that returns whether the user prefers reduced motion.
|
|
39
|
+
*
|
|
40
|
+
* @ai-hint This hook reactively tracks the `prefers-reduced-motion` media query.
|
|
41
|
+
* It updates automatically when the user changes their system preference.
|
|
42
|
+
* Use this hook to conditionally apply or skip animations.
|
|
43
|
+
*
|
|
44
|
+
* @returns `true` if the user prefers reduced motion, `false` otherwise
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* function AnimatedComponent() {
|
|
49
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
50
|
+
*
|
|
51
|
+
* return (
|
|
52
|
+
* <motion.div
|
|
53
|
+
* animate={{ x: 100 }}
|
|
54
|
+
* transition={prefersReducedMotion ? { duration: 0 } : { duration: 0.5 }}
|
|
55
|
+
* >
|
|
56
|
+
* Content
|
|
57
|
+
* </motion.div>
|
|
58
|
+
* );
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* // Skip animation entirely when reduced motion is preferred
|
|
65
|
+
* function FadeInComponent({ children }: { children: React.ReactNode }) {
|
|
66
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
67
|
+
*
|
|
68
|
+
* if (prefersReducedMotion) {
|
|
69
|
+
* return <div>{children}</div>;
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* return (
|
|
73
|
+
* <motion.div
|
|
74
|
+
* initial={{ opacity: 0 }}
|
|
75
|
+
* animate={{ opacity: 1 }}
|
|
76
|
+
* transition={{ duration: 0.3 }}
|
|
77
|
+
* >
|
|
78
|
+
* {children}
|
|
79
|
+
* </motion.div>
|
|
80
|
+
* );
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function useReducedMotion() {
|
|
85
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {
|
|
86
|
+
// Return false during SSR
|
|
87
|
+
if (typeof window === "undefined") {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return window.matchMedia(REDUCED_MOTION_QUERY).matches;
|
|
91
|
+
});
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
const mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY);
|
|
94
|
+
// Set initial value (handles hydration mismatch)
|
|
95
|
+
setPrefersReducedMotion(mediaQuery.matches);
|
|
96
|
+
// Listen for changes to the preference
|
|
97
|
+
const handleChange = (event) => {
|
|
98
|
+
setPrefersReducedMotion(event.matches);
|
|
99
|
+
};
|
|
100
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
101
|
+
return () => {
|
|
102
|
+
mediaQuery.removeEventListener("change", handleChange);
|
|
103
|
+
};
|
|
104
|
+
}, []);
|
|
105
|
+
return prefersReducedMotion;
|
|
106
|
+
}
|
|
107
|
+
// =============================================================================
|
|
108
|
+
// Utility Functions
|
|
109
|
+
// =============================================================================
|
|
110
|
+
/**
|
|
111
|
+
* Returns the appropriate variant based on reduced motion preference.
|
|
112
|
+
*
|
|
113
|
+
* @ai-hint Use this function to provide alternative animation variants for users
|
|
114
|
+
* who prefer reduced motion. The reduced variant should avoid or minimize
|
|
115
|
+
* movement-based animations while potentially preserving opacity/color changes.
|
|
116
|
+
*
|
|
117
|
+
* @param normalVariant - The variant to use when motion is allowed
|
|
118
|
+
* @param reducedVariant - The variant to use when reduced motion is preferred
|
|
119
|
+
* @returns The appropriate variant based on the current reduced motion preference
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```tsx
|
|
123
|
+
* function SlideInCard() {
|
|
124
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
125
|
+
*
|
|
126
|
+
* const normalVariant = {
|
|
127
|
+
* hidden: { x: -100, opacity: 0 },
|
|
128
|
+
* visible: { x: 0, opacity: 1 },
|
|
129
|
+
* };
|
|
130
|
+
*
|
|
131
|
+
* const reducedVariant = {
|
|
132
|
+
* hidden: { opacity: 0 },
|
|
133
|
+
* visible: { opacity: 1 },
|
|
134
|
+
* };
|
|
135
|
+
*
|
|
136
|
+
* const variants = getReducedMotionVariant(
|
|
137
|
+
* normalVariant,
|
|
138
|
+
* reducedVariant,
|
|
139
|
+
* prefersReducedMotion
|
|
140
|
+
* );
|
|
141
|
+
*
|
|
142
|
+
* return (
|
|
143
|
+
* <motion.div
|
|
144
|
+
* variants={variants}
|
|
145
|
+
* initial="hidden"
|
|
146
|
+
* animate="visible"
|
|
147
|
+
* >
|
|
148
|
+
* Card Content
|
|
149
|
+
* </motion.div>
|
|
150
|
+
* );
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```tsx
|
|
156
|
+
* // Using with a hook for reactive updates
|
|
157
|
+
* function AnimatedList({ items }: { items: string[] }) {
|
|
158
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
159
|
+
*
|
|
160
|
+
* const itemVariant = getReducedMotionVariant(
|
|
161
|
+
* { hidden: { y: 20, opacity: 0 }, visible: { y: 0, opacity: 1 } },
|
|
162
|
+
* { hidden: { opacity: 0 }, visible: { opacity: 1 } },
|
|
163
|
+
* prefersReducedMotion
|
|
164
|
+
* );
|
|
165
|
+
*
|
|
166
|
+
* return (
|
|
167
|
+
* <motion.ul>
|
|
168
|
+
* {items.map((item, i) => (
|
|
169
|
+
* <motion.li
|
|
170
|
+
* key={item}
|
|
171
|
+
* variants={itemVariant}
|
|
172
|
+
* initial="hidden"
|
|
173
|
+
* animate="visible"
|
|
174
|
+
* transition={{ delay: i * 0.1 }}
|
|
175
|
+
* >
|
|
176
|
+
* {item}
|
|
177
|
+
* </motion.li>
|
|
178
|
+
* ))}
|
|
179
|
+
* </motion.ul>
|
|
180
|
+
* );
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export function getReducedMotionVariant(normalVariant, reducedVariant, prefersReducedMotion) {
|
|
185
|
+
return prefersReducedMotion ? reducedVariant : normalVariant;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Properties that are considered safe for reduced motion mode.
|
|
189
|
+
* These typically don't involve movement and are accessibility-friendly.
|
|
190
|
+
*
|
|
191
|
+
* @ai-hint Opacity and color changes are generally acceptable even for users
|
|
192
|
+
* who prefer reduced motion, as they don't cause vestibular issues.
|
|
193
|
+
*/
|
|
194
|
+
const _SAFE_ANIMATION_PROPERTIES = new Set(["opacity", "color", "backgroundColor", "borderColor", "fill", "stroke"]);
|
|
195
|
+
/**
|
|
196
|
+
* Filters a variant to only include safe properties for reduced motion.
|
|
197
|
+
*
|
|
198
|
+
* @param variant - The variant to filter
|
|
199
|
+
* @param options - Options for filtering
|
|
200
|
+
* @returns Filtered variant with only safe properties
|
|
201
|
+
*/
|
|
202
|
+
function filterVariantForReducedMotion(variant, options) {
|
|
203
|
+
const { preserveOpacity = true, preserveColors = true } = options;
|
|
204
|
+
const filtered = {};
|
|
205
|
+
for (const [key, value] of Object.entries(variant)) {
|
|
206
|
+
const isOpacityProperty = key === "opacity";
|
|
207
|
+
const isColorProperty = key === "color" || key === "backgroundColor" || key === "borderColor" || key === "fill" || key === "stroke";
|
|
208
|
+
if ((preserveOpacity && isOpacityProperty) || (preserveColors && isColorProperty)) {
|
|
209
|
+
filtered[key] = value;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return filtered;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Wraps Motion props to respect the user's reduced motion preference.
|
|
216
|
+
*
|
|
217
|
+
* @ai-hint This function transforms Motion component props to be accessibility-friendly.
|
|
218
|
+
* When reduced motion is preferred, it either disables animations or preserves
|
|
219
|
+
* only safe properties (like opacity) based on the options provided.
|
|
220
|
+
*
|
|
221
|
+
* @param props - The original Motion props
|
|
222
|
+
* @param prefersReducedMotion - Whether reduced motion is preferred
|
|
223
|
+
* @param options - Options for customizing reduced motion behavior
|
|
224
|
+
* @returns Transformed props that respect reduced motion preference
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```tsx
|
|
228
|
+
* function AccessibleMotionDiv({ children }: { children: React.ReactNode }) {
|
|
229
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
230
|
+
*
|
|
231
|
+
* const baseProps: MotionProps = {
|
|
232
|
+
* initial: { x: -50, opacity: 0 },
|
|
233
|
+
* animate: { x: 0, opacity: 1 },
|
|
234
|
+
* transition: { duration: 0.5 },
|
|
235
|
+
* };
|
|
236
|
+
*
|
|
237
|
+
* const accessibleProps = createReducedMotionProps(
|
|
238
|
+
* baseProps,
|
|
239
|
+
* prefersReducedMotion
|
|
240
|
+
* );
|
|
241
|
+
*
|
|
242
|
+
* return <motion.div {...accessibleProps}>{children}</motion.div>;
|
|
243
|
+
* }
|
|
244
|
+
* ```
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```tsx
|
|
248
|
+
* // Preserve opacity transitions in reduced motion mode
|
|
249
|
+
* function FadeSlideComponent() {
|
|
250
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
251
|
+
*
|
|
252
|
+
* const props = createReducedMotionProps(
|
|
253
|
+
* {
|
|
254
|
+
* initial: { y: 20, opacity: 0 },
|
|
255
|
+
* animate: { y: 0, opacity: 1 },
|
|
256
|
+
* transition: { duration: 0.3 },
|
|
257
|
+
* },
|
|
258
|
+
* prefersReducedMotion,
|
|
259
|
+
* { preserveOpacity: true }
|
|
260
|
+
* );
|
|
261
|
+
*
|
|
262
|
+
* // In reduced motion: only opacity animates, y is instant
|
|
263
|
+
* return <motion.div {...props}>Content</motion.div>;
|
|
264
|
+
* }
|
|
265
|
+
* ```
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```tsx
|
|
269
|
+
* // Custom reduced transition
|
|
270
|
+
* function CustomReducedMotion() {
|
|
271
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
272
|
+
*
|
|
273
|
+
* const props = createReducedMotionProps(
|
|
274
|
+
* {
|
|
275
|
+
* animate: { scale: 1.1 },
|
|
276
|
+
* transition: { duration: 0.5 },
|
|
277
|
+
* },
|
|
278
|
+
* prefersReducedMotion,
|
|
279
|
+
* {
|
|
280
|
+
* reducedTransition: { duration: 0.1, ease: "linear" },
|
|
281
|
+
* }
|
|
282
|
+
* );
|
|
283
|
+
*
|
|
284
|
+
* return <motion.button {...props}>Hover me</motion.button>;
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
export function createReducedMotionProps(props, prefersReducedMotion, options = {}) {
|
|
289
|
+
// If reduced motion is not preferred, return props as-is
|
|
290
|
+
if (!prefersReducedMotion) {
|
|
291
|
+
return props;
|
|
292
|
+
}
|
|
293
|
+
const { preserveOpacity = true, preserveColors = true, reducedTransition } = options;
|
|
294
|
+
// Use provided reduced transition or default to instant
|
|
295
|
+
const transition = reducedTransition ?? INSTANT_TRANSITION;
|
|
296
|
+
// Helper to process variant-like objects
|
|
297
|
+
const processVariant = (variant) => {
|
|
298
|
+
if (variant === undefined || typeof variant === "string" || typeof variant === "boolean") {
|
|
299
|
+
return variant;
|
|
300
|
+
}
|
|
301
|
+
return filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });
|
|
302
|
+
};
|
|
303
|
+
// Helper to process variants object
|
|
304
|
+
const processVariants = (variants) => {
|
|
305
|
+
if (!variants) {
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
const processed = {};
|
|
309
|
+
for (const [key, variant] of Object.entries(variants)) {
|
|
310
|
+
processed[key] = filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });
|
|
311
|
+
}
|
|
312
|
+
return processed;
|
|
313
|
+
};
|
|
314
|
+
// Process animate/exit/whileInView - these don't accept boolean
|
|
315
|
+
const processNonBooleanVariant = (variant) => {
|
|
316
|
+
if (variant === undefined || typeof variant === "string") {
|
|
317
|
+
return variant;
|
|
318
|
+
}
|
|
319
|
+
return filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });
|
|
320
|
+
};
|
|
321
|
+
return {
|
|
322
|
+
...props,
|
|
323
|
+
initial: processVariant(props.initial),
|
|
324
|
+
animate: processNonBooleanVariant(props.animate),
|
|
325
|
+
exit: processNonBooleanVariant(props.exit),
|
|
326
|
+
variants: processVariants(props.variants),
|
|
327
|
+
transition,
|
|
328
|
+
// Disable hover/tap/focus animations in reduced motion mode
|
|
329
|
+
// as they often involve movement
|
|
330
|
+
whileHover: undefined,
|
|
331
|
+
whileTap: undefined,
|
|
332
|
+
whileFocus: undefined,
|
|
333
|
+
whileDrag: undefined,
|
|
334
|
+
whileInView: processNonBooleanVariant(props.whileInView),
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Checks if reduced motion is preferred (non-reactive, for one-time checks).
|
|
339
|
+
*
|
|
340
|
+
* @ai-hint Use this function for one-time checks outside of React components.
|
|
341
|
+
* For reactive behavior within components, prefer the `useReducedMotion` hook.
|
|
342
|
+
*
|
|
343
|
+
* @returns `true` if reduced motion is preferred, `false` otherwise (including SSR)
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```ts
|
|
347
|
+
* // In a utility function
|
|
348
|
+
* function getAnimationDuration(baseDuration: number): number {
|
|
349
|
+
* if (checkReducedMotion()) {
|
|
350
|
+
* return 0;
|
|
351
|
+
* }
|
|
352
|
+
* return baseDuration;
|
|
353
|
+
* }
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
export function checkReducedMotion() {
|
|
357
|
+
if (typeof window === "undefined") {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
return window.matchMedia(REDUCED_MOTION_QUERY).matches;
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=reduced-motion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reduced-motion.js","sourceRoot":"","sources":["../../src/utils/reduced-motion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI-Driven Preset Selection
|
|
3
|
+
*
|
|
4
|
+
* Utilities for intelligently selecting animation presets based on
|
|
5
|
+
* context, use case, and preferences. Designed to be used by AI tools
|
|
6
|
+
* for automatic animation selection.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { type ComponentPreset, type ComponentPresetName, type PresetContext, type PresetUseCase } from "../presets/component-presets";
|
|
11
|
+
import type { MotionStyle } from "../presets/motion-styles";
|
|
12
|
+
/**
|
|
13
|
+
* Criteria for selecting a preset.
|
|
14
|
+
*/
|
|
15
|
+
export interface SelectionCriteria {
|
|
16
|
+
/** Primary use case for the animation */
|
|
17
|
+
useCase?: PresetUseCase;
|
|
18
|
+
/** Context where the animation will be used */
|
|
19
|
+
context?: PresetContext;
|
|
20
|
+
/** Preferred motion style */
|
|
21
|
+
style?: MotionStyle;
|
|
22
|
+
/** Maximum intensity level (1-5) */
|
|
23
|
+
maxIntensity?: number;
|
|
24
|
+
/** Minimum intensity level (1-5) */
|
|
25
|
+
minIntensity?: number;
|
|
26
|
+
/** Whether movement is desired */
|
|
27
|
+
preferMovement?: boolean;
|
|
28
|
+
/** Preferred direction of movement */
|
|
29
|
+
direction?: "up" | "down" | "left" | "right" | "in" | "out";
|
|
30
|
+
/** Whether to prioritize accessibility */
|
|
31
|
+
prioritizeAccessibility?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Result of preset selection with reasoning.
|
|
35
|
+
*/
|
|
36
|
+
export interface SelectionResult {
|
|
37
|
+
/** The selected preset */
|
|
38
|
+
preset: ComponentPreset;
|
|
39
|
+
/** Name of the selected preset */
|
|
40
|
+
presetName: ComponentPresetName;
|
|
41
|
+
/** Recommended motion style */
|
|
42
|
+
style: MotionStyle;
|
|
43
|
+
/** Confidence score (0-1) */
|
|
44
|
+
confidence: number;
|
|
45
|
+
/** Reasoning for the selection */
|
|
46
|
+
reasoning: string;
|
|
47
|
+
/** Alternative presets that could work */
|
|
48
|
+
alternatives: ComponentPresetName[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Preset recommendation for a specific context.
|
|
52
|
+
*/
|
|
53
|
+
export interface PresetRecommendation {
|
|
54
|
+
/** Recommended preset */
|
|
55
|
+
preset: ComponentPreset;
|
|
56
|
+
/** Preset name */
|
|
57
|
+
name: ComponentPresetName;
|
|
58
|
+
/** Why this preset is recommended */
|
|
59
|
+
reason: string;
|
|
60
|
+
/** Score (0-1) */
|
|
61
|
+
score: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Selects the best preset based on criteria.
|
|
65
|
+
*
|
|
66
|
+
* This function analyzes the given criteria and returns the most
|
|
67
|
+
* appropriate animation preset along with reasoning.
|
|
68
|
+
*
|
|
69
|
+
* @ai-hint Use this function to automatically select animations based on
|
|
70
|
+
* the component's context and requirements. Pass as much information as
|
|
71
|
+
* possible for better selection.
|
|
72
|
+
*
|
|
73
|
+
* @param criteria - Selection criteria
|
|
74
|
+
* @returns Selection result with preset and reasoning
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const result = selectPreset({
|
|
79
|
+
* useCase: "entrance",
|
|
80
|
+
* context: "modal",
|
|
81
|
+
* prioritizeAccessibility: true,
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* console.log(result.presetName); // "fadeIn"
|
|
85
|
+
* console.log(result.reasoning); // "Selected 'Fade In' (95% match): ..."
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* // For a hero section with bold animation
|
|
91
|
+
* const result = selectPreset({
|
|
92
|
+
* useCase: "entrance",
|
|
93
|
+
* context: "hero",
|
|
94
|
+
* preferMovement: true,
|
|
95
|
+
* direction: "up",
|
|
96
|
+
* });
|
|
97
|
+
*
|
|
98
|
+
* console.log(result.presetName); // "slideUpScale"
|
|
99
|
+
* console.log(result.style); // "bold"
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare function selectPreset(criteria: SelectionCriteria): SelectionResult;
|
|
103
|
+
/**
|
|
104
|
+
* Gets recommendations for a specific context.
|
|
105
|
+
*
|
|
106
|
+
* Returns multiple preset options ranked by suitability.
|
|
107
|
+
*
|
|
108
|
+
* @param context - The UI context
|
|
109
|
+
* @param options - Additional filtering options
|
|
110
|
+
* @returns Array of recommendations
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* const recommendations = getRecommendations("modal");
|
|
115
|
+
* // Returns: [
|
|
116
|
+
* // { preset: scale, name: "scale", reason: "...", score: 0.9 },
|
|
117
|
+
* // { preset: fadeIn, name: "fadeIn", reason: "...", score: 0.8 },
|
|
118
|
+
* // ...
|
|
119
|
+
* // ]
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare function getRecommendations(context: PresetContext, options?: {
|
|
123
|
+
maxResults?: number;
|
|
124
|
+
minScore?: number;
|
|
125
|
+
}): PresetRecommendation[];
|
|
126
|
+
/**
|
|
127
|
+
* Gets the default preset for a context.
|
|
128
|
+
*
|
|
129
|
+
* Quick helper for getting a sensible default animation.
|
|
130
|
+
*
|
|
131
|
+
* @param context - The UI context
|
|
132
|
+
* @returns The default preset for that context
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* const modalPreset = getDefaultPreset("modal");
|
|
137
|
+
* // Returns: scale preset
|
|
138
|
+
*
|
|
139
|
+
* const tooltipPreset = getDefaultPreset("tooltip");
|
|
140
|
+
* // Returns: fadeIn preset
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare function getDefaultPreset(context: PresetContext): ComponentPreset;
|
|
144
|
+
/**
|
|
145
|
+
* Suggests animation combinations for a component.
|
|
146
|
+
*
|
|
147
|
+
* Returns entrance, exit, and interaction animations that work together.
|
|
148
|
+
*
|
|
149
|
+
* @param context - The UI context
|
|
150
|
+
* @param style - Preferred motion style
|
|
151
|
+
* @returns Object with suggested animations
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* const suggestions = suggestAnimations("card", "standard");
|
|
156
|
+
* // Returns: {
|
|
157
|
+
* // entrance: slideUp,
|
|
158
|
+
* // exit: fadeOut,
|
|
159
|
+
* // interaction: cardHover (from micro-interactions)
|
|
160
|
+
* // }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export declare function suggestAnimations(context: PresetContext, style?: MotionStyle): {
|
|
164
|
+
entrance: ComponentPreset;
|
|
165
|
+
entranceName: ComponentPresetName;
|
|
166
|
+
exit: ComponentPreset;
|
|
167
|
+
exitName: ComponentPresetName;
|
|
168
|
+
style: MotionStyle;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Gets all available preset names.
|
|
172
|
+
*/
|
|
173
|
+
export declare function getAllPresetNames(): ComponentPresetName[];
|
|
174
|
+
/**
|
|
175
|
+
* Gets all available contexts.
|
|
176
|
+
*/
|
|
177
|
+
export declare function getAllContexts(): PresetContext[];
|
|
178
|
+
/**
|
|
179
|
+
* Gets all available use cases.
|
|
180
|
+
*/
|
|
181
|
+
export declare function getAllUseCases(): PresetUseCase[];
|
|
182
|
+
/**
|
|
183
|
+
* Gets preset metadata by name.
|
|
184
|
+
*/
|
|
185
|
+
export declare function getPresetMetadata(name: ComponentPresetName): import("..").PresetMetadata;
|
|
186
|
+
//# sourceMappingURL=select-preset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-preset.d.ts","sourceRoot":"","sources":["../../src/utils/select-preset.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EACH,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAGxB,KAAK,aAAa,EAClB,KAAK,aAAa,EACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM5D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,yCAAyC;IACzC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC;IAC5D,0CAA0C;IAC1C,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,0BAA0B;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,kCAAkC;IAClC,UAAU,EAAE,mBAAmB,CAAC;IAChC,+BAA+B;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,YAAY,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,yBAAyB;IACzB,MAAM,EAAE,eAAe,CAAC;IACxB,kBAAkB;IAClB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;CACjB;AA8HD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,iBAAiB,GAAG,eAAe,CAiCzE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE;IACL,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAChB,GACP,oBAAoB,EAAE,CAyBxB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,eAAe,CAgBxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,aAAa,EACtB,KAAK,GAAE,WAAwB,GAChC;IACC,QAAQ,EAAE,eAAe,CAAC;IAC1B,YAAY,EAAE,mBAAmB,CAAC;IAClC,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,KAAK,EAAE,WAAW,CAAC;CACtB,CAsBA;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,EAAE,CAEzD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,aAAa,EAAE,CAEhD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,aAAa,EAAE,CAEhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,+BAE1D"}
|