use-scroll-animate 4.2.0 → 4.4.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 (143) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/chunks/{base-BPG5zvex.js → base-BtJDNCB6.js} +45 -5
  3. package/dist/chunks/base-BtJDNCB6.js.map +1 -0
  4. package/dist/chunks/{base-CXx7jZ-o.cjs → base-DE2yzxE7.cjs} +47 -4
  5. package/dist/chunks/base-DE2yzxE7.cjs.map +1 -0
  6. package/dist/chunks/{core-BRIIoKeS.cjs → core-BC9S2osy.cjs} +2 -2
  7. package/dist/chunks/{core-BRIIoKeS.cjs.map → core-BC9S2osy.cjs.map} +1 -1
  8. package/dist/chunks/{core-IaorbTdu.cjs → core-DPYjLqA0.cjs} +2 -2
  9. package/dist/chunks/{core-IaorbTdu.cjs.map → core-DPYjLqA0.cjs.map} +1 -1
  10. package/dist/chunks/{core-LkGRmgES.js → core-DS1nrx5L.js} +2 -2
  11. package/dist/chunks/{core-LkGRmgES.js.map → core-DS1nrx5L.js.map} +1 -1
  12. package/dist/chunks/{core-eXX8rB_b.js → core-DX6pdOoY.js} +2 -2
  13. package/dist/chunks/{core-eXX8rB_b.js.map → core-DX6pdOoY.js.map} +1 -1
  14. package/dist/chunks/{spring-BziPsW3r.js → spring-CxRz49Wk.js} +2 -2
  15. package/dist/chunks/{spring-BziPsW3r.js.map → spring-CxRz49Wk.js.map} +1 -1
  16. package/dist/chunks/{spring-2OTnYCzm.cjs → spring-hsmgd7ml.cjs} +2 -2
  17. package/dist/chunks/{spring-2OTnYCzm.cjs.map → spring-hsmgd7ml.cjs.map} +1 -1
  18. package/dist/chunks/{variants-BNIrn4ch.cjs → variants-CM2zaG8v.cjs} +2 -2
  19. package/dist/chunks/{variants-BNIrn4ch.cjs.map → variants-CM2zaG8v.cjs.map} +1 -1
  20. package/dist/chunks/{variants-BVYMcxRv.js → variants-dD6SbUMR.js} +2 -2
  21. package/dist/chunks/{variants-BVYMcxRv.js.map → variants-dD6SbUMR.js.map} +1 -1
  22. package/dist/components/a11y.cjs +239 -0
  23. package/dist/components/a11y.cjs.map +1 -0
  24. package/dist/components/a11y.d.cts +120 -0
  25. package/dist/components/a11y.d.ts +120 -0
  26. package/dist/components/a11y.js +224 -0
  27. package/dist/components/a11y.js.map +1 -0
  28. package/dist/components/angular.cjs +7 -6
  29. package/dist/components/angular.cjs.map +1 -1
  30. package/dist/components/angular.d.cts +80 -76
  31. package/dist/components/angular.d.ts +80 -76
  32. package/dist/components/angular.js +7 -6
  33. package/dist/components/angular.js.map +1 -1
  34. package/dist/components/background.cjs +2 -2
  35. package/dist/components/background.d.cts +10 -0
  36. package/dist/components/background.d.ts +10 -0
  37. package/dist/components/background.js +3 -3
  38. package/dist/components/cards.cjs +2 -2
  39. package/dist/components/cards.d.cts +10 -0
  40. package/dist/components/cards.d.ts +10 -0
  41. package/dist/components/cards.js +3 -3
  42. package/dist/components/click.cjs +2 -2
  43. package/dist/components/click.d.cts +10 -0
  44. package/dist/components/click.d.ts +10 -0
  45. package/dist/components/click.js +3 -3
  46. package/dist/components/depth.cjs +3 -3
  47. package/dist/components/depth.d.cts +10 -0
  48. package/dist/components/depth.d.ts +10 -0
  49. package/dist/components/depth.js +4 -4
  50. package/dist/components/feedback.cjs +1 -1
  51. package/dist/components/feedback.d.cts +10 -0
  52. package/dist/components/feedback.d.ts +10 -0
  53. package/dist/components/feedback.js +2 -2
  54. package/dist/components/gesture.cjs +3 -3
  55. package/dist/components/gesture.d.cts +10 -0
  56. package/dist/components/gesture.d.ts +10 -0
  57. package/dist/components/gesture.js +5 -5
  58. package/dist/components/interaction.cjs +1 -1
  59. package/dist/components/interaction.d.cts +10 -0
  60. package/dist/components/interaction.d.ts +10 -0
  61. package/dist/components/interaction.js +2 -2
  62. package/dist/components/layout.cjs +1 -1
  63. package/dist/components/layout.d.cts +10 -0
  64. package/dist/components/layout.d.ts +10 -0
  65. package/dist/components/layout.js +2 -2
  66. package/dist/components/packs.cjs +1 -1
  67. package/dist/components/packs.d.cts +10 -0
  68. package/dist/components/packs.d.ts +10 -0
  69. package/dist/components/packs.js +2 -2
  70. package/dist/components/page.cjs +6 -3
  71. package/dist/components/page.cjs.map +1 -1
  72. package/dist/components/page.d.cts +10 -0
  73. package/dist/components/page.d.ts +10 -0
  74. package/dist/components/page.js +7 -4
  75. package/dist/components/page.js.map +1 -1
  76. package/dist/components/physics.cjs +2 -2
  77. package/dist/components/physics.d.cts +10 -0
  78. package/dist/components/physics.d.ts +10 -0
  79. package/dist/components/physics.js +4 -4
  80. package/dist/components/reveal.cjs +1 -1
  81. package/dist/components/reveal.d.cts +10 -0
  82. package/dist/components/reveal.d.ts +10 -0
  83. package/dist/components/reveal.js +2 -2
  84. package/dist/components/solid.cjs +7 -6
  85. package/dist/components/solid.cjs.map +1 -1
  86. package/dist/components/solid.d.cts +80 -76
  87. package/dist/components/solid.d.ts +80 -76
  88. package/dist/components/solid.js +7 -6
  89. package/dist/components/solid.js.map +1 -1
  90. package/dist/components/svelte.cjs +7 -6
  91. package/dist/components/svelte.cjs.map +1 -1
  92. package/dist/components/svelte.d.cts +80 -76
  93. package/dist/components/svelte.d.ts +80 -76
  94. package/dist/components/svelte.js +7 -6
  95. package/dist/components/svelte.js.map +1 -1
  96. package/dist/components/svg.cjs +1 -1
  97. package/dist/components/svg.d.cts +10 -0
  98. package/dist/components/svg.d.ts +10 -0
  99. package/dist/components/svg.js +2 -2
  100. package/dist/components/text.cjs +284 -11
  101. package/dist/components/text.cjs.map +1 -1
  102. package/dist/components/text.d.cts +166 -3
  103. package/dist/components/text.d.ts +166 -3
  104. package/dist/components/text.js +280 -13
  105. package/dist/components/text.js.map +1 -1
  106. package/dist/components/timeline.cjs +2 -2
  107. package/dist/components/timeline.d.cts +10 -0
  108. package/dist/components/timeline.d.ts +10 -0
  109. package/dist/components/timeline.js +4 -4
  110. package/dist/components/transitions.cjs +1 -1
  111. package/dist/components/transitions.d.cts +10 -0
  112. package/dist/components/transitions.d.ts +10 -0
  113. package/dist/components/transitions.js +2 -2
  114. package/dist/components/ui.cjs +3 -3
  115. package/dist/components/ui.d.cts +10 -0
  116. package/dist/components/ui.d.ts +10 -0
  117. package/dist/components/ui.js +5 -5
  118. package/dist/components/vue.cjs +7 -6
  119. package/dist/components/vue.cjs.map +1 -1
  120. package/dist/components/vue.d.cts +80 -76
  121. package/dist/components/vue.d.ts +80 -76
  122. package/dist/components/vue.js +7 -6
  123. package/dist/components/vue.js.map +1 -1
  124. package/dist/components/webgl.cjs +1 -1
  125. package/dist/components/webgl.d.cts +10 -0
  126. package/dist/components/webgl.d.ts +10 -0
  127. package/dist/components/webgl.js +2 -2
  128. package/dist/components.cjs +27 -5
  129. package/dist/components.cjs.map +1 -1
  130. package/dist/components.d.cts +289 -108
  131. package/dist/components.d.ts +289 -108
  132. package/dist/components.js +9 -8
  133. package/dist/components.js.map +1 -1
  134. package/dist/components.umd.js +2 -2
  135. package/dist/components.umd.js.map +1 -1
  136. package/dist/index.cjs +2 -2
  137. package/dist/index.js +2 -2
  138. package/dist/index.umd.js.map +1 -1
  139. package/docs/ROADMAP.md +2 -2
  140. package/docs/accessibility.md +28 -0
  141. package/package.json +11 -1
  142. package/dist/chunks/base-BPG5zvex.js.map +0 -1
  143. package/dist/chunks/base-CXx7jZ-o.cjs.map +0 -1
