@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
package/dist/index.mjs CHANGED
@@ -1,5 +1,819 @@
1
+ // src/hooks/use-count-up.ts
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+
4
+ // src/presets/motion-styles.ts
5
+ var subtleStyle = {
6
+ name: "Subtle",
7
+ description: "Gentle, minimal animations ideal for professional UIs",
8
+ duration: {
9
+ fast: 150,
10
+ normal: 200,
11
+ slow: 300
12
+ },
13
+ spring: {
14
+ stiffness: 400,
15
+ damping: 35,
16
+ mass: 0.8
17
+ },
18
+ easing: {
19
+ enter: "easeOut",
20
+ exit: "easeIn",
21
+ interactive: "easeInOut"
22
+ },
23
+ staggerDelay: 30
24
+ };
25
+ var standardStyle = {
26
+ name: "Standard",
27
+ description: "Balanced, professional animations for general use",
28
+ duration: {
29
+ fast: 200,
30
+ normal: 300,
31
+ slow: 400
32
+ },
33
+ spring: {
34
+ stiffness: 300,
35
+ damping: 28,
36
+ mass: 1
37
+ },
38
+ easing: {
39
+ enter: "easeOut",
40
+ exit: "easeIn",
41
+ interactive: "easeInOut"
42
+ },
43
+ staggerDelay: 50
44
+ };
45
+ var boldStyle = {
46
+ name: "Bold",
47
+ description: "Dramatic, attention-grabbing animations for emphasis",
48
+ duration: {
49
+ fast: 250,
50
+ normal: 400,
51
+ slow: 600
52
+ },
53
+ spring: {
54
+ stiffness: 250,
55
+ damping: 22,
56
+ mass: 1.2
57
+ },
58
+ easing: {
59
+ enter: "easeOut",
60
+ exit: "easeIn",
61
+ interactive: "easeInOut"
62
+ },
63
+ staggerDelay: 80
64
+ };
65
+ var playfulStyle = {
66
+ name: "Playful",
67
+ description: "Bouncy, fun animations with elastic spring physics",
68
+ duration: {
69
+ fast: 200,
70
+ normal: 350,
71
+ slow: 500
72
+ },
73
+ spring: {
74
+ stiffness: 200,
75
+ damping: 15,
76
+ mass: 1
77
+ },
78
+ easing: {
79
+ enter: "easeOut",
80
+ exit: "easeIn",
81
+ interactive: "easeInOut"
82
+ },
83
+ staggerDelay: 60
84
+ };
85
+ var motionStyles = {
86
+ subtle: subtleStyle,
87
+ standard: standardStyle,
88
+ bold: boldStyle,
89
+ playful: playfulStyle
90
+ };
91
+ function getMotionStyle(style) {
92
+ return motionStyles[style];
93
+ }
94
+ function getSpringConfig(style) {
95
+ return motionStyles[style].spring;
96
+ }
97
+ function getDuration(style, speed) {
98
+ return motionStyles[style].duration[speed];
99
+ }
100
+ function msToSeconds(ms) {
101
+ return ms / 1e3;
102
+ }
103
+
104
+ // src/hooks/use-count-up.ts
105
+ var easingFunctions = {
106
+ linear: (t) => t,
107
+ easeOut: (t) => 1 - (1 - t) ** 3,
108
+ easeOutExpo: (t) => t === 1 ? 1 : 1 - 2 ** (-10 * t),
109
+ easeInOut: (t) => t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2,
110
+ spring: (t) => {
111
+ const c4 = 2 * Math.PI / 3;
112
+ return t === 0 ? 0 : t === 1 ? 1 : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
113
+ }
114
+ };
115
+ function useReducedMotion() {
116
+ const [prefersReducedMotion2, setPrefersReducedMotion] = useState(() => {
117
+ if (typeof window === "undefined") return false;
118
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
119
+ });
120
+ useEffect(() => {
121
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
122
+ setPrefersReducedMotion(mediaQuery.matches);
123
+ const handler = (e) => {
124
+ setPrefersReducedMotion(e.matches);
125
+ };
126
+ mediaQuery.addEventListener("change", handler);
127
+ return () => mediaQuery.removeEventListener("change", handler);
128
+ }, []);
129
+ return prefersReducedMotion2;
130
+ }
131
+ function createDefaultFormatter(decimals, useLocale, locale) {
132
+ return (value) => {
133
+ if (useLocale) {
134
+ return value.toLocaleString(locale, {
135
+ minimumFractionDigits: decimals,
136
+ maximumFractionDigits: decimals
137
+ });
138
+ }
139
+ return value.toFixed(decimals);
140
+ };
141
+ }
142
+ function useCountUp(options) {
143
+ const {
144
+ from = 0,
145
+ to,
146
+ duration: customDuration,
147
+ motionStyle = "standard",
148
+ easing = "easeOutExpo",
149
+ decimals = 0,
150
+ useLocale = true,
151
+ locale,
152
+ formatter: customFormatter,
153
+ delay = 0,
154
+ autoStart = true,
155
+ onComplete,
156
+ onUpdate,
157
+ prefix = "",
158
+ suffix = "",
159
+ enabled = true
160
+ } = options;
161
+ const duration = customDuration ?? getDuration(motionStyle, "slow");
162
+ const [value, setValue] = useState(from);
163
+ const [isAnimating, setIsAnimating] = useState(false);
164
+ const [isComplete, setIsComplete] = useState(false);
165
+ const animationRef = useRef(null);
166
+ const startTimeRef = useRef(null);
167
+ const pausedTimeRef = useRef(null);
168
+ const currentFromRef = useRef(from);
169
+ const currentToRef = useRef(to);
170
+ const prefersReducedMotion2 = useReducedMotion();
171
+ const formatter = customFormatter ?? createDefaultFormatter(decimals, useLocale, locale);
172
+ const displayValue = `${prefix}${formatter(value)}${suffix}`;
173
+ const cancelAnimation = useCallback(() => {
174
+ if (animationRef.current !== null) {
175
+ cancelAnimationFrame(animationRef.current);
176
+ animationRef.current = null;
177
+ }
178
+ }, []);
179
+ const animate = useCallback(
180
+ (timestamp) => {
181
+ if (startTimeRef.current === null) {
182
+ startTimeRef.current = timestamp;
183
+ }
184
+ const elapsed = timestamp - startTimeRef.current;
185
+ const progress = Math.min(elapsed / duration, 1);
186
+ const easedProgress = easingFunctions[easing](progress);
187
+ const currentValue = currentFromRef.current + (currentToRef.current - currentFromRef.current) * easedProgress;
188
+ setValue(currentValue);
189
+ onUpdate?.(currentValue);
190
+ if (progress < 1) {
191
+ animationRef.current = requestAnimationFrame(animate);
192
+ } else {
193
+ setIsAnimating(false);
194
+ setIsComplete(true);
195
+ onComplete?.();
196
+ }
197
+ },
198
+ [duration, easing, onComplete, onUpdate]
199
+ );
200
+ const start = useCallback(() => {
201
+ if (!enabled) {
202
+ setValue(currentToRef.current);
203
+ setIsComplete(true);
204
+ return;
205
+ }
206
+ if (prefersReducedMotion2) {
207
+ setValue(currentToRef.current);
208
+ setIsComplete(true);
209
+ onComplete?.();
210
+ return;
211
+ }
212
+ cancelAnimation();
213
+ setIsComplete(false);
214
+ startTimeRef.current = null;
215
+ pausedTimeRef.current = null;
216
+ const startAnimation = () => {
217
+ setIsAnimating(true);
218
+ animationRef.current = requestAnimationFrame(animate);
219
+ };
220
+ if (delay > 0) {
221
+ setTimeout(startAnimation, delay);
222
+ } else {
223
+ startAnimation();
224
+ }
225
+ }, [enabled, prefersReducedMotion2, cancelAnimation, animate, delay, onComplete]);
226
+ const pause = useCallback(() => {
227
+ if (isAnimating && animationRef.current !== null) {
228
+ pausedTimeRef.current = performance.now();
229
+ cancelAnimation();
230
+ setIsAnimating(false);
231
+ }
232
+ }, [isAnimating, cancelAnimation]);
233
+ const resume = useCallback(() => {
234
+ if (!isAnimating && !isComplete && pausedTimeRef.current !== null && startTimeRef.current !== null) {
235
+ const pausedDuration = performance.now() - pausedTimeRef.current;
236
+ startTimeRef.current += pausedDuration;
237
+ pausedTimeRef.current = null;
238
+ setIsAnimating(true);
239
+ animationRef.current = requestAnimationFrame(animate);
240
+ }
241
+ }, [isAnimating, isComplete, animate]);
242
+ const reset = useCallback(() => {
243
+ cancelAnimation();
244
+ setValue(currentFromRef.current);
245
+ setIsAnimating(false);
246
+ setIsComplete(false);
247
+ startTimeRef.current = null;
248
+ pausedTimeRef.current = null;
249
+ }, [cancelAnimation]);
250
+ const update = useCallback(
251
+ (newTo) => {
252
+ currentFromRef.current = value;
253
+ currentToRef.current = newTo;
254
+ start();
255
+ },
256
+ [value, start]
257
+ );
258
+ useEffect(() => {
259
+ if (autoStart) {
260
+ currentFromRef.current = from;
261
+ currentToRef.current = to;
262
+ start();
263
+ }
264
+ return () => {
265
+ cancelAnimation();
266
+ };
267
+ }, []);
268
+ useEffect(() => {
269
+ if (to !== currentToRef.current && isComplete) {
270
+ update(to);
271
+ }
272
+ }, [to, isComplete, update]);
273
+ return {
274
+ value,
275
+ displayValue,
276
+ isAnimating,
277
+ isComplete,
278
+ start,
279
+ pause,
280
+ resume,
281
+ reset,
282
+ update,
283
+ prefersReducedMotion: prefersReducedMotion2
284
+ };
285
+ }
286
+
287
+ // src/components/CountUp.tsx
288
+ import { Fragment, jsx } from "react/jsx-runtime";
289
+ var CountUp = ({
290
+ to,
291
+ from = 0,
292
+ duration,
293
+ motionStyle = "standard",
294
+ easing = "easeOutExpo",
295
+ decimals = 0,
296
+ useLocale = true,
297
+ locale,
298
+ formatter,
299
+ delay = 0,
300
+ autoStart = true,
301
+ onComplete,
302
+ onUpdate,
303
+ prefix = "",
304
+ suffix = "",
305
+ enabled = true,
306
+ children,
307
+ ...spanProps
308
+ }) => {
309
+ const hookOptions = {
310
+ from,
311
+ to,
312
+ motionStyle,
313
+ easing,
314
+ decimals,
315
+ useLocale,
316
+ delay,
317
+ autoStart,
318
+ prefix,
319
+ suffix,
320
+ enabled,
321
+ // Only include optional props if they are defined
322
+ ...duration !== void 0 && { duration },
323
+ ...locale !== void 0 && { locale },
324
+ ...formatter !== void 0 && { formatter },
325
+ ...onComplete !== void 0 && { onComplete },
326
+ ...onUpdate !== void 0 && { onUpdate }
327
+ };
328
+ const { value, displayValue, isAnimating } = useCountUp(hookOptions);
329
+ if (typeof children === "function") {
330
+ return /* @__PURE__ */ jsx(Fragment, { children: children({ value, displayValue, isAnimating }) });
331
+ }
332
+ return /* @__PURE__ */ jsx("span", { ...spanProps, children: displayValue });
333
+ };
334
+
335
+ // src/components/MotionDiv.tsx
336
+ import { motion } from "motion/react";
337
+
338
+ // src/hooks/use-component-animation.ts
339
+ import { useEffect as useEffect2, useMemo, useState as useState2 } from "react";
340
+ function useReducedMotion2() {
341
+ const [prefersReducedMotion2, setPrefersReducedMotion] = useState2(() => {
342
+ if (typeof window === "undefined") return false;
343
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
344
+ });
345
+ useEffect2(() => {
346
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
347
+ setPrefersReducedMotion(mediaQuery.matches);
348
+ const handler = (e) => {
349
+ setPrefersReducedMotion(e.matches);
350
+ };
351
+ mediaQuery.addEventListener("change", handler);
352
+ return () => mediaQuery.removeEventListener("change", handler);
353
+ }, []);
354
+ return prefersReducedMotion2;
355
+ }
356
+ function createDisabledProps(skipInitial) {
357
+ return {
358
+ initial: skipInitial ? false : { opacity: 1 },
359
+ animate: { opacity: 1 },
360
+ exit: { opacity: 1 },
361
+ transition: { type: "tween", duration: 0 }
362
+ };
363
+ }
364
+ function useComponentAnimation(preset, style = "standard", options = {}) {
365
+ const { enabled = true, skipInitial = false, ...presetOptions } = options;
366
+ const prefersReducedMotion2 = useReducedMotion2();
367
+ const memoizedPresetOptions = useMemo(() => presetOptions, [JSON.stringify(presetOptions)]);
368
+ const animationProps = useMemo(() => {
369
+ if (!enabled) {
370
+ return createDisabledProps(skipInitial);
371
+ }
372
+ const props = preset.getProps(style, memoizedPresetOptions);
373
+ if (skipInitial) {
374
+ return {
375
+ ...props,
376
+ initial: false
377
+ };
378
+ }
379
+ return props;
380
+ }, [preset, style, memoizedPresetOptions, enabled, skipInitial]);
381
+ return {
382
+ ...animationProps,
383
+ prefersReducedMotion: prefersReducedMotion2,
384
+ isEnabled: enabled
385
+ };
386
+ }
387
+ function useDelayedAnimation(preset, style = "standard", index, options = {}) {
388
+ const { delayMultiplier = 50, maxDelay = 500, ...restOptions } = options;
389
+ const calculatedDelay = Math.min(index * delayMultiplier, maxDelay);
390
+ return useComponentAnimation(preset, style, {
391
+ ...restOptions,
392
+ delay: (restOptions.delay ?? 0) + calculatedDelay
393
+ });
394
+ }
395
+ function useAnimationVariants(preset, style = "standard", options = {}) {
396
+ const { enabled = true, ...presetOptions } = options;
397
+ const memoizedPresetOptions = useMemo(() => presetOptions, [JSON.stringify(presetOptions)]);
398
+ return useMemo(() => {
399
+ if (!enabled) {
400
+ return {
401
+ variants: {
402
+ initial: { opacity: 0 },
403
+ animate: { opacity: 1 },
404
+ exit: { opacity: 0 }
405
+ },
406
+ transition: { type: "tween", duration: 0.15 }
407
+ };
408
+ }
409
+ const props = preset.getProps(style, memoizedPresetOptions);
410
+ return {
411
+ variants: {
412
+ initial: props.initial,
413
+ animate: props.animate,
414
+ exit: props.exit ?? props.initial
415
+ },
416
+ transition: props.transition
417
+ };
418
+ }, [preset, style, memoizedPresetOptions, enabled]);
419
+ }
420
+
421
+ // src/components/MotionDiv.tsx
422
+ import { jsx as jsx2 } from "react/jsx-runtime";
423
+ function MotionDiv({
424
+ preset,
425
+ exit: exitPreset,
426
+ as = "div",
427
+ motionStyle = "standard",
428
+ presetOptions,
429
+ enabled = true,
430
+ skipInitial = false,
431
+ children,
432
+ ...motionProps
433
+ }) {
434
+ const animation = useComponentAnimation(preset, motionStyle, {
435
+ ...presetOptions,
436
+ enabled,
437
+ skipInitial
438
+ });
439
+ const exitAnimation = exitPreset && typeof exitPreset === "object" && "getProps" in exitPreset && typeof exitPreset.getProps === "function" ? exitPreset.getProps(motionStyle, presetOptions) : null;
440
+ const { prefersReducedMotion: prefersReducedMotion2, isEnabled, ...animationProps } = animation;
441
+ const exitValue = exitAnimation ? exitAnimation.initial : void 0;
442
+ const MotionComponent = motion[as];
443
+ const finalProps = {
444
+ ...motionProps,
445
+ ...animationProps,
446
+ ...exitValue !== void 0 && { exit: exitValue },
447
+ "data-reduced-motion": prefersReducedMotion2,
448
+ "data-animation-enabled": isEnabled
449
+ };
450
+ return /* @__PURE__ */ jsx2(MotionComponent, { ...finalProps, children });
451
+ }
452
+ function createMotionProps(preset, style = "standard", options) {
453
+ return preset.getProps(style, options);
454
+ }
455
+ function createAccessibleMotionProps(preset, style = "standard", options) {
456
+ return preset.getProps(style, options);
457
+ }
458
+
459
+ // src/components/StaggerContainer.tsx
460
+ import { Children, cloneElement, isValidElement } from "react";
461
+
462
+ // src/hooks/use-stagger.ts
463
+ import { useMemo as useMemo2 } from "react";
464
+ function calculateDelay(index, total, direction, baseDelay) {
465
+ switch (direction) {
466
+ case "forward":
467
+ return index * baseDelay;
468
+ case "reverse":
469
+ return (total - 1 - index) * baseDelay;
470
+ case "center": {
471
+ const center = (total - 1) / 2;
472
+ const distanceFromCenter = Math.abs(index - center);
473
+ return distanceFromCenter * baseDelay;
474
+ }
475
+ case "edges": {
476
+ const center = (total - 1) / 2;
477
+ const distanceFromCenter = Math.abs(index - center);
478
+ const maxDistance = center;
479
+ return (maxDistance - distanceFromCenter) * baseDelay;
480
+ }
481
+ case "random":
482
+ return Math.random() * total * baseDelay * 0.5;
483
+ default:
484
+ return index * baseDelay;
485
+ }
486
+ }
487
+ function useStagger(style = "standard", options = {}) {
488
+ const { direction = "forward", totalItems = 10, delayMultiplier, maxDelay = 1e3, useSpring = true, getDelay: customGetDelay } = options;
489
+ const styleConfig = getMotionStyle(style);
490
+ const baseDelay = delayMultiplier ?? styleConfig.staggerDelay;
491
+ const result = useMemo2(() => {
492
+ const getDelayForIndex = (index) => {
493
+ if (customGetDelay) {
494
+ return Math.min(customGetDelay(index, totalItems), maxDelay);
495
+ }
496
+ return Math.min(calculateDelay(index, totalItems, direction, baseDelay), maxDelay);
497
+ };
498
+ const containerVariants = {
499
+ hidden: { opacity: 0 },
500
+ visible: {
501
+ opacity: 1,
502
+ transition: {
503
+ staggerChildren: msToSeconds(baseDelay),
504
+ delayChildren: 0,
505
+ when: "beforeChildren"
506
+ }
507
+ }
508
+ };
509
+ const itemTransition = useSpring ? {
510
+ type: "spring",
511
+ stiffness: styleConfig.spring.stiffness,
512
+ damping: styleConfig.spring.damping,
513
+ mass: styleConfig.spring.mass
514
+ } : {
515
+ type: "tween",
516
+ duration: msToSeconds(styleConfig.duration.normal),
517
+ ease: [0.25, 0.1, 0.25, 1]
518
+ };
519
+ const itemVariants = {
520
+ hidden: {
521
+ opacity: 0,
522
+ y: 20
523
+ },
524
+ visible: (custom) => ({
525
+ opacity: 1,
526
+ y: 0,
527
+ transition: {
528
+ ...itemTransition,
529
+ delay: msToSeconds(getDelayForIndex(custom))
530
+ }
531
+ })
532
+ };
533
+ const containerProps = {
534
+ initial: "hidden",
535
+ animate: "visible",
536
+ exit: "hidden",
537
+ variants: containerVariants
538
+ };
539
+ const getItemProps = (index) => ({
540
+ variants: itemVariants,
541
+ custom: index
542
+ });
543
+ return {
544
+ containerVariants,
545
+ itemVariants,
546
+ containerProps,
547
+ getItemProps
548
+ };
549
+ }, [direction, totalItems, baseDelay, maxDelay, useSpring, customGetDelay, styleConfig]);
550
+ return result;
551
+ }
552
+ function gridStagger(columns, baseDelay = 50) {
553
+ return (index) => {
554
+ const row = Math.floor(index / columns);
555
+ const col = index % columns;
556
+ return (row + col) * baseDelay;
557
+ };
558
+ }
559
+ function waveStagger(amplitude = 100, frequency = 0.5, baseDelay = 30) {
560
+ return (index) => {
561
+ const wave = Math.sin(index * frequency) * amplitude;
562
+ return index * baseDelay + Math.abs(wave);
563
+ };
564
+ }
565
+ function cascadeStagger(baseDelay = 80, acceleration = 0.8) {
566
+ return (index) => {
567
+ const factor = acceleration ** index;
568
+ return baseDelay * (1 - factor) * (1 / (1 - acceleration));
569
+ };
570
+ }
571
+ function explodeStagger(baseDelay = 20) {
572
+ return (index, total) => {
573
+ const center = (total - 1) / 2;
574
+ const distance = Math.abs(index - center);
575
+ return distance * baseDelay;
576
+ };
577
+ }
578
+
579
+ // src/components/StaggerContainer.tsx
580
+ import { jsx as jsx3 } from "react/jsx-runtime";
581
+ function StaggerItem({ children, index, variants }) {
582
+ if (!isValidElement(children)) {
583
+ return children;
584
+ }
585
+ const motionProps = {
586
+ variants,
587
+ custom: index,
588
+ initial: "hidden",
589
+ animate: "visible",
590
+ exit: "hidden"
591
+ };
592
+ return cloneElement(children, motionProps);
593
+ }
594
+ function StaggerContainer({
595
+ children,
596
+ style = "standard",
597
+ direction = "forward",
598
+ delay,
599
+ maxDelay = 1e3,
600
+ useSpring = true,
601
+ getDelay,
602
+ className,
603
+ as: Element = "div",
604
+ animate = true
605
+ }) {
606
+ const childArray = Children.toArray(children);
607
+ const totalItems = childArray.length;
608
+ const staggerOptions = {
609
+ direction,
610
+ totalItems,
611
+ ...delay !== void 0 && { delayMultiplier: delay },
612
+ maxDelay,
613
+ useSpring,
614
+ ...getDelay !== void 0 && { getDelay }
615
+ };
616
+ const { itemVariants } = useStagger(style, staggerOptions);
617
+ if (!animate) {
618
+ return /* @__PURE__ */ jsx3(Element, { className, children });
619
+ }
620
+ return /* @__PURE__ */ jsx3(Element, { className, children: childArray.map((child, index) => {
621
+ if (!isValidElement(child)) {
622
+ return child;
623
+ }
624
+ return /* @__PURE__ */ jsx3(StaggerItem, { index, variants: itemVariants, children: child }, child.key ?? index);
625
+ }) });
626
+ }
627
+ function withStagger(WrappedComponent) {
628
+ return function StaggerWrapper({
629
+ style = "standard",
630
+ direction = "forward",
631
+ delay,
632
+ maxDelay,
633
+ useSpring,
634
+ getDelay,
635
+ children,
636
+ ...props
637
+ }) {
638
+ const staggerProps = {
639
+ children: /* @__PURE__ */ jsx3(WrappedComponent, { ...props, children }),
640
+ style,
641
+ direction,
642
+ ...delay !== void 0 && { delay },
643
+ ...maxDelay !== void 0 && { maxDelay },
644
+ ...useSpring !== void 0 && { useSpring },
645
+ ...getDelay !== void 0 && { getDelay }
646
+ };
647
+ return /* @__PURE__ */ jsx3(StaggerContainer, { ...staggerProps });
648
+ };
649
+ }
650
+
651
+ // src/hooks/use-draw-path.ts
652
+ import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
653
+ var easingFunctions2 = {
654
+ linear: (t) => t,
655
+ easeOut: (t) => 1 - (1 - t) ** 3,
656
+ easeOutExpo: (t) => t === 1 ? 1 : 1 - 2 ** (-10 * t),
657
+ easeInOut: (t) => t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2,
658
+ spring: (t) => {
659
+ const c4 = 2 * Math.PI / 3;
660
+ return t === 0 ? 0 : t === 1 ? 1 : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
661
+ }
662
+ };
663
+ function useReducedMotion3() {
664
+ const [prefersReducedMotion2, setPrefersReducedMotion] = useState3(() => {
665
+ if (typeof window === "undefined") return false;
666
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
667
+ });
668
+ useEffect3(() => {
669
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
670
+ setPrefersReducedMotion(mediaQuery.matches);
671
+ const handler = (e) => {
672
+ setPrefersReducedMotion(e.matches);
673
+ };
674
+ mediaQuery.addEventListener("change", handler);
675
+ return () => mediaQuery.removeEventListener("change", handler);
676
+ }, []);
677
+ return prefersReducedMotion2;
678
+ }
679
+ function useDrawPath(options) {
680
+ const {
681
+ from = 0,
682
+ to,
683
+ duration: customDuration,
684
+ motionStyle = "standard",
685
+ easing = "easeOutExpo",
686
+ delay = 0,
687
+ autoStart = true,
688
+ onComplete,
689
+ onUpdate,
690
+ enabled = true
691
+ } = options;
692
+ const duration = customDuration ?? getDuration(motionStyle, "slow");
693
+ const [pathLength, setPathLength] = useState3(from);
694
+ const [isAnimating, setIsAnimating] = useState3(false);
695
+ const [isComplete, setIsComplete] = useState3(false);
696
+ const animationRef = useRef2(null);
697
+ const startTimeRef = useRef2(null);
698
+ const pausedTimeRef = useRef2(null);
699
+ const currentFromRef = useRef2(from);
700
+ const currentToRef = useRef2(to);
701
+ const prefersReducedMotion2 = useReducedMotion3();
702
+ const cancelAnimation = useCallback2(() => {
703
+ if (animationRef.current !== null) {
704
+ cancelAnimationFrame(animationRef.current);
705
+ animationRef.current = null;
706
+ }
707
+ }, []);
708
+ const animate = useCallback2(
709
+ (timestamp) => {
710
+ if (startTimeRef.current === null) {
711
+ startTimeRef.current = timestamp;
712
+ }
713
+ const elapsed = timestamp - startTimeRef.current;
714
+ const progress = Math.min(elapsed / duration, 1);
715
+ const easedProgress = easingFunctions2[easing](progress);
716
+ const currentPathLength = currentFromRef.current + (currentToRef.current - currentFromRef.current) * easedProgress;
717
+ setPathLength(currentPathLength);
718
+ onUpdate?.(currentPathLength);
719
+ if (progress < 1) {
720
+ animationRef.current = requestAnimationFrame(animate);
721
+ } else {
722
+ setIsAnimating(false);
723
+ setIsComplete(true);
724
+ onComplete?.();
725
+ }
726
+ },
727
+ [duration, easing, onComplete, onUpdate]
728
+ );
729
+ const start = useCallback2(() => {
730
+ if (!enabled) {
731
+ setPathLength(currentToRef.current);
732
+ setIsComplete(true);
733
+ return;
734
+ }
735
+ if (prefersReducedMotion2) {
736
+ setPathLength(currentToRef.current);
737
+ setIsComplete(true);
738
+ onComplete?.();
739
+ return;
740
+ }
741
+ cancelAnimation();
742
+ setIsComplete(false);
743
+ startTimeRef.current = null;
744
+ pausedTimeRef.current = null;
745
+ const startAnimation = () => {
746
+ setIsAnimating(true);
747
+ animationRef.current = requestAnimationFrame(animate);
748
+ };
749
+ if (delay > 0) {
750
+ setTimeout(startAnimation, delay);
751
+ } else {
752
+ startAnimation();
753
+ }
754
+ }, [enabled, prefersReducedMotion2, cancelAnimation, animate, delay, onComplete]);
755
+ const pause = useCallback2(() => {
756
+ if (isAnimating && animationRef.current !== null) {
757
+ pausedTimeRef.current = performance.now();
758
+ cancelAnimation();
759
+ setIsAnimating(false);
760
+ }
761
+ }, [isAnimating, cancelAnimation]);
762
+ const resume = useCallback2(() => {
763
+ if (!isAnimating && !isComplete && pausedTimeRef.current !== null && startTimeRef.current !== null) {
764
+ const pausedDuration = performance.now() - pausedTimeRef.current;
765
+ startTimeRef.current += pausedDuration;
766
+ pausedTimeRef.current = null;
767
+ setIsAnimating(true);
768
+ animationRef.current = requestAnimationFrame(animate);
769
+ }
770
+ }, [isAnimating, isComplete, animate]);
771
+ const reset = useCallback2(() => {
772
+ cancelAnimation();
773
+ setPathLength(currentFromRef.current);
774
+ setIsAnimating(false);
775
+ setIsComplete(false);
776
+ startTimeRef.current = null;
777
+ pausedTimeRef.current = null;
778
+ }, [cancelAnimation]);
779
+ const update = useCallback2(
780
+ (newTo) => {
781
+ currentFromRef.current = pathLength;
782
+ currentToRef.current = newTo;
783
+ start();
784
+ },
785
+ [pathLength, start]
786
+ );
787
+ useEffect3(() => {
788
+ if (autoStart) {
789
+ currentFromRef.current = from;
790
+ currentToRef.current = to;
791
+ start();
792
+ }
793
+ return () => {
794
+ cancelAnimation();
795
+ };
796
+ }, []);
797
+ useEffect3(() => {
798
+ if (to !== currentToRef.current && isComplete) {
799
+ update(to);
800
+ }
801
+ }, [to, isComplete, update]);
802
+ return {
803
+ pathLength,
804
+ isAnimating,
805
+ isComplete,
806
+ start,
807
+ pause,
808
+ resume,
809
+ reset,
810
+ update,
811
+ prefersReducedMotion: prefersReducedMotion2
812
+ };
813
+ }
814
+
1
815
  // src/hooks/use-motion-preset.ts
