use-scroll-animate 4.0.1 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/chunks/{base-ZARFccur.js → base-BPG5zvex.js} +2 -2
  3. package/dist/chunks/{base-ZARFccur.js.map → base-BPG5zvex.js.map} +1 -1
  4. package/dist/chunks/{core-DXqZm5Il.cjs → core-BRIIoKeS.cjs} +55 -12
  5. package/dist/chunks/core-BRIIoKeS.cjs.map +1 -0
  6. package/dist/chunks/{core-Co-6AL0h.js → core-LkGRmgES.js} +56 -14
  7. package/dist/chunks/core-LkGRmgES.js.map +1 -0
  8. package/dist/chunks/{core-DKY-fVzR.js → core-eXX8rB_b.js} +2 -2
  9. package/dist/chunks/{core-DKY-fVzR.js.map → core-eXX8rB_b.js.map} +1 -1
  10. package/dist/chunks/{spring-E2ickYNI.js → spring-BziPsW3r.js} +2 -2
  11. package/dist/chunks/{spring-E2ickYNI.js.map → spring-BziPsW3r.js.map} +1 -1
  12. package/dist/chunks/{variants-DvnxvRCM.js → variants-BVYMcxRv.js} +2 -2
  13. package/dist/chunks/{variants-DvnxvRCM.js.map → variants-BVYMcxRv.js.map} +1 -1
  14. package/dist/components/angular.cjs +2 -1
  15. package/dist/components/angular.cjs.map +1 -1
  16. package/dist/components/angular.d.cts +32 -8
  17. package/dist/components/angular.d.ts +32 -8
  18. package/dist/components/angular.js +6 -5
  19. package/dist/components/angular.js.map +1 -1
  20. package/dist/components/background.js +3 -3
  21. package/dist/components/cards.js +3 -3
  22. package/dist/components/click.js +3 -3
  23. package/dist/components/depth.js +4 -4
  24. package/dist/components/feedback.js +2 -2
  25. package/dist/components/gesture.js +5 -5
  26. package/dist/components/interaction.js +2 -2
  27. package/dist/components/layout.js +2 -2
  28. package/dist/components/packs.js +2 -2
  29. package/dist/components/page.js +3 -3
  30. package/dist/components/physics.js +4 -4
  31. package/dist/components/reveal.js +2 -2
  32. package/dist/components/solid.cjs +2 -1
  33. package/dist/components/solid.cjs.map +1 -1
  34. package/dist/components/solid.d.cts +32 -8
  35. package/dist/components/solid.d.ts +32 -8
  36. package/dist/components/solid.js +6 -5
  37. package/dist/components/solid.js.map +1 -1
  38. package/dist/components/svelte.cjs +2 -1
  39. package/dist/components/svelte.cjs.map +1 -1
  40. package/dist/components/svelte.d.cts +32 -8
  41. package/dist/components/svelte.d.ts +32 -8
  42. package/dist/components/svelte.js +6 -5
  43. package/dist/components/svelte.js.map +1 -1
  44. package/dist/components/svg.js +2 -2
  45. package/dist/components/text.js +2 -2
  46. package/dist/components/timeline.cjs +10 -2
  47. package/dist/components/timeline.cjs.map +1 -1
  48. package/dist/components/timeline.d.cts +36 -10
  49. package/dist/components/timeline.d.ts +36 -10
  50. package/dist/components/timeline.js +12 -5
  51. package/dist/components/timeline.js.map +1 -1
  52. package/dist/components/tokens.cjs +226 -0
  53. package/dist/components/tokens.cjs.map +1 -0
  54. package/dist/components/tokens.d.cts +74 -0
  55. package/dist/components/tokens.d.ts +74 -0
  56. package/dist/components/tokens.js +211 -0
  57. package/dist/components/tokens.js.map +1 -0
  58. package/dist/components/transitions.js +2 -2
  59. package/dist/components/ui.js +5 -5
  60. package/dist/components/vue.cjs +2 -1
  61. package/dist/components/vue.cjs.map +1 -1
  62. package/dist/components/vue.d.cts +32 -8
  63. package/dist/components/vue.d.ts +32 -8
  64. package/dist/components/vue.js +6 -5
  65. package/dist/components/vue.js.map +1 -1
  66. package/dist/components/webgl.js +2 -2
  67. package/dist/components.cjs +17 -1
  68. package/dist/components.cjs.map +1 -1
  69. package/dist/components.d.cts +109 -11
  70. package/dist/components.d.ts +109 -11
  71. package/dist/components.js +8 -7
  72. package/dist/components.js.map +1 -1
  73. package/dist/components.umd.js +2 -2
  74. package/dist/components.umd.js.map +1 -1
  75. package/dist/index.cjs +3 -1
  76. package/dist/index.cjs.map +1 -1
  77. package/dist/index.d.cts +33 -9
  78. package/dist/index.d.ts +33 -9
  79. package/dist/index.js +3 -2
  80. package/dist/index.js.map +1 -1
  81. package/dist/index.umd.js +2 -2
  82. package/dist/index.umd.js.map +1 -1
  83. package/docs/API.md +3 -1
  84. package/docs/ROADMAP.md +2 -2
  85. package/docs/motion-tokens.css +31 -0
  86. package/docs/motion-tokens.md +46 -0
  87. package/docs/motion.tokens.json +132 -0
  88. package/package.json +11 -1
  89. package/dist/chunks/core-Co-6AL0h.js.map +0 -1
  90. package/dist/chunks/core-DXqZm5Il.cjs.map +0 -1