@@ -0,0 +1,224 @@
1
+ import { e as getMotionSensitivity, a as MOTION_SENSITIVITY_LEVELS, d as configureComponents, j as adoptStyles } from '../chunks/base-BtJDNCB6.js';
2
+ export { b as adaptKeyframes } from '../chunks/base-BtJDNCB6.js';
3
+ import { C as COMPONENT_CATEGORIES } from '../chunks/index-tags-43Xtd01A.js';
4
+
5
+ /**
6
+ * use-scroll-animate/components/a11y — accessibility toolkit (4.4).
7
+ *
8
+ * - Motion-sensitivity levels: `setMotionSensitivity('full' | 'gentle' | 'minimal' | 'static')`.
9
+ * - Static alternatives: what every component shows when motion is off, and
10
+ * `staticAlternative(root)` to freeze any subtree at its final state.
11
+ * - `aria-live` conventions: one shared polite and one assertive region,
12
+ * `announce(message, { politeness })`.
13
+ * - `auditMotionA11y(root)`: the rules the automated regression tests run
14
+ * over every `<usa-*>` element — usable in your own tests too.
15
+ *
16
+ * ```ts
17
+ * import { setMotionSensitivity, announce, auditMotionA11y } from 'use-scroll-animate/components/a11y';
18
+ * setMotionSensitivity('gentle', true); // no spins / zooms / parallax, remembered
19
+ * announce('3 items added to cart'); // polite live region
20
+ * expect(auditMotionA11y(document.body).errors).toEqual([]);
21
+ * ```
22
+ */
23
+ const KEY = 'usa:sensitivity';
24
+ /** What each level allows, for docs and settings UIs. */
25
+ const MOTION_SENSITIVITY = {
26
+ full: { en: 'All motion', zh: '全部动效', allows: ['fade', 'translate', 'scale', 'rotate', 'parallax', 'loop', 'flash'] },
27
+ gentle: { en: 'Gentle — no spins, zooms or parallax', zh: '温和 —— 无旋转、缩放与视差', allows: ['fade', 'translate', 'loop'] },
28
+ minimal: { en: 'Minimal — fades only', zh: '最少 —— 仅淡入淡出', allows: ['fade'] },
29
+ static: { en: 'Static — no animation', zh: '静态 —— 无动画', allows: [] },
30
+ };
31
+ /** CSS applied at the `static` / `minimal` / `gentle` levels (also stops your own CSS animations under `static`). */
32
+ const SENSITIVITY_CSS = 'html[data-usa-sensitivity="static"] *,html[data-usa-sensitivity="static"] *::before,html[data-usa-sensitivity="static"] *::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}' +
33
+ 'html[data-usa-sensitivity="minimal"] *,html[data-usa-sensitivity="minimal"] *::before,html[data-usa-sensitivity="minimal"] *::after{animation-duration:1ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}' +
34
+ 'html[data-usa-sensitivity="gentle"]{--usa-parallax:0;--usa-tilt:0}';
35
+ /**
36
+ * Set the motion-sensitivity level for every `<usa-*>` component and the page:
37
+ * sets `data-usa-sensitivity` on `<html>`, adapts component keyframes, and
38
+ * with `persist` remembers the choice (`restoreMotionSensitivity()`).
39
+ * Dispatches `usa:sensitivity` on `document`.
40
+ */
41
+ function setMotionSensitivity(level, persist = false) {
42
+ if (!MOTION_SENSITIVITY_LEVELS.includes(level))
43
+ return;
44
+ configureComponents({ motionSensitivity: level });
45
+ adoptStyles('a11y-sensitivity', SENSITIVITY_CSS);
46
+ if (persist) {
47
+ try {
48
+ localStorage.setItem(KEY, level);
49
+ }
50
+ catch {
51
+ /* private mode */
52
+ }
53
+ }
54
+ if (level === 'static' && typeof document !== 'undefined')
55
+ staticAlternative(document.documentElement);
56
+ if (typeof document !== 'undefined')
57
+ document.dispatchEvent(new CustomEvent('usa:sensitivity', { detail: { level } }));
58
+ }
59
+ /** Re-apply a persisted level (call early on page load). Returns the active level. */
60
+ function restoreMotionSensitivity() {
61
+ try {
62
+ const v = localStorage.getItem(KEY);
63
+ if (v && MOTION_SENSITIVITY_LEVELS.includes(v))
64
+ setMotionSensitivity(v);
65
+ }
66
+ catch {
67
+ /* ignore */
68
+ }
69
+ return getMotionSensitivity();
70
+ }
71
+ /** `true` when the current level allows a kind of motion (`'rotate'`, `'parallax'`, `'loop'`…). */
72
+ function motionAllowed(kind, level = getMotionSensitivity()) {
73
+ return MOTION_SENSITIVITY[level].allows.includes(kind);
74
+ }
75
+ /** The static alternative of each category: what its elements show without motion. */
76
+ const STATIC_ALTERNATIVES = {
77
+ reveal: 'Content visible in place; progress bars show the current value.',
78
+ text: 'Full final text (screen readers always get a plain copy).',
79
+ interaction: 'Normal hover / focus styles; no tilt, magnet or ripple.',
80
+ feedback: 'Spinners become a static busy indicator; progress shows its value; toasts appear without sliding.',
81
+ background: 'A still frame of the background (gradient / pattern); particles and marquees stop.',
82
+ transitions: 'Dialogs, accordions and views switch instantly.',
83
+ physics: 'Values jump to their target; drag still works, without inertia.',
84
+ cards: 'Cards are shown flat and fully readable; stacks become lists.',
85
+ click: 'Clicks work and states are announced; no bursts, confetti or deformation.',
86
+ ui: 'Tabs, drawers, sheets and popovers open instantly with focus management intact.',
87
+ page: 'Page transitions are instant; cursors and ambient layers are hidden.',
88
+ timeline: 'Every step is shown at its final state.',
89
+ gesture: 'Buttons / keys provide the same actions as swipes and pinches.',
90
+ svg: 'Drawings and icons are shown complete.',
91
+ webgl: 'A static poster image or CSS gradient instead of the shader.',
92
+ depth: 'Flat, front-facing layout.',
93
+ layout: 'Items reflow instantly.',
94
+ packs: 'Roles are styled but not animated.',
95
+ };
96
+ /**
97
+ * Freeze a subtree at its static alternative: finishes running animations
98
+ * (`finish()`, so content lands on its final state), marks the root with
99
+ * `data-usa-static` and returns an undo that removes the mark.
100
+ */
101
+ function staticAlternative(root) {
102
+ const getAll = root.getAnimations;
103
+ if (typeof getAll === 'function') {
104
+ for (const a of getAll.call(root, { subtree: true })) {
105
+ try {
106
+ const it = a.effect?.getComputedTiming().iterations;
107
+ if (it === Infinity)
108
+ a.cancel();
109
+ else
110
+ a.finish();
111
+ }
112
+ catch {
113
+ /* finished already */
114
+ }
115
+ }
116
+ }
117
+ root.setAttribute('data-usa-static', '');
118
+ return () => root.removeAttribute('data-usa-static');
119
+ }
120
+ /** The ids of the shared live regions. */
121
+ const LIVE_REGION_IDS = { polite: 'usa-live-polite', assertive: 'usa-live-assertive' };
122
+ /** The shared live region (created once, visually hidden, `role="status"` / `role="alert"`). */
123
+ function liveRegion(politeness = 'polite') {
124
+ if (typeof document === 'undefined' || !document.body)
125
+ return null;
126
+ const id = LIVE_REGION_IDS[politeness];
127
+ let el = document.getElementById(id);
128
+ if (!el) {
129
+ el = document.createElement('div');
130
+ el.id = id;
131
+ el.className = 'usa-sr';
132
+ el.setAttribute('role', politeness === 'assertive' ? 'alert' : 'status');
133
+ el.setAttribute('aria-live', politeness);
134
+ el.setAttribute('aria-atomic', 'true');
135
+ document.body.appendChild(el);
136
+ }
137
+ return el;
138
+ }
139
+ let lastMsg = '';
140
+ let lastAt = 0;
141
+ /**
142
+ * Announce a message through the shared live region. Conventions: `polite`
143
+ * for results of the user's own actions (added, saved, copied), `assertive`
144
+ * only for errors that block them. Identical messages within `dedupe` ms
145
+ * (default 500) are dropped; the region is cleared first so repeats are read.
146
+ */
147
+ function announce(message, options = {}) {
148
+ const { politeness = 'polite', dedupe = 500 } = options;
149
+ const t = Date.now();
150
+ if (!message || (message === lastMsg && t - lastAt < dedupe))
151
+ return false;
152
+ lastMsg = message;
153
+ lastAt = t;
154
+ const el = liveRegion(politeness);
155
+ if (!el)
156
+ return false;
157
+ el.textContent = '';
158
+ el.textContent = message;
159
+ return true;
160
+ }
161
+ const FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
162
+ const NAMED_ROLES = ['button', 'switch', 'checkbox', 'slider', 'tab', 'progressbar', 'radiogroup', 'dialog'];
163
+ function accessibleName(el) {
164
+ const label = el.getAttribute('aria-label');
165
+ if (label)
166
+ return label;
167
+ const by = el.getAttribute('aria-labelledby');
168
+ if (by)
169
+ return by.split(/\s+/).map((id) => el.ownerDocument.getElementById(id)?.textContent || '').join(' ').trim();
170
+ return (el.textContent || el.getAttribute('title') || '').trim();
171
+ }
172
+ /**
173
+ * Check a subtree against the library's motion-a11y rules:
174
+ * - `aria-hidden-focusable` (error): focusable content inside `aria-hidden`.
175
+ * - `role-name` (error): a widget role without an accessible name.
176
+ * - `range-value` (error): a slider / determinate progressbar without `aria-valuenow`.
177
+ * - `img-alt` (error): an `<img>` without `alt`.
178
+ * - `assertive-live` (warning): `aria-live="assertive"` outside `role="alert"`.
179
+ * - `infinite-no-control` (warning, WCAG 2.2.2): an endless animation on a
180
+ * page with no way to pause motion (`<usa-motion-switch>` or `[data-usa-pause]`).
181
+ */
182
+ function auditMotionA11y(root) {
183
+ const issues = [];
184
+ const add = (rule, level, element, message) => issues.push({ rule, level, element, message });
185
+ const scope = root;
186
+ scope.querySelectorAll('[aria-hidden="true"]').forEach((h) => {
187
+ const f = (h.matches(FOCUSABLE) ? [h] : Array.from(h.querySelectorAll(FOCUSABLE))).filter((x) => !x.closest('[inert]'));
188
+ f.forEach((x) => add('aria-hidden-focusable', 'error', x, `focusable <${x.tagName.toLowerCase()}> inside aria-hidden`));
189
+ });
190
+ scope.querySelectorAll('[role]').forEach((el) => {
191
+ const role = el.getAttribute('role');
192
+ if (NAMED_ROLES.includes(role) && !accessibleName(el))
193
+ add('role-name', 'error', el, `role="${role}" has no accessible name`);
194
+ if (role === 'slider' && !el.hasAttribute('aria-valuenow'))
195
+ add('range-value', 'error', el, 'slider without aria-valuenow');
196
+ });
197
+ scope.querySelectorAll('img:not([alt])').forEach((el) => add('img-alt', 'error', el, '<img> without alt'));
198
+ scope.querySelectorAll('[aria-live="assertive"]').forEach((el) => {
199
+ if (el.getAttribute('role') !== 'alert')
200
+ add('assertive-live', 'warning', el, 'assertive live region outside role="alert"');
201
+ });
202
+ const doc = root.ownerDocument || root;
203
+ const anims = typeof root.getAnimations === 'function' ? root.getAnimations({ subtree: true }) : [];
204
+ const control = doc && (doc.querySelector('usa-motion-switch, [data-usa-pause]') || doc.documentElement.hasAttribute('data-usa-sensitivity'));
205
+ if (!control)
206
+ anims.forEach((a) => {
207
+ try {
208
+ if (a.effect?.getComputedTiming().iterations === Infinity) {
209
+ const t = a.effect.target;
210
+ if (t)
211
+ add('infinite-no-control', 'warning', t, 'endless animation and no motion control on the page');
212
+ }
213
+ }
214
+ catch {
215
+ /* ignore */
216
+ }
217
+ });
218
+ return { errors: issues.filter((i) => i.level === 'error'), warnings: issues.filter((i) => i.level === 'warning') };
219
+ }
220
+ /** Every `<usa-*>` tag, for sweeping audits. */
221
+ const ALL_TAGS = Object.values(COMPONENT_CATEGORIES).flat();
222
+
223
+ export { ALL_TAGS, LIVE_REGION_IDS, MOTION_SENSITIVITY, MOTION_SENSITIVITY_LEVELS, SENSITIVITY_CSS, STATIC_ALTERNATIVES, announce, auditMotionA11y, getMotionSensitivity, liveRegion, motionAllowed, restoreMotionSensitivity, setMotionSensitivity, staticAlternative };
224
+ //# sourceMappingURL=a11y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y.js","sources":["../../src/components/a11y/index.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/a11y — accessibility toolkit (4.4).\n *\n * - Motion-sensitivity levels: `setMotionSensitivity('full' | 'gentle' | 'minimal' | 'static')`.\n * - Static alternatives: what every component shows when motion is off, and\n * `staticAlternative(root)` to freeze any subtree at its final state.\n * - `aria-live` conventions: one shared polite and one assertive region,\n * `announce(message, { politeness })`.\n * - `auditMotionA11y(root)`: the rules the automated regression tests run\n * over every `<usa-*>` element — usable in your own tests too.\n *\n * ```ts\n * import { setMotionSensitivity, announce, auditMotionA11y } from 'use-scroll-animate/components/a11y';\n * setMotionSensitivity('gentle', true); // no spins / zooms / parallax, remembered\n * announce('3 items added to cart'); // polite live region\n * expect(auditMotionA11y(document.body).errors).toEqual([]);\n * ```\n */\nimport {\n configureComponents,\n getMotionSensitivity,\n adaptKeyframes,\n adoptStyles,\n MOTION_SENSITIVITY_LEVELS,\n type MotionSensitivity,\n} from '../base';\nimport { COMPONENT_CATEGORIES, type ComponentCategory } from '../index-tags';\n\nexport { getMotionSensitivity, adaptKeyframes, MOTION_SENSITIVITY_LEVELS };\nexport type { MotionSensitivity };\n\nconst KEY = 'usa:sensitivity';\n\n/** What each level allows, for docs and settings UIs. */\nexport const MOTION_SENSITIVITY: Record<MotionSensitivity, { en: string; zh: string; allows: string[] }> = {\n full: { en: 'All motion', zh: '全部动效', allows: ['fade', 'translate', 'scale', 'rotate', 'parallax', 'loop', 'flash'] },\n gentle: { en: 'Gentle — no spins, zooms or parallax', zh: '温和 —— 无旋转、缩放与视差', allows: ['fade', 'translate', 'loop'] },\n minimal: { en: 'Minimal — fades only', zh: '最少 —— 仅淡入淡出', allows: ['fade'] },\n static: { en: 'Static — no animation', zh: '静态 —— 无动画', allows: [] },\n};\n\n/** CSS applied at the `static` / `minimal` / `gentle` levels (also stops your own CSS animations under `static`). */\nexport const SENSITIVITY_CSS =\n 'html[data-usa-sensitivity=\"static\"] *,html[data-usa-sensitivity=\"static\"] *::before,html[data-usa-sensitivity=\"static\"] *::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}' +\n 'html[data-usa-sensitivity=\"minimal\"] *,html[data-usa-sensitivity=\"minimal\"] *::before,html[data-usa-sensitivity=\"minimal\"] *::after{animation-duration:1ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}' +\n 'html[data-usa-sensitivity=\"gentle\"]{--usa-parallax:0;--usa-tilt:0}';\n\n/**\n * Set the motion-sensitivity level for every `<usa-*>` component and the page:\n * sets `data-usa-sensitivity` on `<html>`, adapts component keyframes, and\n * with `persist` remembers the choice (`restoreMotionSensitivity()`).\n * Dispatches `usa:sensitivity` on `document`.\n */\nexport function setMotionSensitivity(level: MotionSensitivity, persist = false): void {\n if (!MOTION_SENSITIVITY_LEVELS.includes(level)) return;\n configureComponents({ motionSensitivity: level });\n adoptStyles('a11y-sensitivity', SENSITIVITY_CSS);\n if (persist) {\n try {\n localStorage.setItem(KEY, level);\n } catch {\n /* private mode */\n }\n }\n if (level === 'static' && typeof document !== 'undefined') staticAlternative(document.documentElement);\n if (typeof document !== 'undefined') document.dispatchEvent(new CustomEvent('usa:sensitivity', { detail: { level } }));\n}\n\n/** Re-apply a persisted level (call early on page load). Returns the active level. */\nexport function restoreMotionSensitivity(): MotionSensitivity {\n try {\n const v = localStorage.getItem(KEY) as MotionSensitivity | null;\n if (v && MOTION_SENSITIVITY_LEVELS.includes(v)) setMotionSensitivity(v);\n } catch {\n /* ignore */\n }\n return getMotionSensitivity();\n}\n\n/** `true` when the current level allows a kind of motion (`'rotate'`, `'parallax'`, `'loop'`…). */\nexport function motionAllowed(kind: string, level: MotionSensitivity = getMotionSensitivity()): boolean {\n return MOTION_SENSITIVITY[level].allows.includes(kind);\n}\n\n/** The static alternative of each category: what its elements show without motion. */\nexport const STATIC_ALTERNATIVES: Record<ComponentCategory, string> = {\n reveal: 'Content visible in place; progress bars show the current value.',\n text: 'Full final text (screen readers always get a plain copy).',\n interaction: 'Normal hover / focus styles; no tilt, magnet or ripple.',\n feedback: 'Spinners become a static busy indicator; progress shows its value; toasts appear without sliding.',\n background: 'A still frame of the background (gradient / pattern); particles and marquees stop.',\n transitions: 'Dialogs, accordions and views switch instantly.',\n physics: 'Values jump to their target; drag still works, without inertia.',\n cards: 'Cards are shown flat and fully readable; stacks become lists.',\n click: 'Clicks work and states are announced; no bursts, confetti or deformation.',\n ui: 'Tabs, drawers, sheets and popovers open instantly with focus management intact.',\n page: 'Page transitions are instant; cursors and ambient layers are hidden.',\n timeline: 'Every step is shown at its final state.',\n gesture: 'Buttons / keys provide the same actions as swipes and pinches.',\n svg: 'Drawings and icons are shown complete.',\n webgl: 'A static poster image or CSS gradient instead of the shader.',\n depth: 'Flat, front-facing layout.',\n layout: 'Items reflow instantly.',\n packs: 'Roles are styled but not animated.',\n};\n\n/**\n * Freeze a subtree at its static alternative: finishes running animations\n * (`finish()`, so content lands on its final state), marks the root with\n * `data-usa-static` and returns an undo that removes the mark.\n */\nexport function staticAlternative(root: Element): () => void {\n const getAll = (root as any).getAnimations as undefined | ((o: { subtree: boolean }) => Animation[]);\n if (typeof getAll === 'function') {\n for (const a of getAll.call(root, { subtree: true })) {\n try {\n const it = a.effect?.getComputedTiming().iterations;\n if (it === Infinity) a.cancel();\n else a.finish();\n } catch {\n /* finished already */\n }\n }\n }\n root.setAttribute('data-usa-static', '');\n return () => root.removeAttribute('data-usa-static');\n}\n\n// --- aria-live conventions ---------------------------------------------------\n\nexport type Politeness = 'polite' | 'assertive';\n/** The ids of the shared live regions. */\nexport const LIVE_REGION_IDS: Record<Politeness, string> = { polite: 'usa-live-polite', assertive: 'usa-live-assertive' };\n\n/** The shared live region (created once, visually hidden, `role=\"status\"` / `role=\"alert\"`). */\nexport function liveRegion(politeness: Politeness = 'polite'): HTMLElement | null {\n if (typeof document === 'undefined' || !document.body) return null;\n const id = LIVE_REGION_IDS[politeness];\n let el = document.getElementById(id);\n if (!el) {\n el = document.createElement('div');\n el.id = id;\n el.className = 'usa-sr';\n el.setAttribute('role', politeness === 'assertive' ? 'alert' : 'status');\n el.setAttribute('aria-live', politeness);\n el.setAttribute('aria-atomic', 'true');\n document.body.appendChild(el);\n }\n return el;\n}\n\nlet lastMsg = '';\nlet lastAt = 0;\n/**\n * Announce a message through the shared live region. Conventions: `polite`\n * for results of the user's own actions (added, saved, copied), `assertive`\n * only for errors that block them. Identical messages within `dedupe` ms\n * (default 500) are dropped; the region is cleared first so repeats are read.\n */\nexport function announce(message: string, options: { politeness?: Politeness; dedupe?: number } = {}): boolean {\n const { politeness = 'polite', dedupe = 500 } = options;\n const t = Date.now();\n if (!message || (message === lastMsg && t - lastAt < dedupe)) return false;\n lastMsg = message;\n lastAt = t;\n const el = liveRegion(politeness);\n if (!el) return false;\n el.textContent = '';\n el.textContent = message;\n return true;\n}\n\n// --- audit ---------------------------------------------------------------------\n\nexport interface A11yIssue {\n rule: string;\n level: 'error' | 'warning';\n element: Element;\n message: string;\n}\n\nconst FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\nconst NAMED_ROLES = ['button', 'switch', 'checkbox', 'slider', 'tab', 'progressbar', 'radiogroup', 'dialog'];\n\nfunction accessibleName(el: Element): string {\n const label = el.getAttribute('aria-label');\n if (label) return label;\n const by = el.getAttribute('aria-labelledby');\n if (by) return by.split(/\\s+/).map((id) => el.ownerDocument.getElementById(id)?.textContent || '').join(' ').trim();\n return (el.textContent || el.getAttribute('title') || '').trim();\n}\n\n/**\n * Check a subtree against the library's motion-a11y rules:\n * - `aria-hidden-focusable` (error): focusable content inside `aria-hidden`.\n * - `role-name` (error): a widget role without an accessible name.\n * - `range-value` (error): a slider / determinate progressbar without `aria-valuenow`.\n * - `img-alt` (error): an `<img>` without `alt`.\n * - `assertive-live` (warning): `aria-live=\"assertive\"` outside `role=\"alert\"`.\n * - `infinite-no-control` (warning, WCAG 2.2.2): an endless animation on a\n * page with no way to pause motion (`<usa-motion-switch>` or `[data-usa-pause]`).\n */\nexport function auditMotionA11y(root: Element | Document): { errors: A11yIssue[]; warnings: A11yIssue[] } {\n const issues: A11yIssue[] = [];\n const add = (rule: string, level: A11yIssue['level'], element: Element, message: string) => issues.push({ rule, level, element, message });\n const scope = root as ParentNode;\n scope.querySelectorAll('[aria-hidden=\"true\"]').forEach((h) => {\n const f = (h.matches(FOCUSABLE) ? [h] : Array.from(h.querySelectorAll(FOCUSABLE))).filter((x) => !x.closest('[inert]'));\n f.forEach((x) => add('aria-hidden-focusable', 'error', x, `focusable <${x.tagName.toLowerCase()}> inside aria-hidden`));\n });\n scope.querySelectorAll('[role]').forEach((el) => {\n const role = el.getAttribute('role')!;\n if (NAMED_ROLES.includes(role) && !accessibleName(el)) add('role-name', 'error', el, `role=\"${role}\" has no accessible name`);\n if (role === 'slider' && !el.hasAttribute('aria-valuenow'))\n add('range-value', 'error', el, 'slider without aria-valuenow');\n });\n scope.querySelectorAll('img:not([alt])').forEach((el) => add('img-alt', 'error', el, '<img> without alt'));\n scope.querySelectorAll('[aria-live=\"assertive\"]').forEach((el) => {\n if (el.getAttribute('role') !== 'alert') add('assertive-live', 'warning', el, 'assertive live region outside role=\"alert\"');\n });\n const doc = (root as Node).ownerDocument || (root as Document);\n const anims = typeof (root as any).getAnimations === 'function' ? ((root as any).getAnimations({ subtree: true }) as Animation[]) : [];\n const control = doc && (doc.querySelector('usa-motion-switch, [data-usa-pause]') || doc.documentElement.hasAttribute('data-usa-sensitivity'));\n if (!control)\n anims.forEach((a) => {\n try {\n if (a.effect?.getComputedTiming().iterations === Infinity) {\n const t = (a.effect as KeyframeEffect).target;\n if (t) add('infinite-no-control', 'warning', t, 'endless animation and no motion control on the page');\n }\n } catch {\n /* ignore */\n }\n });\n return { errors: issues.filter((i) => i.level === 'error'), warnings: issues.filter((i) => i.level === 'warning') };\n}\n\n/** Every `<usa-*>` tag, for sweeping audits. */\nexport const ALL_TAGS: string[] = (Object.values(COMPONENT_CATEGORIES) as readonly (readonly string[])[]).flat();\n"],"names":[],"mappings":"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"}
@@ -3,29 +3,30 @@
3
3
  var components = require('../components.cjs');