2
- import { useEffect, useMemo, useState } from "react";
816
+ import { useEffect as useEffect4, useMemo as useMemo3, useState as useState4 } from "react";
3
817
 
4
818
  // src/presets/motion-presets.ts
5
819
  var ambientPaths = {
@@ -53,29 +867,27 @@ function applyMotionPreset(preset, baseConfig) {
53
867
  }
54
868
 
55
869
  // src/hooks/use-motion-preset.ts
56
- var DEFAULT_CSS_VARS = {
57
- durationMultiplier: 1,
58
- opacityMin: 0.35,
59
- opacityMax: 0.6
60
- };
61
870
  function readCSSVariables() {
62
871
  if (typeof window === "undefined") {
63
- return DEFAULT_CSS_VARS;
872
+ throw new Error("useMotionPreset/readCSSVariables requires a browser environment");
64
873
  }
65
874
  const root = document.documentElement;
66
875
  const styles = getComputedStyle(root);
67
- const parseFloat_ = (value, fallback) => {
876
+ const parseMotionVar = (value) => {
68
877
  const parsed = parseFloat(value);
69
- return Number.isNaN(parsed) ? fallback : parsed;
878
+ if (Number.isNaN(parsed)) {
879
+ throw new Error("Motion CSS variable could not be parsed as a number");
880
+ }
881
+ return parsed;
70
882
  };
71
883
  return {
72
- durationMultiplier: parseFloat_(styles.getPropertyValue("--motion-duration-multiplier"), DEFAULT_CSS_VARS.durationMultiplier),
73
- opacityMin: parseFloat_(styles.getPropertyValue("--motion-opacity-min"), DEFAULT_CSS_VARS.opacityMin),
74
- opacityMax: parseFloat_(styles.getPropertyValue("--motion-opacity-max"), DEFAULT_CSS_VARS.opacityMax)
884
+ durationMultiplier: parseMotionVar(styles.getPropertyValue("--motion-duration-multiplier")),
885
+ opacityMin: parseMotionVar(styles.getPropertyValue("--motion-opacity-min")),
886
+ opacityMax: parseMotionVar(styles.getPropertyValue("--motion-opacity-max"))
75
887
  };
76
888
  }
77
- function computePathsMotion(preset, cssVars, prefersReducedMotion) {
78
- if (prefersReducedMotion) {
889
+ function computePathsMotion(preset, cssVars, prefersReducedMotion2) {
890
+ if (prefersReducedMotion2) {
79
891
  return {
80
892
  baseDuration: 0,
81
893
  opacity: [cssVars.opacityMin, cssVars.opacityMin, cssVars.opacityMin],
@@ -98,8 +910,8 @@ function computePathsMotion(preset, cssVars, prefersReducedMotion) {
98
910
  prefersReducedMotion: false
99
911
  };
100
912
  }
101
- function computeRaysMotion(preset, cssVars, prefersReducedMotion) {
102
- if (prefersReducedMotion) {
913
+ function computeRaysMotion(preset, cssVars, prefersReducedMotion2) {
914
+ if (prefersReducedMotion2) {
103
915
  return {
104
916
  cycleDuration: 0,
105
917
  intensity: 0,
@@ -115,19 +927,24 @@ function computeRaysMotion(preset, cssVars, prefersReducedMotion) {
115
927
  };
116
928
  }
117
929
  function useMotionPreset(component, preset) {
118
- const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {
930
+ const [prefersReducedMotion2, setPrefersReducedMotion] = useState4(() => {
119
931
  if (typeof window === "undefined") return false;
120
932
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
121
933
  });
122
- const [cssVars, setCssVars] = useState(DEFAULT_CSS_VARS);
123
- useEffect(() => {
934
+ const [cssVars, setCssVars] = useState4(() => {
935
+ if (typeof window === "undefined") {
936
+ throw new Error("useMotionPreset requires a browser environment");
937
+ }
938
+ return readCSSVariables();
939
+ });
940
+ useEffect4(() => {
124
941
  const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
125
942
  setPrefersReducedMotion(mediaQuery.matches);
126
943
  const handler = (e) => setPrefersReducedMotion(e.matches);
127
944
  mediaQuery.addEventListener("change", handler);
128
945
  return () => mediaQuery.removeEventListener("change", handler);
129
946
  }, []);
130
- useEffect(() => {
947
+ useEffect4(() => {
131
948
  setCssVars(readCSSVariables());
132
949
  const observer = new MutationObserver(() => {
133
950
  setCssVars(readCSSVariables());
@@ -138,20 +955,1513 @@ function useMotionPreset(component, preset) {
138
955
  });
139
956
  return () => observer.disconnect();
140
957
  }, []);
141
- return useMemo(() => {
958
+ return useMemo3(() => {
142
959
  if (component === "paths") {
143
960
  const presetConfig2 = getPreset(preset, "paths");
144
- return computePathsMotion(presetConfig2, cssVars, prefersReducedMotion);
961
+ return computePathsMotion(presetConfig2, cssVars, prefersReducedMotion2);
145
962
  }
146
963
  const presetConfig = getPreset(preset, "rays");
147
- return computeRaysMotion(presetConfig, cssVars, prefersReducedMotion);
148
- }, [component, preset, cssVars, prefersReducedMotion]);
964
+ return computeRaysMotion(presetConfig, cssVars, prefersReducedMotion2);
965
+ }, [component, preset, cssVars, prefersReducedMotion2]);
966
+ }
967
+
968
+ // src/presets/component-presets.ts
969
+ function createTweenTransition(style, options) {
970
+ const duration = options?.duration ?? getDuration(style, "normal");
971
+ return {
972
+ type: "tween",
973
+ duration: msToSeconds(duration),
974
+ ease: [0.25, 0.1, 0.25, 1],
975
+ // cubic-bezier ease-out
976
+ delay: options?.delay ? msToSeconds(options.delay) : 0
977
+ };
978
+ }
979
+ function createSpringTransition(style, options) {
980
+ const spring = getSpringConfig(style);
981
+ return {
982
+ type: "spring",
983
+ stiffness: spring.stiffness,
984
+ damping: spring.damping,
985
+ mass: spring.mass,
986
+ delay: options?.delay ? msToSeconds(options.delay) : 0
987
+ };
149
988
  }
989
+ function getTransition(style, preferSpring, options) {
990
+ const useSpring = options?.useSpring ?? preferSpring;
991
+ return useSpring ? createSpringTransition(style, options) : createTweenTransition(style, options);
992
+ }
993
+ var fadeIn = {
994
+ metadata: {
995
+ id: "fadeIn",
996
+ name: "Fade In",
997
+ description: "Smooth opacity transition from invisible to visible",
998
+ useCase: ["entrance", "reveal"],
999
+ context: ["tooltip", "dropdown", "modal", "notification"],
1000
+ intensity: 2,
1001
+ hasMovement: false
1002
+ },
1003
+ getProps: (style, options) => ({
1004
+ initial: { opacity: 0 },
1005
+ animate: { opacity: 1 },
1006
+ exit: { opacity: 0 },
1007
+ transition: createTweenTransition(style, options)
1008
+ })
1009
+ };
1010
+ var fadeOut = {
1011
+ metadata: {
1012
+ id: "fadeOut",
1013
+ name: "Fade Out",
1014
+ description: "Smooth opacity transition from visible to invisible",
1015
+ useCase: ["exit"],
1016
+ context: ["tooltip", "dropdown", "modal", "notification"],
1017
+ intensity: 2,
1018
+ hasMovement: false
1019
+ },
1020
+ getProps: (style, options) => ({
1021
+ initial: { opacity: 1 },
1022
+ animate: { opacity: 0 },
1023
+ transition: createTweenTransition(style, options)
1024
+ })
1025
+ };
1026
+ var DEFAULT_SLIDE_DISTANCE = 20;
1027
+ var slideUp = {
1028
+ metadata: {
1029
+ id: "slideUp",
1030
+ name: "Slide Up",
1031
+ description: "Element slides upward while fading in",
1032
+ useCase: ["entrance", "reveal"],
1033
+ context: ["modal", "card", "list-item", "notification"],
1034
+ intensity: 3,
1035
+ hasMovement: true,
1036
+ direction: "up"
1037
+ },
1038
+ getProps: (style, options) => {
1039
+ const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;
1040
+ return {
1041
+ initial: { opacity: 0, y: distance },
1042
+ animate: { opacity: 1, y: 0 },
1043
+ exit: { opacity: 0, y: distance },
1044
+ transition: getTransition(style, true, options)
1045
+ };
1046
+ }
1047
+ };
1048
+ var slideDown = {
1049
+ metadata: {
1050
+ id: "slideDown",
1051
+ name: "Slide Down",
1052
+ description: "Element slides downward while fading in",
1053
+ useCase: ["entrance", "reveal"],
1054
+ context: ["dropdown", "tooltip", "notification"],
1055
+ intensity: 3,
1056
+ hasMovement: true,
1057
+ direction: "down"
1058
+ },
1059
+ getProps: (style, options) => {
1060
+ const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;
1061
+ return {
1062
+ initial: { opacity: 0, y: -distance },
1063
+ animate: { opacity: 1, y: 0 },
1064
+ exit: { opacity: 0, y: -distance },
1065
+ transition: getTransition(style, true, options)
1066
+ };
1067
+ }
1068
+ };
1069
+ var slideLeft = {
1070
+ metadata: {
1071
+ id: "slideLeft",
1072
+ name: "Slide Left",
1073
+ description: "Element slides leftward while fading in",
1074
+ useCase: ["entrance", "transition"],
1075
+ context: ["drawer", "page", "section"],
1076
+ intensity: 3,
1077
+ hasMovement: true,
1078
+ direction: "left"
1079
+ },
1080
+ getProps: (style, options) => {
1081
+ const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;
1082
+ return {
1083
+ initial: { opacity: 0, x: distance },
1084
+ animate: { opacity: 1, x: 0 },
1085
+ exit: { opacity: 0, x: -distance },
1086
+ transition: getTransition(style, true, options)
1087
+ };
1088
+ }
1089
+ };
1090
+ var slideRight = {
1091
+ metadata: {
1092
+ id: "slideRight",
1093
+ name: "Slide Right",
1094
+ description: "Element slides rightward while fading in",
1095
+ useCase: ["entrance", "transition"],
1096
+ context: ["drawer", "page", "section"],
1097
+ intensity: 3,
1098
+ hasMovement: true,
1099
+ direction: "right"
1100
+ },
1101
+ getProps: (style, options) => {
1102
+ const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;
1103
+ return {
1104
+ initial: { opacity: 0, x: -distance },
1105
+ animate: { opacity: 1, x: 0 },
1106
+ exit: { opacity: 0, x: distance },
1107
+ transition: getTransition(style, true, options)
1108
+ };
1109
+ }
1110
+ };
1111
+ var DEFAULT_SCALE_FROM = 0.95;
1112
+ var DEFAULT_ZOOM_SCALE = 0.5;
1113
+ var scale = {
1114
+ metadata: {
1115
+ id: "scale",
1116
+ name: "Scale",
1117
+ description: "Subtle scale transition with fade",
1118
+ useCase: ["entrance", "emphasis"],
1119
+ context: ["modal", "card", "notification"],
1120
+ intensity: 3,
1121
+ hasMovement: true,
1122
+ direction: "in"
1123
+ },
1124
+ getProps: (style, options) => {
1125
+ const scaleFrom = options?.scale ?? DEFAULT_SCALE_FROM;
1126
+ return {
1127
+ initial: { opacity: 0, scale: scaleFrom },
1128
+ animate: { opacity: 1, scale: 1 },
1129
+ exit: { opacity: 0, scale: scaleFrom },
1130
+ transition: getTransition(style, true, options)
1131
+ };
1132
+ }
1133
+ };
1134
+ var zoomIn = {
1135
+ metadata: {
1136
+ id: "zoomIn",
1137
+ name: "Zoom In",
1138
+ description: "Dramatic zoom from small to full size",
1139
+ useCase: ["entrance", "emphasis"],
1140
+ context: ["hero", "modal", "card"],
1141
+ intensity: 4,
1142
+ hasMovement: true,
1143
+ direction: "in"
1144
+ },
1145
+ getProps: (style, options) => {
1146
+ const scaleFrom = options?.scale ?? DEFAULT_ZOOM_SCALE;
1147
+ return {
1148
+ initial: { opacity: 0, scale: scaleFrom },
1149
+ animate: { opacity: 1, scale: 1 },
1150
+ exit: { opacity: 0, scale: scaleFrom },
1151
+ transition: getTransition(style, true, options)
1152
+ };
1153
+ }
1154
+ };
1155
+ var zoomOut = {
1156
+ metadata: {
1157
+ id: "zoomOut",
1158
+ name: "Zoom Out",
1159
+ description: "Scale from larger to normal size",
1160
+ useCase: ["entrance", "emphasis"],
1161
+ context: ["hero", "modal"],
1162
+ intensity: 4,
1163
+ hasMovement: true,
1164
+ direction: "out"
1165
+ },
1166
+ getProps: (style, options) => {
1167
+ const scaleTo = options?.scale ?? 1.1;
1168
+ return {
1169
+ initial: { opacity: 0, scale: scaleTo },
1170
+ animate: { opacity: 1, scale: 1 },
1171
+ exit: { opacity: 0, scale: scaleTo },
1172
+ transition: getTransition(style, true, options)
1173
+ };
1174
+ }
1175
+ };
1176
+ var DEFAULT_ROTATION = 10;
1177
+ var rotate = {
1178
+ metadata: {
1179
+ id: "rotate",
1180
+ name: "Rotate",
1181
+ description: "Subtle rotation animation with fade",
1182
+ useCase: ["entrance", "emphasis"],
1183
+ context: ["card", "notification"],
1184
+ intensity: 4,
1185
+ hasMovement: true
1186
+ },
1187
+ getProps: (style, options) => {
1188
+ const rotation = options?.rotation ?? DEFAULT_ROTATION;
1189
+ return {
1190
+ initial: { opacity: 0, rotate: -rotation },
1191
+ animate: { opacity: 1, rotate: 0 },
1192
+ exit: { opacity: 0, rotate: rotation },
1193
+ transition: getTransition(style, true, options)
1194
+ };
1195
+ }
1196
+ };
1197
+ var slideUpScale = {
1198
+ metadata: {
1199
+ id: "slideUpScale",
1200
+ name: "Slide Up & Scale",
1201
+ description: "Combines upward slide with subtle scale",
1202
+ useCase: ["entrance", "emphasis"],
1203
+ context: ["hero", "card", "section"],
1204
+ intensity: 4,
1205
+ hasMovement: true,
1206
+ direction: "up"
1207
+ },
1208
+ getProps: (style, options) => {
1209
+ const distance = options?.distance ?? DEFAULT_SLIDE_DISTANCE;
1210
+ const scaleFrom = options?.scale ?? 0.98;
1211
+ return {
1212
+ initial: { opacity: 0, y: distance, scale: scaleFrom },
1213
+ animate: { opacity: 1, y: 0, scale: 1 },
1214
+ exit: { opacity: 0, y: distance, scale: scaleFrom },
1215
+ transition: getTransition(style, true, options)
1216
+ };
1217
+ }
1218
+ };
1219
+ var flip = {
1220
+ metadata: {
1221
+ id: "flip",
1222
+ name: "Flip",
1223
+ description: "3D flip animation on the X axis",
1224
+ useCase: ["entrance", "transition"],
1225
+ context: ["card"],
1226
+ intensity: 5,
1227
+ hasMovement: true
1228
+ },
1229
+ getProps: (style, options) => {
1230
+ const rotation = options?.rotation ?? 90;
1231
+ return {
1232
+ initial: { opacity: 0, rotateX: rotation },
1233
+ animate: { opacity: 1, rotateX: 0 },
1234
+ exit: { opacity: 0, rotateX: -rotation },
1235
+ transition: getTransition(style, true, options)
1236
+ };
1237
+ }
1238
+ };
1239
+ var expand = {
1240
+ metadata: {
1241
+ id: "expand",
1242
+ name: "Expand",
1243
+ description: "Height expansion animation",
1244
+ useCase: ["entrance", "reveal"],
1245
+ context: ["section"],
1246
+ intensity: 2,
1247
+ hasMovement: true,
1248
+ direction: "down"
1249
+ },
1250
+ getProps: (style, options) => ({
1251
+ initial: { opacity: 0, height: 0 },
1252
+ animate: { opacity: 1, height: "auto" },
1253
+ exit: { opacity: 0, height: 0 },
1254
+ transition: createTweenTransition(style, options)
1255
+ })
1256
+ };
1257
+ var componentPresets = {
1258
+ fadeIn,
1259
+ fadeOut,
1260
+ slideUp,
1261
+ slideDown,
1262
+ slideLeft,
1263
+ slideRight,
1264
+ scale,
1265
+ zoomIn,
1266
+ zoomOut,
1267
+ rotate,
1268
+ slideUpScale,
1269
+ flip,
1270
+ expand
1271
+ };
1272
+ function getComponentPreset(name) {
1273
+ return componentPresets[name];
1274
+ }
1275
+ function getPresetsByUseCase(useCase) {
1276
+ return Object.values(componentPresets).filter((preset) => preset.metadata.useCase.includes(useCase));
1277
+ }
1278
+ function getPresetsByContext(context) {
1279
+ return Object.values(componentPresets).filter((preset) => preset.metadata.context.includes(context));
1280
+ }
1281
+
1282
+ // src/presets/micro-interactions.ts
1283
+ function prefersReducedMotion() {
1284
+ if (typeof window === "undefined") return false;
1285
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1286
+ }
1287
+ function getReducedMotionProps() {
1288
+ return {};
1289
+ }
1290
+ var buttonPress = {
1291
+ name: "buttonPress",
1292
+ description: "Scale down slightly on press, spring back on release",
1293
+ useCase: ["buttons", "clickable cards", "list items", "interactive elements", "call-to-action"],
1294
+ getProps: (style) => {
1295
+ if (prefersReducedMotion()) return getReducedMotionProps();
1296
+ const config = getMotionStyle(style);
1297
+ const scaleAmount = style === "subtle" ? 0.98 : style === "playful" ? 0.92 : 0.95;
1298
+ return {
1299
+ whileTap: {
1300
+ scale: scaleAmount
1301
+ },
1302
+ whileHover: {
1303
+ scale: style === "subtle" ? 1.01 : 1.02
1304
+ },
1305
+ transition: {
1306
+ type: "spring",
1307
+ stiffness: config.spring.stiffness,
1308
+ damping: config.spring.damping,
1309
+ mass: config.spring.mass
1310
+ }
1311
+ };
1312
+ }
1313
+ };
1314
+ var cardHover = {
1315
+ name: "cardHover",
1316
+ description: "Subtle lift with shadow enhancement on hover",
1317
+ useCase: ["cards", "tiles", "panels", "content blocks", "media items", "product listings"],
1318
+ getProps: (style) => {
1319
+ if (prefersReducedMotion()) return getReducedMotionProps();
1320
+ const config = getMotionStyle(style);
1321
+ const liftAmount = style === "subtle" ? -2 : style === "playful" ? -8 : -4;
1322
+ const shadowIntensity = style === "subtle" ? 0.08 : style === "playful" ? 0.2 : 0.12;
1323
+ return {
1324
+ whileHover: {
1325
+ y: liftAmount,
1326
+ boxShadow: `0 ${Math.abs(liftAmount) * 2}px ${Math.abs(liftAmount) * 4}px rgba(0, 0, 0, ${shadowIntensity})`
1327
+ },
1328
+ transition: {
1329
+ type: "spring",
1330
+ stiffness: config.spring.stiffness,
1331
+ damping: config.spring.damping,
1332
+ mass: config.spring.mass
1333
+ }
1334
+ };
1335
+ }
1336
+ };
1337
+ var iconSpin = {
1338
+ name: "iconSpin",
1339
+ description: "360 degree rotation animation",
1340
+ useCase: ["refresh buttons", "sync icons", "loading indicators", "settings icons", "interactive icons"],
1341
+ getProps: (style) => {
1342
+ if (prefersReducedMotion()) return getReducedMotionProps();
1343
+ const config = getMotionStyle(style);
1344
+ return {
1345
+ whileTap: {
1346
+ rotate: 360
1347
+ },
1348
+ whileHover: {
1349
+ rotate: style === "playful" ? 15 : 5
1350
+ },
1351
+ transition: {
1352
+ type: "spring",
1353
+ stiffness: config.spring.stiffness * 0.8,
1354
+ damping: config.spring.damping,
1355
+ mass: config.spring.mass
1356
+ }
1357
+ };
1358
+ }
1359
+ };
1360
+ var pulse = {
1361
+ name: "pulse",
1362
+ description: "Scale pulse animation with breathing effect",
1363
+ useCase: ["notifications", "live indicators", "attention grabbers", "status badges", "loading states"],
1364
+ getProps: (style) => {
1365
+ if (prefersReducedMotion()) return getReducedMotionProps();
1366
+ const config = getMotionStyle(style);
1367
+ const scaleRange = style === "subtle" ? 1.03 : style === "playful" ? 1.12 : 1.06;
1368
+ return {
1369
+ initial: {
1370
+ scale: 1
1371
+ },
1372
+ animate: {
1373
+ scale: [1, scaleRange, 1]
1374
+ },
1375
+ transition: {
1376
+ duration: msToSeconds(config.duration.slow),
1377
+ repeat: Infinity,
1378
+ ease: config.easing.interactive
1379
+ }
1380
+ };
1381
+ }
1382
+ };
1383
+ var shake = {
1384
+ name: "shake",
1385
+ description: "Horizontal shake animation for error states",
1386
+ useCase: ["error states", "invalid inputs", "denied actions", "form validation", "authentication failures"],
1387
+ getProps: (style) => {
1388
+ if (prefersReducedMotion()) return getReducedMotionProps();
1389
+ const config = getMotionStyle(style);
1390
+ const shakeDistance = style === "subtle" ? 4 : style === "playful" ? 12 : 8;
1391
+ return {
1392
+ initial: {
1393
+ x: 0
1394
+ },
1395
+ animate: {
1396
+ x: [0, -shakeDistance, shakeDistance, -shakeDistance, shakeDistance, 0]
1397
+ },
1398
+ transition: {
1399
+ duration: msToSeconds(config.duration.fast),
1400
+ ease: config.easing.interactive
1401
+ }
1402
+ };
1403
+ }
1404
+ };
1405
+ var wiggle = {
1406
+ name: "wiggle",
1407
+ description: "Playful rotation wiggle animation",
1408
+ useCase: ["playful interfaces", "gamification", "attention indicators", "celebration elements", "decorative icons"],
1409
+ getProps: (style) => {
1410
+ if (prefersReducedMotion()) return getReducedMotionProps();
1411
+ const config = getMotionStyle(style);
1412
+ const wiggleAngle = style === "subtle" ? 3 : style === "playful" ? 12 : 6;
1413
+ return {
1414
+ whileHover: {
1415
+ rotate: [0, -wiggleAngle, wiggleAngle, -wiggleAngle, wiggleAngle, 0]
1416
+ },
1417
+ transition: {
1418
+ duration: msToSeconds(config.duration.normal),
1419
+ ease: config.easing.interactive
1420
+ }
1421
+ };
1422
+ }
1423
+ };
1424
+ var heartbeat = {
1425
+ name: "heartbeat",
1426
+ description: "Double-pulse heartbeat pattern animation",
1427
+ useCase: ["like buttons", "health apps", "love reactions", "favorite indicators", "activity monitors"],
1428
+ getProps: (style) => {
1429
+ if (prefersReducedMotion()) return getReducedMotionProps();
1430
+ const config = getMotionStyle(style);
1431
+ const pulseScale = style === "subtle" ? 1.1 : style === "playful" ? 1.3 : 1.2;
1432
+ return {
1433
+ initial: {
1434
+ scale: 1
1435
+ },
1436
+ animate: {
1437
+ scale: [1, pulseScale, 1, pulseScale * 0.95, 1]
1438
+ },
1439
+ transition: {
1440
+ duration: msToSeconds(config.duration.slow * 1.5),
1441
+ repeat: Infinity,
1442
+ repeatDelay: msToSeconds(config.duration.normal),
1443
+ ease: config.easing.interactive
1444
+ }
1445
+ };
1446
+ }
1447
+ };
1448
+ var rubberBand = {
1449
+ name: "rubberBand",
1450
+ description: "Elastic stretch and snap back animation",
1451
+ useCase: ["emphasis animations", "attention grabbers", "playful buttons", "celebration effects", "interactive feedback"],
1452
+ getProps: (style) => {
1453
+ if (prefersReducedMotion()) return getReducedMotionProps();
1454
+ const config = getMotionStyle(style);
1455
+ const stretchX = style === "subtle" ? 1.05 : style === "playful" ? 1.25 : 1.15;
1456
+ const stretchY = style === "subtle" ? 0.95 : style === "playful" ? 0.75 : 0.85;
1457
+ return {
1458
+ whileTap: {
1459
+ scaleX: [1, stretchX, 0.95, 1.05, 1],
1460
+ scaleY: [1, stretchY, 1.05, 0.95, 1]
1461
+ },
1462
+ whileHover: {
1463
+ scaleX: 1.02,
1464
+ scaleY: 0.98
1465
+ },
1466
+ transition: {
1467
+ type: "spring",
1468
+ stiffness: config.spring.stiffness * 0.6,
1469
+ damping: config.spring.damping * 0.5,
1470
+ mass: config.spring.mass
1471
+ }
1472
+ };
1473
+ }
1474
+ };
1475
+ var scale2 = {
1476
+ name: "scale",
1477
+ description: "Scale up animation for selection feedback",
1478
+ useCase: ["checkboxes", "toggles", "radio buttons", "selection states", "activation feedback"],
1479
+ getProps: (style) => {
1480
+ if (prefersReducedMotion()) return getReducedMotionProps();
1481
+ const config = getMotionStyle(style);
1482
+ const scaleAmount = style === "subtle" ? 1.05 : style === "playful" ? 1.2 : 1.1;
1483
+ return {
1484
+ initial: {
1485
+ scale: 0.8,
1486
+ opacity: 0
1487
+ },
1488
+ animate: {
1489
+ scale: [0.8, scaleAmount, 1],
1490
+ opacity: 1
1491
+ },
1492
+ transition: {
1493
+ type: "spring",
1494
+ stiffness: config.spring.stiffness,
1495
+ damping: config.spring.damping,
1496
+ mass: config.spring.mass
1497
+ }
1498
+ };
1499
+ }
1500
+ };
1501
+ var shimmer = {
1502
+ name: "shimmer",
1503
+ description: "Gradient shimmer effect that slides across the element",
1504
+ useCase: ["skeleton loading", "placeholder content", "progress indicators", "loading states", "content placeholders"],
1505
+ getProps: (style) => {
1506
+ if (prefersReducedMotion()) return getReducedMotionProps();
1507
+ const config = getMotionStyle(style);
1508
+ const duration = style === "subtle" ? 2 : style === "playful" ? 1.2 : 1.5;
1509
+ return {
1510
+ initial: {
1511
+ backgroundPosition: "200% 0"
1512
+ },
1513
+ animate: {
1514
+ backgroundPosition: ["-200% 0", "200% 0"]
1515
+ },
1516
+ transition: {
1517
+ duration,
1518
+ repeat: Infinity,
1519
+ ease: config.easing.exit,
1520
+ repeatDelay: 0.5
1521
+ }
1522
+ };
1523
+ }
1524
+ };
1525
+ var glowPulse = {
1526
+ name: "glowPulse",
1527
+ description: "Glowing pulse effect for emphasis and AI indicators",
1528
+ useCase: ["AI content indicators", "featured items", "premium elements", "special badges", "magical effects"],
1529
+ getProps: (style) => {
1530
+ if (prefersReducedMotion()) return getReducedMotionProps();
1531
+ const config = getMotionStyle(style);
1532
+ const glowIntensity = style === "subtle" ? 8 : style === "playful" ? 20 : 12;
1533
+ const glowColor = "rgba(99, 102, 241, 0.6)";
1534
+ return {
1535
+ initial: {
1536
+ boxShadow: `0 0 0 rgba(99, 102, 241, 0)`
1537
+ },
1538
+ animate: {
1539
+ boxShadow: [`0 0 0 rgba(99, 102, 241, 0)`, `0 0 ${glowIntensity}px ${glowColor}`, `0 0 0 rgba(99, 102, 241, 0)`]
1540
+ },
1541
+ transition: {
1542
+ duration: msToSeconds(config.duration.slow * 1.5),
1543
+ repeat: Infinity,
1544
+ ease: config.easing.interactive
1545
+ }
1546
+ };
1547
+ }
1548
+ };
1549
+ var progressFill = {
1550
+ name: "progressFill",
1551
+ description: "Animated fill from 0% to target width for progress bars",
1552
+ useCase: ["progress bars", "completion indicators", "skill bars", "loading progress", "data visualization"],
1553
+ getProps: (style) => {
1554
+ if (prefersReducedMotion()) return getReducedMotionProps();
1555
+ const config = getMotionStyle(style);
1556
+ const duration = style === "subtle" ? 0.6 : style === "playful" ? 1.2 : 0.8;
1557
+ return {
1558
+ initial: {
1559
+ scaleX: 0
1560
+ },
1561
+ animate: {
1562
+ scaleX: 1
1563
+ },
1564
+ transition: {
1565
+ duration,
1566
+ ease: config.easing.exit
1567
+ }
1568
+ };
1569
+ }
1570
+ };
1571
+ var checkmarkDraw = {
1572
+ name: "checkmarkDraw",
1573
+ description: "Animated checkmark draw effect for success states",
1574
+ useCase: ["success confirmations", "completed tasks", "checkboxes", "form submissions", "achievement unlocks"],
1575
+ getProps: (style) => {
1576
+ if (prefersReducedMotion()) return getReducedMotionProps();
1577
+ const config = getMotionStyle(style);
1578
+ const duration = style === "subtle" ? config.duration.fast : style === "playful" ? config.duration.slow : config.duration.normal;
1579
+ return {
1580
+ initial: {
1581
+ pathLength: 0,
1582
+ opacity: 0
1583
+ },
1584
+ animate: {
1585
+ pathLength: 1,
1586
+ opacity: 1
1587
+ },
1588
+ transition: {
1589
+ duration: msToSeconds(duration),
1590
+ ease: config.easing.interactive
1591
+ }
1592
+ };
1593
+ }
1594
+ };
1595
+ var successFlash = {
1596
+ name: "successFlash",
1597
+ description: "Brief success highlight flash animation",
1598
+ useCase: ["success toasts", "inline confirmations", "save indicators", "completion feedback", "achievement notifications"],
1599
+ getProps: (style) => {
1600
+ if (prefersReducedMotion()) return getReducedMotionProps();
1601
+ const config = getMotionStyle(style);
1602
+ const scale3 = style === "subtle" ? 1.02 : style === "playful" ? 1.08 : 1.05;
1603
+ return {
1604
+ initial: {
1605
+ scale: 1,
1606
+ backgroundColor: "transparent"
1607
+ },
1608
+ animate: {
1609
+ scale: [1, scale3, 1],
1610
+ backgroundColor: ["transparent", "var(--color-surface-success-subtle)", "transparent"]
1611
+ },
1612
+ transition: {
1613
+ duration: msToSeconds(config.duration.fast),
1614
+ ease: config.easing.interactive
1615
+ }
1616
+ };
1617
+ }
1618
+ };
1619
+ var badgePop = {
1620
+ name: "badgePop",
1621
+ description: "Pop animation for badge count changes",
1622
+ useCase: ["notification badges", "count indicators", "numeric updates", "inventory changes", "score updates"],
1623
+ getProps: (style) => {
1624
+ if (prefersReducedMotion()) return getReducedMotionProps();
1625
+ const config = getMotionStyle(style);
1626
+ const scale3 = style === "subtle" ? 1.15 : style === "playful" ? 1.4 : 1.25;
1627
+ return {
1628
+ initial: {
1629
+ scale: 0,
1630
+ opacity: 0
1631
+ },
1632
+ animate: {
1633
+ scale: [0, scale3, 1],
1634
+ opacity: [0, 1, 1]
1635
+ },
1636
+ transition: {
1637
+ duration: msToSeconds(config.duration.fast),
1638
+ ease: config.easing.interactive
1639
+ }
1640
+ };
1641
+ }
1642
+ };
1643
+ var microInteractions = {
1644
+ buttonPress,
1645
+ cardHover,
1646
+ iconSpin,
1647
+ pulse,
1648
+ scale: scale2,
1649
+ shake,
1650
+ wiggle,
1651
+ heartbeat,
1652
+ rubberBand,
1653
+ shimmer,
1654
+ glowPulse,
1655
+ progressFill,
1656
+ checkmarkDraw,
1657
+ successFlash,
1658
+ badgePop
1659
+ };
1660
+ function getMicroInteraction(name) {
1661
+ return microInteractions[name];
1662
+ }
1663
+ function getMicroInteractionNames() {
1664
+ return Object.keys(microInteractions);
1665
+ }
1666
+ function findPresetsForUseCase(useCase) {
1667
+ const searchTerm = useCase.toLowerCase();
1668
+ return Object.values(microInteractions).filter((preset) => preset.useCase.some((uc) => uc.toLowerCase().includes(searchTerm)));
1669
+ }
1670
+
1671
+ // src/presets/stagger-presets.ts
1672
+ function createBaseItemVariants(style) {
1673
+ const config = getMotionStyle(style);
1674
+ return {
1675
+ hidden: {
1676
+ opacity: 0,
1677
+ y: 20
1678
+ },
1679
+ visible: {
1680
+ opacity: 1,
1681
+ y: 0,
1682
+ transition: {
1683
+ type: "spring",
1684
+ stiffness: config.spring.stiffness,
1685
+ damping: config.spring.damping,
1686
+ mass: config.spring.mass
1687
+ }
1688
+ }
1689
+ };
1690
+ }
1691
+ var staggerSequential = {
1692
+ name: "Sequential",
1693
+ description: "Items animate one after another from top to bottom",
1694
+ useCase: ["Navigation menus", "Vertical lists", "Table rows", "Form fields", "Sidebar items"],
1695
+ getDelay(index, _total, style) {
1696
+ const config = getMotionStyle(style);
1697
+ return msToSeconds(config.staggerDelay * index);
1698
+ },
1699
+ getContainerVariants(style) {
1700
+ const config = getMotionStyle(style);
1701
+ return {
1702
+ hidden: { opacity: 0 },
1703
+ visible: {
1704
+ opacity: 1,
1705
+ transition: {
1706
+ staggerChildren: msToSeconds(config.staggerDelay),
1707
+ delayChildren: msToSeconds(config.duration.fast * 0.5)
1708
+ }
1709
+ }
1710
+ };
1711
+ },
1712
+ getItemVariants: createBaseItemVariants
1713
+ };
1714
+ var staggerReverse = {
1715
+ name: "Reverse",
1716
+ description: "Items animate from bottom to top",
1717
+ useCase: ["Toast notifications", "Chat messages (newest first)", "Bottom-anchored content", "Rising effect animations", "Upward reveals"],
1718
+ getDelay(index, total, style) {
1719
+ const config = getMotionStyle(style);
1720
+ const reverseIndex = total - 1 - index;
1721
+ return msToSeconds(config.staggerDelay * reverseIndex);
1722
+ },
1723
+ getContainerVariants(style) {
1724
+ const config = getMotionStyle(style);
1725
+ return {
1726
+ hidden: { opacity: 0 },
1727
+ visible: {
1728
+ opacity: 1,
1729
+ transition: {
1730
+ staggerChildren: msToSeconds(config.staggerDelay),
1731
+ staggerDirection: -1,
1732
+ delayChildren: msToSeconds(config.duration.fast * 0.5)
1733
+ }
1734
+ }
1735
+ };
1736
+ },
1737
+ getItemVariants(style) {
1738
+ const config = getMotionStyle(style);
1739
+ return {
1740
+ hidden: {
1741
+ opacity: 0,
1742
+ y: -20
1743
+ },
1744
+ visible: {
1745
+ opacity: 1,
1746
+ y: 0,
1747
+ transition: {
1748
+ type: "spring",
1749
+ stiffness: config.spring.stiffness,
1750
+ damping: config.spring.damping,
1751
+ mass: config.spring.mass
1752
+ }
1753
+ }
1754
+ };
1755
+ }
1756
+ };
1757
+ var staggerCenter = {
1758
+ name: "Center",
1759
+ description: "Items animate from center outward",
1760
+ useCase: ["Hero sections", "Featured content", "Pricing cards", "Centered navigation", "Focus-based reveals"],
1761
+ getDelay(index, total, style) {
1762
+ const config = getMotionStyle(style);
1763
+ const centerIndex = (total - 1) / 2;
1764
+ const distanceFromCenter = Math.abs(index - centerIndex);
1765
+ return msToSeconds(config.staggerDelay * distanceFromCenter);
1766
+ },
1767
+ getContainerVariants(style) {
1768
+ const config = getMotionStyle(style);
1769
+ return {
1770
+ hidden: { opacity: 0 },
1771
+ visible: {
1772
+ opacity: 1,
1773
+ transition: {
1774
+ staggerChildren: msToSeconds(config.staggerDelay),
1775
+ delayChildren: msToSeconds(config.duration.fast * 0.5)
1776
+ }
1777
+ }
1778
+ };
1779
+ },
1780
+ getItemVariants(style) {
1781
+ const config = getMotionStyle(style);
1782
+ return {
1783
+ hidden: {
1784
+ opacity: 0,
1785
+ scale: 0.8
1786
+ },
1787
+ visible: {
1788
+ opacity: 1,
1789
+ scale: 1,
1790
+ transition: {
1791
+ type: "spring",
1792
+ stiffness: config.spring.stiffness,
1793
+ damping: config.spring.damping,
1794
+ mass: config.spring.mass
1795
+ }
1796
+ }
1797
+ };
1798
+ }
1799
+ };
1800
+ var staggerRandom = {
1801
+ name: "Random",
1802
+ description: "Items animate in random order",
1803
+ useCase: ["Photo galleries", "Tag clouds", "Creative portfolios", "Playful interfaces", "Organic reveals"],
1804
+ getDelay(index, total, style) {
1805
+ const config = getMotionStyle(style);
1806
+ const seed = index * 7919 % total / total;
1807
+ const maxDelay = config.staggerDelay * total;
1808
+ return msToSeconds(seed * maxDelay);
1809
+ },
1810
+ getContainerVariants(style) {
1811
+ const config = getMotionStyle(style);
1812
+ return {
1813
+ hidden: { opacity: 0 },
1814
+ visible: {
1815
+ opacity: 1,
1816
+ transition: {
1817
+ staggerChildren: msToSeconds(config.staggerDelay * 0.3),
1818
+ delayChildren: msToSeconds(config.duration.fast * 0.5)
1819
+ }
1820
+ }
1821
+ };
1822
+ },
1823
+ getItemVariants(style) {
1824
+ const config = getMotionStyle(style);
1825
+ return {
1826
+ hidden: {
1827
+ opacity: 0,
1828
+ scale: 0.9,
1829
+ rotate: -5
1830
+ },
1831
+ visible: {
1832
+ opacity: 1,
1833
+ scale: 1,
1834
+ rotate: 0,
1835
+ transition: {
1836
+ type: "spring",
1837
+ stiffness: config.spring.stiffness,
1838
+ damping: config.spring.damping,
1839
+ mass: config.spring.mass
1840
+ }
1841
+ }
1842
+ };
1843
+ }
1844
+ };
1845
+ var staggerGrid = {
1846
+ name: "Grid",
1847
+ description: "2D diagonal wave pattern for grid layouts",
1848
+ useCase: ["Image galleries", "Card grids", "Dashboard widgets", "Product catalogs", "Portfolio items"],
1849
+ getDelay(index, _total, style, columns = 4) {
1850
+ const config = getMotionStyle(style);
1851
+ const row = Math.floor(index / columns);
1852
+ const col = index % columns;
1853
+ const diagonalIndex = row + col;
1854
+ return msToSeconds(config.staggerDelay * diagonalIndex);
1855
+ },
1856
+ getContainerVariants(style) {
1857
+ const config = getMotionStyle(style);
1858
+ return {
1859
+ hidden: { opacity: 0 },
1860
+ visible: {
1861
+ opacity: 1,
1862
+ transition: {
1863
+ staggerChildren: msToSeconds(config.staggerDelay * 0.8),
1864
+ delayChildren: msToSeconds(config.duration.fast * 0.5)
1865
+ }
1866
+ }
1867
+ };
1868
+ },
1869
+ getItemVariants(style) {
1870
+ const config = getMotionStyle(style);
1871
+ return {
1872
+ hidden: {
1873
+ opacity: 0,
1874
+ scale: 0.9,
1875
+ y: 10
1876
+ },
1877
+ visible: {
1878
+ opacity: 1,
1879
+ scale: 1,
1880
+ y: 0,
1881
+ transition: {
1882
+ type: "spring",
1883
+ stiffness: config.spring.stiffness,
1884
+ damping: config.spring.damping,
1885
+ mass: config.spring.mass
1886
+ }
1887
+ }
1888
+ };
1889
+ }
1890
+ };
1891
+ var staggerWave = {
1892
+ name: "Wave",
1893
+ description: "Sine-wave based stagger pattern for organic motion",
1894
+ useCase: ["Audio visualizers", "Timeline animations", "Organic reveals", "Music interfaces", "Flowing sequences"],
1895
+ getDelay(index, total, style) {
1896
+ const config = getMotionStyle(style);
1897
+ const wavePosition = index / total * Math.PI * 2;
1898
+ const waveOffset = (Math.sin(wavePosition) + 1) / 2;
1899
+ const baseDelay = config.staggerDelay * index;
1900
+ const waveDelay = config.staggerDelay * waveOffset * 2;
1901
+ return msToSeconds(baseDelay + waveDelay);
1902
+ },
1903
+ getContainerVariants(style) {
1904
+ const config = getMotionStyle(style);
1905
+ return {
1906
+ hidden: { opacity: 0 },
1907
+ visible: {
1908
+ opacity: 1,
1909
+ transition: {
1910
+ staggerChildren: msToSeconds(config.staggerDelay * 0.6),
1911
+ delayChildren: msToSeconds(config.duration.fast * 0.5)
1912
+ }
1913
+ }
1914
+ };
1915
+ },
1916
+ getItemVariants(style) {
1917
+ const config = getMotionStyle(style);
1918
+ return {
1919
+ hidden: {
1920
+ opacity: 0,
1921
+ y: 15,
1922
+ x: -5
1923
+ },
1924
+ visible: {
1925
+ opacity: 1,
1926
+ y: 0,
1927
+ x: 0,
1928
+ transition: {
1929
+ type: "spring",
1930
+ stiffness: config.spring.stiffness,
1931
+ damping: config.spring.damping,
1932
+ mass: config.spring.mass
1933
+ }
1934
+ }
1935
+ };
1936
+ }
1937
+ };
1938
+ var staggerCascade = {
1939
+ name: "Cascade",
1940
+ description: "Fast initial items, progressively slower later ones",
1941
+ useCase: ["Long lists", "Data tables", "Search results", "Infinite scroll content", "Progressive reveals"],
1942
+ getDelay(index, total, style) {
1943
+ const config = getMotionStyle(style);
1944
+ const normalizedIndex = index / Math.max(total - 1, 1);
1945
+ const cascadeFactor = Math.sqrt(normalizedIndex);
1946
+ const maxDuration = config.staggerDelay * total;
1947
+ return msToSeconds(cascadeFactor * maxDuration);
1948
+ },
1949
+ getContainerVariants(style) {
1950
+ const config = getMotionStyle(style);
1951
+ return {
1952
+ hidden: { opacity: 0 },
1953
+ visible: {
1954
+ opacity: 1,
1955
+ transition: {
1956
+ staggerChildren: msToSeconds(config.staggerDelay * 0.4),
1957
+ delayChildren: msToSeconds(config.duration.fast * 0.3)
1958
+ }
1959
+ }
1960
+ };
1961
+ },
1962
+ getItemVariants(style) {
1963
+ const config = getMotionStyle(style);
1964
+ return {
1965
+ hidden: {
1966
+ opacity: 0,
1967
+ x: -10
1968
+ },
1969
+ visible: {
1970
+ opacity: 1,
1971
+ x: 0,
1972
+ transition: {
1973
+ type: "spring",
1974
+ stiffness: config.spring.stiffness + 50,
1975
+ // Slightly snappier
1976
+ damping: config.spring.damping + 5,
1977
+ mass: config.spring.mass * 0.9
1978
+ }
1979
+ }
1980
+ };
1981
+ }
1982
+ };
1983
+ var staggerPresets = {
1984
+ sequential: staggerSequential,
1985
+ reverse: staggerReverse,
1986
+ center: staggerCenter,
1987
+ random: staggerRandom,
1988
+ grid: staggerGrid,
1989
+ wave: staggerWave,
1990
+ cascade: staggerCascade
1991
+ };
1992
+ function getStaggerPreset(name) {
1993
+ const preset = staggerPresets[name];
1994
+ if (!preset) {
1995
+ throw new Error(`Unknown stagger preset: ${name}. Available: ${Object.keys(staggerPresets).join(", ")}`);
1996
+ }
1997
+ return preset;
1998
+ }
1999
+ function calculateStaggerDelays(preset, total, style) {
2000
+ const staggerPreset = getStaggerPreset(preset);
2001
+ return Array.from({ length: total }, (_, index) => staggerPreset.getDelay(index, total, style));
2002
+ }
2003
+
2004
+ // src/utils/easing.ts
2005
+ var linear = [0, 0, 1, 1];
2006
+ var easeIn = [0.4, 0, 1, 1];
2007
+ var easeOut = [0, 0, 0.2, 1];
2008
+ var easeInOut = [0.4, 0, 0.2, 1];
2009
+ var easeOutQuart = [0.25, 1, 0.5, 1];
2010
+ var easeInOutCubic = [0.65, 0, 0.35, 1];
2011
+ var easeOutBack = [0.34, 1.56, 0.64, 1];
2012
+ var easeOutExpo = [0.16, 1, 0.3, 1];
2013
+ var easeInOutQuint = [0.83, 0, 0.17, 1];
2014
+ function createTween(duration, ease) {
2015
+ return {
2016
+ type: "tween",
2017
+ duration,
2018
+ ease: ease ?? easeOut
2019
+ };
2020
+ }
2021
+ function createTweenFromParams(params) {
2022
+ const result = {
2023
+ type: "tween",
2024
+ duration: params.duration
2025
+ };
2026
+ if (params.ease !== void 0) {
2027
+ return { ...result, ease: params.ease };
2028
+ }
2029
+ return result;
2030
+ }
2031
+ var durations = {
2032
+ /** Micro-interactions: hover states, small toggles (100ms) */
2033
+ instant: 0.1,
2034
+ /** Quick feedback: button clicks, checkboxes (200ms) */
2035
+ fast: 0.2,
2036
+ /** Standard transitions: most UI elements (300ms) */
2037
+ normal: 0.3,
2038
+ /** Emphasized transitions: modals, drawers (400ms) */
2039
+ slow: 0.4,
2040
+ /** Dramatic transitions: page changes, reveals (600ms) */
2041
+ slower: 0.6
2042
+ };
2043
+ var easingPresets = {
2044
+ linear,
2045
+ easeIn,
2046
+ easeOut,
2047
+ easeInOut,
2048
+ easeOutQuart,
2049
+ easeInOutCubic,
2050
+ easeOutBack,
2051
+ easeOutExpo,
2052
+ easeInOutQuint
2053
+ };
2054
+ var tweenPresets = {
2055
+ /** Quick fade for hover states and micro-interactions */
2056
+ instant: createTween(durations.instant, easeOut),
2057
+ /** Snappy transition for interactive elements */
2058
+ fast: createTween(durations.fast, easeOut),
2059
+ /** Balanced transition for most UI elements */
2060
+ normal: createTween(durations.normal, easeOutQuart),
2061
+ /** Smooth transition for modals and overlays */
2062
+ slow: createTween(durations.slow, easeOutQuart),
2063
+ /** Dramatic transition for page-level changes */
2064
+ slower: createTween(durations.slower, easeInOutCubic)
2065
+ };
2066
+
2067
+ // src/utils/reduced-motion.ts
2068
+ import { useEffect as useEffect5, useState as useState5 } from "react";
2069
+ var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
2070
+ var INSTANT_TRANSITION = {
2071
+ duration: 0,
2072
+ delay: 0
2073
+ };
2074
+ function getReducedMotionVariant(normalVariant, reducedVariant, prefersReducedMotion2) {
2075
+ return prefersReducedMotion2 ? reducedVariant : normalVariant;
2076
+ }
2077
+ function filterVariantForReducedMotion(variant, options) {
2078
+ const { preserveOpacity = true, preserveColors = true } = options;
2079
+ const filtered = {};
2080
+ for (const [key, value] of Object.entries(variant)) {
2081
+ const isOpacityProperty = key === "opacity";
2082
+ const isColorProperty = key === "color" || key === "backgroundColor" || key === "borderColor" || key === "fill" || key === "stroke";
2083
+ if (preserveOpacity && isOpacityProperty || preserveColors && isColorProperty) {
2084
+ filtered[key] = value;
2085
+ }
2086
+ }
2087
+ return filtered;
2088
+ }
2089
+ function createReducedMotionProps(props, prefersReducedMotion2, options = {}) {
2090
+ if (!prefersReducedMotion2) {
2091
+ return props;
2092
+ }
2093
+ const { preserveOpacity = true, preserveColors = true, reducedTransition } = options;
2094
+ const transition = reducedTransition ?? INSTANT_TRANSITION;
2095
+ const processVariant = (variant) => {
2096
+ if (variant === void 0 || typeof variant === "string" || typeof variant === "boolean") {
2097
+ return variant;
2098
+ }
2099
+ return filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });
2100
+ };
2101
+ const processVariants = (variants) => {
2102
+ if (!variants) {
2103
+ return void 0;
2104
+ }
2105
+ const processed = {};
2106
+ for (const [key, variant] of Object.entries(variants)) {
2107
+ processed[key] = filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });
2108
+ }
2109
+ return processed;
2110
+ };
2111
+ const processNonBooleanVariant = (variant) => {
2112
+ if (variant === void 0 || typeof variant === "string") {
2113
+ return variant;
2114
+ }
2115
+ return filterVariantForReducedMotion(variant, { preserveOpacity, preserveColors });
2116
+ };
2117
+ return {
2118
+ ...props,
2119
+ initial: processVariant(props.initial),
2120
+ animate: processNonBooleanVariant(props.animate),
2121
+ exit: processNonBooleanVariant(props.exit),
2122
+ variants: processVariants(props.variants),
2123
+ transition,
2124
+ // Disable hover/tap/focus animations in reduced motion mode
2125
+ // as they often involve movement
2126
+ whileHover: void 0,
2127
+ whileTap: void 0,
2128
+ whileFocus: void 0,
2129
+ whileDrag: void 0,
2130
+ whileInView: processNonBooleanVariant(props.whileInView)
2131
+ };
2132
+ }
2133
+ function checkReducedMotion() {
2134
+ if (typeof window === "undefined") {
2135
+ return false;
2136
+ }
2137
+ return window.matchMedia(REDUCED_MOTION_QUERY).matches;
2138
+ }
2139
+
2140
+ // src/utils/select-preset.ts
2141
+ function calculateMatchScore(preset, criteria) {
2142
+ let score = 0;
2143
+ let factors = 0;
2144
+ if (criteria.useCase) {
2145
+ factors++;
2146
+ if (preset.metadata.useCase.includes(criteria.useCase)) {
2147
+ score += 1;
2148
+ }
2149
+ }
2150
+ if (criteria.context) {
2151
+ factors++;
2152
+ if (preset.metadata.context.includes(criteria.context)) {
2153
+ score += 1;
2154
+ }
2155
+ }
2156
+ if (criteria.maxIntensity !== void 0) {
2157
+ factors++;
2158
+ if (preset.metadata.intensity <= criteria.maxIntensity) {
2159
+ score += 1;
2160
+ }
2161
+ }
2162
+ if (criteria.minIntensity !== void 0) {
2163
+ factors++;
2164
+ if (preset.metadata.intensity >= criteria.minIntensity) {
2165
+ score += 1;
2166
+ }
2167
+ }
2168
+ if (criteria.preferMovement !== void 0) {
2169
+ factors++;
2170
+ if (preset.metadata.hasMovement === criteria.preferMovement) {
2171
+ score += 1;
2172
+ }
2173
+ }
2174
+ if (criteria.direction && preset.metadata.direction) {
2175
+ factors++;
2176
+ if (preset.metadata.direction === criteria.direction) {
2177
+ score += 1;
2178
+ }
2179
+ }
2180
+ if (criteria.prioritizeAccessibility) {
2181
+ factors++;
2182
+ score += (5 - preset.metadata.intensity) / 5;
2183
+ }
2184
+ return factors > 0 ? score / factors : 0;
2185
+ }
2186
+ function determineStyle(criteria) {
2187
+ if (criteria.style) {
2188
+ return criteria.style;
2189
+ }
2190
+ if (criteria.prioritizeAccessibility) {
2191
+ return "subtle";
2192
+ }
2193
+ if (criteria.context === "hero" || criteria.context === "page") {
2194
+ return "bold";
2195
+ }
2196
+ if (criteria.context === "tooltip" || criteria.context === "dropdown") {
2197
+ return "subtle";
2198
+ }
2199
+ return "standard";
2200
+ }
2201
+ function generateReasoning(preset, criteria, score) {
2202
+ const reasons = [];
2203
+ if (criteria.useCase && preset.metadata.useCase.includes(criteria.useCase)) {
2204
+ reasons.push(`matches use case "${criteria.useCase}"`);
2205
+ }
2206
+ if (criteria.context && preset.metadata.context.includes(criteria.context)) {
2207
+ reasons.push(`suitable for "${criteria.context}" context`);
2208
+ }
2209
+ if (criteria.direction && preset.metadata.direction === criteria.direction) {
2210
+ reasons.push(`provides "${criteria.direction}" movement`);
2211
+ }
2212
+ if (criteria.prioritizeAccessibility && preset.metadata.intensity <= 2) {
2213
+ reasons.push("has low intensity for accessibility");
2214
+ }
2215
+ if (reasons.length === 0) {
2216
+ reasons.push("general-purpose animation");
2217
+ }
2218
+ return `Selected "${preset.metadata.name}" (${Math.round(score * 100)}% match): ${reasons.join(", ")}.`;
2219
+ }
2220
+ function selectPreset(criteria) {
2221
+ const allPresets = Object.entries(componentPresets);
2222
+ const scoredPresets = allPresets.map(([name, preset]) => ({
2223
+ name,
2224
+ preset,
2225
+ score: calculateMatchScore(preset, criteria)
2226
+ }));
2227
+ scoredPresets.sort((a, b) => b.score - a.score);
2228
+ const best = scoredPresets[0];
2229
+ const style = determineStyle(criteria);
2230
+ if (!best) {
2231
+ throw new Error("selectPreset: no presets available; cannot select a preset.");
2232
+ }
2233
+ const alternatives = scoredPresets.slice(1, 4).filter((p) => p.score > 0.3).map((p) => p.name);
2234
+ return {
2235
+ preset: best.preset,
2236
+ presetName: best.name,
2237
+ style,
2238
+ confidence: best.score,
2239
+ reasoning: generateReasoning(best.preset, criteria, best.score),
2240
+ alternatives
2241
+ };
2242
+ }
2243
+ function getRecommendations(context, options = {}) {
2244
+ const { maxResults = 5, minScore = 0.3 } = options;
2245
+ const contextPresets = getPresetsByContext(context);
2246
+ const recommendations = contextPresets.map((preset) => {
2247
+ const name = Object.entries(componentPresets).find(([_, p]) => p === preset)?.[0];
2248
+ const contextFit = preset.metadata.context.indexOf(context) === 0 ? 1 : 0.7;
2249
+ const intensityFit = 1 - Math.abs(preset.metadata.intensity - 3) / 4;
2250
+ const score = (contextFit + intensityFit) / 2;
2251
+ return {
2252
+ preset,
2253
+ name,
2254
+ reason: `${preset.metadata.description}. Ideal for ${preset.metadata.context.slice(0, 2).join(", ")}.`,
2255
+ score
2256
+ };
2257
+ });
2258
+ return recommendations.filter((r) => r.score >= minScore).sort((a, b) => b.score - a.score).slice(0, maxResults);
2259
+ }
2260
+ function getDefaultPreset(context) {
2261
+ const defaults = {
2262
+ modal: "scale",
2263
+ dropdown: "slideDown",
2264
+ tooltip: "fadeIn",
2265
+ drawer: "slideRight",
2266
+ card: "fadeIn",
2267
+ "list-item": "slideUp",
2268
+ notification: "slideRight",
2269
+ page: "fadeIn",
2270
+ section: "slideUp",
2271
+ hero: "slideUpScale"
2272
+ };
2273
+ return componentPresets[defaults[context]];
2274
+ }
2275
+ function suggestAnimations(context, style = "standard") {
2276
+ const entranceResult = selectPreset({
2277
+ useCase: "entrance",
2278
+ context,
2279
+ style
2280
+ });
2281
+ const exitResult = selectPreset({
2282
+ useCase: "exit",
2283
+ context,
2284
+ style
2285
+ });
2286
+ return {
2287
+ entrance: entranceResult.preset,
2288
+ entranceName: entranceResult.presetName,
2289
+ exit: exitResult.preset,
2290
+ exitName: exitResult.presetName,
2291
+ style
2292
+ };
2293
+ }
2294
+ function getAllPresetNames() {
2295
+ return Object.keys(componentPresets);
2296
+ }
2297
+ function getAllContexts() {
2298
+ return ["modal", "dropdown", "tooltip", "drawer", "card", "list-item", "notification", "page", "section", "hero"];
2299
+ }
2300
+ function getAllUseCases() {
2301
+ return ["entrance", "exit", "transition", "emphasis", "reveal"];
2302
+ }
2303
+ function getPresetMetadata(name) {
2304
+ return componentPresets[name].metadata;
2305
+ }
2306
+
2307
+ // src/utils/spring-configs.ts
2308
+ var springGentle = {
2309
+ type: "spring",
2310
+ stiffness: 200,
2311
+ damping: 30,
2312
+ mass: 1
2313
+ };
2314
+ var springSnappy = {
2315
+ type: "spring",
2316
+ stiffness: 400,
2317
+ damping: 30,
2318
+ mass: 0.8
2319
+ };
2320
+ var springBouncy = {
2321
+ type: "spring",
2322
+ stiffness: 300,
2323
+ damping: 15,
2324
+ mass: 1
2325
+ };
2326
+ var springStiff = {
2327
+ type: "spring",
2328
+ stiffness: 500,
2329
+ damping: 35,
2330
+ mass: 0.6
2331
+ };
2332
+ function createSpring(stiffness, damping, mass) {
2333
+ return {
2334
+ type: "spring",
2335
+ stiffness,
2336
+ damping,
2337
+ mass
2338
+ };
2339
+ }
2340
+ function createSpringFromParams(params) {
2341
+ return {
2342
+ type: "spring",
2343
+ stiffness: params.stiffness,
2344
+ damping: params.damping,
2345
+ mass: params.mass
2346
+ };
2347
+ }
2348
+ var springPresets = {
2349
+ gentle: springGentle,
2350
+ snappy: springSnappy,
2351
+ bouncy: springBouncy,
2352
+ stiff: springStiff
2353
+ };
150
2354
  export {
2355
+ CountUp,
2356
+ INSTANT_TRANSITION,
2357
+ MotionDiv,
2358
+ REDUCED_MOTION_QUERY,
2359
+ StaggerContainer,
151
2360
  ambientPaths,
152
2361
  applyMotionPreset,
2362
+ badgePop,
2363
+ boldStyle,
2364
+ buttonPress,
2365
+ calculateStaggerDelays,
2366
+ cardHover,
2367
+ cascadeStagger,
2368
+ checkReducedMotion,
2369
+ checkmarkDraw,
2370
+ componentPresets,
2371
+ createAccessibleMotionProps,
2372
+ createMotionProps,
2373
+ createReducedMotionProps,
2374
+ createSpring,
2375
+ createSpringFromParams,
2376
+ createTween,
2377
+ createTweenFromParams,
2378
+ durations,
2379
+ easeIn,
2380
+ easeInOut,
2381
+ easeInOutCubic,
2382
+ easeInOutQuint,
2383
+ easeOut,
2384
+ easeOutBack,
2385
+ easeOutExpo,
2386
+ easeOutQuart,
2387
+ easingPresets,
2388
+ expand,
2389
+ explodeStagger,
2390
+ fadeIn,
2391
+ fadeOut,
2392
+ findPresetsForUseCase,
2393
+ flip,
2394
+ getAllContexts,
2395
+ getAllPresetNames,
2396
+ getAllUseCases,
2397
+ getComponentPreset,
2398
+ getDefaultPreset,
2399
+ getDuration,
2400
+ getMicroInteraction,
2401
+ getMicroInteractionNames,
2402
+ getMotionStyle,
153
2403
  getPreset,
2404
+ getPresetMetadata,
2405
+ getPresetsByContext,
2406
+ getPresetsByUseCase,
2407
+ getRecommendations,
2408
+ getReducedMotionVariant,
2409
+ getSpringConfig,
2410
+ getStaggerPreset,
2411
+ glowPulse,
2412
+ gridStagger,
2413
+ heartbeat,
2414
+ iconSpin,
154
2415
  lightRays,
155
- useMotionPreset
2416
+ linear,
2417
+ microInteractions,
2418
+ motionStyles,
2419
+ msToSeconds,
2420
+ playfulStyle,
2421
+ progressFill,
2422
+ pulse,
2423
+ rotate,
2424
+ rubberBand,
2425
+ scale,
2426
+ scale2 as scaleMicro,
2427
+ selectPreset,
2428
+ shake,
2429
+ shimmer,
2430
+ slideDown,
2431
+ slideLeft,
2432
+ slideRight,
2433
+ slideUp,
2434
+ slideUpScale,
2435
+ springBouncy,
2436
+ springGentle,
2437
+ springPresets,
2438
+ springSnappy,
2439
+ springStiff,
2440
+ staggerCascade,
2441
+ staggerCenter,
2442
+ staggerGrid,
2443
+ staggerPresets,
2444
+ staggerRandom,
2445
+ staggerReverse,
2446
+ staggerSequential,
2447
+ staggerWave,
2448
+ standardStyle,
2449
+ subtleStyle,
2450
+ successFlash,
2451
+ suggestAnimations,
2452
+ tweenPresets,
2453
+ useAnimationVariants,
2454
+ useComponentAnimation,
2455
+ useCountUp,
2456
+ useDelayedAnimation,
2457
+ useDrawPath,
2458
+ useMotionPreset,
2459
+ useReducedMotion2 as useReducedMotion,
2460
+ useStagger,
2461
+ waveStagger,
2462
+ wiggle,
2463
+ withStagger,
2464
+ zoomIn,
2465
+ zoomOut
156
2466
  };
157
2467
  //# sourceMappingURL=index.mjs.map