@@ -53,9 +53,9 @@ interface UsaElement extends HTMLElement {
53
53
  */
54
54
  type TimelinePosition = number | string;
55
55
  interface TimelineStepOptions {
56
- /** Duration in ms (default: timeline default, 600). */
57
- duration?: number;
58
- /** CSS easing (default `cubic-bezier(0.22, 1, 0.36, 1)`). */
56
+ /** Duration in ms or a motion token name (`'fast'`, `'slow'`…; 4.2). Default: timeline default, 600. */
57
+ duration?: number | string;
58
+ /** CSS easing or a motion token name (`'emphasized'`, `'spring'`…; 4.2). Default `cubic-bezier(0.22, 1, 0.36, 1)`. */
59
59
  easing?: string;
60
60
  /** Start position, see `TimelinePosition`. */
61
61
  at?: TimelinePosition;
@@ -73,11 +73,29 @@ interface TimelineOptions {
73
73
  onUpdate?: (progress: number) => void;
74
74
  }
75
75
  interface ScrubOptions {
76
- /** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts. */
76
+ /** Scroll offset (px) before the source's top reaches the viewport bottom where progress starts (JS engine only). */
77
77
  offset?: number;
78
- /** Smoothing 0–1 (0 = immediate, default 0). */
78
+ /** Smoothing 0–1 (0 = immediate, default 0). Smoothing needs the JS engine. */
79
79
  smooth?: number;
80
+ /**
81
+ * 4.1: which progress source drives the timeline.
82
+ * - `'view'` (default): `source` moving through the viewport (CSS `ViewTimeline`, range `cover`).
83
+ * - `'scroll'`: the scroll position of `source` itself (a scroll container; CSS `ScrollTimeline`).
84
+ */
85
+ source?: 'view' | 'scroll';
86
+ /** 4.1: `'auto'` (default) uses the browser's native scroll-driven animations when available, `'js'` forces the fallback. */
87
+ engine?: 'auto' | 'native' | 'js';
88
+ /** 4.1: scroll axis, `'block'` (default) · `'inline'` · `'x'` · `'y'`. */
89
+ axis?: 'block' | 'inline' | 'x' | 'y';
90
+ }
91
+ /** The function `scrub()` returns: call it to stop. `native` tells which engine runs it. */
92
+ interface ScrubHandle {
93
+ (): void;
94
+ /** `true` when the browser's ScrollTimeline / ViewTimeline drives it (compositor, no JS per frame). */
95
+ readonly native: boolean;
80
96
  }
97
+ /** 4.1: whether `scrub()` can use native ScrollTimeline / ViewTimeline here. */
98
+ declare function supportsNativeScrub(source?: 'view' | 'scroll'): boolean;
81
99
  interface Timeline {
82
100
  /** Total length in ms. */
83
101
  readonly duration: number;
@@ -100,8 +118,14 @@ interface Timeline {
100
118
  seek(to: TimelinePosition): Timeline;
101
119
  /** Get or set progress 0–1. */
102
120
  progress(p?: number): number;
103
- /** Tie progress to the scroll position of `source` (it moves through the viewport). Returns a stop function. */
104
- scrub(source: Element, options?: ScrubOptions): () => void;
121
+ /**
122
+ * Tie progress to scroll: `source` moving through the viewport (or, with
123
+ * `{ source: 'scroll' }`, a scroll container's own position). Runs on native
124
+ * ScrollTimeline / ViewTimeline when available (and no `smooth`, `offset`,
125
+ * `call()` cues or `onUpdate` need JS), else on a rAF-throttled listener.
126
+ * Returns a stop function with a `native` flag.
127
+ */
128
+ scrub(source: Element, options?: ScrubOptions): ScrubHandle;
105
129
  /** Stop and drop every animation (elements keep their last frame). */
106
130
  cancel(): void;
107
131
  }
@@ -133,7 +157,9 @@ declare function timeline(options?: TimelineOptions): Timeline;
133
157
  * Attributes: `trigger` (`view` default · `click` · `manual`), `scrub`
134
158
  * (progress follows scroll instead of playing), `overlap` (ms each step
135
159
  * overlaps the previous, default 0), `duration` (600), `stagger` (ms),
136
- * `repeat` (replay every time it enters the viewport). Methods: `play()`,
160
+ * `repeat` (replay every time it enters the viewport). 4.1: `scrub` runs on native
161
+ * ScrollTimeline / ViewTimeline when supported (`data-native` is set); `scrub="js"`,
162
+ * `scrub="scroll"` and `smooth` tune it. Methods: `play()`,
137
163
  * `reverse()`, `seek(t)`; property `timeline`. Event `usa:complete`.
138
164
  * Reduced motion: steps appear in their final state.
139
165
  */
@@ -160,5 +186,5 @@ declare global {
160
186
  }
161
187
  }
162
188
 
163
- export { TIMELINE_PRESETS, configureComponents, defineTimeline, defineTimelineComponents, prefersReducedMotion, resolvePosition, timeline };
164
- export type { ComponentsConfig, ScrubOptions, Timeline, TimelineOptions, TimelinePosition, TimelineStepOptions, UsaElement, UsaTimelineElement };
189
+ export { TIMELINE_PRESETS, configureComponents, defineTimeline, defineTimelineComponents, prefersReducedMotion, resolvePosition, supportsNativeScrub, timeline };
190
+ export type { ComponentsConfig, ScrubHandle, ScrubOptions, Timeline, TimelineOptions, TimelinePosition, TimelineStepOptions, UsaElement, UsaTimelineElement };
@@ -1,7 +1,8 @@
1
- import { h as defineElement } from '../chunks/base-ZARFccur.js';
2
- export { a as configureComponents, p as prefersReducedMotion } from '../chunks/base-ZARFccur.js';
3
- import { t as timeline, T as TIMELINE_PRESETS } from '../chunks/core-Co-6AL0h.js';
4
- export { r as resolvePosition } from '../chunks/core-Co-6AL0h.js';
1
+ import { h as defineElement } from '../chunks/base-BPG5zvex.js';
2
+ export { a as configureComponents, p as prefersReducedMotion } from '../chunks/base-BPG5zvex.js';
3
+ import { t as timeline, T as TIMELINE_PRESETS } from '../chunks/core-LkGRmgES.js';
4
+ export { r as resolvePosition, s as supportsNativeScrub } from '../chunks/core-LkGRmgES.js';
5
+ import './tokens.js';
5
6
 
6
7
  var css = "usa-timeline{display:block}usa-timeline[scrub]{position:relative}@media (prefers-reduced-motion:reduce){usa-timeline [data-tl]{opacity:1 !important;transform:none !important;filter:none !important;clip-path:none !important}}";
7
8
 
@@ -44,7 +45,13 @@ function defineTimeline(tag = 'usa-timeline') {
44
45
  return;
45
46
  }
46
47
  if (this.flag('scrub')) {
47
- this.onCleanup(tl.scrub(this, { smooth: 0.2 }));
48
+ // 4.1: native ScrollTimeline / ViewTimeline when available; `smooth`
49
+ // (0–0.95) or `scrub="js"` opt into the JS engine, `scrub="scroll"`
50
+ // follows this element's own scroll position.
51
+ const v = this.str('scrub');
52
+ const stop = tl.scrub(this, { smooth: this.num('smooth', 0), engine: v === 'js' ? 'js' : 'auto', source: v === 'scroll' ? 'scroll' : 'view' });
53
+ this.toggleAttribute('data-native', stop.native);
54
+ this.onCleanup(stop);
48
55
  return;
49
56
  }
50
57
  const trigger = this.str('trigger', 'view');
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.js","sources":["../../src/components/timeline/timeline-el.ts","../../src/components/timeline/index.ts"],"sourcesContent":["import { defineElement, type UsaElement } from '../base';\nimport { timeline, TIMELINE_PRESETS, type Timeline } from './core';\nimport css from './timeline.css?raw';\n\n/**\n * `<usa-timeline>` — declarative choreography. Every descendant with\n * `data-tl=\"<preset>\"` becomes a step, in document order; `data-at`\n * (`'-=200'`, `'<'`, `'label+=100'`, ms), `data-duration` and `data-label`\n * fine-tune it.\n *\n * Attributes: `trigger` (`view` default · `click` · `manual`), `scrub`\n * (progress follows scroll instead of playing), `overlap` (ms each step\n * overlaps the previous, default 0), `duration` (600), `stagger` (ms),\n * `repeat` (replay every time it enters the viewport). Methods: `play()`,\n * `reverse()`, `seek(t)`; property `timeline`. Event `usa:complete`.\n * Reduced motion: steps appear in their final state.\n */\nexport interface UsaTimelineElement extends UsaElement {\n readonly timeline: Timeline | null;\n play(): Promise<void>;\n reverse(): Promise<void>;\n seek(to: number | string): void;\n}\n\nexport function defineTimeline(tag = 'usa-timeline'): CustomElementConstructor | undefined {\n return defineElement(\n tag,\n (Base) =>\n class UsaTimeline extends Base {\n static get observedAttributes(): string[] {\n return ['scrub', 'trigger', 'overlap'];\n }\n private _tl: Timeline | null = null;\n\n get timeline(): Timeline | null {\n return this._tl;\n }\n\n play(): Promise<void> {\n return this._tl ? this._tl.play(0).then(() => void this.emit('complete')) : Promise.resolve();\n }\n\n reverse(): Promise<void> {\n return this._tl ? this._tl.reverse() : Promise.resolve();\n }\n\n seek(to: number | string): void {\n this._tl?.seek(to);\n }\n\n mount(): void {\n const overlap = this.num('overlap', 0);\n const tl = (this._tl = timeline({ defaults: { duration: this.num('duration', 600), stagger: this.num('stagger', 0) } }));\n this.querySelectorAll<HTMLElement>('[data-tl]').forEach((el, i) => {\n if (el.dataset.label) tl.label(el.dataset.label);\n const name = el.dataset.tl || 'fade';\n tl.to(el, TIMELINE_PRESETS[name] ? name : 'fade', {\n at: el.dataset.at ?? (i && overlap ? `-=${overlap}` : undefined),\n duration: el.dataset.duration ? Number(el.dataset.duration) : undefined,\n });\n });\n this.onCleanup(() => tl.cancel());\n if (this.reduced) {\n tl.seek(tl.duration);\n return;\n }\n if (this.flag('scrub')) {\n this.onCleanup(tl.scrub(this, { smooth: 0.2 }));\n return;\n }\n const trigger = this.str('trigger', 'view');\n if (trigger === 'click') {\n // 4.0.1: show the finished composition until the first click\n // (it used to sit invisible at t=0); Enter / Space replay it too.\n tl.seek(tl.duration);\n this.listen(this, 'click', () => void this.play());\n this.listen(this, 'keydown', (e: KeyboardEvent) => {\n if (e.target === this && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n void this.play();\n }\n });\n if (!this.hasAttribute('tabindex')) this.tabIndex = 0;\n return;\n }\n tl.seek(0);\n if (trigger === 'view') {\n let played = false;\n this.inView((v) => {\n if (v && (!played || this.flag('repeat'))) {\n played = true;\n void this.play();\n } else if (!v && this.flag('repeat')) tl.seek(0);\n }, { threshold: 0.2 });\n }\n }\n\n unmount(): void {\n this._tl = null;\n }\n },\n { id: 'timeline', text: css }\n );\n}\n","/**\n * use-scroll-animate/components/timeline — choreography (v3.1).\n * `timeline()` chains, overlaps, labels, seeks, reverses and scroll-scrubs\n * WAAPI animations on one playhead; `<usa-timeline>` builds one from\n * `data-tl` children.\n */\nimport { defineTimeline, type UsaTimelineElement } from './timeline-el';\n\nexport { defineTimeline };\nexport { timeline, resolvePosition, TIMELINE_PRESETS } from './core';\nexport type { Timeline, TimelineOptions, TimelineStepOptions, TimelinePosition, ScrubOptions } from './core';\nexport type { UsaTimelineElement };\nexport { configureComponents, prefersReducedMotion } from '../base';\nexport type { ComponentsConfig, UsaElement } from '../base';\n\n/** Register every component of this category under its default tag. */\nexport function defineTimelineComponents(): void {\n defineTimeline();\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'usa-timeline': UsaTimelineElement;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline.js","sources":["../../src/components/timeline/timeline-el.ts","../../src/components/timeline/index.ts"],"sourcesContent":["import { defineElement, type UsaElement } from '../base';\nimport { timeline, TIMELINE_PRESETS, type Timeline } from './core';\nimport css from './timeline.css?raw';\n\n/**\n * `<usa-timeline>` — declarative choreography. Every descendant with\n * `data-tl=\"<preset>\"` becomes a step, in document order; `data-at`\n * (`'-=200'`, `'<'`, `'label+=100'`, ms), `data-duration` and `data-label`\n * fine-tune it.\n *\n * Attributes: `trigger` (`view` default · `click` · `manual`), `scrub`\n * (progress follows scroll instead of playing), `overlap` (ms each step\n * overlaps the previous, default 0), `duration` (600), `stagger` (ms),\n * `repeat` (replay every time it enters the viewport). 4.1: `scrub` runs on native\n * ScrollTimeline / ViewTimeline when supported (`data-native` is set); `scrub=\"js\"`,\n * `scrub=\"scroll\"` and `smooth` tune it. Methods: `play()`,\n * `reverse()`, `seek(t)`; property `timeline`. Event `usa:complete`.\n * Reduced motion: steps appear in their final state.\n */\nexport interface UsaTimelineElement extends UsaElement {\n readonly timeline: Timeline | null;\n play(): Promise<void>;\n reverse(): Promise<void>;\n seek(to: number | string): void;\n}\n\nexport function defineTimeline(tag = 'usa-timeline'): CustomElementConstructor | undefined {\n return defineElement(\n tag,\n (Base) =>\n class UsaTimeline extends Base {\n static get observedAttributes(): string[] {\n return ['scrub', 'trigger', 'overlap'];\n }\n private _tl: Timeline | null = null;\n\n get timeline(): Timeline | null {\n return this._tl;\n }\n\n play(): Promise<void> {\n return this._tl ? this._tl.play(0).then(() => void this.emit('complete')) : Promise.resolve();\n }\n\n reverse(): Promise<void> {\n return this._tl ? this._tl.reverse() : Promise.resolve();\n }\n\n seek(to: number | string): void {\n this._tl?.seek(to);\n }\n\n mount(): void {\n const overlap = this.num('overlap', 0);\n const tl = (this._tl = timeline({ defaults: { duration: this.num('duration', 600), stagger: this.num('stagger', 0) } }));\n this.querySelectorAll<HTMLElement>('[data-tl]').forEach((el, i) => {\n if (el.dataset.label) tl.label(el.dataset.label);\n const name = el.dataset.tl || 'fade';\n tl.to(el, TIMELINE_PRESETS[name] ? name : 'fade', {\n at: el.dataset.at ?? (i && overlap ? `-=${overlap}` : undefined),\n duration: el.dataset.duration ? Number(el.dataset.duration) : undefined,\n });\n });\n this.onCleanup(() => tl.cancel());\n if (this.reduced) {\n tl.seek(tl.duration);\n return;\n }\n if (this.flag('scrub')) {\n // 4.1: native ScrollTimeline / ViewTimeline when available; `smooth`\n // (0–0.95) or `scrub=\"js\"` opt into the JS engine, `scrub=\"scroll\"`\n // follows this element's own scroll position.\n const v = this.str('scrub');\n const stop = tl.scrub(this, { smooth: this.num('smooth', 0), engine: v === 'js' ? 'js' : 'auto', source: v === 'scroll' ? 'scroll' : 'view' });\n this.toggleAttribute('data-native', stop.native);\n this.onCleanup(stop);\n return;\n }\n const trigger = this.str('trigger', 'view');\n if (trigger === 'click') {\n // 4.0.1: show the finished composition until the first click\n // (it used to sit invisible at t=0); Enter / Space replay it too.\n tl.seek(tl.duration);\n this.listen(this, 'click', () => void this.play());\n this.listen(this, 'keydown', (e: KeyboardEvent) => {\n if (e.target === this && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n void this.play();\n }\n });\n if (!this.hasAttribute('tabindex')) this.tabIndex = 0;\n return;\n }\n tl.seek(0);\n if (trigger === 'view') {\n let played = false;\n this.inView((v) => {\n if (v && (!played || this.flag('repeat'))) {\n played = true;\n void this.play();\n } else if (!v && this.flag('repeat')) tl.seek(0);\n }, { threshold: 0.2 });\n }\n }\n\n unmount(): void {\n this._tl = null;\n }\n },\n { id: 'timeline', text: css }\n );\n}\n","/**\n * use-scroll-animate/components/timeline — choreography (v3.1).\n * `timeline()` chains, overlaps, labels, seeks, reverses and scroll-scrubs\n * WAAPI animations on one playhead; `<usa-timeline>` builds one from\n * `data-tl` children.\n */\nimport { defineTimeline, type UsaTimelineElement } from './timeline-el';\n\nexport { defineTimeline };\nexport { timeline, resolvePosition, TIMELINE_PRESETS, supportsNativeScrub } from './core';\nexport type { Timeline, TimelineOptions, TimelineStepOptions, TimelinePosition, ScrubOptions, ScrubHandle } from './core';\nexport type { UsaTimelineElement };\nexport { configureComponents, prefersReducedMotion } from '../base';\nexport type { ComponentsConfig, UsaElement } from '../base';\n\n/** Register every component of this category under its default tag. */\nexport function defineTimelineComponents(): void {\n defineTimeline();\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'usa-timeline': UsaTimelineElement;\n }\n}\n"],"names":[],"mappings":";;;;;;;;AA0BM,SAAU,cAAc,CAAC,GAAG,GAAG,cAAc,EAAA;AACjD,IAAA,OAAO,aAAa,CAClB,GAAG,EACH,CAAC,IAAI,KACH,MAAM,WAAY,SAAQ,IAAI,CAAA;AAA9B,QAAA,WAAA,GAAA;;YAIU,IAAA,CAAA,GAAG,GAAoB,IAAI;QA0ErC;AA7EE,QAAA,WAAW,kBAAkB,GAAA;AAC3B,YAAA,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;QACxC;AAGA,QAAA,IAAI,QAAQ,GAAA;YACV,OAAO,IAAI,CAAC,GAAG;QACjB;QAEA,IAAI,GAAA;AACF,YAAA,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE;QAC/F;QAEA,OAAO,GAAA;AACL,YAAA,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE;QAC1D;AAEA,QAAA,IAAI,CAAC,EAAmB,EAAA;AACtB,YAAA,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;QACpB;QAEA,KAAK,GAAA;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;AACtC,YAAA,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxH,YAAA,IAAI,CAAC,gBAAgB,CAAc,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAI;AAChE,gBAAA,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK;oBAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;gBAChD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,MAAM;AACpC,gBAAA,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM,EAAE;oBAChD,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,OAAO,GAAG,CAAA,EAAA,EAAK,OAAO,EAAE,GAAG,SAAS,CAAC;oBAChE,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,SAAS;AACxE,iBAAA,CAAC;AACJ,YAAA,CAAC,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;AACjC,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,gBAAA,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;gBACpB;YACF;AACA,YAAA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;;;;gBAItB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAC3B,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,QAAQ,GAAG,QAAQ,GAAG,MAAM,EAAE,CAAC;gBAC9I,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC;AAChD,gBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBACpB;YACF;YACA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC;AAC3C,YAAA,IAAI,OAAO,KAAK,OAAO,EAAE;;;AAGvB,gBAAA,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;AACpB,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAgB,KAAI;oBAChD,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE;wBAC7D,CAAC,CAAC,cAAc,EAAE;AAClB,wBAAA,KAAK,IAAI,CAAC,IAAI,EAAE;oBAClB;AACF,gBAAA,CAAC,CAAC;AACF,gBAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;AAAE,oBAAA,IAAI,CAAC,QAAQ,GAAG,CAAC;gBACrD;YACF;AACA,YAAA,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACV,YAAA,IAAI,OAAO,KAAK,MAAM,EAAE;gBACtB,IAAI,MAAM,GAAG,KAAK;AAClB,gBAAA,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;AAChB,oBAAA,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;wBACzC,MAAM,GAAG,IAAI;AACb,wBAAA,KAAK,IAAI,CAAC,IAAI,EAAE;oBAClB;yBAAO,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;AAAE,wBAAA,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAClD,gBAAA,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;YACxB;QACF;QAEA,OAAO,GAAA;AACL,YAAA,IAAI,CAAC,GAAG,GAAG,IAAI;QACjB;KACD,EACH,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,CAC9B;AACH;;AC/GA;;;;;AAKG;AAUH;SACgB,wBAAwB,GAAA;AACtC,IAAA,cAAc,EAAE;AAClB;;;;"}
@@ -0,0 +1,226 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * use-scroll-animate/components/tokens — motion design tokens (4.2).
5
+ *
6
+ * One source of truth for durations, easings and springs: as CSS custom
7
+ * properties (`--usa-duration-fast`, `--usa-easing-emphasized`,
8
+ * `--usa-spring-bouncy-stiffness`…), as W3C Design Tokens JSON, and importable
9
+ * from Figma Tokens (Tokens Studio) or Style Dictionary exports.
10
+ *
11
+ * ```ts
12
+ * import { applyMotionTokens, importMotionTokens, motionToken } from 'use-scroll-animate/components/tokens';
13
+ * applyMotionTokens(importMotionTokens(await (await fetch('/tokens.json')).json()));
14
+ * el.animate(frames, { duration: motionToken('duration', 'slow'), easing: motionToken('easing', 'emphasized') });
15
+ * ```
16
+ */
17
+ /** The default motion scale (Material / Fluent-inspired). */
18
+ const MOTION_TOKENS = {
19
+ duration: { instant: 0, fast: 150, normal: 300, slow: 600, slower: 900, slowest: 1400 },
20
+ easing: {
21
+ linear: 'linear',
22
+ standard: 'cubic-bezier(0.2, 0, 0, 1)',
23
+ emphasized: 'cubic-bezier(0.22, 1, 0.36, 1)',
24
+ decelerate: 'cubic-bezier(0, 0, 0, 1)',
25
+ accelerate: 'cubic-bezier(0.3, 0, 1, 1)',
26
+ spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
27
+ bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
28
+ },
29
+ spring: {
30
+ gentle: { stiffness: 120, damping: 14, mass: 1 },
31
+ snappy: { stiffness: 300, damping: 30, mass: 1 },
32
+ bouncy: { stiffness: 260, damping: 12, mass: 1 },
33
+ wobbly: { stiffness: 180, damping: 8, mass: 1 },
34
+ stiff: { stiffness: 500, damping: 40, mass: 1 },
35
+ },
36
+ };
37
+ let active = clone(MOTION_TOKENS);
38
+ function clone(t) {
39
+ return { duration: { ...t.duration }, easing: { ...t.easing }, spring: Object.fromEntries(Object.entries(t.spring).map(([k, v]) => [k, { ...v }])) };
40
+ }
41
+ /** Merge partial tokens over a base (defaults: the built-in scale). */
42
+ function mergeMotionTokens(partial, base = MOTION_TOKENS) {
43
+ const out = clone(base);
44
+ Object.assign(out.duration, partial.duration || {});
45
+ Object.assign(out.easing, partial.easing || {});
46
+ for (const [k, v] of Object.entries(partial.spring || {}))
47
+ out.spring[k] = { ...(out.spring[k] || { stiffness: 170, damping: 26, mass: 1 }), ...v };
48
+ return out;
49
+ }
50
+ const kebab = (s) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[\s_.]+/g, '-').toLowerCase();
51
+ /** The custom-property map: `{ '--usa-duration-fast': '150ms', … }`. */
52
+ function motionTokensToVars(tokens = active, prefix = '--usa') {
53
+ const vars = {};
54
+ for (const [k, v] of Object.entries(tokens.duration))
55
+ vars[`${prefix}-duration-${kebab(k)}`] = `${v}ms`;
56
+ for (const [k, v] of Object.entries(tokens.easing))
57
+ vars[`${prefix}-easing-${kebab(k)}`] = v;
58
+ for (const [k, v] of Object.entries(tokens.spring)) {
59
+ vars[`${prefix}-spring-${kebab(k)}-stiffness`] = String(v.stiffness);
60
+ vars[`${prefix}-spring-${kebab(k)}-damping`] = String(v.damping);
61
+ vars[`${prefix}-spring-${kebab(k)}-mass`] = String(v.mass);
62
+ }
63
+ return vars;
64
+ }
65
+ /** A stylesheet string: `:root { --usa-duration-fast: 150ms; … }`. */
66
+ function motionTokensToCss(tokens = active, selector = ':root', prefix = '--usa') {
67
+ const body = Object.entries(motionTokensToVars(tokens, prefix)).map(([k, v]) => ` ${k}: ${v};`).join('\n');
68
+ return `${selector} {\n${body}\n}\n`;
69
+ }
70
+ /** W3C Design Tokens (DTCG) JSON: `{ motion: { duration: { fast: { $type: 'duration', $value: '150ms' } } } }`. */
71
+ function motionTokensToJSON(tokens = active) {
72
+ const grp = (o, f) => Object.fromEntries(Object.entries(o).map(([k, v]) => [k, f(v)]));
73
+ return {
74
+ motion: {
75
+ duration: grp(tokens.duration, (v) => ({ $type: 'duration', $value: `${v}ms` })),
76
+ easing: grp(tokens.easing, (v) => {
77
+ const m = /^cubic-bezier\(([^)]+)\)$/.exec(v);
78
+ return m ? { $type: 'cubicBezier', $value: m[1].split(',').map(Number) } : { $type: 'string', $value: v };
79
+ }),
80
+ spring: grp(tokens.spring, (v) => ({ $type: 'spring', $value: { ...v } })),
81
+ },
82
+ };
83
+ }
84
+ /** Parse `150ms`, `0.15s`, `150` → ms. */
85
+ function parseDuration(v) {
86
+ if (typeof v === 'number' && isFinite(v))
87
+ return v;
88
+ if (typeof v === 'object' && v && 'value' in v && 'unit' in v)
89
+ return parseDuration(`${v.value}${v.unit}`);
90
+ const m = /^\s*(-?\d*\.?\d+)\s*(ms|s)?\s*$/.exec(String(v ?? ''));
91
+ if (!m)
92
+ return undefined;
93
+ return m[2] === 's' ? Number(m[1]) * 1000 : Number(m[1]);
94
+ }
95
+ /** Parse `[x1,y1,x2,y2]`, `'cubic-bezier(…)'`, `'0.2, 0, 0, 1'` or a keyword → CSS easing. */
96
+ function parseEasing(v) {
97
+ if (Array.isArray(v) && v.length === 4 && v.every((n) => typeof n === 'number'))
98
+ return `cubic-bezier(${v.join(', ')})`;
99
+ if (typeof v !== 'string' || !v.trim())
100
+ return undefined;
101
+ const s = v.trim();
102
+ if (/^-?\d*\.?\d+(\s*,\s*-?\d*\.?\d+){3}$/.test(s))
103
+ return `cubic-bezier(${s.split(/\s*,\s*/).join(', ')})`;
104
+ return s;
105
+ }
106
+ const isLeaf = (o) => o && typeof o === 'object' && ('$value' in o || 'value' in o);
107
+ const leafValue = (o) => ('$value' in o ? o.$value : o.value);
108
+ const leafType = (o) => String(o.$type ?? o.type ?? '').toLowerCase();
109
+ /**
110
+ * Import tokens from W3C DTCG JSON, Figma Tokens / Tokens Studio
111
+ * (`{ value, type }`) or Style Dictionary (`{ value }`, nested) — anything
112
+ * under a `duration` / `easing` / `spring` group (any depth, e.g.
113
+ * `motion.duration.fast` or `global.animation.easing.out`), or typed leaves
114
+ * (`duration`, `cubicBezier`, `transition`, `spring`). Unknown values are
115
+ * skipped; the result is merged over the defaults.
116
+ */
117
+ function importMotionTokens(json, base = MOTION_TOKENS) {
118
+ const partial = { duration: {}, easing: {}, spring: {} };
119
+ const walk = (node, path) => {
120
+ if (!node || typeof node !== 'object')
121
+ return;
122
+ if (isLeaf(node)) {
123
+ const name = path[path.length - 1];
124
+ const type = leafType(node);
125
+ const group = path.slice(0, -1).map((p) => p.toLowerCase());
126
+ const val = leafValue(node);
127
+ const inGroup = (g) => group.some((p) => g.includes(p));
128
+ if (type === 'duration' || (!type && inGroup(['duration', 'durations'])) || (type !== 'cubicbezier' && inGroup(['duration', 'durations']))) {
129
+ const ms = parseDuration(val);
130
+ if (ms !== undefined)
131
+ partial.duration[name] = ms;
132
+ }
133
+ else if (type === 'cubicbezier' || type === 'easing' || inGroup(['easing', 'easings', 'ease'])) {
134
+ const e = parseEasing(val);
135
+ if (e)
136
+ partial.easing[name] = e;
137
+ }
138
+ else if (type === 'spring' || inGroup(['spring', 'springs'])) {
139
+ if (val && typeof val === 'object')
140
+ partial.spring[name] = { stiffness: Number(val.stiffness ?? 170), damping: Number(val.damping ?? 26), mass: Number(val.mass ?? 1) };
141
+ }
142
+ else if (type === 'transition' && val && typeof val === 'object') {
143
+ const ms = parseDuration(val.duration);
144
+ if (ms !== undefined)
145
+ partial.duration[name] = ms;
146
+ const e = parseEasing(val.timingFunction);
147
+ if (e)
148
+ partial.easing[name] = e;
149
+ }
150
+ return;
151
+ }
152
+ for (const [k, v] of Object.entries(node))
153
+ if (!k.startsWith('$'))
154
+ walk(v, [...path, k]);
155
+ };
156
+ walk(json, []);
157
+ return mergeMotionTokens(partial, base);
158
+ }
159
+ /** The tokens currently applied (via `applyMotionTokens`), or the defaults. */
160
+ function getMotionTokens() {
161
+ return clone(active);
162
+ }
163
+ /**
164
+ * Write tokens as CSS custom properties on `root` (default `<html>`) and make
165
+ * them the active set for `motionToken()`. Returns an undo function.
166
+ */
167
+ function applyMotionTokens(tokens = MOTION_TOKENS, root, prefix = '--usa') {
168
+ const prev = active;
169
+ active = mergeMotionTokens(tokens, MOTION_TOKENS);
170
+ const el = root || (typeof document !== 'undefined' ? document.documentElement : null);
171
+ const vars = motionTokensToVars(active, prefix);
172
+ const old = {};
173
+ if (el)
174
+ for (const [k, v] of Object.entries(vars))
175
+ ((old[k] = el.style.getPropertyValue(k)), el.style.setProperty(k, v));
176
+ return () => {
177
+ active = prev;
178
+ if (el)
179
+ for (const [k, v] of Object.entries(old))
180
+ v ? el.style.setProperty(k, v) : el.style.removeProperty(k);
181
+ };
182
+ }
183
+ function motionToken(group, name) {
184
+ const g = active[group];
185
+ return g[name] ?? MOTION_TOKENS[group][name];
186
+ }
187
+ /** `var(--usa-duration-fast, 150ms)` — a CSS reference with the current value as fallback. */
188
+ function motionVar(group, name, prop, prefix = '--usa') {
189
+ if (group === 'spring') {
190
+ const s = motionToken('spring', name);
191
+ const p = prop || 'stiffness';
192
+ return `var(${prefix}-spring-${kebab(name)}-${p}, ${s ? s[p] : ''})`;
193
+ }
194
+ const v = group === 'duration' ? `${motionToken('duration', name)}ms` : motionToken('easing', name);
195
+ return `var(${prefix}-${group}-${kebab(name)}, ${v})`;
196
+ }
197
+ /** Resolve a duration that may be a token name (`'fast'`) or ms. */
198
+ function resolveDurationToken(v, fallback) {
199
+ if (typeof v === 'number')
200
+ return v;
201
+ if (typeof v === 'string')
202
+ return (active.duration[v] ?? parseDuration(v)) ?? fallback;
203
+ return fallback;
204
+ }
205
+ /** Resolve an easing that may be a token name (`'emphasized'`) or CSS. */
206
+ function resolveEasingToken(v, fallback) {
207
+ if (!v)
208
+ return fallback;
209
+ return active.easing[v] ?? v;
210
+ }
211
+
212
+ exports.MOTION_TOKENS = MOTION_TOKENS;
213
+ exports.applyMotionTokens = applyMotionTokens;
214
+ exports.getMotionTokens = getMotionTokens;
215
+ exports.importMotionTokens = importMotionTokens;
216
+ exports.mergeMotionTokens = mergeMotionTokens;
217
+ exports.motionToken = motionToken;
218
+ exports.motionTokensToCss = motionTokensToCss;
219
+ exports.motionTokensToJSON = motionTokensToJSON;
220
+ exports.motionTokensToVars = motionTokensToVars;
221
+ exports.motionVar = motionVar;
222
+ exports.parseDuration = parseDuration;
223
+ exports.parseEasing = parseEasing;
224
+ exports.resolveDurationToken = resolveDurationToken;
225
+ exports.resolveEasingToken = resolveEasingToken;
226
+ //# sourceMappingURL=tokens.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.cjs","sources":["../../src/components/tokens/index.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/tokens — motion design tokens (4.2).\n *\n * One source of truth for durations, easings and springs: as CSS custom\n * properties (`--usa-duration-fast`, `--usa-easing-emphasized`,\n * `--usa-spring-bouncy-stiffness`…), as W3C Design Tokens JSON, and importable\n * from Figma Tokens (Tokens Studio) or Style Dictionary exports.\n *\n * ```ts\n * import { applyMotionTokens, importMotionTokens, motionToken } from 'use-scroll-animate/components/tokens';\n * applyMotionTokens(importMotionTokens(await (await fetch('/tokens.json')).json()));\n * el.animate(frames, { duration: motionToken('duration', 'slow'), easing: motionToken('easing', 'emphasized') });\n * ```\n */\n\nexport interface SpringToken {\n stiffness: number;\n damping: number;\n mass: number;\n}\n\nexport interface MotionTokens {\n /** Durations in ms. */\n duration: Record<string, number>;\n /** CSS easing strings. */\n easing: Record<string, string>;\n /** Spring physics parameters. */\n spring: Record<string, SpringToken>;\n}\n\n/** The default motion scale (Material / Fluent-inspired). */\nexport const MOTION_TOKENS: MotionTokens = {\n duration: { instant: 0, fast: 150, normal: 300, slow: 600, slower: 900, slowest: 1400 },\n easing: {\n linear: 'linear',\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n emphasized: 'cubic-bezier(0.22, 1, 0.36, 1)',\n decelerate: 'cubic-bezier(0, 0, 0, 1)',\n accelerate: 'cubic-bezier(0.3, 0, 1, 1)',\n spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n },\n spring: {\n gentle: { stiffness: 120, damping: 14, mass: 1 },\n snappy: { stiffness: 300, damping: 30, mass: 1 },\n bouncy: { stiffness: 260, damping: 12, mass: 1 },\n wobbly: { stiffness: 180, damping: 8, mass: 1 },\n stiff: { stiffness: 500, damping: 40, mass: 1 },\n },\n};\n\nexport type MotionTokenGroup = keyof MotionTokens;\nexport type DeepPartialTokens = { [K in keyof MotionTokens]?: Partial<MotionTokens[K]> };\n\nlet active: MotionTokens = clone(MOTION_TOKENS);\n\nfunction clone(t: MotionTokens): MotionTokens {\n return { duration: { ...t.duration }, easing: { ...t.easing }, spring: Object.fromEntries(Object.entries(t.spring).map(([k, v]) => [k, { ...v }])) };\n}\n\n/** Merge partial tokens over a base (defaults: the built-in scale). */\nexport function mergeMotionTokens(partial: DeepPartialTokens, base: MotionTokens = MOTION_TOKENS): MotionTokens {\n const out = clone(base);\n Object.assign(out.duration, partial.duration || {});\n Object.assign(out.easing, partial.easing || {});\n for (const [k, v] of Object.entries(partial.spring || {})) out.spring[k] = { ...(out.spring[k] || { stiffness: 170, damping: 26, mass: 1 }), ...v };\n return out;\n}\n\nconst kebab = (s: string) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[\\s_.]+/g, '-').toLowerCase();\n\n/** The custom-property map: `{ '--usa-duration-fast': '150ms', … }`. */\nexport function motionTokensToVars(tokens: MotionTokens = active, prefix = '--usa'): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const [k, v] of Object.entries(tokens.duration)) vars[`${prefix}-duration-${kebab(k)}`] = `${v}ms`;\n for (const [k, v] of Object.entries(tokens.easing)) vars[`${prefix}-easing-${kebab(k)}`] = v;\n for (const [k, v] of Object.entries(tokens.spring)) {\n vars[`${prefix}-spring-${kebab(k)}-stiffness`] = String(v.stiffness);\n vars[`${prefix}-spring-${kebab(k)}-damping`] = String(v.damping);\n vars[`${prefix}-spring-${kebab(k)}-mass`] = String(v.mass);\n }\n return vars;\n}\n\n/** A stylesheet string: `:root { --usa-duration-fast: 150ms; … }`. */\nexport function motionTokensToCss(tokens: MotionTokens = active, selector = ':root', prefix = '--usa'): string {\n const body = Object.entries(motionTokensToVars(tokens, prefix)).map(([k, v]) => ` ${k}: ${v};`).join('\\n');\n return `${selector} {\\n${body}\\n}\\n`;\n}\n\n/** W3C Design Tokens (DTCG) JSON: `{ motion: { duration: { fast: { $type: 'duration', $value: '150ms' } } } }`. */\nexport function motionTokensToJSON(tokens: MotionTokens = active): Record<string, unknown> {\n const grp = <T>(o: Record<string, T>, f: (v: T) => unknown) => Object.fromEntries(Object.entries(o).map(([k, v]) => [k, f(v)]));\n return {\n motion: {\n duration: grp(tokens.duration, (v) => ({ $type: 'duration', $value: `${v}ms` })),\n easing: grp(tokens.easing, (v) => {\n const m = /^cubic-bezier\\(([^)]+)\\)$/.exec(v);\n return m ? { $type: 'cubicBezier', $value: m[1].split(',').map(Number) } : { $type: 'string', $value: v };\n }),\n spring: grp(tokens.spring, (v) => ({ $type: 'spring', $value: { ...v } })),\n },\n };\n}\n\n/** Parse `150ms`, `0.15s`, `150` → ms. */\nexport function parseDuration(v: unknown): number | undefined {\n if (typeof v === 'number' && isFinite(v)) return v;\n if (typeof v === 'object' && v && 'value' in (v as any) && 'unit' in (v as any)) return parseDuration(`${(v as any).value}${(v as any).unit}`);\n const m = /^\\s*(-?\\d*\\.?\\d+)\\s*(ms|s)?\\s*$/.exec(String(v ?? ''));\n if (!m) return undefined;\n return m[2] === 's' ? Number(m[1]) * 1000 : Number(m[1]);\n}\n\n/** Parse `[x1,y1,x2,y2]`, `'cubic-bezier(…)'`, `'0.2, 0, 0, 1'` or a keyword → CSS easing. */\nexport function parseEasing(v: unknown): string | undefined {\n if (Array.isArray(v) && v.length === 4 && v.every((n) => typeof n === 'number')) return `cubic-bezier(${v.join(', ')})`;\n if (typeof v !== 'string' || !v.trim()) return undefined;\n const s = v.trim();\n if (/^-?\\d*\\.?\\d+(\\s*,\\s*-?\\d*\\.?\\d+){3}$/.test(s)) return `cubic-bezier(${s.split(/\\s*,\\s*/).join(', ')})`;\n return s;\n}\n\nconst isLeaf = (o: any) => o && typeof o === 'object' && ('$value' in o || 'value' in o);\nconst leafValue = (o: any) => ('$value' in o ? o.$value : o.value);\nconst leafType = (o: any) => String(o.$type ?? o.type ?? '').toLowerCase();\n\n/**\n * Import tokens from W3C DTCG JSON, Figma Tokens / Tokens Studio\n * (`{ value, type }`) or Style Dictionary (`{ value }`, nested) — anything\n * under a `duration` / `easing` / `spring` group (any depth, e.g.\n * `motion.duration.fast` or `global.animation.easing.out`), or typed leaves\n * (`duration`, `cubicBezier`, `transition`, `spring`). Unknown values are\n * skipped; the result is merged over the defaults.\n */\nexport function importMotionTokens(json: unknown, base: MotionTokens = MOTION_TOKENS): MotionTokens {\n const partial: Required<DeepPartialTokens> = { duration: {}, easing: {}, spring: {} };\n const walk = (node: any, path: string[]) => {\n if (!node || typeof node !== 'object') return;\n if (isLeaf(node)) {\n const name = path[path.length - 1];\n const type = leafType(node);\n const group = path.slice(0, -1).map((p) => p.toLowerCase());\n const val = leafValue(node);\n const inGroup = (g: string[]) => group.some((p) => g.includes(p));\n if (type === 'duration' || (!type && inGroup(['duration', 'durations'])) || (type !== 'cubicbezier' && inGroup(['duration', 'durations']))) {\n const ms = parseDuration(val);\n if (ms !== undefined) partial.duration[name] = ms;\n } else if (type === 'cubicbezier' || type === 'easing' || inGroup(['easing', 'easings', 'ease'])) {\n const e = parseEasing(val);\n if (e) partial.easing[name] = e;\n } else if (type === 'spring' || inGroup(['spring', 'springs'])) {\n if (val && typeof val === 'object') partial.spring[name] = { stiffness: Number(val.stiffness ?? 170), damping: Number(val.damping ?? 26), mass: Number(val.mass ?? 1) };\n } else if (type === 'transition' && val && typeof val === 'object') {\n const ms = parseDuration(val.duration);\n if (ms !== undefined) partial.duration[name] = ms;\n const e = parseEasing(val.timingFunction);\n if (e) partial.easing[name] = e;\n }\n return;\n }\n for (const [k, v] of Object.entries(node)) if (!k.startsWith('$')) walk(v, [...path, k]);\n };\n walk(json, []);\n return mergeMotionTokens(partial, base);\n}\n\n/** The tokens currently applied (via `applyMotionTokens`), or the defaults. */\nexport function getMotionTokens(): MotionTokens {\n return clone(active);\n}\n\n/**\n * Write tokens as CSS custom properties on `root` (default `<html>`) and make\n * them the active set for `motionToken()`. Returns an undo function.\n */\nexport function applyMotionTokens(tokens: DeepPartialTokens | MotionTokens = MOTION_TOKENS, root?: HTMLElement, prefix = '--usa'): () => void {\n const prev = active;\n active = mergeMotionTokens(tokens as DeepPartialTokens, MOTION_TOKENS);\n const el = root || (typeof document !== 'undefined' ? document.documentElement : null);\n const vars = motionTokensToVars(active, prefix);\n const old: Record<string, string> = {};\n if (el) for (const [k, v] of Object.entries(vars)) ((old[k] = el.style.getPropertyValue(k)), el.style.setProperty(k, v));\n return () => {\n active = prev;\n if (el) for (const [k, v] of Object.entries(old)) v ? el.style.setProperty(k, v) : el.style.removeProperty(k);\n };\n}\n\n/** Look up a token: `motionToken('duration', 'fast')` → `150`; `motionToken('easing', 'emphasized')` → CSS easing. */\nexport function motionToken(group: 'duration', name: string): number;\nexport function motionToken(group: 'easing', name: string): string;\nexport function motionToken(group: 'spring', name: string): SpringToken;\nexport function motionToken(group: MotionTokenGroup, name: string): number | string | SpringToken | undefined {\n const g = active[group] as Record<string, any>;\n return g[name] ?? (MOTION_TOKENS[group] as Record<string, any>)[name];\n}\n\n/** `var(--usa-duration-fast, 150ms)` — a CSS reference with the current value as fallback. */\nexport function motionVar(group: MotionTokenGroup, name: string, prop?: 'stiffness' | 'damping' | 'mass', prefix = '--usa'): string {\n if (group === 'spring') {\n const s = motionToken('spring', name);\n const p = prop || 'stiffness';\n return `var(${prefix}-spring-${kebab(name)}-${p}, ${s ? s[p] : ''})`;\n }\n const v = group === 'duration' ? `${motionToken('duration', name)}ms` : motionToken('easing', name);\n return `var(${prefix}-${group}-${kebab(name)}, ${v})`;\n}\n\n/** Resolve a duration that may be a token name (`'fast'`) or ms. */\nexport function resolveDurationToken(v: number | string | undefined, fallback: number): number {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') return (active.duration[v] ?? parseDuration(v)) ?? fallback;\n return fallback;\n}\n\n/** Resolve an easing that may be a token name (`'emphasized'`) or CSS. */\nexport function resolveEasingToken(v: string | undefined, fallback: string): string {\n if (!v) return fallback;\n return active.easing[v] ?? v;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * use-scroll-animate/components/tokens — motion design tokens (4.2).
3
+ *
4
+ * One source of truth for durations, easings and springs: as CSS custom
5
+ * properties (`--usa-duration-fast`, `--usa-easing-emphasized`,
6
+ * `--usa-spring-bouncy-stiffness`…), as W3C Design Tokens JSON, and importable
7
+ * from Figma Tokens (Tokens Studio) or Style Dictionary exports.
8
+ *
9
+ * ```ts
10
+ * import { applyMotionTokens, importMotionTokens, motionToken } from 'use-scroll-animate/components/tokens';
11
+ * applyMotionTokens(importMotionTokens(await (await fetch('/tokens.json')).json()));
12
+ * el.animate(frames, { duration: motionToken('duration', 'slow'), easing: motionToken('easing', 'emphasized') });
13
+ * ```
14
+ */
15
+ interface SpringToken {
16
+ stiffness: number;
17
+ damping: number;
18
+ mass: number;
19
+ }
20
+ interface MotionTokens {
21
+ /** Durations in ms. */
22
+ duration: Record<string, number>;
23
+ /** CSS easing strings. */
24
+ easing: Record<string, string>;
25
+ /** Spring physics parameters. */
26
+ spring: Record<string, SpringToken>;
27
+ }
28
+ /** The default motion scale (Material / Fluent-inspired). */
29
+ declare const MOTION_TOKENS: MotionTokens;
30
+ type MotionTokenGroup = keyof MotionTokens;
31
+ type DeepPartialTokens = {
32
+ [K in keyof MotionTokens]?: Partial<MotionTokens[K]>;
33
+ };
34
+ /** Merge partial tokens over a base (defaults: the built-in scale). */
35
+ declare function mergeMotionTokens(partial: DeepPartialTokens, base?: MotionTokens): MotionTokens;
36
+ /** The custom-property map: `{ '--usa-duration-fast': '150ms', … }`. */
37
+ declare function motionTokensToVars(tokens?: MotionTokens, prefix?: string): Record<string, string>;
38
+ /** A stylesheet string: `:root { --usa-duration-fast: 150ms; … }`. */
39
+ declare function motionTokensToCss(tokens?: MotionTokens, selector?: string, prefix?: string): string;
40
+ /** W3C Design Tokens (DTCG) JSON: `{ motion: { duration: { fast: { $type: 'duration', $value: '150ms' } } } }`. */
41
+ declare function motionTokensToJSON(tokens?: MotionTokens): Record<string, unknown>;
42
+ /** Parse `150ms`, `0.15s`, `150` → ms. */
43
+ declare function parseDuration(v: unknown): number | undefined;
44
+ /** Parse `[x1,y1,x2,y2]`, `'cubic-bezier(…)'`, `'0.2, 0, 0, 1'` or a keyword → CSS easing. */
45
+ declare function parseEasing(v: unknown): string | undefined;
46
+ /**
47
+ * Import tokens from W3C DTCG JSON, Figma Tokens / Tokens Studio
48
+ * (`{ value, type }`) or Style Dictionary (`{ value }`, nested) — anything
49
+ * under a `duration` / `easing` / `spring` group (any depth, e.g.
50
+ * `motion.duration.fast` or `global.animation.easing.out`), or typed leaves
51
+ * (`duration`, `cubicBezier`, `transition`, `spring`). Unknown values are
52
+ * skipped; the result is merged over the defaults.
53
+ */
54
+ declare function importMotionTokens(json: unknown, base?: MotionTokens): MotionTokens;
55
+ /** The tokens currently applied (via `applyMotionTokens`), or the defaults. */
56
+ declare function getMotionTokens(): MotionTokens;
57
+ /**
58
+ * Write tokens as CSS custom properties on `root` (default `<html>`) and make
59
+ * them the active set for `motionToken()`. Returns an undo function.
60
+ */
61
+ declare function applyMotionTokens(tokens?: DeepPartialTokens | MotionTokens, root?: HTMLElement, prefix?: string): () => void;
62
+ /** Look up a token: `motionToken('duration', 'fast')` → `150`; `motionToken('easing', 'emphasized')` → CSS easing. */
63
+ declare function motionToken(group: 'duration', name: string): number;
64
+ declare function motionToken(group: 'easing', name: string): string;
65
+ declare function motionToken(group: 'spring', name: string): SpringToken;
66
+ /** `var(--usa-duration-fast, 150ms)` — a CSS reference with the current value as fallback. */
67
+ declare function motionVar(group: MotionTokenGroup, name: string, prop?: 'stiffness' | 'damping' | 'mass', prefix?: string): string;
68
+ /** Resolve a duration that may be a token name (`'fast'`) or ms. */
69
+ declare function resolveDurationToken(v: number | string | undefined, fallback: number): number;
70
+ /** Resolve an easing that may be a token name (`'emphasized'`) or CSS. */
71
+ declare function resolveEasingToken(v: string | undefined, fallback: string): string;
72
+
73
+ export { MOTION_TOKENS, applyMotionTokens, getMotionTokens, importMotionTokens, mergeMotionTokens, motionToken, motionTokensToCss, motionTokensToJSON, motionTokensToVars, motionVar, parseDuration, parseEasing, resolveDurationToken, resolveEasingToken };
74
+ export type { DeepPartialTokens, MotionTokenGroup, MotionTokens, SpringToken };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * use-scroll-animate/components/tokens — motion design tokens (4.2).
3
+ *
4
+ * One source of truth for durations, easings and springs: as CSS custom
5
+ * properties (`--usa-duration-fast`, `--usa-easing-emphasized`,
6
+ * `--usa-spring-bouncy-stiffness`…), as W3C Design Tokens JSON, and importable
7
+ * from Figma Tokens (Tokens Studio) or Style Dictionary exports.
8
+ *
9
+ * ```ts
10
+ * import { applyMotionTokens, importMotionTokens, motionToken } from 'use-scroll-animate/components/tokens';
11
+ * applyMotionTokens(importMotionTokens(await (await fetch('/tokens.json')).json()));
12
+ * el.animate(frames, { duration: motionToken('duration', 'slow'), easing: motionToken('easing', 'emphasized') });
13
+ * ```
14
+ */
15
+ interface SpringToken {
16
+ stiffness: number;
17
+ damping: number;
18
+ mass: number;
19
+ }
20
+ interface MotionTokens {
21
+ /** Durations in ms. */
22
+ duration: Record<string, number>;
23
+ /** CSS easing strings. */
24
+ easing: Record<string, string>;
25
+ /** Spring physics parameters. */
26
+ spring: Record<string, SpringToken>;
27
+ }
28
+ /** The default motion scale (Material / Fluent-inspired). */
29
+ declare const MOTION_TOKENS: MotionTokens;
30
+ type MotionTokenGroup = keyof MotionTokens;
31
+ type DeepPartialTokens = {
32
+ [K in keyof MotionTokens]?: Partial<MotionTokens[K]>;
33
+ };
34
+ /** Merge partial tokens over a base (defaults: the built-in scale). */
35
+ declare function mergeMotionTokens(partial: DeepPartialTokens, base?: MotionTokens): MotionTokens;
36
+ /** The custom-property map: `{ '--usa-duration-fast': '150ms', … }`. */
37
+ declare function motionTokensToVars(tokens?: MotionTokens, prefix?: string): Record<string, string>;
38
+ /** A stylesheet string: `:root { --usa-duration-fast: 150ms; … }`. */
39
+ declare function motionTokensToCss(tokens?: MotionTokens, selector?: string, prefix?: string): string;
40
+ /** W3C Design Tokens (DTCG) JSON: `{ motion: { duration: { fast: { $type: 'duration', $value: '150ms' } } } }`. */
41
+ declare function motionTokensToJSON(tokens?: MotionTokens): Record<string, unknown>;
42
+ /** Parse `150ms`, `0.15s`, `150` → ms. */
43
+ declare function parseDuration(v: unknown): number | undefined;
44
+ /** Parse `[x1,y1,x2,y2]`, `'cubic-bezier(…)'`, `'0.2, 0, 0, 1'` or a keyword → CSS easing. */
45
+ declare function parseEasing(v: unknown): string | undefined;
46
+ /**
47
+ * Import tokens from W3C DTCG JSON, Figma Tokens / Tokens Studio
48
+ * (`{ value, type }`) or Style Dictionary (`{ value }`, nested) — anything
49
+ * under a `duration` / `easing` / `spring` group (any depth, e.g.
50
+ * `motion.duration.fast` or `global.animation.easing.out`), or typed leaves
51
+ * (`duration`, `cubicBezier`, `transition`, `spring`). Unknown values are
52
+ * skipped; the result is merged over the defaults.
53
+ */
54
+ declare function importMotionTokens(json: unknown, base?: MotionTokens): MotionTokens;
55
+ /** The tokens currently applied (via `applyMotionTokens`), or the defaults. */
56
+ declare function getMotionTokens(): MotionTokens;
57
+ /**
58
+ * Write tokens as CSS custom properties on `root` (default `<html>`) and make
59
+ * them the active set for `motionToken()`. Returns an undo function.
60
+ */
61
+ declare function applyMotionTokens(tokens?: DeepPartialTokens | MotionTokens, root?: HTMLElement, prefix?: string): () => void;
62
+ /** Look up a token: `motionToken('duration', 'fast')` → `150`; `motionToken('easing', 'emphasized')` → CSS easing. */
63
+ declare function motionToken(group: 'duration', name: string): number;
64
+ declare function motionToken(group: 'easing', name: string): string;
65
+ declare function motionToken(group: 'spring', name: string): SpringToken;
66
+ /** `var(--usa-duration-fast, 150ms)` — a CSS reference with the current value as fallback. */
67
+ declare function motionVar(group: MotionTokenGroup, name: string, prop?: 'stiffness' | 'damping' | 'mass', prefix?: string): string;
68
+ /** Resolve a duration that may be a token name (`'fast'`) or ms. */
69
+ declare function resolveDurationToken(v: number | string | undefined, fallback: number): number;
70
+ /** Resolve an easing that may be a token name (`'emphasized'`) or CSS. */
71
+ declare function resolveEasingToken(v: string | undefined, fallback: string): string;
72
+
73
+ export { MOTION_TOKENS, applyMotionTokens, getMotionTokens, importMotionTokens, mergeMotionTokens, motionToken, motionTokensToCss, motionTokensToJSON, motionTokensToVars, motionVar, parseDuration, parseEasing, resolveDurationToken, resolveEasingToken };
74
+ export type { DeepPartialTokens, MotionTokenGroup, MotionTokens, SpringToken };