4
4
  var bind = require('../chunks/bind-Ui43-n2d.cjs');
5
5
  require('./reveal.cjs');
6
- require('../chunks/base-CXx7jZ-o.cjs');
6
+ require('../chunks/base-DE2yzxE7.cjs');
7
7
  require('./text.cjs');
8
+ require('../chunks/core-BC9S2osy.cjs');
9
+ require('./tokens.cjs');
8
10
  require('./interaction.cjs');
9
11
  require('./feedback.cjs');
10
12
  require('./background.cjs');
11
- require('../chunks/variants-BNIrn4ch.cjs');
13
+ require('../chunks/variants-CM2zaG8v.cjs');
12
14
  require('./transitions.cjs');
13
15
  require('./physics.cjs');
14
- require('../chunks/spring-2OTnYCzm.cjs');
16
+ require('../chunks/spring-hsmgd7ml.cjs');
15
17
  require('./cards.cjs');
16
18
  require('./click.cjs');
17
19
  require('./ui.cjs');
18
20
  require('./page.cjs');
19
21
  require('./timeline.cjs');
20
- require('../chunks/core-BRIIoKeS.cjs');
21
- require('./tokens.cjs');
22
22
  require('./gesture.cjs');
23
- require('../chunks/core-IaorbTdu.cjs');
23
+ require('../chunks/core-DPYjLqA0.cjs');
24
24
  require('./svg.cjs');
