use-scroll-animate 3.7.0 → 3.9.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 (129) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -0
  3. package/README_ja.md +1 -0
  4. package/README_zh.md +1 -0
  5. package/dist/chunks/{base-BpROOcey.js → base-BRIPyPtX.js} +11 -2
  6. package/dist/chunks/{base-BpROOcey.js.map → base-BRIPyPtX.js.map} +1 -1
  7. package/dist/chunks/{base-CXx7jZ-o.cjs → base-Dm6ee5ug.cjs} +11 -1
  8. package/dist/chunks/{base-CXx7jZ-o.cjs.map → base-Dm6ee5ug.cjs.map} +1 -1
  9. package/dist/chunks/bind-B_CTL6Qn.js +22 -0
  10. package/dist/chunks/bind-B_CTL6Qn.js.map +1 -0
  11. package/dist/chunks/bind-Ui43-n2d.cjs +25 -0
  12. package/dist/chunks/bind-Ui43-n2d.cjs.map +1 -0
  13. package/dist/chunks/{core-IaorbTdu.cjs → core-CHAtivHV.cjs} +2 -2
  14. package/dist/chunks/{core-IaorbTdu.cjs.map → core-CHAtivHV.cjs.map} +1 -1
  15. package/dist/chunks/{core-uxs3ETou.js → core-CYozf_E-.js} +2 -2
  16. package/dist/chunks/{core-uxs3ETou.js.map → core-CYozf_E-.js.map} +1 -1
  17. package/dist/chunks/{index-tags-BANJ-e4H.js → index-tags-BmQR17Sb.js} +2 -1
  18. package/dist/chunks/{index-tags-BANJ-e4H.js.map → index-tags-BmQR17Sb.js.map} +1 -1
  19. package/dist/chunks/{index-tags-wbuPiMR6.cjs → index-tags-DYYsgbba.cjs} +2 -1
  20. package/dist/chunks/{index-tags-wbuPiMR6.cjs.map → index-tags-DYYsgbba.cjs.map} +1 -1
  21. package/dist/chunks/{spring-2OTnYCzm.cjs → spring-Dp5BllPB.cjs} +2 -2
  22. package/dist/chunks/{spring-2OTnYCzm.cjs.map → spring-Dp5BllPB.cjs.map} +1 -1
  23. package/dist/chunks/{spring-C-fw7_9f.js → spring-UBPhrh1X.js} +2 -2
  24. package/dist/chunks/{spring-C-fw7_9f.js.map → spring-UBPhrh1X.js.map} +1 -1
  25. package/dist/chunks/{variants-CHe1VbSn.js → variants-DTypaOH3.js} +2 -2
  26. package/dist/chunks/{variants-CHe1VbSn.js.map → variants-DTypaOH3.js.map} +1 -1
  27. package/dist/chunks/{variants-BNIrn4ch.cjs → variants-_dC-ey6R.cjs} +2 -2
  28. package/dist/chunks/{variants-BNIrn4ch.cjs.map → variants-_dC-ey6R.cjs.map} +1 -1
  29. package/dist/components/angular.cjs +68 -0
  30. package/dist/components/angular.cjs.map +1 -0
  31. package/dist/components/angular.d.cts +1687 -0
  32. package/dist/components/angular.d.ts +1687 -0
  33. package/dist/components/angular.js +62 -0
  34. package/dist/components/angular.js.map +1 -0
  35. package/dist/components/background.cjs +2 -2
  36. package/dist/components/background.js +3 -3
  37. package/dist/components/cards.cjs +2 -2
  38. package/dist/components/cards.js +3 -3
  39. package/dist/components/click.cjs +2 -2
  40. package/dist/components/click.js +3 -3
  41. package/dist/components/depth.cjs +3 -3
  42. package/dist/components/depth.js +4 -4
  43. package/dist/components/feedback.cjs +1 -1
  44. package/dist/components/feedback.js +2 -2
  45. package/dist/components/gesture.cjs +3 -3
  46. package/dist/components/gesture.js +5 -5
  47. package/dist/components/interaction.cjs +1 -1
  48. package/dist/components/interaction.js +2 -2
  49. package/dist/components/jsx.d.cts +1 -0
  50. package/dist/components/jsx.d.ts +1 -0
  51. package/dist/components/layout.cjs +1 -1
  52. package/dist/components/layout.js +2 -2
  53. package/dist/components/lazy.cjs +2 -1
  54. package/dist/components/lazy.cjs.map +1 -1
  55. package/dist/components/lazy.d.cts +1 -0
  56. package/dist/components/lazy.d.ts +1 -0
  57. package/dist/components/lazy.js +2 -1
  58. package/dist/components/lazy.js.map +1 -1
  59. package/dist/components/packs.cjs +194 -0
  60. package/dist/components/packs.cjs.map +1 -0
  61. package/dist/components/packs.css +3 -0
  62. package/dist/components/packs.d.cts +107 -0
  63. package/dist/components/packs.d.ts +107 -0
  64. package/dist/components/packs.js +185 -0
  65. package/dist/components/packs.js.map +1 -0
  66. package/dist/components/page.cjs +2 -2
  67. package/dist/components/page.js +3 -3
  68. package/dist/components/physics.cjs +2 -2
  69. package/dist/components/physics.js +4 -4
  70. package/dist/components/react.cjs +1 -1
  71. package/dist/components/react.js +1 -1
  72. package/dist/components/reveal.cjs +1 -1
  73. package/dist/components/reveal.js +2 -2
  74. package/dist/components/solid.cjs +63 -0
  75. package/dist/components/solid.cjs.map +1 -0
  76. package/dist/components/solid.d.cts +1718 -0
  77. package/dist/components/solid.d.ts +1718 -0
  78. package/dist/components/solid.js +59 -0
  79. package/dist/components/solid.js.map +1 -0
  80. package/dist/components/svelte.cjs +60 -0
  81. package/dist/components/svelte.cjs.map +1 -0
  82. package/dist/components/svelte.d.cts +1686 -0
  83. package/dist/components/svelte.d.ts +1686 -0
  84. package/dist/components/svelte.js +56 -0
  85. package/dist/components/svelte.js.map +1 -0
  86. package/dist/components/svg.cjs +1 -1
  87. package/dist/components/svg.js +2 -2
  88. package/dist/components/text.cjs +1 -1
  89. package/dist/components/text.js +2 -2
  90. package/dist/components/timeline.cjs +1 -1
  91. package/dist/components/timeline.js +2 -2
  92. package/dist/components/transitions.cjs +5 -1
  93. package/dist/components/transitions.cjs.map +1 -1
  94. package/dist/components/transitions.d.cts +2 -0
  95. package/dist/components/transitions.d.ts +2 -0
  96. package/dist/components/transitions.js +6 -2
  97. package/dist/components/transitions.js.map +1 -1
  98. package/dist/components/ui.cjs +3 -3
  99. package/dist/components/ui.js +5 -5
  100. package/dist/components/vue.cjs +6 -5
  101. package/dist/components/vue.cjs.map +1 -1
  102. package/dist/components/vue.d.cts +25 -0
  103. package/dist/components/vue.d.ts +25 -0
  104. package/dist/components/vue.js +6 -5
  105. package/dist/components/vue.js.map +1 -1
  106. package/dist/components/webgl.cjs +1 -1
  107. package/dist/components/webgl.js +2 -2
  108. package/dist/components.cjs +14 -5
  109. package/dist/components.cjs.map +1 -1
  110. package/dist/components.css +1 -0
  111. package/dist/components.d.cts +65 -2
  112. package/dist/components.d.ts +65 -2
  113. package/dist/components.js +11 -8
  114. package/dist/components.js.map +1 -1
  115. package/dist/components.umd.js +2 -2
  116. package/dist/components.umd.js.map +1 -1
  117. package/dist/index.cjs +7 -0
  118. package/dist/index.cjs.map +1 -1
  119. package/dist/index.d.cts +2 -0
  120. package/dist/index.d.ts +2 -0
  121. package/dist/index.js +7 -0
  122. package/dist/index.js.map +1 -1
  123. package/dist/index.umd.js +2 -2
  124. package/dist/index.umd.js.map +1 -1
  125. package/docs/components.md +24 -0
  126. package/docs/frameworks-ssr.md +36 -0
  127. package/docs/hybrid-apps.md +130 -0
  128. package/docs/upgrading-4.md +65 -0
  129. package/package.json +43 -2
