@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.
Files changed (82) hide show
  1. package/api-schema.json +206 -0
  2. package/dist/components/CountUp.d.ts +84 -0
  3. package/dist/components/CountUp.d.ts.map +1 -0
  4. package/dist/components/CountUp.js +68 -0
  5. package/dist/components/CountUp.js.map +1 -0
  6. package/dist/components/MotionDiv.d.ts +159 -0
  7. package/dist/components/MotionDiv.d.ts.map +1 -0
  8. package/dist/components/MotionDiv.js +162 -0
  9. package/dist/components/MotionDiv.js.map +1 -0
  10. package/dist/components/StaggerContainer.d.ts +136 -0
  11. package/dist/components/StaggerContainer.d.ts.map +1 -0
  12. package/dist/components/StaggerContainer.js +166 -0
  13. package/dist/components/StaggerContainer.js.map +1 -0
  14. package/dist/hooks/use-component-animation.d.ts +156 -0
  15. package/dist/hooks/use-component-animation.d.ts.map +1 -0
  16. package/dist/hooks/use-component-animation.js +231 -0
  17. package/dist/hooks/use-component-animation.js.map +1 -0
  18. package/dist/hooks/use-count-up.d.ts +111 -0
  19. package/dist/hooks/use-count-up.d.ts.map +1 -0
  20. package/dist/hooks/use-count-up.js +246 -0
  21. package/dist/hooks/use-count-up.js.map +1 -0
  22. package/dist/hooks/use-draw-path.d.ts +96 -0
  23. package/dist/hooks/use-draw-path.d.ts.map +1 -0
  24. package/dist/hooks/use-draw-path.js +227 -0
  25. package/dist/hooks/use-draw-path.js.map +1 -0
  26. package/dist/hooks/use-motion-preset.d.ts.map +1 -1
  27. package/dist/hooks/use-motion-preset.js +17 -16
  28. package/dist/hooks/use-motion-preset.js.map +1 -1
  29. package/dist/hooks/use-stagger.d.ts +174 -0
  30. package/dist/hooks/use-stagger.d.ts.map +1 -0
  31. package/dist/hooks/use-stagger.js +256 -0
  32. package/dist/hooks/use-stagger.js.map +1 -0
  33. package/dist/index.d.ts +17 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2442 -26
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.mjs +2335 -25
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/presets/component-presets.d.ts +246 -0
  40. package/dist/presets/component-presets.d.ts.map +1 -0
  41. package/dist/presets/component-presets.js +472 -0
  42. package/dist/presets/component-presets.js.map +1 -0
  43. package/dist/presets/micro-interactions.d.ts +451 -0
  44. package/dist/presets/micro-interactions.d.ts.map +1 -0
  45. package/dist/presets/micro-interactions.js +856 -0
  46. package/dist/presets/micro-interactions.js.map +1 -0
  47. package/dist/presets/motion-presets.d.ts.map +1 -1
  48. package/dist/presets/motion-presets.js +0 -1
  49. package/dist/presets/motion-presets.js.map +1 -1
  50. package/dist/presets/motion-styles.d.ts +186 -0
  51. package/dist/presets/motion-styles.d.ts.map +1 -0
  52. package/dist/presets/motion-styles.js +204 -0
  53. package/dist/presets/motion-styles.js.map +1 -0
  54. package/dist/presets/stagger-presets.d.ts +378 -0
  55. package/dist/presets/stagger-presets.d.ts.map +1 -0
  56. package/dist/presets/stagger-presets.js +582 -0
  57. package/dist/presets/stagger-presets.js.map +1 -0
  58. package/dist/showcase/motion-presets.demo.d.ts +25 -0
  59. package/dist/showcase/motion-presets.demo.d.ts.map +1 -0
  60. package/dist/showcase/motion-presets.demo.js +96 -0
  61. package/dist/showcase/motion-presets.demo.js.map +1 -0
  62. package/dist/showcase/motion-presets.story.d.ts +37 -0
  63. package/dist/showcase/motion-presets.story.d.ts.map +1 -0
  64. package/dist/showcase/motion-presets.story.js +151 -0
  65. package/dist/showcase/motion-presets.story.js.map +1 -0
  66. package/dist/utils/easing.d.ts +294 -0
  67. package/dist/utils/easing.d.ts.map +1 -0
  68. package/dist/utils/easing.js +265 -0
  69. package/dist/utils/easing.js.map +1 -0
  70. package/dist/utils/reduced-motion.d.ts +322 -0
  71. package/dist/utils/reduced-motion.d.ts.map +1 -0
  72. package/dist/utils/reduced-motion.js +362 -0
  73. package/dist/utils/reduced-motion.js.map +1 -0
  74. package/dist/utils/select-preset.d.ts +186 -0
  75. package/dist/utils/select-preset.d.ts.map +1 -0
  76. package/dist/utils/select-preset.js +320 -0
  77. package/dist/utils/select-preset.js.map +1 -0
  78. package/dist/utils/spring-configs.d.ts +187 -0
  79. package/dist/utils/spring-configs.d.ts.map +1 -0
  80. package/dist/utils/spring-configs.js +169 -0
  81. package/dist/utils/spring-configs.js.map +1 -0
  82. 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"}