25
25
  require('./webgl.cjs');
26
26
  require('./depth.cjs');
27
27
  require('./layout.cjs');
28
28
  require('./packs.cjs');
29
+ require('./a11y.cjs');
29
30
  require('../chunks/index-tags-BQh_uGqH.cjs');
30
31
 
31
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"angular.cjs","sources":["../../src/components/frameworks/angular.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/angular — Angular integration (v3.8).\n * Angular renders `<usa-*>` tags once the component (or NgModule) allows\n * custom elements with `CUSTOM_ELEMENTS_SCHEMA`; property binding\n * `[checked]=\"on\"` and event binding `(usa:change)=\"…\"` then work as is.\n * This entry is framework-free (no `@angular/*` import):\n *\n * ```ts\n * import { CUSTOM_ELEMENTS_SCHEMA, Component, APP_INITIALIZER } from '@angular/core';\n * import { usaInitializer } from 'use-scroll-animate/components/angular';\n *\n * // app.config.ts\n * providers: [{ provide: APP_INITIALIZER, multi: true, useFactory: usaInitializer(['click', 'ui']) }]\n *\n * @Component({ standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA],\n * template: `<usa-toggle [checked]=\"on\" (usa:change)=\"on = $any($event).detail.checked\"></usa-toggle>` })\n * ```\n * `bindUsa(el, { props, on })` is available for directives that bind imperatively.\n */\nimport { defineComponents, type ComponentCategory } from '../index';\n\nexport { bindUsa, usaEventName } from './bind';\nexport type { UsaBinding } from './bind';\n\n/** `APP_INITIALIZER` factory: registers the elements in the browser (no-op during SSR). */\nexport function usaInitializer(categories?: ComponentCategory[]): () => () => void {\n return () => () => {\n if (typeof window !== 'undefined') defineComponents(categories);\n };\n}\n\n/** Register the elements directly (e.g. in `main.ts` before `bootstrapApplication`). */\nexport function defineUsa(categories?: ComponentCategory[]): void {\n if (typeof window !== 'undefined') defineComponents(categories);\n}\n\n/** Read `event.detail` from a `usa:*` event in a template handler: `(usa:change)=\"on = usaDetail($event).checked\"`. */\nexport const usaDetail = <T = any>(e: Event): T => (e as CustomEvent<T>).detail;\n"],"names":["defineComponents"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;AAkBG;AAMH;AACM,SAAU,cAAc,CAAC,UAAgC,EAAA;AAC7D,IAAA,OAAO,MAAM,MAAK;QAChB,IAAI,OAAO,MAAM,KAAK,WAAW;YAAEA,2BAAgB,CAAC,UAAU,CAAC;AACjE,IAAA,CAAC;AACH;AAEA;AACM,SAAU,SAAS,CAAC,UAAgC,EAAA;IACxD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAEA,2BAAgB,CAAC,UAAU,CAAC;AACjE;AAEA;AACO,MAAM,SAAS,GAAG,CAAU,CAAQ,KAAS,CAAoB,CAAC;;;;;;;;"}
1
+ {"version":3,"file":"angular.cjs","sources":["../../src/components/frameworks/angular.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/angular — Angular integration (v3.8).\n * Angular renders `<usa-*>` tags once the component (or NgModule) allows\n * custom elements with `CUSTOM_ELEMENTS_SCHEMA`; property binding\n * `[checked]=\"on\"` and event binding `(usa:change)=\"…\"` then work as is.\n * This entry is framework-free (no `@angular/*` import):\n *\n * ```ts\n * import { CUSTOM_ELEMENTS_SCHEMA, Component, APP_INITIALIZER } from '@angular/core';\n * import { usaInitializer } from 'use-scroll-animate/components/angular';\n *\n * // app.config.ts\n * providers: [{ provide: APP_INITIALIZER, multi: true, useFactory: usaInitializer(['click', 'ui']) }]\n *\n * @Component({ standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA],\n * template: `<usa-toggle [checked]=\"on\" (usa:change)=\"on = $any($event).detail.checked\"></usa-toggle>` })\n * ```\n * `bindUsa(el, { props, on })` is available for directives that bind imperatively.\n */\nimport { defineComponents, type ComponentCategory } from '../index';\n\nexport { bindUsa, usaEventName } from './bind';\nexport type { UsaBinding } from './bind';\n\n/** `APP_INITIALIZER` factory: registers the elements in the browser (no-op during SSR). */\nexport function usaInitializer(categories?: ComponentCategory[]): () => () => void {\n return () => () => {\n if (typeof window !== 'undefined') defineComponents(categories);\n };\n}\n\n/** Register the elements directly (e.g. in `main.ts` before `bootstrapApplication`). */\nexport function defineUsa(categories?: ComponentCategory[]): void {\n if (typeof window !== 'undefined') defineComponents(categories);\n}\n\n/** Read `event.detail` from a `usa:*` event in a template handler: `(usa:change)=\"on = usaDetail($event).checked\"`. */\nexport const usaDetail = <T = any>(e: Event): T => (e as CustomEvent<T>).detail;\n"],"names":["defineComponents"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;AAkBG;AAMH;AACM,SAAU,cAAc,CAAC,UAAgC,EAAA;AAC7D,IAAA,OAAO,MAAM,MAAK;QAChB,IAAI,OAAO,MAAM,KAAK,WAAW;YAAEA,2BAAgB,CAAC,UAAU,CAAC;AACjE,IAAA,CAAC;AACH;AAEA;AACM,SAAU,SAAS,CAAC,UAAgC,EAAA;IACxD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAEA,2BAAgB,CAAC,UAAU,CAAC;AACjE;AAEA;AACO,MAAM,SAAS,GAAG,CAAU,CAAQ,KAAS,CAAoB,CAAC;;;;;;;;"}
@@ -117,7 +117,11 @@ interface UsaTypewriterElement extends UsaElement {
117
117
  * them in a cascade (pure CSS animation per unit, transform / opacity /
118
118
  * filter only). Words never break across lines.
119
119
  *
120
- * Attributes: `by` (`chars` | `words`, default `chars`), `effect`
120
+ * 4.3: `Intl.Segmenter`-aware (emoji, CJK words), Arabic-script words are
121
+ * never split below the word, `by="lines"` reveals line by line, and `from`
122
+ * (`start` · `end` · `center` · `edges` · `random`) sets the cascade order.
123
+ *
124
+ * Attributes: `by` (`chars` | `words` | `lines`, default `chars`), `effect`
121
125
  * (`rise` | `fade` | `blur` | `flip` | `pop`, default `rise`), `stagger`
122
126
  * (ms between units, 28 for chars / 70 for words), `duration` (ms, 620),
123
127
  * `delay` (ms, 0), `trigger` (`view` | `load` | `manual`, default `view`),
@@ -230,6 +234,81 @@ interface UsaScrollHighlightElement extends UsaElement {
230
234
  readonly progress: number;
231
235
  }
232
236
 
237
+ /**
238
+ * Where a step starts on a timeline:
239
+ * - a number: absolute time in ms
240
+ * - `'>'` (default): when the previous step ends · `'<'`: when it starts
241
+ * - `'+=200'` / `'-=200'`: after / overlapping the previous end
242
+ * - `'<+=100'`: 100ms after the previous step's start
243
+ * - `'intro'` / `'intro+=150'`: at (or relative to) a label
244
+ */
245
+ type TimelinePosition = number | string;
246
+ interface TimelineStepOptions {
247
+ /** Duration in ms or a motion token name (`'fast'`, `'slow'`…; 4.2). Default: timeline default, 600. */
248
+ duration?: number | string;
249
+ /** CSS easing or a motion token name (`'emphasized'`, `'spring'`…; 4.2). Default `cubic-bezier(0.22, 1, 0.36, 1)`. */
250
+ easing?: string;
251
+ /** Start position, see `TimelinePosition`. */
252
+ at?: TimelinePosition;
253
+ /** ms between targets when the selector matches several elements. */
254
+ stagger?: number;
255
+ }
256
+ interface ScrubOptions {
257
+ /** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts (JS engine only). */
258
+ offset?: number;
259
+ /** Smoothing 0–1 (0 = immediate, default 0). Smoothing needs the JS engine. */
260
+ smooth?: number;
261
+ /**
262
+ * 4.1: which progress source drives the timeline.
263
+ * - `'view'` (default): `source` moving through the viewport (CSS `ViewTimeline`, range `cover`).
264
+ * - `'scroll'`: the scroll position of `source` itself (a scroll container; CSS `ScrollTimeline`).
265
+ */
266
+ source?: 'view' | 'scroll';
267
+ /** 4.1: `'auto'` (default) uses the browser's native scroll-driven animations when available, `'js'` forces the fallback. */
268
+ engine?: 'auto' | 'native' | 'js';
269
+ /** 4.1: scroll axis, `'block'` (default) · `'inline'` · `'x'` · `'y'`. */
270
+ axis?: 'block' | 'inline' | 'x' | 'y';
271
+ }
272
+ /** The function `scrub()` returns: call it to stop. `native` tells which engine runs it. */
273
+ interface ScrubHandle {
274
+ (): void;
275
+ /** `true` when the browser's ScrollTimeline / ViewTimeline drives it (compositor, no JS per frame). */
276
+ readonly native: boolean;
277
+ }
278
+ interface Timeline {
279
+ /** Total length in ms. */
280
+ readonly duration: number;
281
+ /** Label positions in ms. */
282
+ readonly labels: Readonly<Record<string, number>>;
283
+ /** Current playhead in ms. */
284
+ readonly time: number;
285
+ /** Add a step: animate `target` with keyframes or a preset name (`fade-up`, `scale`…). */
286
+ to(target: string | Element | Element[] | NodeList, frames: Keyframe[] | string, options?: TimelineStepOptions): Timeline;
287
+ /** Name a position (default: the current end). */
288
+ label(name: string, at?: TimelinePosition): Timeline;
289
+ /** Run `fn` when the playhead passes `at`. */
290
+ call(fn: () => void, at?: TimelinePosition): Timeline;
291
+ /** Play forwards from the playhead (from 0 when at the end). Resolves at the end. */
292
+ play(from?: TimelinePosition): Promise<void>;
293
+ /** Play backwards to 0. */
294
+ reverse(): Promise<void>;
295
+ pause(): Timeline;
296
+ /** Jump to a time (ms) or label. */
297
+ seek(to: TimelinePosition): Timeline;
298
+ /** Get or set progress 0–1. */
299
+ progress(p?: number): number;
300
+ /**
301
+ * Tie progress to scroll: `source` moving through the viewport (or, with
302
+ * `{ source: 'scroll' }`, a scroll container's own position). Runs on native
303
+ * ScrollTimeline / ViewTimeline when available (and no `smooth`, `offset`,
304
+ * `call()` cues or `onUpdate` need JS), else on a rAF-throttled listener.
305
+ * Returns a stop function with a `native` flag.
306
+ */
307
+ scrub(source: Element, options?: ScrubOptions): ScrubHandle;
308
+ /** Stop and drop every animation (elements keep their last frame). */
309
+ cancel(): void;
310
+ }
311
+
233
312
  /**
234
313
  * use-scroll-animate/components/text — text effects.
235
314
  * `<usa-typewriter>`, `<usa-split-text>`, `<usa-scramble>`, `<usa-counter>`,
@@ -1275,81 +1354,6 @@ declare global {
1275
1354
  }
1276
1355
  }
1277
1356
 
1278
- /**
1279
- * Where a step starts on a timeline:
1280
- * - a number: absolute time in ms
1281
- * - `'>'` (default): when the previous step ends · `'<'`: when it starts
1282
- * - `'+=200'` / `'-=200'`: after / overlapping the previous end
1283
- * - `'<+=100'`: 100ms after the previous step's start
1284
- * - `'intro'` / `'intro+=150'`: at (or relative to) a label
1285
- */
1286
- type TimelinePosition = number | string;
1287
- interface TimelineStepOptions {
1288
- /** Duration in ms or a motion token name (`'fast'`, `'slow'`…; 4.2). Default: timeline default, 600. */
1289
- duration?: number | string;
1290
- /** CSS easing or a motion token name (`'emphasized'`, `'spring'`…; 4.2). Default `cubic-bezier(0.22, 1, 0.36, 1)`. */
1291
- easing?: string;
1292
- /** Start position, see `TimelinePosition`. */
1293
- at?: TimelinePosition;
1294
- /** ms between targets when the selector matches several elements. */
1295
- stagger?: number;
1296
- }
1297
- interface ScrubOptions {
1298
- /** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts (JS engine only). */
1299
- offset?: number;
1300
- /** Smoothing 0–1 (0 = immediate, default 0). Smoothing needs the JS engine. */
1301
- smooth?: number;
1302
- /**
1303
- * 4.1: which progress source drives the timeline.
1304
- * - `'view'` (default): `source` moving through the viewport (CSS `ViewTimeline`, range `cover`).
1305
- * - `'scroll'`: the scroll position of `source` itself (a scroll container; CSS `ScrollTimeline`).
1306
- */
1307
- source?: 'view' | 'scroll';
1308
- /** 4.1: `'auto'` (default) uses the browser's native scroll-driven animations when available, `'js'` forces the fallback. */
1309
- engine?: 'auto' | 'native' | 'js';
1310
- /** 4.1: scroll axis, `'block'` (default) · `'inline'` · `'x'` · `'y'`. */
1311
- axis?: 'block' | 'inline' | 'x' | 'y';
1312
- }
1313
- /** The function `scrub()` returns: call it to stop. `native` tells which engine runs it. */
1314
- interface ScrubHandle {
1315
- (): void;
1316
- /** `true` when the browser's ScrollTimeline / ViewTimeline drives it (compositor, no JS per frame). */
1317
- readonly native: boolean;
1318
- }
1319
- interface Timeline {
1320
- /** Total length in ms. */
1321
- readonly duration: number;
1322
- /** Label positions in ms. */
1323
- readonly labels: Readonly<Record<string, number>>;
1324
- /** Current playhead in ms. */
1325
- readonly time: number;
1326
- /** Add a step: animate `target` with keyframes or a preset name (`fade-up`, `scale`…). */
1327
- to(target: string | Element | Element[] | NodeList, frames: Keyframe[] | string, options?: TimelineStepOptions): Timeline;
1328
- /** Name a position (default: the current end). */
1329
- label(name: string, at?: TimelinePosition): Timeline;
1330
- /** Run `fn` when the playhead passes `at`. */
1331
- call(fn: () => void, at?: TimelinePosition): Timeline;
1332
- /** Play forwards from the playhead (from 0 when at the end). Resolves at the end. */
1333
- play(from?: TimelinePosition): Promise<void>;
1334
- /** Play backwards to 0. */
1335
- reverse(): Promise<void>;
1336
- pause(): Timeline;
1337
- /** Jump to a time (ms) or label. */
1338
- seek(to: TimelinePosition): Timeline;
1339
- /** Get or set progress 0–1. */
1340
- progress(p?: number): number;
1341
- /**
1342
- * Tie progress to scroll: `source` moving through the viewport (or, with
1343
- * `{ source: 'scroll' }`, a scroll container's own position). Runs on native
1344
- * ScrollTimeline / ViewTimeline when available (and no `smooth`, `offset`,
1345
- * `call()` cues or `onUpdate` need JS), else on a rAF-throttled listener.
1346
- * Returns a stop function with a `native` flag.
1347
- */
1348
- scrub(source: Element, options?: ScrubOptions): ScrubHandle;
1349
- /** Stop and drop every animation (elements keep their last frame). */
1350
- cancel(): void;
1351
- }
1352
-
1353
1357
  /**
1354
1358
  * `<usa-timeline>` — declarative choreography. Every descendant with
1355
1359
  * `data-tl="<preset>"` becomes a step, in document order; `data-at`