@@ -0,0 +1,194 @@
1
+ 'use strict';
2
+
3
+ var base = require('../chunks/base-Dm6ee5ug.cjs');
4
+
5
+ const anim = (el, frames, o) => {
6
+ if (typeof el.animate !== 'function')
7
+ return null;
8
+ const k = base.motionScale();
9
+ return el.animate(frames, { ...o, duration: (o.duration ?? 400) * k, delay: (o.delay ?? 0) * k });
10
+ };
11
+ const on = (el, type, fn) => {
12
+ el.addEventListener(type, fn);
13
+ return () => el.removeEventListener(type, fn);
14
+ };
15
+ const io = (el, cb) => {
16
+ if (typeof IntersectionObserver === 'undefined')
17
+ return void cb();
18
+ const o = new IntersectionObserver((es) => es.some((e) => e.isIntersecting) && (o.disconnect(), cb()), { threshold: 0.15 });
19
+ o.observe(el);
20
+ return () => o.disconnect();
21
+ };
22
+ /** Count `el`'s number up from 0 when it enters the view (keeps prefix / suffix / decimals). */
23
+ function countUp(el, duration = 1200) {
24
+ const text = el.textContent || '';
25
+ const m = /(-?[\d,]*\.?\d+)/.exec(text);
26
+ if (!m || base.prefersReducedMotion())
27
+ return () => { };
28
+ const target = Number(m[1].replace(/,/g, ''));
29
+ const dec = (m[1].split('.')[1] || '').length;
30
+ const fmt = (v) => text.replace(m[1], v.toLocaleString('en-US', { minimumFractionDigits: dec, maximumFractionDigits: dec }));
31
+ el.setAttribute('aria-label', text.trim());
32
+ el.textContent = fmt(0);
33
+ let stop = false;
34
+ const off = io(el, () => {
35
+ const t0 = base.now();
36
+ const d = duration * base.motionScale() || 1;
37
+ const step = () => {
38
+ if (stop)
39
+ return;
40
+ const p = base.clamp((base.now() - t0) / d, 0, 1);
41
+ el.textContent = fmt(target * (1 - Math.pow(1 - p, 3)));
42
+ if (p < 1)
43
+ base.raf(step);
44
+ };
45
+ base.raf(step);
46
+ });
47
+ return () => {
48
+ stop = true;
49
+ off();
50
+ el.textContent = text;
51
+ };
52
+ }
53
+ /**
54
+ * Fly a copy of `from` (e.g. a product image) into `to` (the cart icon) along
55
+ * an arc, then bump the target. Resolves when it lands. Instant under
56
+ * reduced motion (only the bump's state change, no flight).
57
+ */
58
+ async function flyToCart(from, to, o = {}) {
59
+ if (base.prefersReducedMotion() || typeof document === 'undefined')
60
+ return;
61
+ const a = from.getBoundingClientRect();
62
+ const b = to.getBoundingClientRect();
63
+ const ghost = from.cloneNode(true);
64
+ ghost.setAttribute('aria-hidden', 'true');
65
+ Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none' });
66
+ document.body.appendChild(ghost);
67
+ const dx = b.left + b.width / 2 - (a.left + a.width / 2);
68
+ const dy = b.top + b.height / 2 - (a.top + a.height / 2);
69
+ const f = anim(ghost, [
70
+ { transform: 'translate(0, 0) scale(1)', opacity: 1 },
71
+ { transform: `translate(${dx * 0.5}px, ${dy * 0.5 - 80}px) scale(0.6)`, opacity: 0.9, offset: 0.5 },
72
+ { transform: `translate(${dx}px, ${dy}px) scale(0.15)`, opacity: 0.4 },
73
+ ], { duration: o.duration ?? 700, easing: 'cubic-bezier(0.5, 0, 0.5, 1)' });
74
+ await f?.finished.catch(() => undefined);
75
+ ghost.remove();
76
+ anim(to, [{ transform: 'scale(1)' }, { transform: 'scale(1.3)' }, { transform: 'scale(1)' }], { duration: 380, easing: base.EASE_SPRING });
77
+ }
78
+ const PRIMITIVES = {
79
+ reveal: (el, c) => {
80
+ if (c.reduced)
81
+ return;
82
+ el.style.opacity = '0';
83
+ const off = io(el, () => {
84
+ el.style.opacity = '';
85
+ anim(el, [{ opacity: 0, transform: 'translateY(24px)' }, { opacity: 1, transform: 'none' }], { duration: 600, delay: Math.min(c.index, 8) * 70, easing: base.EASE_OUT, fill: 'backwards' });
86
+ });
87
+ return () => (off(), (el.style.opacity = ''));
88
+ },
89
+ lift: (el, c) => {
90
+ if (c.reduced)
91
+ return;
92
+ const a = on(el, 'pointerenter', () => anim(el, [{ transform: 'none' }, { transform: 'translateY(-6px) scale(1.02)' }], { duration: 220, easing: base.EASE_OUT, fill: 'forwards' }));
93
+ const b = on(el, 'pointerleave', () => anim(el, [{ transform: 'translateY(-6px) scale(1.02)' }, { transform: 'none' }], { duration: 260, easing: base.EASE_OUT, fill: 'forwards' }));
94
+ return () => (a(), b());
95
+ },
96
+ press: (el, c) => (c.reduced ? undefined : on(el, 'pointerdown', () => anim(el, [{ transform: 'scale(1)' }, { transform: 'scale(0.94)' }, { transform: 'scale(1)' }], { duration: 260, easing: base.EASE_SPRING }))),
97
+ 'count-up': (el) => countUp(el),
98
+ pulse: (el, c) => {
99
+ if (c.reduced)
100
+ return;
101
+ const a = anim(el, [{ boxShadow: '0 0 0 0 rgba(124, 92, 255, 0.55)' }, { boxShadow: '0 0 0 14px rgba(124, 92, 255, 0)' }], { duration: 1600, iterations: Infinity });
102
+ return () => a?.cancel();
103
+ },
104
+ float: (el, c) => {
105
+ if (c.reduced)
106
+ return;
107
+ const a = anim(el, [{ transform: 'translateY(0)' }, { transform: 'translateY(-8px)' }, { transform: 'translateY(0)' }], { duration: 3000, delay: c.index * 300, iterations: Infinity, easing: 'ease-in-out' });
108
+ return () => a?.cancel();
109
+ },
110
+ shake: (el, c) => (c.reduced ? undefined : on(el, 'click', () => anim(el, [0, -8, 8, -6, 6, -3, 0].map((x) => ({ transform: `translateX(${x}px)` })), { duration: 420 }))),
111
+ bump: (el, c) => (c.reduced ? undefined : on(el, 'usa:bump', () => anim(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)' }, { transform: 'scale(1)' }], { duration: 360, easing: base.EASE_SPRING }))),
112
+ 'fly-to-cart': (el, c) => on(el, 'click', () => {
113
+ const cart = c.root.querySelector('[data-role="cart"]') || document.querySelector('[data-role="cart"]');
114
+ const item = el.closest('[data-role="product"]')?.querySelector('img, [data-role="thumb"]') || el;
115
+ if (cart)
116
+ void flyToCart(item, cart).then(() => cart.dispatchEvent(new CustomEvent('usa:added', { bubbles: true })));
117
+ }),
118
+ };
119
+ /** The five effect packs: `data-role` → primitives. */
120
+ const PACKS = {
121
+ ecommerce: { product: ['reveal', 'lift'], 'add-to-cart': ['press', 'fly-to-cart'], cart: ['bump'], price: ['count-up'], badge: ['pulse'] },
122
+ portfolio: { project: ['reveal', 'lift'], heading: ['reveal'], stat: ['count-up'], contact: ['press', 'pulse'] },
123
+ dashboard: { card: ['reveal'], stat: ['count-up'], alert: ['pulse'], action: ['press'] },
124
+ game: { button: ['press'], score: ['count-up', 'bump'], item: ['float'], hit: ['shake'], reward: ['pulse'] },
125
+ landing: { hero: ['reveal'], feature: ['reveal', 'lift'], cta: ['press', 'pulse'], logo: ['float'], stat: ['count-up'] },
126
+ };
127
+ /**
128
+ * Apply an effect pack to `root`: every descendant with a `data-role` the
129
+ * pack knows gets its effects (staggered by index). Returns an undo function.
130
+ * Reduced motion: only non-motion behaviour (e.g. the cart event) remains.
131
+ *
132
+ * @example
133
+ * applyPack('ecommerce', document.querySelector('main'));
134
+ * // <article data-role="product">… <button data-role="add-to-cart"> … <a data-role="cart">
135
+ */
136
+ function applyPack(name, root = document) {
137
+ const pack = PACKS[name];
138
+ if (!pack || typeof document === 'undefined')
139
+ return () => { };
140
+ const r = root.documentElement ? root.body : root;
141
+ const reduced = base.prefersReducedMotion();
142
+ const cleanups = [];
143
+ for (const [role, fx] of Object.entries(pack)) {
144
+ r.querySelectorAll(`[data-role="${role}"]`).forEach((el, index) => {
145
+ for (const f of fx) {
146
+ const c = PRIMITIVES[f]?.(el, { root: r, index, reduced });
147
+ if (c)
148
+ cleanups.push(c);
149
+ }
150
+ });
151
+ }
152
+ return () => cleanups.splice(0).forEach((c) => c());
153
+ }
154
+ /** Primitive names a pack uses (for docs / tooling). */
155
+ const PACK_PRIMITIVES = Object.keys(PRIMITIVES);
156
+
157
+ function definePack(tag = 'usa-pack') {
158
+ return base.defineElement(tag, (Base) => class UsaPack extends Base {
159
+ static get observedAttributes() {
160
+ return ['name'];
161
+ }
162
+ get roles() {
163
+ return Object.keys(PACKS[this.str('name', 'landing')] || {});
164
+ }
165
+ mount() {
166
+ var _a;
167
+ (_a = this.style).display || (_a.display = 'block');
168
+ this.onCleanup(applyPack(this.str('name', 'landing'), this));
169
+ }
170
+ });
171
+ }
172
+
173
+ /**
174
+ * use-scroll-animate/components/packs — effect packs (v3.9).
175
+ * Ready-made motion for e-commerce, portfolio, dashboard, game UI and
176
+ * landing pages: mark elements with `data-role` and apply a pack with
177
+ * `<usa-pack name="…">` or `applyPack(name, root)`. Includes `flyToCart()`
178
+ * and `countUp()`.
179
+ */
180
+ /** Register every component of this category under its default tag. */
181
+ function definePacksComponents() {
182
+ definePack();
183
+ }
184
+
185
+ exports.configureComponents = base.configureComponents;
186
+ exports.prefersReducedMotion = base.prefersReducedMotion;
187
+ exports.PACKS = PACKS;
188
+ exports.PACK_PRIMITIVES = PACK_PRIMITIVES;
189
+ exports.applyPack = applyPack;
190
+ exports.countUp = countUp;
191
+ exports.definePack = definePack;
192
+ exports.definePacksComponents = definePacksComponents;
193
+ exports.flyToCart = flyToCart;
194
+ //# sourceMappingURL=packs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packs.cjs","sources":["../../src/components/packs/core.ts","../../src/components/packs/pack-el.ts","../../src/components/packs/index.ts"],"sourcesContent":["import { prefersReducedMotion, motionScale, EASE_OUT, EASE_SPRING, raf, now, clamp } from '../base';\n\ntype Cleanup = () => void;\n/** A pack primitive: wire one element, return a cleanup. */\ntype Effect = (el: HTMLElement, ctx: PackContext) => Cleanup | void;\n\nexport interface PackContext {\n root: HTMLElement;\n /** Index of the element among those with the same role (for staggering). */\n index: number;\n reduced: boolean;\n}\n\nconst anim = (el: Element, frames: Keyframe[], o: KeyframeAnimationOptions): Animation | null => {\n if (typeof (el as HTMLElement).animate !== 'function') return null;\n const k = motionScale();\n return (el as HTMLElement).animate(frames, { ...o, duration: ((o.duration as number) ?? 400) * k, delay: (o.delay ?? 0) * k });\n};\nconst on = (el: EventTarget, type: string, fn: (e: any) => void): Cleanup => {\n el.addEventListener(type, fn);\n return () => el.removeEventListener(type, fn);\n};\nconst io = (el: Element, cb: () => void): Cleanup => {\n if (typeof IntersectionObserver === 'undefined') return void cb() as unknown as Cleanup;\n const o = new IntersectionObserver((es) => es.some((e) => e.isIntersecting) && (o.disconnect(), cb()), { threshold: 0.15 });\n o.observe(el);\n return () => o.disconnect();\n};\n\n/** Count `el`'s number up from 0 when it enters the view (keeps prefix / suffix / decimals). */\nexport function countUp(el: HTMLElement, duration = 1200): Cleanup {\n const text = el.textContent || '';\n const m = /(-?[\\d,]*\\.?\\d+)/.exec(text);\n if (!m || prefersReducedMotion()) return () => {};\n const target = Number(m[1].replace(/,/g, ''));\n const dec = (m[1].split('.')[1] || '').length;\n const fmt = (v: number) => text.replace(m[1], v.toLocaleString('en-US', { minimumFractionDigits: dec, maximumFractionDigits: dec }));\n el.setAttribute('aria-label', text.trim());\n el.textContent = fmt(0);\n let stop = false;\n const off = io(el, () => {\n const t0 = now();\n const d = duration * motionScale() || 1;\n const step = () => {\n if (stop) return;\n const p = clamp((now() - t0) / d, 0, 1);\n el.textContent = fmt(target * (1 - Math.pow(1 - p, 3)));\n if (p < 1) raf(step);\n };\n raf(step);\n });\n return () => {\n stop = true;\n off();\n el.textContent = text;\n };\n}\n\n/**\n * Fly a copy of `from` (e.g. a product image) into `to` (the cart icon) along\n * an arc, then bump the target. Resolves when it lands. Instant under\n * reduced motion (only the bump's state change, no flight).\n */\nexport async function flyToCart(from: Element, to: Element, o: { duration?: number } = {}): Promise<void> {\n if (prefersReducedMotion() || typeof document === 'undefined') return;\n const a = from.getBoundingClientRect();\n const b = to.getBoundingClientRect();\n const ghost = from.cloneNode(true) as HTMLElement;\n ghost.setAttribute('aria-hidden', 'true');\n Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none' });\n document.body.appendChild(ghost);\n const dx = b.left + b.width / 2 - (a.left + a.width / 2);\n const dy = b.top + b.height / 2 - (a.top + a.height / 2);\n const f = anim(ghost, [\n { transform: 'translate(0, 0) scale(1)', opacity: 1 },\n { transform: `translate(${dx * 0.5}px, ${dy * 0.5 - 80}px) scale(0.6)`, opacity: 0.9, offset: 0.5 },\n { transform: `translate(${dx}px, ${dy}px) scale(0.15)`, opacity: 0.4 },\n ], { duration: o.duration ?? 700, easing: 'cubic-bezier(0.5, 0, 0.5, 1)' });\n await f?.finished.catch(() => undefined);\n ghost.remove();\n anim(to, [{ transform: 'scale(1)' }, { transform: 'scale(1.3)' }, { transform: 'scale(1)' }], { duration: 380, easing: EASE_SPRING });\n}\n\nconst PRIMITIVES: Record<string, Effect> = {\n reveal: (el, c) => {\n if (c.reduced) return;\n el.style.opacity = '0';\n const off = io(el, () => {\n el.style.opacity = '';\n anim(el, [{ opacity: 0, transform: 'translateY(24px)' }, { opacity: 1, transform: 'none' }], { duration: 600, delay: Math.min(c.index, 8) * 70, easing: EASE_OUT, fill: 'backwards' });\n });\n return () => (off(), (el.style.opacity = ''));\n },\n lift: (el, c) => {\n if (c.reduced) return;\n const a = on(el, 'pointerenter', () => anim(el, [{ transform: 'none' }, { transform: 'translateY(-6px) scale(1.02)' }], { duration: 220, easing: EASE_OUT, fill: 'forwards' }));\n const b = on(el, 'pointerleave', () => anim(el, [{ transform: 'translateY(-6px) scale(1.02)' }, { transform: 'none' }], { duration: 260, easing: EASE_OUT, fill: 'forwards' }));\n return () => (a(), b());\n },\n press: (el, c) => (c.reduced ? undefined : on(el, 'pointerdown', () => anim(el, [{ transform: 'scale(1)' }, { transform: 'scale(0.94)' }, { transform: 'scale(1)' }], { duration: 260, easing: EASE_SPRING }))),\n 'count-up': (el) => countUp(el),\n pulse: (el, c) => {\n if (c.reduced) return;\n const a = anim(el, [{ boxShadow: '0 0 0 0 rgba(124, 92, 255, 0.55)' }, { boxShadow: '0 0 0 14px rgba(124, 92, 255, 0)' }], { duration: 1600, iterations: Infinity });\n return () => a?.cancel();\n },\n float: (el, c) => {\n if (c.reduced) return;\n const a = anim(el, [{ transform: 'translateY(0)' }, { transform: 'translateY(-8px)' }, { transform: 'translateY(0)' }], { duration: 3000, delay: c.index * 300, iterations: Infinity, easing: 'ease-in-out' });\n return () => a?.cancel();\n },\n shake: (el, c) => (c.reduced ? undefined : on(el, 'click', () => anim(el, [0, -8, 8, -6, 6, -3, 0].map((x) => ({ transform: `translateX(${x}px)` })), { duration: 420 }))),\n bump: (el, c) => (c.reduced ? undefined : on(el, 'usa:bump', () => anim(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)' }, { transform: 'scale(1)' }], { duration: 360, easing: EASE_SPRING }))),\n 'fly-to-cart': (el, c) =>\n on(el, 'click', () => {\n const cart = c.root.querySelector('[data-role=\"cart\"]') || document.querySelector('[data-role=\"cart\"]');\n const item = el.closest('[data-role=\"product\"]')?.querySelector('img, [data-role=\"thumb\"]') || el;\n if (cart) void flyToCart(item, cart).then(() => cart.dispatchEvent(new CustomEvent('usa:added', { bubbles: true })));\n }),\n};\n\n/** The five effect packs: `data-role` → primitives. */\nexport const PACKS: Record<string, Record<string, string[]>> = {\n ecommerce: { product: ['reveal', 'lift'], 'add-to-cart': ['press', 'fly-to-cart'], cart: ['bump'], price: ['count-up'], badge: ['pulse'] },\n portfolio: { project: ['reveal', 'lift'], heading: ['reveal'], stat: ['count-up'], contact: ['press', 'pulse'] },\n dashboard: { card: ['reveal'], stat: ['count-up'], alert: ['pulse'], action: ['press'] },\n game: { button: ['press'], score: ['count-up', 'bump'], item: ['float'], hit: ['shake'], reward: ['pulse'] },\n landing: { hero: ['reveal'], feature: ['reveal', 'lift'], cta: ['press', 'pulse'], logo: ['float'], stat: ['count-up'] },\n};\n\nexport type PackName = keyof typeof PACKS;\n\n/**\n * Apply an effect pack to `root`: every descendant with a `data-role` the\n * pack knows gets its effects (staggered by index). Returns an undo function.\n * Reduced motion: only non-motion behaviour (e.g. the cart event) remains.\n *\n * @example\n * applyPack('ecommerce', document.querySelector('main'));\n * // <article data-role=\"product\">… <button data-role=\"add-to-cart\"> … <a data-role=\"cart\">\n */\nexport function applyPack(name: PackName | string, root: HTMLElement | Document = document): Cleanup {\n const pack = PACKS[name];\n if (!pack || typeof document === 'undefined') return () => {};\n const r = (root as Document).documentElement ? (root as Document).body : (root as HTMLElement);\n const reduced = prefersReducedMotion();\n const cleanups: Cleanup[] = [];\n for (const [role, fx] of Object.entries(pack)) {\n r.querySelectorAll<HTMLElement>(`[data-role=\"${role}\"]`).forEach((el, index) => {\n for (const f of fx) {\n const c = PRIMITIVES[f]?.(el, { root: r, index, reduced });\n if (c) cleanups.push(c);\n }\n });\n }\n return () => cleanups.splice(0).forEach((c) => c());\n}\n\n/** Primitive names a pack uses (for docs / tooling). */\nexport const PACK_PRIMITIVES = Object.keys(PRIMITIVES);\n","import { defineElement, type UsaElement } from '../base';\nimport { applyPack, PACKS } from './core';\n\n/**\n * `<usa-pack name=\"ecommerce\">` — applies an effect pack (`ecommerce` ·\n * `portfolio` · `dashboard` · `game` · `landing`) to its subtree:\n * descendants opt in with `data-role` (see `PACKS`). Re-applies when\n * `name` changes; undone on disconnect.\n */\nexport interface UsaPackElement extends UsaElement {\n readonly roles: string[];\n}\n\nexport function definePack(tag = 'usa-pack'): CustomElementConstructor | undefined {\n return defineElement(tag, (Base) =>\n class UsaPack extends Base {\n static get observedAttributes(): string[] {\n return ['name'];\n }\n get roles(): string[] {\n return Object.keys(PACKS[this.str('name', 'landing')] || {});\n }\n mount(): void {\n this.style.display ||= 'block';\n this.onCleanup(applyPack(this.str('name', 'landing'), this));\n }\n }\n );\n}\n","/**\n * use-scroll-animate/components/packs — effect packs (v3.9).\n * Ready-made motion for e-commerce, portfolio, dashboard, game UI and\n * landing pages: mark elements with `data-role` and apply a pack with\n * `<usa-pack name=\"…\">` or `applyPack(name, root)`. Includes `flyToCart()`\n * and `countUp()`.\n */\nimport { definePack, type UsaPackElement } from './pack-el';\n\nexport { definePack };\nexport { applyPack, flyToCart, countUp, PACKS, PACK_PRIMITIVES } from './core';\nexport type { PackName, PackContext } from './core';\nexport type { UsaPackElement };\nexport { configureComponents, prefersReducedMotion } from '../base';\nexport type { ComponentsConfig, UsaElement } from '../base';\n\n/** Register every component of this category under its default tag. */\nexport function definePacksComponents(): void {\n definePack();\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'usa-pack': UsaPackElement;\n }\n}\n"],"names":["motionScale","prefersReducedMotion","now","clamp","raf","EASE_SPRING","EASE_OUT","defineElement"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /* use-scroll-animate/components/packs */
2
+ .usa-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
3
+
@@ -0,0 +1,107 @@
1
+ /**
2
+ * use-scroll-animate/components — shared base for the `<usa-*>` custom elements.
3
+ *
4
+ * Everything here is lazy: nothing touches `window`, `document`,
5
+ * `HTMLElement` or `matchMedia` at import time, so the components can be
6
+ * imported during SSR (Next, Nuxt, Astro…) and in Electron/Tauri preload
7
+ * scripts. Classes are created the first time a `define*()` function runs.
8
+ */
9
+ interface ComponentsConfig {
10
+ /**
11
+ * Inject each component's CSS when it is defined (default `true`). Uses a
12
+ * constructable stylesheet (`document.adoptedStyleSheets`, which a strict
13
+ * `style-src` CSP does not block) and falls back to a `<style>` tag. Set
14
+ * to `false` when you load `use-scroll-animate/components.css` yourself.
15
+ */
16
+ injectStyles?: boolean;
17
+ /**
18
+ * `'user'` (default) follows `prefers-reduced-motion`; `'reduce'` always
19
+ * uses the reduced variants (e.g. a kiosk / battery-saver mode);
20
+ * `'no-preference'` ignores the OS setting (only for demos — respect your users).
21
+ */
22
+ reducedMotion?: 'user' | 'reduce' | 'no-preference';
23
+ /**
24
+ * Global motion intensity (v2.7): `'off'` (same as reduced motion),
25
+ * `'low'` (shorter, calmer), `'normal'` (default) or `'high'`. Scales every
26
+ * component animation's duration and sets `--usa-motion` (0 / 0.6 / 1 /
27
+ * 1.25) on `<html>` for your own CSS. See `setMotionIntensity()`.
28
+ */
29
+ motionIntensity?: MotionIntensity;
30
+ }
31
+ type MotionIntensity = 'off' | 'low' | 'normal' | 'high';
32
+ /** Change global component settings (call before `define*()` for `injectStyles`). */
33
+ declare function configureComponents(options: ComponentsConfig): void;
34
+ /** `true` when animations should be reduced (OS setting or `configureComponents`). */
35
+ declare function prefersReducedMotion(): boolean;
36
+ /**
37
+ * Members shared by every `<usa-*>` element. Attribute helpers, a cleanup
38
+ * bag that is emptied on disconnect, and motion helpers that degrade to the
39
+ * final state without WAAPI or under reduced motion.
40
+ */
41
+ interface UsaElement extends HTMLElement {
42
+ /** `true` while reduced motion applies to this element. */
43
+ readonly reduced: boolean;
44
+ }
45
+
46
+ /**
47
+ * `<usa-pack name="ecommerce">` — applies an effect pack (`ecommerce` ·
48
+ * `portfolio` · `dashboard` · `game` · `landing`) to its subtree:
49
+ * descendants opt in with `data-role` (see `PACKS`). Re-applies when
50
+ * `name` changes; undone on disconnect.
51
+ */
52
+ interface UsaPackElement extends UsaElement {
53
+ readonly roles: string[];
54
+ }
55
+ declare function definePack(tag?: string): CustomElementConstructor | undefined;
56
+
57
+ type Cleanup = () => void;
58
+ interface PackContext {
59
+ root: HTMLElement;
60
+ /** Index of the element among those with the same role (for staggering). */
61
+ index: number;
62
+ reduced: boolean;
63
+ }
64
+ /** Count `el`'s number up from 0 when it enters the view (keeps prefix / suffix / decimals). */
65
+ declare function countUp(el: HTMLElement, duration?: number): Cleanup;
66
+ /**
67
+ * Fly a copy of `from` (e.g. a product image) into `to` (the cart icon) along
68
+ * an arc, then bump the target. Resolves when it lands. Instant under
69
+ * reduced motion (only the bump's state change, no flight).
70
+ */
71
+ declare function flyToCart(from: Element, to: Element, o?: {
72
+ duration?: number;
73
+ }): Promise<void>;
74
+ /** The five effect packs: `data-role` → primitives. */
75
+ declare const PACKS: Record<string, Record<string, string[]>>;
76
+ type PackName = keyof typeof PACKS;
77
+ /**
78
+ * Apply an effect pack to `root`: every descendant with a `data-role` the
79
+ * pack knows gets its effects (staggered by index). Returns an undo function.
80
+ * Reduced motion: only non-motion behaviour (e.g. the cart event) remains.
81
+ *
82
+ * @example
83
+ * applyPack('ecommerce', document.querySelector('main'));
84
+ * // <article data-role="product">… <button data-role="add-to-cart"> … <a data-role="cart">
85
+ */
86
+ declare function applyPack(name: PackName | string, root?: HTMLElement | Document): Cleanup;
87
+ /** Primitive names a pack uses (for docs / tooling). */
88
+ declare const PACK_PRIMITIVES: string[];
89
+
90
+ /**
91
+ * use-scroll-animate/components/packs — effect packs (v3.9).
92
+ * Ready-made motion for e-commerce, portfolio, dashboard, game UI and
93
+ * landing pages: mark elements with `data-role` and apply a pack with
94
+ * `<usa-pack name="…">` or `applyPack(name, root)`. Includes `flyToCart()`
95
+ * and `countUp()`.
96
+ */
97
+
98
+ /** Register every component of this category under its default tag. */
99
+ declare function definePacksComponents(): void;
100
+ declare global {
101
+ interface HTMLElementTagNameMap {
102
+ 'usa-pack': UsaPackElement;
103
+ }
104
+ }
105
+
106
+ export { PACKS, PACK_PRIMITIVES, applyPack, configureComponents, countUp, definePack, definePacksComponents, flyToCart, prefersReducedMotion };
107
+ export type { ComponentsConfig, PackContext, PackName, UsaElement, UsaPackElement };
@@ -0,0 +1,107 @@
1
+ /**
2
+ * use-scroll-animate/components — shared base for the `<usa-*>` custom elements.
3
+ *
4
+ * Everything here is lazy: nothing touches `window`, `document`,
5
+ * `HTMLElement` or `matchMedia` at import time, so the components can be
6
+ * imported during SSR (Next, Nuxt, Astro…) and in Electron/Tauri preload
7
+ * scripts. Classes are created the first time a `define*()` function runs.
8
+ */
9
+ interface ComponentsConfig {
10
+ /**
11
+ * Inject each component's CSS when it is defined (default `true`). Uses a
12
+ * constructable stylesheet (`document.adoptedStyleSheets`, which a strict
13
+ * `style-src` CSP does not block) and falls back to a `<style>` tag. Set
14
+ * to `false` when you load `use-scroll-animate/components.css` yourself.
15
+ */
16
+ injectStyles?: boolean;
17
+ /**
18
+ * `'user'` (default) follows `prefers-reduced-motion`; `'reduce'` always
19
+ * uses the reduced variants (e.g. a kiosk / battery-saver mode);
20
+ * `'no-preference'` ignores the OS setting (only for demos — respect your users).
21
+ */
22
+ reducedMotion?: 'user' | 'reduce' | 'no-preference';
23
+ /**
24
+ * Global motion intensity (v2.7): `'off'` (same as reduced motion),
25
+ * `'low'` (shorter, calmer), `'normal'` (default) or `'high'`. Scales every
26
+ * component animation's duration and sets `--usa-motion` (0 / 0.6 / 1 /
27
+ * 1.25) on `<html>` for your own CSS. See `setMotionIntensity()`.
28
+ */
29
+ motionIntensity?: MotionIntensity;
30
+ }
31
+ type MotionIntensity = 'off' | 'low' | 'normal' | 'high';
32
+ /** Change global component settings (call before `define*()` for `injectStyles`). */
33
+ declare function configureComponents(options: ComponentsConfig): void;
34
+ /** `true` when animations should be reduced (OS setting or `configureComponents`). */
35
+ declare function prefersReducedMotion(): boolean;
36
+ /**
37
+ * Members shared by every `<usa-*>` element. Attribute helpers, a cleanup
38
+ * bag that is emptied on disconnect, and motion helpers that degrade to the
39
+ * final state without WAAPI or under reduced motion.
40
+ */
41
+ interface UsaElement extends HTMLElement {
42
+ /** `true` while reduced motion applies to this element. */
43
+ readonly reduced: boolean;
44
+ }
45
+
46
+ /**
47
+ * `<usa-pack name="ecommerce">` — applies an effect pack (`ecommerce` ·
48
+ * `portfolio` · `dashboard` · `game` · `landing`) to its subtree:
49
+ * descendants opt in with `data-role` (see `PACKS`). Re-applies when
50
+ * `name` changes; undone on disconnect.
51
+ */
52
+ interface UsaPackElement extends UsaElement {
53
+ readonly roles: string[];
54
+ }
55
+ declare function definePack(tag?: string): CustomElementConstructor | undefined;
56
+
57
+ type Cleanup = () => void;
58
+ interface PackContext {
59
+ root: HTMLElement;
60
+ /** Index of the element among those with the same role (for staggering). */
61
+ index: number;
62
+ reduced: boolean;
63
+ }
64
+ /** Count `el`'s number up from 0 when it enters the view (keeps prefix / suffix / decimals). */
65
+ declare function countUp(el: HTMLElement, duration?: number): Cleanup;
66
+ /**
67
+ * Fly a copy of `from` (e.g. a product image) into `to` (the cart icon) along
68
+ * an arc, then bump the target. Resolves when it lands. Instant under
69
+ * reduced motion (only the bump's state change, no flight).
70
+ */
71
+ declare function flyToCart(from: Element, to: Element, o?: {
72
+ duration?: number;
73
+ }): Promise<void>;
74
+ /** The five effect packs: `data-role` → primitives. */
75
+ declare const PACKS: Record<string, Record<string, string[]>>;
76
+ type PackName = keyof typeof PACKS;
77
+ /**
78
+ * Apply an effect pack to `root`: every descendant with a `data-role` the
79
+ * pack knows gets its effects (staggered by index). Returns an undo function.
80
+ * Reduced motion: only non-motion behaviour (e.g. the cart event) remains.
81
+ *
82
+ * @example
83
+ * applyPack('ecommerce', document.querySelector('main'));
84
+ * // <article data-role="product">… <button data-role="add-to-cart"> … <a data-role="cart">
85
+ */
86
+ declare function applyPack(name: PackName | string, root?: HTMLElement | Document): Cleanup;
87
+ /** Primitive names a pack uses (for docs / tooling). */
88
+ declare const PACK_PRIMITIVES: string[];
89
+
90
+ /**
91
+ * use-scroll-animate/components/packs — effect packs (v3.9).
92
+ * Ready-made motion for e-commerce, portfolio, dashboard, game UI and
93
+ * landing pages: mark elements with `data-role` and apply a pack with
94
+ * `<usa-pack name="…">` or `applyPack(name, root)`. Includes `flyToCart()`
95
+ * and `countUp()`.
96
+ */
97
+
98
+ /** Register every component of this category under its default tag. */
99
+ declare function definePacksComponents(): void;
100
+ declare global {
101
+ interface HTMLElementTagNameMap {
102
+ 'usa-pack': UsaPackElement;
103
+ }
104
+ }
105
+
106
+ export { PACKS, PACK_PRIMITIVES, applyPack, configureComponents, countUp, definePack, definePacksComponents, flyToCart, prefersReducedMotion };
107
+ export type { ComponentsConfig, PackContext, PackName, UsaElement, UsaPackElement };
@@ -0,0 +1,185 @@
1
+ import { p as prefersReducedMotion, n as now, m as motionScale, r as raf, h as EASE_OUT, b as clamp, E as EASE_SPRING, i as defineElement } from '../chunks/base-BRIPyPtX.js';
2
+ export { a as configureComponents } from '../chunks/base-BRIPyPtX.js';
3
+
4
+ const anim = (el, frames, o) => {
5
+ if (typeof el.animate !== 'function')
6
+ return null;
7
+ const k = motionScale();
8
+ return el.animate(frames, { ...o, duration: (o.duration ?? 400) * k, delay: (o.delay ?? 0) * k });
9
+ };
10
+ const on = (el, type, fn) => {
11
+ el.addEventListener(type, fn);
12
+ return () => el.removeEventListener(type, fn);
13
+ };
14
+ const io = (el, cb) => {
15
+ if (typeof IntersectionObserver === 'undefined')
16
+ return void cb();
17
+ const o = new IntersectionObserver((es) => es.some((e) => e.isIntersecting) && (o.disconnect(), cb()), { threshold: 0.15 });
18
+ o.observe(el);
19
+ return () => o.disconnect();
20
+ };
21
+ /** Count `el`'s number up from 0 when it enters the view (keeps prefix / suffix / decimals). */
22
+ function countUp(el, duration = 1200) {
23
+ const text = el.textContent || '';
24
+ const m = /(-?[\d,]*\.?\d+)/.exec(text);
25
+ if (!m || prefersReducedMotion())
26
+ return () => { };
27
+ const target = Number(m[1].replace(/,/g, ''));
28
+ const dec = (m[1].split('.')[1] || '').length;
29
+ const fmt = (v) => text.replace(m[1], v.toLocaleString('en-US', { minimumFractionDigits: dec, maximumFractionDigits: dec }));
30
+ el.setAttribute('aria-label', text.trim());
31
+ el.textContent = fmt(0);
32
+ let stop = false;
33
+ const off = io(el, () => {
34
+ const t0 = now();
35
+ const d = duration * motionScale() || 1;
36
+ const step = () => {
37
+ if (stop)
38
+ return;
39
+ const p = clamp((now() - t0) / d, 0, 1);
40
+ el.textContent = fmt(target * (1 - Math.pow(1 - p, 3)));
41
+ if (p < 1)
42
+ raf(step);
43
+ };
44
+ raf(step);
45
+ });
46
+ return () => {
47
+ stop = true;
48
+ off();
49
+ el.textContent = text;
50
+ };
51
+ }
52
+ /**
53
+ * Fly a copy of `from` (e.g. a product image) into `to` (the cart icon) along
54
+ * an arc, then bump the target. Resolves when it lands. Instant under
55
+ * reduced motion (only the bump's state change, no flight).
56
+ */
57
+ async function flyToCart(from, to, o = {}) {
58
+ if (prefersReducedMotion() || typeof document === 'undefined')
59
+ return;
60
+ const a = from.getBoundingClientRect();
61
+ const b = to.getBoundingClientRect();
62
+ const ghost = from.cloneNode(true);
63
+ ghost.setAttribute('aria-hidden', 'true');
64
+ Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none' });
65
+ document.body.appendChild(ghost);
66
+ const dx = b.left + b.width / 2 - (a.left + a.width / 2);
67
+ const dy = b.top + b.height / 2 - (a.top + a.height / 2);
68
+ const f = anim(ghost, [
69
+ { transform: 'translate(0, 0) scale(1)', opacity: 1 },
70
+ { transform: `translate(${dx * 0.5}px, ${dy * 0.5 - 80}px) scale(0.6)`, opacity: 0.9, offset: 0.5 },
71
+ { transform: `translate(${dx}px, ${dy}px) scale(0.15)`, opacity: 0.4 },
72
+ ], { duration: o.duration ?? 700, easing: 'cubic-bezier(0.5, 0, 0.5, 1)' });
73
+ await f?.finished.catch(() => undefined);
74
+ ghost.remove();
75
+ anim(to, [{ transform: 'scale(1)' }, { transform: 'scale(1.3)' }, { transform: 'scale(1)' }], { duration: 380, easing: EASE_SPRING });
76
+ }
77
+ const PRIMITIVES = {
78
+ reveal: (el, c) => {
79
+ if (c.reduced)
80
+ return;
81
+ el.style.opacity = '0';
82
+ const off = io(el, () => {
83
+ el.style.opacity = '';
84
+ anim(el, [{ opacity: 0, transform: 'translateY(24px)' }, { opacity: 1, transform: 'none' }], { duration: 600, delay: Math.min(c.index, 8) * 70, easing: EASE_OUT, fill: 'backwards' });
85
+ });
86
+ return () => (off(), (el.style.opacity = ''));
87
+ },
88
+ lift: (el, c) => {
89
+ if (c.reduced)
90
+ return;
91
+ const a = on(el, 'pointerenter', () => anim(el, [{ transform: 'none' }, { transform: 'translateY(-6px) scale(1.02)' }], { duration: 220, easing: EASE_OUT, fill: 'forwards' }));
92
+ const b = on(el, 'pointerleave', () => anim(el, [{ transform: 'translateY(-6px) scale(1.02)' }, { transform: 'none' }], { duration: 260, easing: EASE_OUT, fill: 'forwards' }));
93
+ return () => (a(), b());
94
+ },
95
+ press: (el, c) => (c.reduced ? undefined : on(el, 'pointerdown', () => anim(el, [{ transform: 'scale(1)' }, { transform: 'scale(0.94)' }, { transform: 'scale(1)' }], { duration: 260, easing: EASE_SPRING }))),
96
+ 'count-up': (el) => countUp(el),
97
+ pulse: (el, c) => {
98
+ if (c.reduced)
99
+ return;
100
+ const a = anim(el, [{ boxShadow: '0 0 0 0 rgba(124, 92, 255, 0.55)' }, { boxShadow: '0 0 0 14px rgba(124, 92, 255, 0)' }], { duration: 1600, iterations: Infinity });
101
+ return () => a?.cancel();
102
+ },
103
+ float: (el, c) => {
104
+ if (c.reduced)
105
+ return;
106
+ const a = anim(el, [{ transform: 'translateY(0)' }, { transform: 'translateY(-8px)' }, { transform: 'translateY(0)' }], { duration: 3000, delay: c.index * 300, iterations: Infinity, easing: 'ease-in-out' });
107
+ return () => a?.cancel();
108
+ },
109
+ shake: (el, c) => (c.reduced ? undefined : on(el, 'click', () => anim(el, [0, -8, 8, -6, 6, -3, 0].map((x) => ({ transform: `translateX(${x}px)` })), { duration: 420 }))),
110
+ bump: (el, c) => (c.reduced ? undefined : on(el, 'usa:bump', () => anim(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)' }, { transform: 'scale(1)' }], { duration: 360, easing: EASE_SPRING }))),
111
+ 'fly-to-cart': (el, c) => on(el, 'click', () => {
112
+ const cart = c.root.querySelector('[data-role="cart"]') || document.querySelector('[data-role="cart"]');
113
+ const item = el.closest('[data-role="product"]')?.querySelector('img, [data-role="thumb"]') || el;
114
+ if (cart)
115
+ void flyToCart(item, cart).then(() => cart.dispatchEvent(new CustomEvent('usa:added', { bubbles: true })));
116
+ }),
117
+ };
118
+ /** The five effect packs: `data-role` → primitives. */
119
+ const PACKS = {
120
+ ecommerce: { product: ['reveal', 'lift'], 'add-to-cart': ['press', 'fly-to-cart'], cart: ['bump'], price: ['count-up'], badge: ['pulse'] },
121
+ portfolio: { project: ['reveal', 'lift'], heading: ['reveal'], stat: ['count-up'], contact: ['press', 'pulse'] },
122
+ dashboard: { card: ['reveal'], stat: ['count-up'], alert: ['pulse'], action: ['press'] },
123
+ game: { button: ['press'], score: ['count-up', 'bump'], item: ['float'], hit: ['shake'], reward: ['pulse'] },
124
+ landing: { hero: ['reveal'], feature: ['reveal', 'lift'], cta: ['press', 'pulse'], logo: ['float'], stat: ['count-up'] },
125
+ };
126
+ /**
127
+ * Apply an effect pack to `root`: every descendant with a `data-role` the
128
+ * pack knows gets its effects (staggered by index). Returns an undo function.
129
+ * Reduced motion: only non-motion behaviour (e.g. the cart event) remains.
130
+ *
131
+ * @example
132
+ * applyPack('ecommerce', document.querySelector('main'));
133
+ * // <article data-role="product">… <button data-role="add-to-cart"> … <a data-role="cart">
134
+ */
135
+ function applyPack(name, root = document) {
136
+ const pack = PACKS[name];
137
+ if (!pack || typeof document === 'undefined')
138
+ return () => { };
139
+ const r = root.documentElement ? root.body : root;
140
+ const reduced = prefersReducedMotion();
141
+ const cleanups = [];
142
+ for (const [role, fx] of Object.entries(pack)) {
143
+ r.querySelectorAll(`[data-role="${role}"]`).forEach((el, index) => {
144
+ for (const f of fx) {
145
+ const c = PRIMITIVES[f]?.(el, { root: r, index, reduced });
146
+ if (c)
147
+ cleanups.push(c);
148
+ }
149
+ });
150
+ }
151
+ return () => cleanups.splice(0).forEach((c) => c());
152
+ }
153
+ /** Primitive names a pack uses (for docs / tooling). */
154
+ const PACK_PRIMITIVES = Object.keys(PRIMITIVES);
155
+
156
+ function definePack(tag = 'usa-pack') {
157
+ return defineElement(tag, (Base) => class UsaPack extends Base {
158
+ static get observedAttributes() {
159
+ return ['name'];
160
+ }
161
+ get roles() {
162
+ return Object.keys(PACKS[this.str('name', 'landing')] || {});
163
+ }
164
+ mount() {
165
+ var _a;
166
+ (_a = this.style).display || (_a.display = 'block');
167
+ this.onCleanup(applyPack(this.str('name', 'landing'), this));
168
+ }
169
+ });
170
+ }
171
+
172
+ /**
173
+ * use-scroll-animate/components/packs — effect packs (v3.9).
174
+ * Ready-made motion for e-commerce, portfolio, dashboard, game UI and
175
+ * landing pages: mark elements with `data-role` and apply a pack with
176
+ * `<usa-pack name="…">` or `applyPack(name, root)`. Includes `flyToCart()`
177
+ * and `countUp()`.
178
+ */
179
+ /** Register every component of this category under its default tag. */
180
+ function definePacksComponents() {
181
+ definePack();
182
+ }
183
+
184
+ export { PACKS, PACK_PRIMITIVES, applyPack, countUp, definePack, definePacksComponents, flyToCart, prefersReducedMotion };
185
+ //# sourceMappingURL=packs.js.map