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
@@ -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`
@@ -2,29 +2,30 @@ import { defineComponents } from '../components.js';
2
2
  import { b as bindUsa } from '../chunks/bind-B_CTL6Qn.js';
3
3
  export { u as usaEventName } from '../chunks/bind-B_CTL6Qn.js';
4
4
  import './reveal.js';
5
- import '../chunks/base-BPG5zvex.js';
5
+ import '../chunks/base-BtJDNCB6.js';
6
6
  import './text.js';
7
+ import '../chunks/core-DS1nrx5L.js';
8
+ import './tokens.js';
7
9
  import './interaction.js';
8
10
  import './feedback.js';
9
11
  import './background.js';
10
- import '../chunks/variants-BVYMcxRv.js';
12
+ import '../chunks/variants-dD6SbUMR.js';
11
13
  import './transitions.js';
12
14
  import './physics.js';
13
- import '../chunks/spring-BziPsW3r.js';
15
+ import '../chunks/spring-CxRz49Wk.js';
14
16
  import './cards.js';
15
17
  import './click.js';
16
18
  import './ui.js';
17
19
  import './page.js';
18
20
  import './timeline.js';
19
- import '../chunks/core-LkGRmgES.js';
20
- import './tokens.js';
21
21
  import './gesture.js';
22
- import '../chunks/core-eXX8rB_b.js';
22
+ import '../chunks/core-DX6pdOoY.js';
23
23
  import './svg.js';
24
24
  import './webgl.js';
25
25
  import './depth.js';
26
26
  import './layout.js';
27
27
  import './packs.js';
28
+ import './a11y.js';
28
29
  import '../chunks/index-tags-43Xtd01A.js';
29
30
 
30
31
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"svelte.js","sources":["../../src/components/frameworks/svelte.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/svelte — Svelte integration (v3.8).\n * Svelte (3, 4, 5) renders `<usa-*>` tags natively; `use:usa` sets\n * **properties** and `usa:*` listeners in one place, and `defineUsa()`\n * registers the elements on the client only (safe in SvelteKit SSR).\n *\n * ```svelte\n * <script>\n * import { usa, defineUsa } from 'use-scroll-animate/components/svelte';\n * import { onMount } from 'svelte';\n * onMount(() => defineUsa(['click', 'ui']));\n * let on = false;\n * </script>\n * <usa-toggle use:usa={{ props: { checked: on }, on: { change: (e) => (on = e.detail.checked) } }}></usa-toggle>\n * ```\n * Plain `on:usa:change` does not compile in Svelte 3/4 (colon); use the action or `onusa:change` in Svelte 5.\n */\nimport { defineComponents, type ComponentCategory } from '../index';\nimport { bindUsa, type UsaBinding } from './bind';\n\nexport { bindUsa, usaEventName } from './bind';\nexport type { UsaBinding } from './bind';\n\n/** Svelte action: `use:usa={{ props, on }}`. */\nexport function usa(node: HTMLElement, binding: UsaBinding = {}): { update(b: UsaBinding): void; destroy(): void } {\n return bindUsa(node, binding);\n}\n\n/** Register the elements (all, or some categories) — call from `onMount` for SSR apps. */\nexport function defineUsa(categories?: ComponentCategory[]): void {\n if (typeof window !== 'undefined') defineComponents(categories);\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;AAgBG;AAOH;SACgB,GAAG,CAAC,IAAiB,EAAE,UAAsB,EAAE,EAAA;AAC7D,IAAA,OAAO,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;AAC/B;AAEA;AACM,SAAU,SAAS,CAAC,UAAgC,EAAA;IACxD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,gBAAgB,CAAC,UAAU,CAAC;AACjE;;;;"}
1
+ {"version":3,"file":"svelte.js","sources":["../../src/components/frameworks/svelte.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/svelte — Svelte integration (v3.8).\n * Svelte (3, 4, 5) renders `<usa-*>` tags natively; `use:usa` sets\n * **properties** and `usa:*` listeners in one place, and `defineUsa()`\n * registers the elements on the client only (safe in SvelteKit SSR).\n *\n * ```svelte\n * <script>\n * import { usa, defineUsa } from 'use-scroll-animate/components/svelte';\n * import { onMount } from 'svelte';\n * onMount(() => defineUsa(['click', 'ui']));\n * let on = false;\n * </script>\n * <usa-toggle use:usa={{ props: { checked: on }, on: { change: (e) => (on = e.detail.checked) } }}></usa-toggle>\n * ```\n * Plain `on:usa:change` does not compile in Svelte 3/4 (colon); use the action or `onusa:change` in Svelte 5.\n */\nimport { defineComponents, type ComponentCategory } from '../index';\nimport { bindUsa, type UsaBinding } from './bind';\n\nexport { bindUsa, usaEventName } from './bind';\nexport type { UsaBinding } from './bind';\n\n/** Svelte action: `use:usa={{ props, on }}`. */\nexport function usa(node: HTMLElement, binding: UsaBinding = {}): { update(b: UsaBinding): void; destroy(): void } {\n return bindUsa(node, binding);\n}\n\n/** Register the elements (all, or some categories) — call from `onMount` for SSR apps. */\nexport function defineUsa(categories?: ComponentCategory[]): void {\n if (typeof window !== 'undefined') defineComponents(categories);\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;AAgBG;AAOH;SACgB,GAAG,CAAC,IAAiB,EAAE,UAAsB,EAAE,EAAA;AAC7D,IAAA,OAAO,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;AAC/B;AAEA;AACM,SAAU,SAAS,CAAC,UAAgC,EAAA;IACxD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,gBAAgB,CAAC,UAAU,CAAC;AACjE;;;;"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var base = require('../chunks/base-CXx7jZ-o.cjs');
3
+ var base = require('../chunks/base-DE2yzxE7.cjs');
4
4
 
5
5
  const NUM = /-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi;
6
6
  /** `true` when two path strings share the same commands (so their numbers can be interpolated). */
@@ -27,7 +27,17 @@ interface ComponentsConfig {
27
27
  * 1.25) on `<html>` for your own CSS. See `setMotionIntensity()`.
28
28
  */
29
29
  motionIntensity?: MotionIntensity;
30
+ /**
31
+ * Motion-sensitivity level (v4.4), finer than reduced motion:
32
+ * `'full'` (default) · `'gentle'` (no spins, zooms, skews or parallax —
33
+ * translations and fades only, safe for vestibular disorders) ·
34
+ * `'minimal'` (fades only; components use their reduced-motion variants) ·
35
+ * `'static'` (no animation: every component shows its static alternative).
36
+ * See `setMotionSensitivity()` in `use-scroll-animate/components/a11y`.
37
+ */
38
+ motionSensitivity?: MotionSensitivity;
30
39
  }
40
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
31
41
  type MotionIntensity = 'off' | 'low' | 'normal' | 'high';
32
42
  /** Change global component settings (call before `define*()` for `injectStyles`). */
33
43
  declare function configureComponents(options: ComponentsConfig): void;
@@ -27,7 +27,17 @@ interface ComponentsConfig {
27
27
  * 1.25) on `<html>` for your own CSS. See `setMotionIntensity()`.
28
28
  */
29
29
  motionIntensity?: MotionIntensity;
30
+ /**
31
+ * Motion-sensitivity level (v4.4), finer than reduced motion:
32
+ * `'full'` (default) · `'gentle'` (no spins, zooms, skews or parallax —
33
+ * translations and fades only, safe for vestibular disorders) ·
34
+ * `'minimal'` (fades only; components use their reduced-motion variants) ·
35
+ * `'static'` (no animation: every component shows its static alternative).
36
+ * See `setMotionSensitivity()` in `use-scroll-animate/components/a11y`.
37
+ */
38
+ motionSensitivity?: MotionSensitivity;
30
39
  }
40
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
31
41
  type MotionIntensity = 'off' | 'low' | 'normal' | 'high';
32
42
  /** Change global component settings (call before `define*()` for `injectStyles`). */
33
43
  declare function configureComponents(options: ComponentsConfig): void;
@@ -1,5 +1,5 @@
1
- import { b as clamp, m as motionScale, d as caf, p as prefersReducedMotion, n as now, r as raf, h as defineElement, i as EASE_OUT } from '../chunks/base-BPG5zvex.js';
2
- export { a as configureComponents } from '../chunks/base-BPG5zvex.js';
1
+ import { f as clamp, m as motionScale, h as caf, p as prefersReducedMotion, n as now, r as raf, k as defineElement, l as EASE_OUT } from '../chunks/base-BtJDNCB6.js';
2
+ export { d as configureComponents } from '../chunks/base-BtJDNCB6.js';
3
3
 
4
4
  const NUM = /-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi;
5
5
  /** `true` when two path strings share the same commands (so their numbers can be interpolated). */
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var base = require('../chunks/base-CXx7jZ-o.cjs');
3
+ var base = require('../chunks/base-DE2yzxE7.cjs');
4
+ var core = require('../chunks/core-BC9S2osy.cjs');
5
+ require('./tokens.cjs');
4
6
 
5
7
  var css$5 = "usa-typewriter{white-space:pre-wrap}usa-typewriter .usa-tw-caret{display:inline-block;width:var(--usa-caret-width,0.08em);height:1.05em;margin-left:0.06em;vertical-align:-0.12em;background:var(--usa-caret-color,currentColor);animation:usa-caret 1.06s steps(1) infinite}usa-typewriter[data-typing] .usa-tw-caret{animation:none}usa-typewriter[data-no-cursor] .usa-tw-caret{display:none}@keyframes usa-caret{50%{opacity:0}}@media (prefers-reduced-motion:reduce){usa-typewriter .usa-tw-caret,usa-shimmer-text{animation:none}}";
6
8
 
@@ -121,12 +123,255 @@ function defineTypewriter(tag = 'usa-typewriter') {
121
123
 
122
124
  var css$4 = "usa-split-text .usa-split-word{display:inline-block;white-space:nowrap}usa-split-text .usa-split-unit{display:inline-block;white-space:pre}usa-split-text[data-state=\"hidden\"] .usa-split-unit{opacity:0}usa-split-text[data-state=\"play\"] .usa-split-unit{animation:usa-split-rise var(--usa-split-duration,620ms) cubic-bezier(0.22,1,0.36,1) both;animation-delay:calc(var(--usa-split-delay,0ms) + var(--i,0) * var(--usa-split-stagger,28ms))}usa-split-text[effect=\"fade\"][data-state=\"play\"] .usa-split-unit{animation-name:usa-split-fade}usa-split-text[effect=\"blur\"][data-state=\"play\"] .usa-split-unit{animation-name:usa-split-blur}usa-split-text[effect=\"flip\"][data-state=\"play\"] .usa-split-unit{animation-name:usa-split-flip;transform-origin:50% 100%}usa-split-text[effect=\"pop\"][data-state=\"play\"] .usa-split-unit{animation-name:usa-split-pop;animation-timing-function:cubic-bezier(0.34,1.56,0.64,1)}@keyframes usa-split-rise{from{opacity:0;transform:translate3d(0,0.6em,0)}to{opacity:1;transform:none}}@keyframes usa-split-fade{from{opacity:0}to{opacity:1}}@keyframes usa-split-blur{from{opacity:0;filter:blur(8px)}to{opacity:1;filter:none}}@keyframes usa-split-flip{from{opacity:0;transform:perspective(500px) rotateX(-80deg)}to{opacity:1;transform:none}}@keyframes usa-split-pop{from{opacity:0;transform:scale(0.3)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){usa-split-text .usa-split-unit{animation:none !important;opacity:1 !important}}";
123
125
 
126
+ const CJK = /[\u2E80-\u2FFF\u3000-\u303F\u3040-\u30FF\u3100-\u312F\u3130-\u318F\u31A0-\u31FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF00-\uFFEF]/;
127
+ /** Scripts whose letters join (splitting them would break shaping). */
128
+ const JOINING_SCRIPT = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
129
+ const RTL = /[\u0590-\u08FF\uFB1D-\uFDFF\uFE70-\uFEFF]/;
130
+ const 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';
131
+ function segmenter(locale, granularity) {
132
+ const S = globalThis.Intl?.Segmenter;
133
+ if (typeof S !== 'function')
134
+ return null;
135
+ try {
136
+ return new S(locale || undefined, { granularity });
137
+ }
138
+ catch {
139
+ return null;
140
+ }
141
+ }
142
+ /** Grapheme clusters of `s` (emoji / combining marks stay whole). */
143
+ function graphemes(s, locale) {
144
+ const seg = segmenter(locale, 'grapheme');
145
+ if (seg)
146
+ return Array.from(seg.segment(s), (x) => x.segment);
147
+ return Array.from(s);
148
+ }
149
+ /**
150
+ * Word-ish tokens of `s`, whitespace kept as separate tokens. CJK text is
151
+ * segmented into words with `Intl.Segmenter`, or per character without it.
152
+ */
153
+ function words(s, locale) {
154
+ const seg = segmenter(locale, 'word');
155
+ const out = [];
156
+ if (seg) {
157
+ for (const x of seg.segment(s)) {
158
+ const last = out[out.length - 1];
159
+ // glue punctuation onto the previous word so it never starts a line alone
160
+ if (!x.isWordLike && !/^\s+$/.test(x.segment) && last && !/^\s+$/.test(last))
161
+ out[out.length - 1] = last + x.segment;
162
+ else
163
+ out.push(x.segment);
164
+ }
165
+ return out;
166
+ }
167
+ for (const part of s.split(/(\s+)/)) {
168
+ if (!part)
169
+ continue;
170
+ if (/^\s+$/.test(part) || !CJK.test(part))
171
+ out.push(part);
172
+ else {
173
+ let buf = '';
174
+ for (const ch of Array.from(part)) {
175
+ if (CJK.test(ch)) {
176
+ if (buf)
177
+ out.push(buf), (buf = '');
178
+ out.push(ch);
179
+ }
180
+ else if (/[\p{P}]/u.test(ch) && out.length)
181
+ out[out.length - 1] += ch;
182
+ else
183
+ buf += ch;
184
+ }
185
+ if (buf)
186
+ out.push(buf);
187
+ }
188
+ }
189
+ return out;
190
+ }
191
+ function dirOf(el, text) {
192
+ const attr = el.closest?.('[dir]')?.getAttribute('dir');
193
+ if (attr === 'rtl' || attr === 'ltr')
194
+ return attr;
195
+ try {
196
+ const d = getComputedStyle(el).direction;
197
+ if (d === 'rtl')
198
+ return 'rtl';
199
+ }
200
+ catch {
201
+ /* no layout */
202
+ }
203
+ return RTL.test(text) && !/[A-Za-z]/.test(text.replace(RTL, '')) ? 'rtl' : 'ltr';
204
+ }
205
+ function splitText(el, options = {}) {
206
+ const by = new Set((Array.isArray(options.by) ? options.by : String(options.by ?? 'char').split(/[\s,]+/)).filter(Boolean));
207
+ const cls = options.className || 'usa-split';
208
+ const locale = options.locale || el.closest?.('[lang]')?.getAttribute('lang') || undefined;
209
+ const original = Array.from(el.childNodes).map((n) => n.cloneNode(true));
210
+ const text = el.textContent || '';
211
+ const direction = dirOf(el, text);
212
+ const chars = [];
213
+ const wordEls = [];
214
+ let lines = [];
215
+ const doc = el.ownerDocument;
216
+ const span = (c, t) => {
217
+ const s = doc.createElement('span');
218
+ s.className = c;
219
+ if (t !== undefined)
220
+ s.textContent = t;
221
+ return s;
222
+ };
223
+ const splitNode = (node) => {
224
+ if (node.nodeType === 3) {
225
+ const frag = doc.createDocumentFragment();
226
+ for (const w of words(node.nodeValue || '', locale)) {
227
+ if (/^\s+$/.test(w)) {
228
+ frag.append(doc.createTextNode(w));
229
+ continue;
230
+ }
231
+ const wordEl = span(`${cls}-word`);
232
+ wordEl.style.display = 'inline-block';
233
+ wordEl.style.whiteSpace = 'nowrap';
234
+ wordEl.dataset.index = String(wordEls.length);
235
+ wordEls.push(wordEl);
236
+ // Arabic script joins its letters: keep the word whole (shaping), even in char mode.
237
+ if (by.has('char') && !JOINING_SCRIPT.test(w)) {
238
+ for (const g of graphemes(w, locale)) {
239
+ const c = span(`${cls}-char`, g);
240
+ c.style.display = 'inline-block';
241
+ c.dataset.index = String(chars.length);
242
+ chars.push(c);
243
+ wordEl.append(c);
244
+ }
245
+ }
246
+ else {
247
+ wordEl.textContent = w;
248
+ if (by.has('char')) {
249
+ wordEl.dataset.whole = '';
250
+ chars.push(wordEl);
251
+ }
252
+ }
253
+ frag.append(wordEl);
254
+ }
255
+ node.parentNode.replaceChild(frag, node);
256
+ }
257
+ else if (node.nodeType === 1 && !/^(BR|SCRIPT|STYLE|SVG|IMG)$/i.test(node.tagName)) {
258
+ Array.from(node.childNodes).forEach(splitNode);
259
+ }
260
+ };
261
+ const wrap = doc.createElement('span');
262
+ wrap.setAttribute('aria-hidden', 'true');
263
+ wrap.className = `${cls}-body`;
264
+ original.forEach((n) => wrap.append(n.cloneNode(true)));
265
+ Array.from(wrap.childNodes).forEach(splitNode);
266
+ const sr = span(`${cls}-sr`, text.replace(/\s+/g, ' ').trim());
267
+ sr.setAttribute('style', SR);
268
+ el.replaceChildren(sr, wrap);
269
+ el.setAttribute('data-split', [...by].join(' '));
270
+ if (direction === 'rtl')
271
+ el.setAttribute('data-split-dir', 'rtl');
272
+ const relayout = () => {
273
+ // unwrap old lines
274
+ for (const l of lines)
275
+ l.replaceWith(...Array.from(l.childNodes));
276
+ lines = [];
277
+ if (!by.has('line') || !wordEls.length)
278
+ return lines;
279
+ const groups = [];
280
+ let lastTop = null;
281
+ for (const w of wordEls) {
282
+ const top = Math.round(w.offsetTop);
283
+ if (lastTop === null || Math.abs(top - lastTop) > 2)
284
+ groups.push([]);
285
+ groups[groups.length - 1].push(w);
286
+ lastTop = top;
287
+ }
288
+ groups.forEach((g, i) => {
289
+ // only group words that share a parent (inline markup keeps its words)
290
+ const parent = g[0].parentNode;
291
+ const same = g.filter((w) => w.parentNode === parent);
292
+ const line = span(`${cls}-line`);
293
+ line.style.display = 'inline-block';
294
+ line.dataset.index = String(i);
295
+ parent.insertBefore(line, same[0]);
296
+ let n = same[0];
297
+ const end = same[same.length - 1];
298
+ while (n) {
299
+ const next = n.nextSibling;
300
+ line.append(n);
301
+ if (n === end)
302
+ break;
303
+ n = next;
304
+ }
305
+ // keep the space between lines outside the line box
306
+ lines.push(line);
307
+ });
308
+ return lines;
309
+ };
310
+ relayout();
311
+ return {
312
+ chars,
313
+ words: wordEls,
314
+ get lines() {
315
+ return lines;
316
+ },
317
+ direction,
318
+ relayout,
319
+ revert() {
320
+ el.replaceChildren(...original.map((n) => n.cloneNode(true)));
321
+ el.removeAttribute('data-split');
322
+ el.removeAttribute('data-split-dir');
323
+ },
324
+ };
325
+ }
326
+ /** Order indices `0…n-1` by choreography: from the start, end, center outwards, edges inwards, or random (seeded). */
327
+ function splitOrder(n, from = 'start', seed = 1) {
328
+ const idx = Array.from({ length: n }, (_, i) => i);
329
+ const mid = (n - 1) / 2;
330
+ if (from === 'end')
331
+ return idx.map((i) => n - 1 - i);
332
+ if (from === 'center')
333
+ return idx.map((i) => Math.round(Math.abs(i - mid) * 2) / 2);
334
+ if (from === 'edges')
335
+ return idx.map((i) => Math.round((mid - Math.abs(i - mid)) * 2) / 2);
336
+ if (from === 'random') {
337
+ let s = seed;
338
+ const r = () => ((s = (s * 16807) % 2147483647) / 2147483647);
339
+ const shuffled = idx.slice().sort(() => r() - 0.5);
340
+ const rank = [];
341
+ shuffled.forEach((v, i) => (rank[v] = i));
342
+ return rank;
343
+ }
344
+ return idx;
345
+ }
346
+ /**
347
+ * Split `el` and build a `timeline()` with one step per unit — play it,
348
+ * `scrub()` it with scroll, `reverse()` or `seek()` it.
349
+ *
350
+ * ```ts
351
+ * const { timeline: tl } = splitTimeline(h1, { by: 'char', preset: 'blur', from: 'center' });
352
+ * tl.play();
353
+ * ```
354
+ */
355
+ function splitTimeline(el, options = {}) {
356
+ const split = splitText(el, options);
357
+ const by = Array.isArray(options.by) ? options.by : String(options.by ?? 'char').split(/[\s,]+/);
358
+ const unit = options.unit || (by.includes('char') ? 'char' : by.includes('word') ? 'word' : 'line');
359
+ const units = unit === 'char' ? split.chars : unit === 'word' ? split.words : split.lines;
360
+ const stagger = options.stagger ?? (unit === 'char' ? 30 : unit === 'word' ? 80 : 140);
361
+ const order = splitOrder(units.length, options.from);
362
+ const tl = core.timeline({ defaults: { duration: options.duration ?? 500, easing: options.easing } });
363
+ units.forEach((u, i) => tl.to(u, options.preset || 'fade-up', { at: order[i] * stagger }));
364
+ tl.seek(0);
365
+ return { split, timeline: tl };
366
+ }
367
+
124
368
  function defineSplitText(tag = 'usa-split-text') {
125
369
  return base.defineElement(tag, (Base) => class UsaSplitText extends Base {
126
370
  constructor() {
127
371
  super(...arguments);
128
372
  this._source = null;
129
373
  this._timer = 0;
374
+ this._steps = 0;
130
375
  }
131
376
  static get observedAttributes() {
132
377
  return ['by', 'text'];
@@ -138,28 +383,50 @@ function defineSplitText(tag = 'usa-split-text') {
138
383
  if (this._source === null)
139
384
  this._source = this.getAttribute('text') ?? (this.textContent || '').replace(/\s+/g, ' ').trim();
140
385
  const text = this.getAttribute('text') ?? this._source;
141
- const byWords = this.str('by', 'chars') === 'words';
386
+ const mode = this.str('by', 'chars');
387
+ const byWords = mode !== 'chars';
388
+ const lang = this.closest('[lang]')?.getAttribute('lang') || undefined;
142
389
  const frag = document.createDocumentFragment();
143
390
  frag.append(base.srText(text));
144
- let i = 0;
145
- text.split(' ').forEach((word, w) => {
146
- if (w > 0)
391
+ const units = [];
392
+ for (const word of words(text, lang)) {
393
+ if (/^\s+$/.test(word)) {
147
394
  frag.append(' ');
395
+ continue;
396
+ }
148
397
  const wordEl = document.createElement('span');
149
398
  wordEl.className = 'usa-split-word';
150
399
  wordEl.setAttribute('aria-hidden', 'true');
151
- const parts = byWords ? [word] : Array.from(word);
400
+ const parts = byWords || JOINING_SCRIPT.test(word) ? [word] : graphemes(word, lang);
152
401
  for (const part of parts) {
153
402
  const u = document.createElement('span');
154
403
  u.className = 'usa-split-unit';
155
404
  u.textContent = part;
156
- u.style.setProperty('--i', String(i++));
405
+ units.push(u);
157
406
  wordEl.append(u);
158
407
  }
159
408
  frag.append(wordEl);
160
- });
409
+ }
161
410
  this.replaceChildren(frag);
162
- this.style.setProperty('--usa-split-stagger', `${this.num('stagger', byWords ? 70 : 28)}ms`);
411
+ // cascade order: per unit, or per line for by="lines"
412
+ let rank = units.map((_, k) => k);
413
+ if (mode === 'lines') {
414
+ let line = -1;
415
+ let top = null;
416
+ rank = units.map((u) => {
417
+ const t = Math.round(u.parentElement.offsetTop);
418
+ if (top === null || Math.abs(t - top) > 2)
419
+ line++;
420
+ top = t;
421
+ return line;
422
+ });
423
+ }
424
+ const groups = Math.max(0, ...rank) + 1;
425
+ const order = splitOrder(groups, this.str('from', 'start'));
426
+ units.forEach((u, k) => u.style.setProperty('--i', String(order[rank[k]] ?? 0)));
427
+ const i = Math.max(0, ...units.map((_, k) => order[rank[k]] ?? 0)) + 1;
428
+ this._steps = i;
429
+ this.style.setProperty('--usa-split-stagger', `${this.num('stagger', mode === 'lines' ? 140 : byWords ? 70 : 28)}ms`);
163
430
  this.style.setProperty('--usa-split-duration', `${this.num('duration', 620)}ms`);
164
431
  this.style.setProperty('--usa-split-delay', `${this.num('delay', 0)}ms`);
165
432
  this.style.setProperty('--usa-split-count', String(i));
@@ -193,8 +460,8 @@ function defineSplitText(tag = 'usa-split-text') {
193
460
  this.setAttribute('data-state', 'hidden');
194
461
  void this.offsetWidth;
195
462
  this.setAttribute('data-state', 'play');
196
- const n = this.units.length;
197
- const total = this.num('delay', 0) + this.num('duration', 620) + Math.max(0, n - 1) * this.num('stagger', this.str('by') === 'words' ? 70 : 28);
463
+ const by = this.str('by', 'chars');
464
+ const total = this.num('delay', 0) + this.num('duration', 620) + Math.max(0, this._steps - 1) * this.num('stagger', by === 'lines' ? 140 : by === 'words' ? 70 : 28);
198
465
  this._timer = setTimeout(() => {
199
466
  this.setAttribute('data-state', 'shown');
200
467
  this.emit('complete');
@@ -680,6 +947,7 @@ function defineTextComponents() {
680
947
 
681
948
  exports.configureComponents = base.configureComponents;
682
949
  exports.prefersReducedMotion = base.prefersReducedMotion;
950
+ exports.JOINING_SCRIPT = JOINING_SCRIPT;
683
951
  exports.defineCounter = defineCounter;
684
952
  exports.defineGlitch = defineGlitch;
685
953
  exports.defineGradientText = defineGradientText;
@@ -693,5 +961,10 @@ exports.defineTextRotate = defineTextRotate;
693
961
  exports.defineTypewriter = defineTypewriter;
694
962
  exports.defineWaveText = defineWaveText;
695
963
  exports.easeOutExpo = easeOutExpo;
964
+ exports.graphemes = graphemes;
696
965
  exports.scrambleFrame = scrambleFrame;
966
+ exports.splitOrder = splitOrder;
967
+ exports.splitText = splitText;
968
+ exports.splitTimeline = splitTimeline;
969
+ exports.splitWords = words;
697
970
  //# sourceMappingURL=text.cjs.map