use-scroll-animate 4.3.0 → 4.5.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 (147) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/chunks/{base-BPG5zvex.js → base-CZiIAMBc.js} +140 -13
  3. package/dist/chunks/base-CZiIAMBc.js.map +1 -0
  4. package/dist/chunks/{base-CXx7jZ-o.cjs → base-CxYU2NK_.cjs} +148 -12
  5. package/dist/chunks/base-CxYU2NK_.cjs.map +1 -0
  6. package/dist/chunks/{core-LkGRmgES.js → core-CJHJeMI_.js} +2 -2
  7. package/dist/chunks/{core-LkGRmgES.js.map → core-CJHJeMI_.js.map} +1 -1
  8. package/dist/chunks/{core-eXX8rB_b.js → core-COi3DrLx.js} +2 -2
  9. package/dist/chunks/{core-eXX8rB_b.js.map → core-COi3DrLx.js.map} +1 -1
  10. package/dist/chunks/{core-IaorbTdu.cjs → core-CctNfzuP.cjs} +2 -2
  11. package/dist/chunks/{core-IaorbTdu.cjs.map → core-CctNfzuP.cjs.map} +1 -1
  12. package/dist/chunks/{core-BRIIoKeS.cjs → core-HLqH3qkA.cjs} +2 -2
  13. package/dist/chunks/{core-BRIIoKeS.cjs.map → core-HLqH3qkA.cjs.map} +1 -1
  14. package/dist/chunks/{spring-BziPsW3r.js → spring-BS5tg6aK.js} +2 -2
  15. package/dist/chunks/{spring-BziPsW3r.js.map → spring-BS5tg6aK.js.map} +1 -1
  16. package/dist/chunks/{spring-2OTnYCzm.cjs → spring-Dkpygsuj.cjs} +2 -2
  17. package/dist/chunks/{spring-2OTnYCzm.cjs.map → spring-Dkpygsuj.cjs.map} +1 -1
  18. package/dist/chunks/{variants-BNIrn4ch.cjs → variants-CfJzrzMh.cjs} +2 -2
  19. package/dist/chunks/{variants-BNIrn4ch.cjs.map → variants-CfJzrzMh.cjs.map} +1 -1
  20. package/dist/chunks/{variants-BVYMcxRv.js → variants-D9n-3x27.js} +2 -2
  21. package/dist/chunks/{variants-BVYMcxRv.js.map → variants-D9n-3x27.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 -5
  29. package/dist/components/angular.cjs.map +1 -1
  30. package/dist/components/angular.js +7 -5
  31. package/dist/components/angular.js.map +1 -1
  32. package/dist/components/background.cjs +2 -2
  33. package/dist/components/background.d.cts +10 -0
  34. package/dist/components/background.d.ts +10 -0
  35. package/dist/components/background.js +3 -3
  36. package/dist/components/cards.cjs +2 -2
  37. package/dist/components/cards.d.cts +10 -0
  38. package/dist/components/cards.d.ts +10 -0
  39. package/dist/components/cards.js +3 -3
  40. package/dist/components/click.cjs +2 -2
  41. package/dist/components/click.d.cts +10 -0
  42. package/dist/components/click.d.ts +10 -0
  43. package/dist/components/click.js +3 -3
  44. package/dist/components/depth.cjs +3 -3
  45. package/dist/components/depth.d.cts +10 -0
  46. package/dist/components/depth.d.ts +10 -0
  47. package/dist/components/depth.js +4 -4
  48. package/dist/components/feedback.cjs +1 -1
  49. package/dist/components/feedback.d.cts +10 -0
  50. package/dist/components/feedback.d.ts +10 -0
  51. package/dist/components/feedback.js +2 -2
  52. package/dist/components/gesture.cjs +3 -3
  53. package/dist/components/gesture.d.cts +10 -0
  54. package/dist/components/gesture.d.ts +10 -0
  55. package/dist/components/gesture.js +5 -5
  56. package/dist/components/interaction.cjs +1 -1
  57. package/dist/components/interaction.d.cts +10 -0
  58. package/dist/components/interaction.d.ts +10 -0
  59. package/dist/components/interaction.js +2 -2
  60. package/dist/components/layout.cjs +1 -1
  61. package/dist/components/layout.d.cts +10 -0
  62. package/dist/components/layout.d.ts +10 -0
  63. package/dist/components/layout.js +2 -2
  64. package/dist/components/lite.cjs +10398 -0
  65. package/dist/components/lite.cjs.map +1 -0
  66. package/dist/components/lite.d.cts +4 -0
  67. package/dist/components/lite.d.ts +4 -0
  68. package/dist/components/lite.js +10161 -0
  69. package/dist/components/lite.js.map +1 -0
  70. package/dist/components/packs.cjs +1 -1
  71. package/dist/components/packs.d.cts +10 -0
  72. package/dist/components/packs.d.ts +10 -0
  73. package/dist/components/packs.js +2 -2
  74. package/dist/components/page.cjs +6 -3
  75. package/dist/components/page.cjs.map +1 -1
  76. package/dist/components/page.d.cts +10 -0
  77. package/dist/components/page.d.ts +10 -0
  78. package/dist/components/page.js +7 -4
  79. package/dist/components/page.js.map +1 -1
  80. package/dist/components/perf.cjs +121 -0
  81. package/dist/components/perf.cjs.map +1 -0
  82. package/dist/components/perf.d.cts +97 -0
  83. package/dist/components/perf.d.ts +97 -0
  84. package/dist/components/perf.js +111 -0
  85. package/dist/components/perf.js.map +1 -0
  86. package/dist/components/physics.cjs +2 -2
  87. package/dist/components/physics.d.cts +10 -0
  88. package/dist/components/physics.d.ts +10 -0
  89. package/dist/components/physics.js +4 -4
  90. package/dist/components/reveal.cjs +1 -1
  91. package/dist/components/reveal.d.cts +10 -0
  92. package/dist/components/reveal.d.ts +10 -0
  93. package/dist/components/reveal.js +2 -2
  94. package/dist/components/solid.cjs +7 -5
  95. package/dist/components/solid.cjs.map +1 -1
  96. package/dist/components/solid.js +7 -5
  97. package/dist/components/solid.js.map +1 -1
  98. package/dist/components/svelte.cjs +7 -5
  99. package/dist/components/svelte.cjs.map +1 -1
  100. package/dist/components/svelte.js +7 -5
  101. package/dist/components/svelte.js.map +1 -1
  102. package/dist/components/svg.cjs +1 -1
  103. package/dist/components/svg.d.cts +10 -0
  104. package/dist/components/svg.d.ts +10 -0
  105. package/dist/components/svg.js +2 -2
  106. package/dist/components/text.cjs +2 -2
  107. package/dist/components/text.d.cts +10 -0
  108. package/dist/components/text.d.ts +10 -0
  109. package/dist/components/text.js +3 -3
  110. package/dist/components/timeline.cjs +2 -2
  111. package/dist/components/timeline.d.cts +10 -0
  112. package/dist/components/timeline.d.ts +10 -0
  113. package/dist/components/timeline.js +4 -4
  114. package/dist/components/transitions.cjs +1 -1
  115. package/dist/components/transitions.d.cts +10 -0
  116. package/dist/components/transitions.d.ts +10 -0
  117. package/dist/components/transitions.js +2 -2
  118. package/dist/components/ui.cjs +3 -3
  119. package/dist/components/ui.d.cts +10 -0
  120. package/dist/components/ui.d.ts +10 -0
  121. package/dist/components/ui.js +5 -5
  122. package/dist/components/vue.cjs +7 -5
  123. package/dist/components/vue.cjs.map +1 -1
  124. package/dist/components/vue.js +7 -5
  125. package/dist/components/vue.js.map +1 -1
  126. package/dist/components/webgl.cjs +1 -1
  127. package/dist/components/webgl.d.cts +10 -0
  128. package/dist/components/webgl.d.ts +10 -0
  129. package/dist/components/webgl.js +2 -2
  130. package/dist/components.cjs +32 -5
  131. package/dist/components.cjs.map +1 -1
  132. package/dist/components.d.cts +176 -2
  133. package/dist/components.d.ts +176 -2
  134. package/dist/components.js +9 -7
  135. package/dist/components.js.map +1 -1
  136. package/dist/components.umd.js +2 -2
  137. package/dist/components.umd.js.map +1 -1
  138. package/dist/index.cjs +2 -2
  139. package/dist/index.js +2 -2
  140. package/dist/index.umd.js +2 -2
  141. package/dist/index.umd.js.map +1 -1
  142. package/docs/ROADMAP.md +2 -2
  143. package/docs/accessibility.md +28 -0
  144. package/docs/performance.md +24 -0
  145. package/package.json +31 -1
  146. package/dist/chunks/base-BPG5zvex.js.map +0 -1
  147. package/dist/chunks/base-CXx7jZ-o.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var base = require('./base-CXx7jZ-o.cjs');
3
+ var base = require('./base-CxYU2NK_.cjs');
4
4
 
5
5
  const SPRING_PRESETS = {
6
6
  default: { stiffness: 170, damping: 26, mass: 1 },
@@ -229,4 +229,4 @@ exports.springEasing = springEasing;
229
229
  exports.springSamples = springSamples;
230
230
  exports.stepSpring = stepSpring;
231
231
  exports.supportsLinearEasing = supportsLinearEasing;
232
- //# sourceMappingURL=spring-2OTnYCzm.cjs.map
232
+ //# sourceMappingURL=spring-Dkpygsuj.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"spring-2OTnYCzm.cjs","sources":["../../src/components/physics/spring.ts"],"sourcesContent":["import { prefersReducedMotion, motionScale, raf, caf, now, applyFrame, EASE_SPRING } from '../base';\n\n/**\n * Spring physics core (v2.3). A damped harmonic oscillator integrated in\n * 1 ms steps: `stiffness` (k, N/m), `damping` (c) and `mass` (m). Used by\n * the `<usa-spring>`, `<usa-draggable>` and `<usa-overscroll>` elements and\n * exported for your own animations:\n *\n * - `springEasing()` turns a spring into a CSS `linear()` easing + duration\n * for WAAPI / CSS (falls back to a cubic-bezier overshoot where `linear()`\n * is unsupported);\n * - `spring(el, keyframes, cfg)` animates with it;\n * - `createSpring()` is an interruptible, velocity-preserving value for\n * gestures (drag, inertia, snap).\n */\nexport interface SpringConfig {\n /** Spring stiffness (default 170). Higher = faster, snappier. */\n stiffness?: number;\n /** Damping / friction (default 26). Lower = more bounces. */\n damping?: number;\n /** Mass (default 1). Higher = slower, heavier. */\n mass?: number;\n /** Initial velocity in progress units per second (default 0). */\n velocity?: number;\n /** Rest threshold (default 0.001). */\n precision?: number;\n}\n\nexport type SpringPreset = 'default' | 'gentle' | 'wobbly' | 'stiff' | 'bouncy' | 'slow' | 'molasses';\n\nexport const SPRING_PRESETS: Record<SpringPreset, Required<Pick<SpringConfig, 'stiffness' | 'damping' | 'mass'>>> = {\n default: { stiffness: 170, damping: 26, mass: 1 },\n gentle: { stiffness: 120, damping: 14, mass: 1 },\n wobbly: { stiffness: 180, damping: 12, mass: 1 },\n stiff: { stiffness: 210, damping: 20, mass: 1 },\n bouncy: { stiffness: 300, damping: 10, mass: 1 },\n slow: { stiffness: 280, damping: 60, mass: 1 },\n molasses: { stiffness: 280, damping: 120, mass: 1 },\n};\n\nexport type SpringInput = SpringPreset | SpringConfig | string | undefined;\n\n/** Resolve a preset name or a partial config to a full config. */\nexport function resolveSpring(input?: SpringInput): Required<SpringConfig> {\n const base = typeof input === 'string' ? SPRING_PRESETS[input as SpringPreset] || SPRING_PRESETS.default : { ...SPRING_PRESETS.default, ...(input || {}) };\n const pos = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : d);\n const o = (typeof input === 'object' && input) || {};\n return {\n stiffness: pos(base.stiffness, 170),\n damping: Math.max(0, Number.isFinite(base.damping) ? base.damping : 26),\n mass: pos(base.mass, 1),\n velocity: Number.isFinite(o.velocity) ? (o.velocity as number) : 0,\n precision: pos(o.precision, 0.001),\n };\n}\n\n/** One integration step (semi-implicit Euler) towards `to`. Returns [x, v]. */\nexport function stepSpring(cfg: Required<SpringConfig>, x: number, v: number, to: number, dt: number): [number, number] {\n const a = (-cfg.stiffness * (x - to) - cfg.damping * v) / cfg.mass;\n const nv = v + a * dt;\n return [x + nv * dt, nv];\n}\n\nconst cache = new Map<string, { values: number[]; duration: number }>();\n\n/**\n * Sample the spring from 0 to 1 at `fps` (default 60). `values` may exceed 1\n * (overshoot); `duration` is the time to rest, in ms (max 10 s).\n */\nexport function springSamples(input?: SpringInput, fps = 60): { values: number[]; duration: number } {\n const cfg = resolveSpring(input);\n const key = `${cfg.stiffness}|${cfg.damping}|${cfg.mass}|${cfg.velocity}|${cfg.precision}|${fps}`;\n const hit = cache.get(key);\n if (hit) return hit;\n const values = [0];\n let x = 0;\n let v = cfg.velocity;\n const frame = 1000 / fps;\n let t = 0;\n let next = frame;\n while (t < 10000) {\n [x, v] = stepSpring(cfg, x, v, 1, 0.001);\n t += 1;\n if (t >= next) {\n values.push(x);\n next += frame;\n if (Math.abs(1 - x) < cfg.precision && Math.abs(v) < cfg.precision * 10) break;\n }\n }\n values[values.length - 1] = 1;\n const out = { values, duration: Math.round(t) };\n if (cache.size > 64) cache.clear();\n cache.set(key, out);\n return out;\n}\n\n/** `true` when CSS `linear()` easing is supported. */\nexport function supportsLinearEasing(): boolean {\n return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('animation-timing-function', 'linear(0, 1)');\n}\n\n/**\n * The spring as `{ easing, duration }` for `el.animate()` / CSS. `easing` is\n * a `linear(…)` function with at most `points` stops (default 48), or a\n * cubic-bezier overshoot where `linear()` is unsupported.\n */\nexport function springEasing(input?: SpringInput, points = 48): { easing: string; duration: number } {\n const { values, duration } = springSamples(input);\n if (!supportsLinearEasing()) return { easing: EASE_SPRING, duration: Math.min(duration, 1200) };\n return { easing: linearEasing(values, points), duration };\n}\n\n/** Build a CSS `linear()` easing from samples (down-sampled to `points`). */\nexport function linearEasing(values: number[], points = 48): string {\n const n = values.length;\n const step = Math.max(1, Math.ceil((n - 1) / Math.max(2, points - 1)));\n const out: string[] = [];\n for (let i = 0; i < n - 1; i += step) out.push(String(Math.round(values[i] * 1000) / 1000));\n out.push('1');\n return `linear(${out.join(', ')})`;\n}\n\n/**\n * Animate `el` between keyframes with spring timing (WAAPI). Under reduced\n * motion the final frame is applied immediately. Returns the Animation (or\n * `null` without WAAPI / under reduced motion).\n */\nexport function spring(el: Element, keyframes: Keyframe[], input?: SpringInput, options: KeyframeAnimationOptions = {}): Animation | null {\n const target = el as HTMLElement;\n if (prefersReducedMotion() || typeof target.animate !== 'function') {\n applyFrame(target, keyframes[keyframes.length - 1]);\n return null;\n }\n const { easing, duration } = springEasing(input);\n return target.animate(keyframes, { duration: duration * motionScale(), easing, fill: 'both', ...options });\n}\n\n/* ------------------------------------------------------------------ */\n/* Interactive springs */\n/* ------------------------------------------------------------------ */\n\nexport interface SpringValueOptions {\n /** Start value (default 0). */\n value?: number;\n /** Spring config or preset (default `'default'`). */\n spring?: SpringInput;\n /** Called with the value every frame (and on `jump()`). */\n onUpdate?: (value: number, velocity: number) => void;\n /** Called when the value comes to rest at its target. */\n onRest?: (value: number) => void;\n}\n\nexport interface SpringValue {\n readonly value: number;\n /** Units per second. */\n readonly velocity: number;\n readonly target: number;\n readonly animating: boolean;\n /** Animate to `target`, optionally with a new initial velocity (units/s). */\n set(target: number, velocity?: number): void;\n /** Jump to `value` with no animation. */\n jump(value: number): void;\n /** Stop where it is. */\n stop(): void;\n /** Change the spring config. */\n configure(spring: SpringInput): void;\n}\n\n/**\n * An interruptible spring-animated number: call `set()` as often as you like,\n * the motion keeps its velocity (like iOS / Framer springs). Reduced motion\n * jumps straight to the target.\n */\nexport function createSpring(opts: SpringValueOptions = {}): SpringValue {\n let cfg = resolveSpring(opts.spring);\n let x = opts.value ?? 0;\n let v = 0;\n let to = x;\n let id = 0;\n let last = 0;\n let running = false;\n const stop = () => {\n if (running) caf(id);\n running = false;\n };\n const loop = () => {\n const t = now();\n let dt = Math.min(64, Math.max(1, t - last));\n last = t;\n while (dt > 0) {\n const s = Math.min(dt, 4);\n [x, v] = stepSpring(cfg, x, v, to, s / 1000);\n dt -= s;\n }\n const scale = Math.max(1, Math.abs(to) * 0.0005);\n if (Math.abs(to - x) < cfg.precision * scale * 10 && Math.abs(v) < cfg.precision * scale * 100) {\n x = to;\n v = 0;\n running = false;\n opts.onUpdate?.(x, 0);\n opts.onRest?.(x);\n return;\n }\n opts.onUpdate?.(x, v);\n id = raf(loop);\n };\n const api: SpringValue = {\n get value() {\n return x;\n },\n get velocity() {\n return v;\n },\n get target() {\n return to;\n },\n get animating() {\n return running;\n },\n set(target, velocity) {\n to = target;\n if (velocity !== undefined && Number.isFinite(velocity)) v = velocity;\n if (prefersReducedMotion()) {\n api.jump(target);\n opts.onRest?.(target);\n return;\n }\n if (!running) {\n running = true;\n last = now();\n id = raf(loop);\n }\n },\n jump(value) {\n stop();\n x = to = value;\n v = 0;\n opts.onUpdate?.(x, 0);\n },\n stop() {\n stop();\n v = 0;\n to = x;\n },\n configure(input) {\n cfg = resolveSpring(input);\n },\n };\n return api;\n}\n\n/* ------------------------------------------------------------------ */\n/* Inertia + snapping */\n/* ------------------------------------------------------------------ */\n\n/**\n * Where a flick at `velocity` (units/s) comes to rest with exponential\n * decay: `value + velocity · timeConstant` (default 0.325 s, iOS-like).\n */\nexport function projectInertia(value: number, velocity: number, timeConstant = 0.325): number {\n return value + velocity * timeConstant;\n}\n\n/** Snap to a grid (`number`) or the nearest of a list of points. */\nexport function snapTo(value: number, to: number | number[] | null | undefined): number {\n if (Array.isArray(to)) {\n if (!to.length) return value;\n return to.reduce((best, p) => (Math.abs(p - value) < Math.abs(best - value) ? p : best), to[0]);\n }\n if (typeof to === 'number' && to > 0) return Math.round(value / to) * to;\n return value;\n}\n\n/** iOS-style rubber-band resistance: how far content moves when pulled `distance` past an edge. */\nexport function rubberBand(distance: number, dimension: number, constant = 0.55): number {\n if (dimension <= 0) return 0;\n const sign = distance < 0 ? -1 : 1;\n const d = Math.abs(distance);\n return sign * (1 - 1 / ((d * constant) / dimension + 1)) * dimension;\n}\n"],"names":["EASE_SPRING","prefersReducedMotion","applyFrame","motionScale","caf","now","raf"],"mappings":"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"}
1
+ {"version":3,"file":"spring-Dkpygsuj.cjs","sources":["../../src/components/physics/spring.ts"],"sourcesContent":["import { prefersReducedMotion, motionScale, raf, caf, now, applyFrame, EASE_SPRING } from '../base';\n\n/**\n * Spring physics core (v2.3). A damped harmonic oscillator integrated in\n * 1 ms steps: `stiffness` (k, N/m), `damping` (c) and `mass` (m). Used by\n * the `<usa-spring>`, `<usa-draggable>` and `<usa-overscroll>` elements and\n * exported for your own animations:\n *\n * - `springEasing()` turns a spring into a CSS `linear()` easing + duration\n * for WAAPI / CSS (falls back to a cubic-bezier overshoot where `linear()`\n * is unsupported);\n * - `spring(el, keyframes, cfg)` animates with it;\n * - `createSpring()` is an interruptible, velocity-preserving value for\n * gestures (drag, inertia, snap).\n */\nexport interface SpringConfig {\n /** Spring stiffness (default 170). Higher = faster, snappier. */\n stiffness?: number;\n /** Damping / friction (default 26). Lower = more bounces. */\n damping?: number;\n /** Mass (default 1). Higher = slower, heavier. */\n mass?: number;\n /** Initial velocity in progress units per second (default 0). */\n velocity?: number;\n /** Rest threshold (default 0.001). */\n precision?: number;\n}\n\nexport type SpringPreset = 'default' | 'gentle' | 'wobbly' | 'stiff' | 'bouncy' | 'slow' | 'molasses';\n\nexport const SPRING_PRESETS: Record<SpringPreset, Required<Pick<SpringConfig, 'stiffness' | 'damping' | 'mass'>>> = {\n default: { stiffness: 170, damping: 26, mass: 1 },\n gentle: { stiffness: 120, damping: 14, mass: 1 },\n wobbly: { stiffness: 180, damping: 12, mass: 1 },\n stiff: { stiffness: 210, damping: 20, mass: 1 },\n bouncy: { stiffness: 300, damping: 10, mass: 1 },\n slow: { stiffness: 280, damping: 60, mass: 1 },\n molasses: { stiffness: 280, damping: 120, mass: 1 },\n};\n\nexport type SpringInput = SpringPreset | SpringConfig | string | undefined;\n\n/** Resolve a preset name or a partial config to a full config. */\nexport function resolveSpring(input?: SpringInput): Required<SpringConfig> {\n const base = typeof input === 'string' ? SPRING_PRESETS[input as SpringPreset] || SPRING_PRESETS.default : { ...SPRING_PRESETS.default, ...(input || {}) };\n const pos = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : d);\n const o = (typeof input === 'object' && input) || {};\n return {\n stiffness: pos(base.stiffness, 170),\n damping: Math.max(0, Number.isFinite(base.damping) ? base.damping : 26),\n mass: pos(base.mass, 1),\n velocity: Number.isFinite(o.velocity) ? (o.velocity as number) : 0,\n precision: pos(o.precision, 0.001),\n };\n}\n\n/** One integration step (semi-implicit Euler) towards `to`. Returns [x, v]. */\nexport function stepSpring(cfg: Required<SpringConfig>, x: number, v: number, to: number, dt: number): [number, number] {\n const a = (-cfg.stiffness * (x - to) - cfg.damping * v) / cfg.mass;\n const nv = v + a * dt;\n return [x + nv * dt, nv];\n}\n\nconst cache = new Map<string, { values: number[]; duration: number }>();\n\n/**\n * Sample the spring from 0 to 1 at `fps` (default 60). `values` may exceed 1\n * (overshoot); `duration` is the time to rest, in ms (max 10 s).\n */\nexport function springSamples(input?: SpringInput, fps = 60): { values: number[]; duration: number } {\n const cfg = resolveSpring(input);\n const key = `${cfg.stiffness}|${cfg.damping}|${cfg.mass}|${cfg.velocity}|${cfg.precision}|${fps}`;\n const hit = cache.get(key);\n if (hit) return hit;\n const values = [0];\n let x = 0;\n let v = cfg.velocity;\n const frame = 1000 / fps;\n let t = 0;\n let next = frame;\n while (t < 10000) {\n [x, v] = stepSpring(cfg, x, v, 1, 0.001);\n t += 1;\n if (t >= next) {\n values.push(x);\n next += frame;\n if (Math.abs(1 - x) < cfg.precision && Math.abs(v) < cfg.precision * 10) break;\n }\n }\n values[values.length - 1] = 1;\n const out = { values, duration: Math.round(t) };\n if (cache.size > 64) cache.clear();\n cache.set(key, out);\n return out;\n}\n\n/** `true` when CSS `linear()` easing is supported. */\nexport function supportsLinearEasing(): boolean {\n return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('animation-timing-function', 'linear(0, 1)');\n}\n\n/**\n * The spring as `{ easing, duration }` for `el.animate()` / CSS. `easing` is\n * a `linear(…)` function with at most `points` stops (default 48), or a\n * cubic-bezier overshoot where `linear()` is unsupported.\n */\nexport function springEasing(input?: SpringInput, points = 48): { easing: string; duration: number } {\n const { values, duration } = springSamples(input);\n if (!supportsLinearEasing()) return { easing: EASE_SPRING, duration: Math.min(duration, 1200) };\n return { easing: linearEasing(values, points), duration };\n}\n\n/** Build a CSS `linear()` easing from samples (down-sampled to `points`). */\nexport function linearEasing(values: number[], points = 48): string {\n const n = values.length;\n const step = Math.max(1, Math.ceil((n - 1) / Math.max(2, points - 1)));\n const out: string[] = [];\n for (let i = 0; i < n - 1; i += step) out.push(String(Math.round(values[i] * 1000) / 1000));\n out.push('1');\n return `linear(${out.join(', ')})`;\n}\n\n/**\n * Animate `el` between keyframes with spring timing (WAAPI). Under reduced\n * motion the final frame is applied immediately. Returns the Animation (or\n * `null` without WAAPI / under reduced motion).\n */\nexport function spring(el: Element, keyframes: Keyframe[], input?: SpringInput, options: KeyframeAnimationOptions = {}): Animation | null {\n const target = el as HTMLElement;\n if (prefersReducedMotion() || typeof target.animate !== 'function') {\n applyFrame(target, keyframes[keyframes.length - 1]);\n return null;\n }\n const { easing, duration } = springEasing(input);\n return target.animate(keyframes, { duration: duration * motionScale(), easing, fill: 'both', ...options });\n}\n\n/* ------------------------------------------------------------------ */\n/* Interactive springs */\n/* ------------------------------------------------------------------ */\n\nexport interface SpringValueOptions {\n /** Start value (default 0). */\n value?: number;\n /** Spring config or preset (default `'default'`). */\n spring?: SpringInput;\n /** Called with the value every frame (and on `jump()`). */\n onUpdate?: (value: number, velocity: number) => void;\n /** Called when the value comes to rest at its target. */\n onRest?: (value: number) => void;\n}\n\nexport interface SpringValue {\n readonly value: number;\n /** Units per second. */\n readonly velocity: number;\n readonly target: number;\n readonly animating: boolean;\n /** Animate to `target`, optionally with a new initial velocity (units/s). */\n set(target: number, velocity?: number): void;\n /** Jump to `value` with no animation. */\n jump(value: number): void;\n /** Stop where it is. */\n stop(): void;\n /** Change the spring config. */\n configure(spring: SpringInput): void;\n}\n\n/**\n * An interruptible spring-animated number: call `set()` as often as you like,\n * the motion keeps its velocity (like iOS / Framer springs). Reduced motion\n * jumps straight to the target.\n */\nexport function createSpring(opts: SpringValueOptions = {}): SpringValue {\n let cfg = resolveSpring(opts.spring);\n let x = opts.value ?? 0;\n let v = 0;\n let to = x;\n let id = 0;\n let last = 0;\n let running = false;\n const stop = () => {\n if (running) caf(id);\n running = false;\n };\n const loop = () => {\n const t = now();\n let dt = Math.min(64, Math.max(1, t - last));\n last = t;\n while (dt > 0) {\n const s = Math.min(dt, 4);\n [x, v] = stepSpring(cfg, x, v, to, s / 1000);\n dt -= s;\n }\n const scale = Math.max(1, Math.abs(to) * 0.0005);\n if (Math.abs(to - x) < cfg.precision * scale * 10 && Math.abs(v) < cfg.precision * scale * 100) {\n x = to;\n v = 0;\n running = false;\n opts.onUpdate?.(x, 0);\n opts.onRest?.(x);\n return;\n }\n opts.onUpdate?.(x, v);\n id = raf(loop);\n };\n const api: SpringValue = {\n get value() {\n return x;\n },\n get velocity() {\n return v;\n },\n get target() {\n return to;\n },\n get animating() {\n return running;\n },\n set(target, velocity) {\n to = target;\n if (velocity !== undefined && Number.isFinite(velocity)) v = velocity;\n if (prefersReducedMotion()) {\n api.jump(target);\n opts.onRest?.(target);\n return;\n }\n if (!running) {\n running = true;\n last = now();\n id = raf(loop);\n }\n },\n jump(value) {\n stop();\n x = to = value;\n v = 0;\n opts.onUpdate?.(x, 0);\n },\n stop() {\n stop();\n v = 0;\n to = x;\n },\n configure(input) {\n cfg = resolveSpring(input);\n },\n };\n return api;\n}\n\n/* ------------------------------------------------------------------ */\n/* Inertia + snapping */\n/* ------------------------------------------------------------------ */\n\n/**\n * Where a flick at `velocity` (units/s) comes to rest with exponential\n * decay: `value + velocity · timeConstant` (default 0.325 s, iOS-like).\n */\nexport function projectInertia(value: number, velocity: number, timeConstant = 0.325): number {\n return value + velocity * timeConstant;\n}\n\n/** Snap to a grid (`number`) or the nearest of a list of points. */\nexport function snapTo(value: number, to: number | number[] | null | undefined): number {\n if (Array.isArray(to)) {\n if (!to.length) return value;\n return to.reduce((best, p) => (Math.abs(p - value) < Math.abs(best - value) ? p : best), to[0]);\n }\n if (typeof to === 'number' && to > 0) return Math.round(value / to) * to;\n return value;\n}\n\n/** iOS-style rubber-band resistance: how far content moves when pulled `distance` past an edge. */\nexport function rubberBand(distance: number, dimension: number, constant = 0.55): number {\n if (dimension <= 0) return 0;\n const sign = distance < 0 ? -1 : 1;\n const d = Math.abs(distance);\n return sign * (1 - 1 / ((d * constant) / dimension + 1)) * dimension;\n}\n"],"names":["EASE_SPRING","prefersReducedMotion","applyFrame","motionScale","caf","now","raf"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var base = require('./base-CXx7jZ-o.cjs');
3
+ var base = require('./base-CxYU2NK_.cjs');
4
4
 
5
5
  var css = ":root{--usa-accent:#7c5cff;--usa-accent-text:#fff;--usa-surface:#1b1e27;--usa-text:inherit;--usa-radius:14px;--usa-border:1px solid rgb(127 127 127 / 0.25);--usa-shadow:0 10px 30px -12px rgb(0 0 0 / 0.45);--usa-blur:0px;--usa-font:inherit}:where([variant=\"minimal\"],[data-usa-variant=\"minimal\"]){--usa-accent:currentColor;--usa-accent-text:Canvas;--usa-surface:transparent;--usa-radius:6px;--usa-border:1px solid color-mix(in srgb,currentColor 22%,transparent);--usa-shadow:none;--usa-blur:0px}:where([variant=\"neon\"],[data-usa-variant=\"neon\"]){--usa-accent:#00f0ff;--usa-accent-text:#04121a;--usa-surface:#0a0b14;--usa-text:#e6fbff;--usa-radius:10px;--usa-border:1px solid #00f0ff;--usa-shadow:0 0 6px #00f0ff,0 0 22px rgb(0 240 255 / 0.45);--usa-blur:0px}:where([variant=\"glass\"],[data-usa-variant=\"glass\"]){--usa-accent:#a78bfa;--usa-accent-text:#fff;--usa-surface:rgb(255 255 255 / 0.12);--usa-radius:18px;--usa-border:1px solid rgb(255 255 255 / 0.28);--usa-shadow:0 12px 40px -12px rgb(0 0 0 / 0.35);--usa-blur:16px}:where([variant=\"brutalist\"],[data-usa-variant=\"brutalist\"]){--usa-accent:#ff3d00;--usa-accent-text:#000;--usa-surface:#fff;--usa-text:#000;--usa-radius:0px;--usa-border:3px solid #000;--usa-shadow:5px 5px 0 #000;--usa-blur:0px;--usa-font:ui-monospace,\"SFMono-Regular\",Menlo,monospace}:where([variant=\"fluent\"],[data-usa-variant=\"fluent\"]){--usa-accent:#0067c0;--usa-accent-text:#fff;--usa-surface:rgb(249 249 249 / 0.82);--usa-text:#1a1a1a;--usa-radius:8px;--usa-border:1px solid rgb(0 0 0 / 0.08);--usa-shadow:0 2px 4px rgb(0 0 0 / 0.14),0 0 2px rgb(0 0 0 / 0.12);--usa-blur:30px;--usa-font:\"Segoe UI Variable\",\"Segoe UI\",system-ui,sans-serif}:where([variant=\"material\"],[data-usa-variant=\"material\"]){--usa-accent:#6750a4;--usa-accent-text:#fff;--usa-surface:#fffbfe;--usa-text:#1c1b1f;--usa-radius:20px;--usa-border:0 solid transparent;--usa-shadow:0 1px 3px rgb(0 0 0 / 0.3),0 4px 8px 3px rgb(0 0 0 / 0.15);--usa-blur:0px;--usa-font:Roboto,system-ui,sans-serif}@media (prefers-color-scheme:dark){:where([variant=\"fluent\"],[data-usa-variant=\"fluent\"]){--usa-accent:#4cc2ff;--usa-accent-text:#000;--usa-surface:rgb(44 44 44 / 0.8);--usa-text:#fff;--usa-border:1px solid rgb(255 255 255 / 0.08)}:where([variant=\"material\"],[data-usa-variant=\"material\"]){--usa-accent:#d0bcff;--usa-accent-text:#381e72;--usa-surface:#1c1b1f;--usa-text:#e6e1e5}}.usa-surface{background:var(--usa-surface);color:var(--usa-text);border:var(--usa-border);border-radius:var(--usa-radius);box-shadow:var(--usa-shadow);font-family:var(--usa-font);-webkit-backdrop-filter:blur(var(--usa-blur));backdrop-filter:blur(var(--usa-blur))}@media (prefers-reduced-transparency:reduce){.usa-surface{-webkit-backdrop-filter:none;backdrop-filter:none}}";
6
6
 
@@ -36,4 +36,4 @@ function setVariant(variant, root = typeof document !== 'undefined' ? document.d
36
36
  exports.VARIANTS = VARIANTS;
37
37
  exports.adoptVariants = adoptVariants;
38
38
  exports.setVariant = setVariant;
39
- //# sourceMappingURL=variants-BNIrn4ch.cjs.map
39
+ //# sourceMappingURL=variants-CfJzrzMh.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"variants-BNIrn4ch.cjs","sources":["../../src/components/ui/variants.ts"],"sourcesContent":["import { adoptStyles } from '../base';\nimport css from './variants.css?raw';\n\n/**\n * Style variants (v2.6): `variant=\"minimal | neon | glass | brutalist |\n * fluent | material\"` on any `<usa-*>` element — or on any ancestor as\n * `data-usa-variant`, or page-wide with `setVariant()` — sets the shared\n * design tokens every component reads:\n *\n * `--usa-accent`, `--usa-accent-text`, `--usa-surface`, `--usa-text`,\n * `--usa-radius`, `--usa-border`, `--usa-shadow`, `--usa-blur`, `--usa-font`.\n *\n * (`<usa-spinner>`, `<usa-check>` and `<usa-dialog>` already use `variant`\n * for their kind; the token names never clash with those values except\n * `fluent`, which means the same thing there.)\n */\nexport const VARIANTS = ['minimal', 'neon', 'glass', 'brutalist', 'fluent', 'material'] as const;\nexport type Variant = (typeof VARIANTS)[number];\n\n/** Inject the variant token sheet (done automatically by every `ui` component). */\nexport function adoptVariants(): void {\n adoptStyles('variants', css);\n}\n\n/** Apply a variant to the whole page (or `root`); `null` removes it. */\nexport function setVariant(variant: Variant | null, root: Element | null = typeof document !== 'undefined' ? document.documentElement : null): void {\n if (!root) return;\n adoptVariants();\n if (variant) root.setAttribute('data-usa-variant', variant);\n else root.removeAttribute('data-usa-variant');\n}\n"],"names":["adoptStyles"],"mappings":";;;;;;AAGA;;;;;;;;;;;;AAYG;AACI,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU;AAGtF;SACgB,aAAa,GAAA;AAC3B,IAAAA,gBAAW,CAAC,UAAU,EAAE,GAAG,CAAC;AAC9B;AAEA;SACgB,UAAU,CAAC,OAAuB,EAAE,IAAA,GAAuB,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,eAAe,GAAG,IAAI,EAAA;AAC1I,IAAA,IAAI,CAAC,IAAI;QAAE;AACX,IAAA,aAAa,EAAE;AACf,IAAA,IAAI,OAAO;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC;;AACtD,QAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;AAC/C;;;;;;"}
1
+ {"version":3,"file":"variants-CfJzrzMh.cjs","sources":["../../src/components/ui/variants.ts"],"sourcesContent":["import { adoptStyles } from '../base';\nimport css from './variants.css?raw';\n\n/**\n * Style variants (v2.6): `variant=\"minimal | neon | glass | brutalist |\n * fluent | material\"` on any `<usa-*>` element — or on any ancestor as\n * `data-usa-variant`, or page-wide with `setVariant()` — sets the shared\n * design tokens every component reads:\n *\n * `--usa-accent`, `--usa-accent-text`, `--usa-surface`, `--usa-text`,\n * `--usa-radius`, `--usa-border`, `--usa-shadow`, `--usa-blur`, `--usa-font`.\n *\n * (`<usa-spinner>`, `<usa-check>` and `<usa-dialog>` already use `variant`\n * for their kind; the token names never clash with those values except\n * `fluent`, which means the same thing there.)\n */\nexport const VARIANTS = ['minimal', 'neon', 'glass', 'brutalist', 'fluent', 'material'] as const;\nexport type Variant = (typeof VARIANTS)[number];\n\n/** Inject the variant token sheet (done automatically by every `ui` component). */\nexport function adoptVariants(): void {\n adoptStyles('variants', css);\n}\n\n/** Apply a variant to the whole page (or `root`); `null` removes it. */\nexport function setVariant(variant: Variant | null, root: Element | null = typeof document !== 'undefined' ? document.documentElement : null): void {\n if (!root) return;\n adoptVariants();\n if (variant) root.setAttribute('data-usa-variant', variant);\n else root.removeAttribute('data-usa-variant');\n}\n"],"names":["adoptStyles"],"mappings":";;;;;;AAGA;;;;;;;;;;;;AAYG;AACI,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU;AAGtF;SACgB,aAAa,GAAA;AAC3B,IAAAA,gBAAW,CAAC,UAAU,EAAE,GAAG,CAAC;AAC9B;AAEA;SACgB,UAAU,CAAC,OAAuB,EAAE,IAAA,GAAuB,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,eAAe,GAAG,IAAI,EAAA;AAC1I,IAAA,IAAI,CAAC,IAAI;QAAE;AACX,IAAA,aAAa,EAAE;AACf,IAAA,IAAI,OAAO;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC;;AACtD,QAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;AAC/C;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { f as adoptStyles } from './base-BPG5zvex.js';
1
+ import { q as adoptStyles } from './base-CZiIAMBc.js';
2
2
 
3
3
  var css = ":root{--usa-accent:#7c5cff;--usa-accent-text:#fff;--usa-surface:#1b1e27;--usa-text:inherit;--usa-radius:14px;--usa-border:1px solid rgb(127 127 127 / 0.25);--usa-shadow:0 10px 30px -12px rgb(0 0 0 / 0.45);--usa-blur:0px;--usa-font:inherit}:where([variant=\"minimal\"],[data-usa-variant=\"minimal\"]){--usa-accent:currentColor;--usa-accent-text:Canvas;--usa-surface:transparent;--usa-radius:6px;--usa-border:1px solid color-mix(in srgb,currentColor 22%,transparent);--usa-shadow:none;--usa-blur:0px}:where([variant=\"neon\"],[data-usa-variant=\"neon\"]){--usa-accent:#00f0ff;--usa-accent-text:#04121a;--usa-surface:#0a0b14;--usa-text:#e6fbff;--usa-radius:10px;--usa-border:1px solid #00f0ff;--usa-shadow:0 0 6px #00f0ff,0 0 22px rgb(0 240 255 / 0.45);--usa-blur:0px}:where([variant=\"glass\"],[data-usa-variant=\"glass\"]){--usa-accent:#a78bfa;--usa-accent-text:#fff;--usa-surface:rgb(255 255 255 / 0.12);--usa-radius:18px;--usa-border:1px solid rgb(255 255 255 / 0.28);--usa-shadow:0 12px 40px -12px rgb(0 0 0 / 0.35);--usa-blur:16px}:where([variant=\"brutalist\"],[data-usa-variant=\"brutalist\"]){--usa-accent:#ff3d00;--usa-accent-text:#000;--usa-surface:#fff;--usa-text:#000;--usa-radius:0px;--usa-border:3px solid #000;--usa-shadow:5px 5px 0 #000;--usa-blur:0px;--usa-font:ui-monospace,\"SFMono-Regular\",Menlo,monospace}:where([variant=\"fluent\"],[data-usa-variant=\"fluent\"]){--usa-accent:#0067c0;--usa-accent-text:#fff;--usa-surface:rgb(249 249 249 / 0.82);--usa-text:#1a1a1a;--usa-radius:8px;--usa-border:1px solid rgb(0 0 0 / 0.08);--usa-shadow:0 2px 4px rgb(0 0 0 / 0.14),0 0 2px rgb(0 0 0 / 0.12);--usa-blur:30px;--usa-font:\"Segoe UI Variable\",\"Segoe UI\",system-ui,sans-serif}:where([variant=\"material\"],[data-usa-variant=\"material\"]){--usa-accent:#6750a4;--usa-accent-text:#fff;--usa-surface:#fffbfe;--usa-text:#1c1b1f;--usa-radius:20px;--usa-border:0 solid transparent;--usa-shadow:0 1px 3px rgb(0 0 0 / 0.3),0 4px 8px 3px rgb(0 0 0 / 0.15);--usa-blur:0px;--usa-font:Roboto,system-ui,sans-serif}@media (prefers-color-scheme:dark){:where([variant=\"fluent\"],[data-usa-variant=\"fluent\"]){--usa-accent:#4cc2ff;--usa-accent-text:#000;--usa-surface:rgb(44 44 44 / 0.8);--usa-text:#fff;--usa-border:1px solid rgb(255 255 255 / 0.08)}:where([variant=\"material\"],[data-usa-variant=\"material\"]){--usa-accent:#d0bcff;--usa-accent-text:#381e72;--usa-surface:#1c1b1f;--usa-text:#e6e1e5}}.usa-surface{background:var(--usa-surface);color:var(--usa-text);border:var(--usa-border);border-radius:var(--usa-radius);box-shadow:var(--usa-shadow);font-family:var(--usa-font);-webkit-backdrop-filter:blur(var(--usa-blur));backdrop-filter:blur(var(--usa-blur))}@media (prefers-reduced-transparency:reduce){.usa-surface{-webkit-backdrop-filter:none;backdrop-filter:none}}";
4
4
 
@@ -32,4 +32,4 @@ function setVariant(variant, root = typeof document !== 'undefined' ? document.d
32
32
  }
33
33
 
34
34
  export { VARIANTS as V, adoptVariants as a, setVariant as s };
35
- //# sourceMappingURL=variants-BVYMcxRv.js.map
35
+ //# sourceMappingURL=variants-D9n-3x27.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"variants-BVYMcxRv.js","sources":["../../src/components/ui/variants.ts"],"sourcesContent":["import { adoptStyles } from '../base';\nimport css from './variants.css?raw';\n\n/**\n * Style variants (v2.6): `variant=\"minimal | neon | glass | brutalist |\n * fluent | material\"` on any `<usa-*>` element — or on any ancestor as\n * `data-usa-variant`, or page-wide with `setVariant()` — sets the shared\n * design tokens every component reads:\n *\n * `--usa-accent`, `--usa-accent-text`, `--usa-surface`, `--usa-text`,\n * `--usa-radius`, `--usa-border`, `--usa-shadow`, `--usa-blur`, `--usa-font`.\n *\n * (`<usa-spinner>`, `<usa-check>` and `<usa-dialog>` already use `variant`\n * for their kind; the token names never clash with those values except\n * `fluent`, which means the same thing there.)\n */\nexport const VARIANTS = ['minimal', 'neon', 'glass', 'brutalist', 'fluent', 'material'] as const;\nexport type Variant = (typeof VARIANTS)[number];\n\n/** Inject the variant token sheet (done automatically by every `ui` component). */\nexport function adoptVariants(): void {\n adoptStyles('variants', css);\n}\n\n/** Apply a variant to the whole page (or `root`); `null` removes it. */\nexport function setVariant(variant: Variant | null, root: Element | null = typeof document !== 'undefined' ? document.documentElement : null): void {\n if (!root) return;\n adoptVariants();\n if (variant) root.setAttribute('data-usa-variant', variant);\n else root.removeAttribute('data-usa-variant');\n}\n"],"names":[],"mappings":";;;;AAGA;;;;;;;;;;;;AAYG;AACI,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU;AAGtF;SACgB,aAAa,GAAA;AAC3B,IAAA,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC;AAC9B;AAEA;SACgB,UAAU,CAAC,OAAuB,EAAE,IAAA,GAAuB,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,eAAe,GAAG,IAAI,EAAA;AAC1I,IAAA,IAAI,CAAC,IAAI;QAAE;AACX,IAAA,aAAa,EAAE;AACf,IAAA,IAAI,OAAO;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC;;AACtD,QAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;AAC/C;;;;"}
1
+ {"version":3,"file":"variants-D9n-3x27.js","sources":["../../src/components/ui/variants.ts"],"sourcesContent":["import { adoptStyles } from '../base';\nimport css from './variants.css?raw';\n\n/**\n * Style variants (v2.6): `variant=\"minimal | neon | glass | brutalist |\n * fluent | material\"` on any `<usa-*>` element — or on any ancestor as\n * `data-usa-variant`, or page-wide with `setVariant()` — sets the shared\n * design tokens every component reads:\n *\n * `--usa-accent`, `--usa-accent-text`, `--usa-surface`, `--usa-text`,\n * `--usa-radius`, `--usa-border`, `--usa-shadow`, `--usa-blur`, `--usa-font`.\n *\n * (`<usa-spinner>`, `<usa-check>` and `<usa-dialog>` already use `variant`\n * for their kind; the token names never clash with those values except\n * `fluent`, which means the same thing there.)\n */\nexport const VARIANTS = ['minimal', 'neon', 'glass', 'brutalist', 'fluent', 'material'] as const;\nexport type Variant = (typeof VARIANTS)[number];\n\n/** Inject the variant token sheet (done automatically by every `ui` component). */\nexport function adoptVariants(): void {\n adoptStyles('variants', css);\n}\n\n/** Apply a variant to the whole page (or `root`); `null` removes it. */\nexport function setVariant(variant: Variant | null, root: Element | null = typeof document !== 'undefined' ? document.documentElement : null): void {\n if (!root) return;\n adoptVariants();\n if (variant) root.setAttribute('data-usa-variant', variant);\n else root.removeAttribute('data-usa-variant');\n}\n"],"names":[],"mappings":";;;;AAGA;;;;;;;;;;;;AAYG;AACI,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU;AAGtF;SACgB,aAAa,GAAA;AAC3B,IAAA,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC;AAC9B;AAEA;SACgB,UAAU,CAAC,OAAuB,EAAE,IAAA,GAAuB,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,eAAe,GAAG,IAAI,EAAA;AAC1I,IAAA,IAAI,CAAC,IAAI;QAAE;AACX,IAAA,aAAa,EAAE;AACf,IAAA,IAAI,OAAO;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC;;AACtD,QAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;AAC/C;;;;"}
@@ -0,0 +1,239 @@
1
+ 'use strict';
2
+
3
+ var base = require('../chunks/base-CxYU2NK_.cjs');
4
+ var indexTags = require('../chunks/index-tags-BQh_uGqH.cjs');
5
+
6
+ /**
7
+ * use-scroll-animate/components/a11y — accessibility toolkit (4.4).
8
+ *
9
+ * - Motion-sensitivity levels: `setMotionSensitivity('full' | 'gentle' | 'minimal' | 'static')`.
10
+ * - Static alternatives: what every component shows when motion is off, and
11
+ * `staticAlternative(root)` to freeze any subtree at its final state.
12
+ * - `aria-live` conventions: one shared polite and one assertive region,
13
+ * `announce(message, { politeness })`.
14
+ * - `auditMotionA11y(root)`: the rules the automated regression tests run
15
+ * over every `<usa-*>` element — usable in your own tests too.
16
+ *
17
+ * ```ts
18
+ * import { setMotionSensitivity, announce, auditMotionA11y } from 'use-scroll-animate/components/a11y';
19
+ * setMotionSensitivity('gentle', true); // no spins / zooms / parallax, remembered
20
+ * announce('3 items added to cart'); // polite live region
21
+ * expect(auditMotionA11y(document.body).errors).toEqual([]);
22
+ * ```
23
+ */
24
+ const KEY = 'usa:sensitivity';
25
+ /** What each level allows, for docs and settings UIs. */
26
+ const MOTION_SENSITIVITY = {
27
+ full: { en: 'All motion', zh: '全部动效', allows: ['fade', 'translate', 'scale', 'rotate', 'parallax', 'loop', 'flash'] },
28
+ gentle: { en: 'Gentle — no spins, zooms or parallax', zh: '温和 —— 无旋转、缩放与视差', allows: ['fade', 'translate', 'loop'] },
29
+ minimal: { en: 'Minimal — fades only', zh: '最少 —— 仅淡入淡出', allows: ['fade'] },
30
+ static: { en: 'Static — no animation', zh: '静态 —— 无动画', allows: [] },
31
+ };
32
+ /** CSS applied at the `static` / `minimal` / `gentle` levels (also stops your own CSS animations under `static`). */
33
+ 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}' +
34
+ '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}' +
35
+ 'html[data-usa-sensitivity="gentle"]{--usa-parallax:0;--usa-tilt:0}';
36
+ /**
37
+ * Set the motion-sensitivity level for every `<usa-*>` component and the page:
38
+ * sets `data-usa-sensitivity` on `<html>`, adapts component keyframes, and
39
+ * with `persist` remembers the choice (`restoreMotionSensitivity()`).
40
+ * Dispatches `usa:sensitivity` on `document`.
41
+ */
42
+ function setMotionSensitivity(level, persist = false) {
43
+ if (!base.MOTION_SENSITIVITY_LEVELS.includes(level))
44
+ return;
45
+ base.configureComponents({ motionSensitivity: level });
46
+ base.adoptStyles('a11y-sensitivity', SENSITIVITY_CSS);
47
+ if (persist) {
48
+ try {
49
+ localStorage.setItem(KEY, level);
50
+ }
51
+ catch {
52
+ /* private mode */
53
+ }
54
+ }
55
+ if (level === 'static' && typeof document !== 'undefined')
56
+ staticAlternative(document.documentElement);
57
+ if (typeof document !== 'undefined')
58
+ document.dispatchEvent(new CustomEvent('usa:sensitivity', { detail: { level } }));
59
+ }
60
+ /** Re-apply a persisted level (call early on page load). Returns the active level. */
61
+ function restoreMotionSensitivity() {
62
+ try {
63
+ const v = localStorage.getItem(KEY);
64
+ if (v && base.MOTION_SENSITIVITY_LEVELS.includes(v))
65
+ setMotionSensitivity(v);
66
+ }
67
+ catch {
68
+ /* ignore */
69
+ }
70
+ return base.getMotionSensitivity();
71
+ }
72
+ /** `true` when the current level allows a kind of motion (`'rotate'`, `'parallax'`, `'loop'`…). */
73
+ function motionAllowed(kind, level = base.getMotionSensitivity()) {
74
+ return MOTION_SENSITIVITY[level].allows.includes(kind);
75
+ }
76
+ /** The static alternative of each category: what its elements show without motion. */
77
+ const STATIC_ALTERNATIVES = {
78
+ reveal: 'Content visible in place; progress bars show the current value.',
79
+ text: 'Full final text (screen readers always get a plain copy).',
80
+ interaction: 'Normal hover / focus styles; no tilt, magnet or ripple.',
81
+ feedback: 'Spinners become a static busy indicator; progress shows its value; toasts appear without sliding.',
82
+ background: 'A still frame of the background (gradient / pattern); particles and marquees stop.',
83
+ transitions: 'Dialogs, accordions and views switch instantly.',
84
+ physics: 'Values jump to their target; drag still works, without inertia.',
85
+ cards: 'Cards are shown flat and fully readable; stacks become lists.',
86
+ click: 'Clicks work and states are announced; no bursts, confetti or deformation.',
87
+ ui: 'Tabs, drawers, sheets and popovers open instantly with focus management intact.',
88
+ page: 'Page transitions are instant; cursors and ambient layers are hidden.',
89
+ timeline: 'Every step is shown at its final state.',
90
+ gesture: 'Buttons / keys provide the same actions as swipes and pinches.',
91
+ svg: 'Drawings and icons are shown complete.',
92
+ webgl: 'A static poster image or CSS gradient instead of the shader.',
93
+ depth: 'Flat, front-facing layout.',
94
+ layout: 'Items reflow instantly.',
95
+ packs: 'Roles are styled but not animated.',
96
+ };
97
+ /**
98
+ * Freeze a subtree at its static alternative: finishes running animations
99
+ * (`finish()`, so content lands on its final state), marks the root with
100
+ * `data-usa-static` and returns an undo that removes the mark.
101
+ */
102
+ function staticAlternative(root) {
103
+ const getAll = root.getAnimations;
104
+ if (typeof getAll === 'function') {
105
+ for (const a of getAll.call(root, { subtree: true })) {
106
+ try {
107
+ const it = a.effect?.getComputedTiming().iterations;
108
+ if (it === Infinity)
109
+ a.cancel();
110
+ else
111
+ a.finish();
112
+ }
113
+ catch {
114
+ /* finished already */
115
+ }
116
+ }
117
+ }
118
+ root.setAttribute('data-usa-static', '');
119
+ return () => root.removeAttribute('data-usa-static');
120
+ }
121
+ /** The ids of the shared live regions. */
122
+ const LIVE_REGION_IDS = { polite: 'usa-live-polite', assertive: 'usa-live-assertive' };
123
+ /** The shared live region (created once, visually hidden, `role="status"` / `role="alert"`). */
124
+ function liveRegion(politeness = 'polite') {
125
+ if (typeof document === 'undefined' || !document.body)
126
+ return null;
127
+ const id = LIVE_REGION_IDS[politeness];
128
+ let el = document.getElementById(id);
129
+ if (!el) {
130
+ el = document.createElement('div');
131
+ el.id = id;
132
+ el.className = 'usa-sr';
133
+ el.setAttribute('role', politeness === 'assertive' ? 'alert' : 'status');
134
+ el.setAttribute('aria-live', politeness);
135
+ el.setAttribute('aria-atomic', 'true');
136
+ document.body.appendChild(el);
137
+ }
138
+ return el;
139
+ }
140
+ let lastMsg = '';
141
+ let lastAt = 0;
142
+ /**
143
+ * Announce a message through the shared live region. Conventions: `polite`
144
+ * for results of the user's own actions (added, saved, copied), `assertive`
145
+ * only for errors that block them. Identical messages within `dedupe` ms
146
+ * (default 500) are dropped; the region is cleared first so repeats are read.
147
+ */
148
+ function announce(message, options = {}) {
149
+ const { politeness = 'polite', dedupe = 500 } = options;
150
+ const t = Date.now();
151
+ if (!message || (message === lastMsg && t - lastAt < dedupe))
152
+ return false;
153
+ lastMsg = message;
154
+ lastAt = t;
155
+ const el = liveRegion(politeness);
156
+ if (!el)
157
+ return false;
158
+ el.textContent = '';
159
+ el.textContent = message;
160
+ return true;
161
+ }
162
+ const FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
163
+ const NAMED_ROLES = ['button', 'switch', 'checkbox', 'slider', 'tab', 'progressbar', 'radiogroup', 'dialog'];
164
+ function accessibleName(el) {
165
+ const label = el.getAttribute('aria-label');
166
+ if (label)
167
+ return label;
168
+ const by = el.getAttribute('aria-labelledby');
169
+ if (by)
170
+ return by.split(/\s+/).map((id) => el.ownerDocument.getElementById(id)?.textContent || '').join(' ').trim();
171
+ return (el.textContent || el.getAttribute('title') || '').trim();
172
+ }
173
+ /**
174
+ * Check a subtree against the library's motion-a11y rules:
175
+ * - `aria-hidden-focusable` (error): focusable content inside `aria-hidden`.
176
+ * - `role-name` (error): a widget role without an accessible name.
177
+ * - `range-value` (error): a slider / determinate progressbar without `aria-valuenow`.
178
+ * - `img-alt` (error): an `<img>` without `alt`.
179
+ * - `assertive-live` (warning): `aria-live="assertive"` outside `role="alert"`.
180
+ * - `infinite-no-control` (warning, WCAG 2.2.2): an endless animation on a
181
+ * page with no way to pause motion (`<usa-motion-switch>` or `[data-usa-pause]`).
182
+ */
183
+ function auditMotionA11y(root) {
184
+ const issues = [];
185
+ const add = (rule, level, element, message) => issues.push({ rule, level, element, message });
186
+ const scope = root;
187
+ scope.querySelectorAll('[aria-hidden="true"]').forEach((h) => {
188
+ const f = (h.matches(FOCUSABLE) ? [h] : Array.from(h.querySelectorAll(FOCUSABLE))).filter((x) => !x.closest('[inert]'));
189
+ f.forEach((x) => add('aria-hidden-focusable', 'error', x, `focusable <${x.tagName.toLowerCase()}> inside aria-hidden`));
190
+ });
191
+ scope.querySelectorAll('[role]').forEach((el) => {
192
+ const role = el.getAttribute('role');
193
+ if (NAMED_ROLES.includes(role) && !accessibleName(el))
194
+ add('role-name', 'error', el, `role="${role}" has no accessible name`);
195
+ if (role === 'slider' && !el.hasAttribute('aria-valuenow'))
196
+ add('range-value', 'error', el, 'slider without aria-valuenow');
197
+ });
198
+ scope.querySelectorAll('img:not([alt])').forEach((el) => add('img-alt', 'error', el, '<img> without alt'));
199
+ scope.querySelectorAll('[aria-live="assertive"]').forEach((el) => {
200
+ if (el.getAttribute('role') !== 'alert')
201
+ add('assertive-live', 'warning', el, 'assertive live region outside role="alert"');
202
+ });
203
+ const doc = root.ownerDocument || root;
204
+ const anims = typeof root.getAnimations === 'function' ? root.getAnimations({ subtree: true }) : [];
205
+ const control = doc && (doc.querySelector('usa-motion-switch, [data-usa-pause]') || doc.documentElement.hasAttribute('data-usa-sensitivity'));
206
+ if (!control)
207
+ anims.forEach((a) => {
208
+ try {
209
+ if (a.effect?.getComputedTiming().iterations === Infinity) {
210
+ const t = a.effect.target;
211
+ if (t)
212
+ add('infinite-no-control', 'warning', t, 'endless animation and no motion control on the page');
213
+ }
214
+ }
215
+ catch {
216
+ /* ignore */
217
+ }
218
+ });
219
+ return { errors: issues.filter((i) => i.level === 'error'), warnings: issues.filter((i) => i.level === 'warning') };
220
+ }
221
+ /** Every `<usa-*>` tag, for sweeping audits. */
222
+ const ALL_TAGS = Object.values(indexTags.COMPONENT_CATEGORIES).flat();
223
+
224
+ exports.MOTION_SENSITIVITY_LEVELS = base.MOTION_SENSITIVITY_LEVELS;
225
+ exports.adaptKeyframes = base.adaptKeyframes;
226
+ exports.getMotionSensitivity = base.getMotionSensitivity;
227
+ exports.ALL_TAGS = ALL_TAGS;
228
+ exports.LIVE_REGION_IDS = LIVE_REGION_IDS;
229
+ exports.MOTION_SENSITIVITY = MOTION_SENSITIVITY;
230
+ exports.SENSITIVITY_CSS = SENSITIVITY_CSS;
231
+ exports.STATIC_ALTERNATIVES = STATIC_ALTERNATIVES;
232
+ exports.announce = announce;
233
+ exports.auditMotionA11y = auditMotionA11y;
234
+ exports.liveRegion = liveRegion;
235
+ exports.motionAllowed = motionAllowed;
236
+ exports.restoreMotionSensitivity = restoreMotionSensitivity;
237
+ exports.setMotionSensitivity = setMotionSensitivity;
238
+ exports.staticAlternative = staticAlternative;
239
+ //# sourceMappingURL=a11y.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y.cjs","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":["MOTION_SENSITIVITY_LEVELS","configureComponents","adoptStyles","getMotionSensitivity","COMPONENT_CATEGORIES"],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ declare const MOTION_SENSITIVITY_LEVELS: readonly MotionSensitivity[];
3
+ /** The current motion-sensitivity level (v4.4). */
4
+ declare function getMotionSensitivity(): MotionSensitivity;
5
+ /**
6
+ * Adapt keyframes to the sensitivity level: `gentle` drops transforms that
7
+ * spin, zoom or skew (and 3D), `minimal` keeps opacity only, `static` keeps
8
+ * just the final frame. `full` returns them unchanged.
9
+ */
10
+ declare function adaptKeyframes(frames: Keyframe[], level?: MotionSensitivity): Keyframe[];
11
+
12
+ /** The component categories and their default tags. */
13
+ declare const COMPONENT_CATEGORIES: {
14
+ readonly reveal: readonly ["usa-reveal", "usa-stagger", "usa-scroll-progress", "usa-scrolly"];
15
+ readonly text: readonly ["usa-typewriter", "usa-split-text", "usa-scramble", "usa-counter", "usa-shimmer-text", "usa-text-rotate", "usa-wave-text", "usa-glitch", "usa-gradient-text", "usa-handwriting", "usa-scroll-highlight"];
16
+ readonly interaction: readonly ["usa-ripple", "usa-magnetic", "usa-tilt", "usa-spotlight", "usa-press", "usa-toggle"];
17
+ readonly feedback: readonly ["usa-spinner", "usa-skeleton", "usa-progress", "usa-toaster", "usa-check"];
18
+ readonly background: readonly ["usa-aurora", "usa-particles", "usa-grain", "usa-marquee", "usa-acrylic", "usa-grid-glow", "usa-blobs", "usa-water-ripple", "usa-dot-network"];
19
+ readonly transitions: readonly ["usa-dialog", "usa-accordion", "usa-view-switch"];
20
+ readonly physics: readonly ["usa-spring", "usa-draggable", "usa-overscroll"];
21
+ readonly cards: readonly ["usa-card", "usa-card-stack", "usa-sticky-stack", "usa-carousel-3d"];
22
+ readonly click: readonly ["usa-click", "usa-button", "usa-icon-morph", "usa-like", "usa-hold", "usa-double-tap", "usa-checkbox"];
23
+ readonly ui: readonly ["usa-tabs", "usa-drawer", "usa-bottom-sheet", "usa-pull-refresh", "usa-fab", "usa-navbar", "usa-slider", "usa-rating", "usa-tooltip", "usa-popover", "usa-badge", "usa-avatar-stack"];
24
+ readonly page: readonly ["usa-cursor", "usa-fullpage", "usa-loading-bar", "usa-back-to-top", "usa-ambient", "usa-splash", "usa-auto-skeleton", "usa-motion-switch"];
25
+ readonly timeline: readonly ["usa-timeline"];
26
+ readonly gesture: readonly ["usa-swipeable", "usa-pinch-zoom"];
27
+ readonly svg: readonly ["usa-draw", "usa-morph", "usa-mask-reveal", "usa-anim-icon"];
28
+ readonly webgl: readonly ["usa-shader", "usa-distort", "usa-liquid"];
29
+ readonly depth: readonly ["usa-cube", "usa-depth"];
30
+ readonly layout: readonly ["usa-auto-animate", "usa-masonry"];
31
+ readonly packs: readonly ["usa-pack"];
32
+ };
33
+ type ComponentCategory = keyof typeof COMPONENT_CATEGORIES;
34
+
35
+ /**
36
+ * use-scroll-animate/components/a11y — accessibility toolkit (4.4).
37
+ *
38
+ * - Motion-sensitivity levels: `setMotionSensitivity('full' | 'gentle' | 'minimal' | 'static')`.
39
+ * - Static alternatives: what every component shows when motion is off, and
40
+ * `staticAlternative(root)` to freeze any subtree at its final state.
41
+ * - `aria-live` conventions: one shared polite and one assertive region,
42
+ * `announce(message, { politeness })`.
43
+ * - `auditMotionA11y(root)`: the rules the automated regression tests run
44
+ * over every `<usa-*>` element — usable in your own tests too.
45
+ *
46
+ * ```ts
47
+ * import { setMotionSensitivity, announce, auditMotionA11y } from 'use-scroll-animate/components/a11y';
48
+ * setMotionSensitivity('gentle', true); // no spins / zooms / parallax, remembered
49
+ * announce('3 items added to cart'); // polite live region
50
+ * expect(auditMotionA11y(document.body).errors).toEqual([]);
51
+ * ```
52
+ */
53
+
54
+ /** What each level allows, for docs and settings UIs. */
55
+ declare const MOTION_SENSITIVITY: Record<MotionSensitivity, {
56
+ en: string;
57
+ zh: string;
58
+ allows: string[];
59
+ }>;
60
+ /** CSS applied at the `static` / `minimal` / `gentle` levels (also stops your own CSS animations under `static`). */
61
+ declare const SENSITIVITY_CSS: string;
62
+ /**
63
+ * Set the motion-sensitivity level for every `<usa-*>` component and the page:
64
+ * sets `data-usa-sensitivity` on `<html>`, adapts component keyframes, and
65
+ * with `persist` remembers the choice (`restoreMotionSensitivity()`).
66
+ * Dispatches `usa:sensitivity` on `document`.
67
+ */
68
+ declare function setMotionSensitivity(level: MotionSensitivity, persist?: boolean): void;
69
+ /** Re-apply a persisted level (call early on page load). Returns the active level. */
70
+ declare function restoreMotionSensitivity(): MotionSensitivity;
71
+ /** `true` when the current level allows a kind of motion (`'rotate'`, `'parallax'`, `'loop'`…). */
72
+ declare function motionAllowed(kind: string, level?: MotionSensitivity): boolean;
73
+ /** The static alternative of each category: what its elements show without motion. */
74
+ declare const STATIC_ALTERNATIVES: Record<ComponentCategory, string>;
75
+ /**
76
+ * Freeze a subtree at its static alternative: finishes running animations
77
+ * (`finish()`, so content lands on its final state), marks the root with
78
+ * `data-usa-static` and returns an undo that removes the mark.
79
+ */
80
+ declare function staticAlternative(root: Element): () => void;
81
+ type Politeness = 'polite' | 'assertive';
82
+ /** The ids of the shared live regions. */
83
+ declare const LIVE_REGION_IDS: Record<Politeness, string>;
84
+ /** The shared live region (created once, visually hidden, `role="status"` / `role="alert"`). */
85
+ declare function liveRegion(politeness?: Politeness): HTMLElement | null;
86
+ /**
87
+ * Announce a message through the shared live region. Conventions: `polite`
88
+ * for results of the user's own actions (added, saved, copied), `assertive`
89
+ * only for errors that block them. Identical messages within `dedupe` ms
90
+ * (default 500) are dropped; the region is cleared first so repeats are read.
91
+ */
92
+ declare function announce(message: string, options?: {
93
+ politeness?: Politeness;
94
+ dedupe?: number;
95
+ }): boolean;
96
+ interface A11yIssue {
97
+ rule: string;
98
+ level: 'error' | 'warning';
99
+ element: Element;
100
+ message: string;
101
+ }
102
+ /**
103
+ * Check a subtree against the library's motion-a11y rules:
104
+ * - `aria-hidden-focusable` (error): focusable content inside `aria-hidden`.
105
+ * - `role-name` (error): a widget role without an accessible name.
106
+ * - `range-value` (error): a slider / determinate progressbar without `aria-valuenow`.
107
+ * - `img-alt` (error): an `<img>` without `alt`.
108
+ * - `assertive-live` (warning): `aria-live="assertive"` outside `role="alert"`.
109
+ * - `infinite-no-control` (warning, WCAG 2.2.2): an endless animation on a
110
+ * page with no way to pause motion (`<usa-motion-switch>` or `[data-usa-pause]`).
111
+ */
112
+ declare function auditMotionA11y(root: Element | Document): {
113
+ errors: A11yIssue[];
114
+ warnings: A11yIssue[];
115
+ };
116
+ /** Every `<usa-*>` tag, for sweeping audits. */
117
+ declare const ALL_TAGS: string[];
118
+
119
+ export { ALL_TAGS, LIVE_REGION_IDS, MOTION_SENSITIVITY, MOTION_SENSITIVITY_LEVELS, SENSITIVITY_CSS, STATIC_ALTERNATIVES, adaptKeyframes, announce, auditMotionA11y, getMotionSensitivity, liveRegion, motionAllowed, restoreMotionSensitivity, setMotionSensitivity, staticAlternative };
120
+ export type { A11yIssue, MotionSensitivity, Politeness };