motionary 0.0.0-stage → 6.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.
- package/CHANGELOG.md +803 -0
- package/LICENSE +21 -0
- package/README.md +218 -2
- package/README_ja.md +219 -0
- package/README_zh.md +219 -0
- package/bin/usa-codemod-5.mjs +79 -0
- package/bin/usa-codemod-6.mjs +146 -0
- package/dist/chunks/base-BaQV-2ha.cjs +436 -0
- package/dist/chunks/base-BaQV-2ha.cjs.map +1 -0
- package/dist/chunks/base-C_3cAoRz.js +404 -0
- package/dist/chunks/base-C_3cAoRz.js.map +1 -0
- package/dist/chunks/bind-B_CTL6Qn.js +22 -0
- package/dist/chunks/bind-B_CTL6Qn.js.map +1 -0
- package/dist/chunks/bind-Ui43-n2d.cjs +25 -0
- package/dist/chunks/bind-Ui43-n2d.cjs.map +1 -0
- package/dist/chunks/core-B5T0dhFH.cjs +920 -0
- package/dist/chunks/core-B5T0dhFH.cjs.map +1 -0
- package/dist/chunks/core-BGAyaY6L.cjs +265 -0
- package/dist/chunks/core-BGAyaY6L.cjs.map +1 -0
- package/dist/chunks/core-D7cVumUu.js +909 -0
- package/dist/chunks/core-D7cVumUu.js.map +1 -0
- package/dist/chunks/core-VEBw36QK.js +260 -0
- package/dist/chunks/core-VEBw36QK.js.map +1 -0
- package/dist/chunks/core-ps8uvYuN.js +181 -0
- package/dist/chunks/core-ps8uvYuN.js.map +1 -0
- package/dist/chunks/core-zq17EeCI.cjs +185 -0
- package/dist/chunks/core-zq17EeCI.cjs.map +1 -0
- package/dist/chunks/fx-Bs6IrV4Q.js +109 -0
- package/dist/chunks/fx-Bs6IrV4Q.js.map +1 -0
- package/dist/chunks/fx-lBGVtQO1.cjs +114 -0
- package/dist/chunks/fx-lBGVtQO1.cjs.map +1 -0
- package/dist/chunks/generative-D2YyhaeO.js +336 -0
- package/dist/chunks/generative-D2YyhaeO.js.map +1 -0
- package/dist/chunks/generative-DzIZq-_g.cjs +348 -0
- package/dist/chunks/generative-DzIZq-_g.cjs.map +1 -0
- package/dist/chunks/gpu-Bu7qwugO.js +380 -0
- package/dist/chunks/gpu-Bu7qwugO.js.map +1 -0
- package/dist/chunks/gpu-CenK2l6b.cjs +387 -0
- package/dist/chunks/gpu-CenK2l6b.cjs.map +1 -0
- package/dist/chunks/index-tags-DucKMQr_.js +26 -0
- package/dist/chunks/index-tags-DucKMQr_.js.map +1 -0
- package/dist/chunks/index-tags-wv0R_vkO.cjs +28 -0
- package/dist/chunks/index-tags-wv0R_vkO.cjs.map +1 -0
- package/dist/chunks/presets-BYBVJVeP.js +226 -0
- package/dist/chunks/presets-BYBVJVeP.js.map +1 -0
- package/dist/chunks/presets-CUHys3sK.cjs +233 -0
- package/dist/chunks/presets-CUHys3sK.cjs.map +1 -0
- package/dist/chunks/registry-CKNLQpwd.js +121 -0
- package/dist/chunks/registry-CKNLQpwd.js.map +1 -0
- package/dist/chunks/registry-DehBVRDV.cjs +131 -0
- package/dist/chunks/registry-DehBVRDV.cjs.map +1 -0
- package/dist/chunks/spring-CbvHfVtP.js +219 -0
- package/dist/chunks/spring-CbvHfVtP.js.map +1 -0
- package/dist/chunks/spring-Dgx187Vh.cjs +232 -0
- package/dist/chunks/spring-Dgx187Vh.cjs.map +1 -0
- package/dist/chunks/stagger-CCFyhzSw.cjs +86 -0
- package/dist/chunks/stagger-CCFyhzSw.cjs.map +1 -0
- package/dist/chunks/stagger-DtMKo2SK.js +84 -0
- package/dist/chunks/stagger-DtMKo2SK.js.map +1 -0
- package/dist/chunks/variants-BhjyddG8.cjs +39 -0
- package/dist/chunks/variants-BhjyddG8.cjs.map +1 -0
- package/dist/chunks/variants-DRlKVHvu.js +35 -0
- package/dist/chunks/variants-DRlKVHvu.js.map +1 -0
- package/dist/components/a11y.cjs +276 -0
- package/dist/components/a11y.cjs.map +1 -0
- package/dist/components/a11y.d.cts +131 -0
- package/dist/components/a11y.d.ts +131 -0
- package/dist/components/a11y.js +259 -0
- package/dist/components/a11y.js.map +1 -0
- package/dist/components/angular.cjs +76 -0
- package/dist/components/angular.cjs.map +1 -0
- package/dist/components/angular.d.cts +1734 -0
- package/dist/components/angular.d.ts +1734 -0
- package/dist/components/angular.js +70 -0
- package/dist/components/angular.js.map +1 -0
- package/dist/components/background.cjs +659 -0
- package/dist/components/background.cjs.map +1 -0
- package/dist/components/background.css +9 -0
- package/dist/components/background.d.cts +166 -0
- package/dist/components/background.d.ts +166 -0
- package/dist/components/background.js +647 -0
- package/dist/components/background.js.map +1 -0
- package/dist/components/bridge.cjs +154 -0
- package/dist/components/bridge.cjs.map +1 -0
- package/dist/components/bridge.d.cts +63 -0
- package/dist/components/bridge.d.ts +63 -0
- package/dist/components/bridge.js +147 -0
- package/dist/components/bridge.js.map +1 -0
- package/dist/components/cards.cjs +561 -0
- package/dist/components/cards.cjs.map +1 -0
- package/dist/components/cards.css +6 -0
- package/dist/components/cards.d.cts +115 -0
- package/dist/components/cards.d.ts +115 -0
- package/dist/components/cards.js +554 -0
- package/dist/components/cards.js.map +1 -0
- package/dist/components/click.cjs +877 -0
- package/dist/components/click.cjs.map +1 -0
- package/dist/components/click.css +9 -0
- package/dist/components/click.d.cts +218 -0
- package/dist/components/click.d.ts +218 -0
- package/dist/components/click.js +863 -0
- package/dist/components/click.js.map +1 -0
- package/dist/components/depth.cjs +250 -0
- package/dist/components/depth.cjs.map +1 -0
- package/dist/components/depth.css +3 -0
- package/dist/components/depth.d.cts +86 -0
- package/dist/components/depth.d.ts +86 -0
- package/dist/components/depth.js +242 -0
- package/dist/components/depth.js.map +1 -0
- package/dist/components/effects.cjs +2258 -0
- package/dist/components/effects.cjs.map +1 -0
- package/dist/components/effects.d.cts +545 -0
- package/dist/components/effects.d.ts +545 -0
- package/dist/components/effects.js +2200 -0
- package/dist/components/effects.js.map +1 -0
- package/dist/components/feedback.cjs +442 -0
- package/dist/components/feedback.cjs.map +1 -0
- package/dist/components/feedback.css +7 -0
- package/dist/components/feedback.d.cts +144 -0
- package/dist/components/feedback.d.ts +144 -0
- package/dist/components/feedback.js +433 -0
- package/dist/components/feedback.js.map +1 -0
- package/dist/components/fx-gpu.cjs +12 -0
- package/dist/components/fx-gpu.cjs.map +1 -0
- package/dist/components/fx-gpu.d.cts +63 -0
- package/dist/components/fx-gpu.d.ts +63 -0
- package/dist/components/fx-gpu.js +5 -0
- package/dist/components/fx-gpu.js.map +1 -0
- package/dist/components/fx.cjs +169 -0
- package/dist/components/fx.cjs.map +1 -0
- package/dist/components/fx.css +3 -0
- package/dist/components/fx.d.cts +114 -0
- package/dist/components/fx.d.ts +114 -0
- package/dist/components/fx.js +156 -0
- package/dist/components/fx.js.map +1 -0
- package/dist/components/fx2.cjs +25 -0
- package/dist/components/fx2.cjs.map +1 -0
- package/dist/components/fx2.d.cts +136 -0
- package/dist/components/fx2.d.ts +136 -0
- package/dist/components/fx2.js +17 -0
- package/dist/components/fx2.js.map +1 -0
- package/dist/components/gesture.cjs +209 -0
- package/dist/components/gesture.cjs.map +1 -0
- package/dist/components/gesture.css +3 -0
- package/dist/components/gesture.d.cts +134 -0
- package/dist/components/gesture.d.ts +134 -0
- package/dist/components/gesture.js +203 -0
- package/dist/components/gesture.js.map +1 -0
- package/dist/components/interaction.cjs +424 -0
- package/dist/components/interaction.cjs.map +1 -0
- package/dist/components/interaction.css +8 -0
- package/dist/components/interaction.d.cts +115 -0
- package/dist/components/interaction.d.ts +115 -0
- package/dist/components/interaction.js +416 -0
- package/dist/components/interaction.js.map +1 -0
- package/dist/components/jsx.cjs +3 -0
- package/dist/components/jsx.cjs.map +1 -0
- package/dist/components/jsx.d.cts +53 -0
- package/dist/components/jsx.d.ts +53 -0
- package/dist/components/jsx.js +2 -0
- package/dist/components/jsx.js.map +1 -0
- package/dist/components/layout.cjs +257 -0
- package/dist/components/layout.cjs.map +1 -0
- package/dist/components/layout.css +3 -0
- package/dist/components/layout.d.cts +99 -0
- package/dist/components/layout.d.ts +99 -0
- package/dist/components/layout.js +249 -0
- package/dist/components/layout.js.map +1 -0
- package/dist/components/lazy.cjs +92 -0
- package/dist/components/lazy.cjs.map +1 -0
- package/dist/components/lazy.d.cts +48 -0
- package/dist/components/lazy.d.ts +48 -0
- package/dist/components/lazy.js +87 -0
- package/dist/components/lazy.js.map +1 -0
- package/dist/components/lite.cjs +11095 -0
- package/dist/components/lite.cjs.map +1 -0
- package/dist/components/lite.d.cts +4 -0
- package/dist/components/lite.d.ts +4 -0
- package/dist/components/lite.js +10827 -0
- package/dist/components/lite.js.map +1 -0
- package/dist/components/packs.cjs +192 -0
- package/dist/components/packs.cjs.map +1 -0
- package/dist/components/packs.css +3 -0
- package/dist/components/packs.d.cts +72 -0
- package/dist/components/packs.d.ts +72 -0
- package/dist/components/packs.js +184 -0
- package/dist/components/packs.js.map +1 -0
- package/dist/components/page.cjs +824 -0
- package/dist/components/page.cjs.map +1 -0
- package/dist/components/page.css +11 -0
- package/dist/components/page.d.cts +249 -0
- package/dist/components/page.d.ts +249 -0
- package/dist/components/page.js +799 -0
- package/dist/components/page.js.map +1 -0
- package/dist/components/perf.cjs +120 -0
- package/dist/components/perf.cjs.map +1 -0
- package/dist/components/perf.d.cts +98 -0
- package/dist/components/perf.d.ts +98 -0
- package/dist/components/perf.js +110 -0
- package/dist/components/perf.js.map +1 -0
- package/dist/components/physics.cjs +448 -0
- package/dist/components/physics.cjs.map +1 -0
- package/dist/components/physics.css +5 -0
- package/dist/components/physics.d.cts +189 -0
- package/dist/components/physics.d.ts +189 -0
- package/dist/components/physics.js +430 -0
- package/dist/components/physics.js.map +1 -0
- package/dist/components/react.cjs +96 -0
- package/dist/components/react.cjs.map +1 -0
- package/dist/components/react.d.cts +18 -0
- package/dist/components/react.d.ts +18 -0
- package/dist/components/react.js +91 -0
- package/dist/components/react.js.map +1 -0
- package/dist/components/reveal.cjs +362 -0
- package/dist/components/reveal.cjs.map +1 -0
- package/dist/components/reveal.css +5 -0
- package/dist/components/reveal.d.cts +105 -0
- package/dist/components/reveal.d.ts +105 -0
- package/dist/components/reveal.js +353 -0
- package/dist/components/reveal.js.map +1 -0
- package/dist/components/solid.cjs +86 -0
- package/dist/components/solid.cjs.map +1 -0
- package/dist/components/solid.d.cts +1751 -0
- package/dist/components/solid.d.ts +1751 -0
- package/dist/components/solid.js +82 -0
- package/dist/components/solid.js.map +1 -0
- package/dist/components/svelte.cjs +68 -0
- package/dist/components/svelte.cjs.map +1 -0
- package/dist/components/svelte.d.cts +1733 -0
- package/dist/components/svelte.d.ts +1733 -0
- package/dist/components/svelte.js +64 -0
- package/dist/components/svelte.js.map +1 -0
- package/dist/components/svg.cjs +359 -0
- package/dist/components/svg.cjs.map +1 -0
- package/dist/components/svg.css +3 -0
- package/dist/components/svg.d.cts +113 -0
- package/dist/components/svg.d.ts +113 -0
- package/dist/components/svg.js +347 -0
- package/dist/components/svg.js.map +1 -0
- package/dist/components/text.cjs +968 -0
- package/dist/components/text.cjs.map +1 -0
- package/dist/components/text.css +8 -0
- package/dist/components/text.d.cts +342 -0
- package/dist/components/text.d.ts +342 -0
- package/dist/components/text.js +947 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/timeline.cjs +109 -0
- package/dist/components/timeline.cjs.map +1 -0
- package/dist/components/timeline.css +3 -0
- package/dist/components/timeline.d.cts +155 -0
- package/dist/components/timeline.d.ts +155 -0
- package/dist/components/timeline.js +103 -0
- package/dist/components/timeline.js.map +1 -0
- package/dist/components/tokens.cjs +226 -0
- package/dist/components/tokens.cjs.map +1 -0
- package/dist/components/tokens.d.cts +74 -0
- package/dist/components/tokens.d.ts +74 -0
- package/dist/components/tokens.js +211 -0
- package/dist/components/tokens.js.map +1 -0
- package/dist/components/transitions.cjs +430 -0
- package/dist/components/transitions.cjs.map +1 -0
- package/dist/components/transitions.css +5 -0
- package/dist/components/transitions.d.cts +126 -0
- package/dist/components/transitions.d.ts +126 -0
- package/dist/components/transitions.js +423 -0
- package/dist/components/transitions.js.map +1 -0
- package/dist/components/ui.cjs +1050 -0
- package/dist/components/ui.cjs.map +1 -0
- package/dist/components/ui.css +14 -0
- package/dist/components/ui.d.cts +224 -0
- package/dist/components/ui.d.ts +224 -0
- package/dist/components/ui.js +1034 -0
- package/dist/components/ui.js.map +1 -0
- package/dist/components/vue.cjs +67 -0
- package/dist/components/vue.cjs.map +1 -0
- package/dist/components/vue.d.cts +1722 -0
- package/dist/components/vue.d.ts +1722 -0
- package/dist/components/vue.js +64 -0
- package/dist/components/vue.js.map +1 -0
- package/dist/components/webgl.cjs +459 -0
- package/dist/components/webgl.cjs.map +1 -0
- package/dist/components/webgl.css +3 -0
- package/dist/components/webgl.d.cts +133 -0
- package/dist/components/webgl.d.ts +133 -0
- package/dist/components/webgl.js +442 -0
- package/dist/components/webgl.js.map +1 -0
- package/dist/components/widgets.cjs +591 -0
- package/dist/components/widgets.cjs.map +1 -0
- package/dist/components/widgets.d.cts +110 -0
- package/dist/components/widgets.d.ts +110 -0
- package/dist/components/widgets.js +581 -0
- package/dist/components/widgets.js.map +1 -0
- package/dist/components.cjs +351 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.css +75 -0
- package/dist/components.d.cts +2997 -0
- package/dist/components.d.ts +2997 -0
- package/dist/components.js +106 -0
- package/dist/components.js.map +1 -0
- package/dist/components.umd.js +23 -0
- package/dist/components.umd.js.map +1 -0
- package/dist/element.cjs +97 -0
- package/dist/element.cjs.map +1 -0
- package/dist/element.d.cts +215 -0
- package/dist/element.d.ts +215 -0
- package/dist/element.js +95 -0
- package/dist/element.js.map +1 -0
- package/dist/element.umd.js +2 -0
- package/dist/element.umd.js.map +1 -0
- package/dist/index.cjs +149 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +425 -0
- package/dist/index.d.ts +425 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +15 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/presets/extended.cjs +243 -0
- package/dist/presets/extended.cjs.map +1 -0
- package/dist/presets/extended.d.cts +37 -0
- package/dist/presets/extended.d.ts +37 -0
- package/dist/presets/extended.js +239 -0
- package/dist/presets/extended.js.map +1 -0
- package/dist/presets-extended.umd.js +2 -0
- package/dist/presets-extended.umd.js.map +1 -0
- package/dist/react.cjs +68 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +158 -0
- package/dist/react.d.ts +158 -0
- package/dist/react.js +65 -0
- package/dist/react.js.map +1 -0
- package/dist/solid.cjs +93 -0
- package/dist/solid.cjs.map +1 -0
- package/dist/solid.d.cts +249 -0
- package/dist/solid.d.ts +249 -0
- package/dist/solid.js +89 -0
- package/dist/solid.js.map +1 -0
- package/dist/svelte.cjs +66 -0
- package/dist/svelte.cjs.map +1 -0
- package/dist/svelte.d.cts +243 -0
- package/dist/svelte.d.ts +243 -0
- package/dist/svelte.js +63 -0
- package/dist/svelte.js.map +1 -0
- package/dist/vue.cjs +62 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.cts +158 -0
- package/dist/vue.d.ts +158 -0
- package/dist/vue.js +60 -0
- package/dist/vue.js.map +1 -0
- package/dist/widgets.umd.js +2 -0
- package/dist/widgets.umd.js.map +1 -0
- package/docs/API.md +147 -0
- package/docs/ROADMAP.md +14 -0
- package/docs/accessibility.md +60 -0
- package/docs/components.md +564 -0
- package/docs/deprecations.md +30 -0
- package/docs/frameworks-ssr.md +100 -0
- package/docs/hybrid-apps.md +145 -0
- package/docs/images/showcase-detail.png +0 -0
- package/docs/images/showcase-grid.png +0 -0
- package/docs/images/showcase-mobile.png +0 -0
- package/docs/migration-from-aos.md +67 -0
- package/docs/migration-from-gsap-scrolltrigger.md +80 -0
- package/docs/motion-tokens.css +31 -0
- package/docs/motion-tokens.md +46 -0
- package/docs/motion.tokens.json +132 -0
- package/docs/performance.md +24 -0
- package/docs/presets.md +310 -0
- package/docs/upgrading-3.md +21 -0
- package/docs/upgrading-4.md +65 -0
- package/docs/upgrading-5.md +31 -0
- package/docs/upgrading-6.md +32 -0
- package/docs/windows-apps.md +119 -0
- package/package.json +562 -4
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Accessibility (`motionary/components`)
|
|
2
|
+
|
|
3
|
+
Audited in v2.9 (automated sweep in `test/components-a11y-frameworks.test.ts` + per-component tests).
|
|
4
|
+
|
|
5
|
+
## Motion
|
|
6
|
+
- Every `<usa-*>` element honours **`prefers-reduced-motion: reduce`**: entrances fade or appear, loops/particles/cursors stop, springs jump to their target, page transitions update instantly. Override per app with `configureComponents({ reducedMotion: 'reduce' | 'no-preference' | 'user' })`.
|
|
7
|
+
- **Global motion intensity** (v2.7): `setMotionIntensity('off' | 'low' | 'normal' | 'high', persist)` or let users choose with `<usa-motion-switch>`. `off` behaves exactly like reduced motion; `low` shortens every animation to 60 %.
|
|
8
|
+
- No component flashes more than 3×/s; glitch and grain effects are disabled under reduced motion.
|
|
9
|
+
|
|
10
|
+
## Keyboard
|
|
11
|
+
| Component | Keys |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `<usa-toggle>`, `<usa-checkbox>`, `<usa-like>` | Space / Enter |
|
|
14
|
+
| `<usa-hold>` | hold Space / Enter |
|
|
15
|
+
| `<usa-slider>` | ←/→/↑/↓, PageUp/PageDown, Home/End |
|
|
16
|
+
| `<usa-rating>` | ←/→, number keys, Home/End |
|
|
17
|
+
| `<usa-tabs>` | ←/→/↑/↓, Home/End (roving tabindex) |
|
|
18
|
+
| `<usa-draggable>` | arrows (by `step` / `snap`), Home / Esc resets |
|
|
19
|
+
| `<usa-card-stack>` | ← / → swipe |
|
|
20
|
+
| `<usa-carousel-3d>` | ← / → |
|
|
21
|
+
| `<usa-fullpage>` | PageUp/PageDown, ↑/↓, Space, Home/End |
|
|
22
|
+
| `<usa-card effect="flip" trigger="click">`, `effect="expand"` | Enter / Space; Esc collapses |
|
|
23
|
+
| `<usa-drawer>`, `<usa-bottom-sheet>`, `<usa-popover>`, `<usa-fab>`, `<usa-tooltip>`, `<usa-dialog>` | Esc closes, focus returns to the trigger |
|
|
24
|
+
| `<usa-double-tap>` | `L` |
|
|
25
|
+
|
|
26
|
+
## Roles & states
|
|
27
|
+
`switch` (toggle), `checkbox` (+ `aria-checked="mixed"`), `slider` (slider, rating; `aria-valuenow/-text`), `tablist`/`tab`/`tabpanel`, `dialog` + `aria-modal` (drawer, sheet, dialog, popover), `button` + `aria-pressed` (like, click-flip card, icon-morph toggle) / `aria-expanded` (fab, popover, expand card), `progressbar` (progress, loading bar, scroll progress), `status` live regions (toasts, submit button, pull-to-refresh, badge), `radiogroup` (motion switch), `aria-busy` while loading (submit, pull-refresh, auto-skeleton, splash).
|
|
28
|
+
|
|
29
|
+
Animated text (`<usa-split-text>`, `<usa-typewriter>`, `<usa-wave-text>`, `<usa-handwriting>`, `<usa-scroll-highlight>` …) renders an `aria-hidden` animated copy plus a visually hidden plain copy. Decorative layers (`<usa-cursor>`, `<usa-ambient>`, particles, sheens, goo) are `aria-hidden` and never take pointer events.
|
|
30
|
+
|
|
31
|
+
## Transparency & contrast
|
|
32
|
+
Glass, acrylic and Fluent materials fall back to solid surfaces under `prefers-reduced-transparency: reduce` and `forced-colors: active`.
|
|
33
|
+
|
|
34
|
+
## Motion-sensitivity levels (4.4)
|
|
35
|
+
|
|
36
|
+
`import { setMotionSensitivity, restoreMotionSensitivity } from 'motionary/components/a11y'`
|
|
37
|
+
|
|
38
|
+
| Level | What moves | Use for |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `full` (default) | everything | — |
|
|
41
|
+
| `gentle` | fades and translations; **no** spins, zooms, skews, 3D or parallax | vestibular disorders, motion sickness |
|
|
42
|
+
| `minimal` | fades only (components use their reduced-motion variants) | `prefers-reduced-motion` plus |
|
|
43
|
+
| `static` | nothing — every component shows its static alternative; your own CSS animations are stopped too | seizure / attention sensitivity, kiosks, screenshots |
|
|
44
|
+
|
|
45
|
+
`setMotionSensitivity(level, persist)` sets `data-usa-sensitivity` on `<html>` (style your own CSS with it) and dispatches `usa:sensitivity`; `motionAllowed('rotate')` tells your code what the level permits; `adaptKeyframes(frames)` filters your own WAAPI keyframes the same way the components do.
|
|
46
|
+
|
|
47
|
+
## Static alternatives
|
|
48
|
+
|
|
49
|
+
Every category has a defined static rendering (`STATIC_ALTERNATIVES`): content lands on its final, readable state; loops, particles and cursors stop; gestures keep keyboard / button equivalents. `staticAlternative(root)` freezes any subtree (finishes finite animations, cancels endless ones).
|
|
50
|
+
|
|
51
|
+
## aria-live conventions
|
|
52
|
+
|
|
53
|
+
- One shared **polite** region (`#usa-live-polite`, `role="status"`) and one **assertive** region (`#usa-live-assertive`, `role="alert"`) — `announce(message, { politeness })`.
|
|
54
|
+
- Polite for results of the user's own action (added, copied, saved, loading done); assertive only for blocking errors.
|
|
55
|
+
- Identical messages within 500 ms are dropped; the region is cleared before each message so repeats are read.
|
|
56
|
+
- Component-owned regions (toasts, submit button, pull-to-refresh, badge) stay `role="status"` / polite.
|
|
57
|
+
|
|
58
|
+
## Automated regression tests
|
|
59
|
+
|
|
60
|
+
`test/a11y-regression.test.ts` mounts **every** `<usa-*>` element at every sensitivity level and runs `auditMotionA11y()`: focusable content inside `aria-hidden`, widget roles without a name, sliders without `aria-valuenow`, images without `alt` (errors), assertive regions outside `role="alert"` and endless animations without a motion control (WCAG 2.2.2, warnings). Run the same audit in your app's tests.
|
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
# Animated components (`motionary/components`)
|
|
2
|
+
|
|
3
|
+
Since **v2.2** (now **v3**) the package ships **30 animated UI components** as standard Web Components (`<usa-*>` custom elements) plus three transition helpers. They are built only on Custom Elements, CSS and the Web Animations API, so the same code runs:
|
|
4
|
+
|
|
5
|
+
- in any modern browser (Chrome, Edge, Firefox, Safari), and with React, Vue, Svelte, Solid, Angular or no framework;
|
|
6
|
+
- in **Windows desktop software** that renders its UI with a web view — Electron, Tauri (WebView2), WinUI 3 / WPF / WinForms with WebView2, and installed PWAs. See **[Windows apps guide](./windows-apps.md)**.
|
|
7
|
+
|
|
8
|
+
Live gallery: <https://harrisoncn.github.io/motionary/showcase/components.html>
|
|
9
|
+
|
|
10
|
+
## Principles
|
|
11
|
+
|
|
12
|
+
- **Zero dependencies, tree-shakable.** Import one category (`motionary/components/text`) or one component (`import { defineTypewriter } …`) and only that ships.
|
|
13
|
+
- **SSR-safe.** Importing never touches `window`/`document`; every `define*()` is a no-op on the server.
|
|
14
|
+
- **Opt-in registration.** Nothing is registered until you call `define*()` (or load the IIFE bundle). Every `define*()` accepts a custom tag name: `defineSpinner('my-loader')`.
|
|
15
|
+
- **`prefers-reduced-motion` everywhere.** Each component has a calm variant (instant reveal, fade instead of slide, static background…). Override globally with `configureComponents({ reducedMotion: 'reduce' | 'no-preference' | 'user' })`.
|
|
16
|
+
- **GPU-friendly.** Animations use `transform` / `opacity` (plus `filter` for blur effects); layout is read and written in separate phases, at most once per frame, and loops pause when off-screen or the tab is hidden.
|
|
17
|
+
- **Accessible.** Animated text keeps a visually-hidden plain copy for screen readers; switches, progress bars, toasts and dialogs carry the right roles and ARIA states.
|
|
18
|
+
- **Styles included.** Each component injects its own small stylesheet once (as a constructable stylesheet, which a `style-src 'self'` CSP allows). Prefer a file? `import 'motionary/components.css'` (or `/components/<category>.css`) and call `configureComponents({ injectStyles: false })`.
|
|
19
|
+
|
|
20
|
+
## Install & register
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm i motionary
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
// everything
|
|
28
|
+
import { defineComponents } from 'motionary/components';
|
|
29
|
+
defineComponents(); // or defineComponents(['text', 'feedback'])
|
|
30
|
+
|
|
31
|
+
// one category
|
|
32
|
+
import { defineTextComponents } from 'motionary/components/text';
|
|
33
|
+
defineTextComponents();
|
|
34
|
+
|
|
35
|
+
// one component
|
|
36
|
+
import { defineTypewriter } from 'motionary/components/text';
|
|
37
|
+
defineTypewriter();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
No build step (registers every `<usa-*>` and exposes the API as `window.UsaComponents`):
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<script src="https://unpkg.com/motionary@6/dist/components.umd.js"></script>
|
|
44
|
+
<usa-typewriter words="Hello, Windows.|Hello, web."></usa-typewriter>
|
|
45
|
+
<script>UsaComponents.toast('Ready', { type: 'success' });</script>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Entry | Contents |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `motionary/components` | everything + `defineComponents()`, `COMPONENT_CATEGORIES`, `configureComponents()` |
|
|
51
|
+
| `motionary/components/reveal` · `/text` · `/interaction` · `/feedback` · `/background` · `/transitions` | one category + `define<Category>Components()` |
|
|
52
|
+
| `motionary/components.css`, `/components/<category>.css` | the same styles as files |
|
|
53
|
+
| `dist/components.umd.js` | IIFE/UMD bundle for `<script>` tags, auto-registers |
|
|
54
|
+
|
|
55
|
+
## Components by category
|
|
56
|
+
|
|
57
|
+
All attributes are optional unless noted. Events are `CustomEvent`s that bubble, named `usa:*`.
|
|
58
|
+
|
|
59
|
+
### 1. Entrance & scroll — `components/reveal`
|
|
60
|
+
|
|
61
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
62
|
+
|---|---|---|---|
|
|
63
|
+
| `<usa-reveal>` | Reveals content when it enters the viewport | `effect` (`fade`, `fade-up`*, `fade-down`, `fade-left`, `fade-right`, `zoom-in`, `zoom-out`, `blur`, `blur-up`, `flip-up`, `flip-left`, `rise`, or since 6.1 any registered scroll preset name such as `bounce-in-up` / `clip-diamond` once `motionary` or `motionary/presets/extended` is loaded — see [presets.md](./presets.md)), `duration` (700), `delay`, `distance` (32), `easing`, `threshold` (0.15), `root-margin`, `repeat` | `reveal()`, `reset()`, `revealed`; `usa:enter`, `usa:leave`, `usa:complete` |
|
|
64
|
+
| `<usa-stagger>` | Reveals its children one after another | `effect`, `interval` (70 ms), `duration`, `delay`, `distance`, `threshold`, `repeat` | `reveal()`, `reset()`; `usa:enter`, `usa:complete` |
|
|
65
|
+
| `<usa-scroll-progress>` | Reading-progress bar for the page or one article | `target` (selector), `position` (`top`*, `bottom`, `inline`), `label`; CSS `--usa-progress-color/-height/-track` | `progress`, `update()`; `usa:progress` (`detail.progress`); `--usa-progress` on the element |
|
|
66
|
+
| `<usa-scrolly>` | Sticky scrollytelling: `[data-sticky]` stays pinned while `[data-step]` children scroll by | `offset` (trigger line, 0.5) | `active`, `steps`; `usa:step` (`detail.index/step/name`); `data-step-name` + `--usa-step` on the host, `data-active` on the step |
|
|
67
|
+
|
|
68
|
+
### 2. Text — `components/text`
|
|
69
|
+
|
|
70
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
71
|
+
|---|---|---|---|
|
|
72
|
+
| `<usa-typewriter>` | Types text, or cycles phrases (type → pause → delete) | `text` or `words` (`a\|b\|c`), `speed` (55), `delete-speed` (30), `pause` (1400), `delay`, `loop`, `cursor="false"`, `start` (`view`*, `load`, `manual`) | `start()`, `stop()`, `restart()`; `usa:complete` |
|
|
73
|
+
| `<usa-split-text>` | Splits into characters or words and cascades them in | `by` (`chars`*, `words`), `effect` (`rise`*, `fade`, `blur`, `flip`, `pop`), `stagger`, `duration` (620), `delay`, `trigger` (`view`*, `load`, `manual`), `repeat` | `play()`, `reset()`, `units`; `usa:complete` |
|
|
74
|
+
| `<usa-scramble>` | Decodes text out of random glyphs | `text`, `duration` (900), `chars`, `trigger` (`view`*, `hover`, `load`, `manual`) | `play()`; `usa:complete` |
|
|
75
|
+
| `<usa-counter>` | Counts to a number when visible (locale-formatted, tabular digits) | `to` (required), `from`, `duration` (1600), `decimals`, `locale`, `prefix`, `suffix`, `grouping="false"`, `start` | `value` (set to animate), `play(to?)`, `format(n)`; `usa:complete` |
|
|
76
|
+
| `<usa-shimmer-text>` | Light sweep across gradient text (CSS only) | `duration` (2600), `color`, `shine`, `angle` | — |
|
|
77
|
+
| `<usa-text-rotate>` | Cycles words in place without reflow | `words`, `interval` (2200), `effect` (`slide`*, `fade`, `flip`, `blur`), `paused` | `next()`, `index`; `usa:change` |
|
|
78
|
+
|
|
79
|
+
### 3. Interaction — `components/interaction`
|
|
80
|
+
|
|
81
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
82
|
+
|---|---|---|---|
|
|
83
|
+
| `<usa-ripple>` | Ink ripple from the pointer (centre for Space/Enter) | `color`, `opacity` (0.22), `duration` (550), `centered`, `disabled`, `block` | `ripple(x?, y?)` |
|
|
84
|
+
| `<usa-magnetic>` | Content leans toward a nearby pointer and springs back | `strength` (0.35), `radius` (60), `disabled` | — (fine pointers only) |
|
|
85
|
+
| `<usa-tilt>` | 3D tilt toward the pointer, optional glare | `max` (10°), `scale` (1.03), `perspective` (900), `glare`, `reverse`, `disabled` | `--usa-tilt-x/-y` (−1…1) for inner parallax |
|
|
86
|
+
| `<usa-spotlight>` | Windows Fluent **Reveal highlight**: light follows the pointer across a group, lighting borders | `size` (160), `color`, `border` (1), `no-fill`; items = children or `[data-spotlight]` | — |
|
|
87
|
+
| `<usa-press>` | Press feedback: dip + spring back, or `bounce` | `scale` (0.95), `bounce`, `disabled`, `block` | `pressed` |
|
|
88
|
+
| `<usa-toggle>` | Windows 11-style switch, form-associated | `checked`, `disabled`, `name`, `value`, `label` | `checked`, `toggle(force?)`; `change`, `usa:change` |
|
|
89
|
+
|
|
90
|
+
### 4. Loading & feedback — `components/feedback`
|
|
91
|
+
|
|
92
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `<usa-spinner>` | Indeterminate indicators | `kind` (`fluent`* = WinUI ProgressRing, `windows` = Windows 10 orbiting dots, `ring`, `dots`, `pulse`, `bars`), `size` (32), `label`, `paused` | `kind` |
|
|
95
|
+
| `<usa-skeleton>` | Shimmer placeholders; content fades in when loading ends | `loading`, `lines` (3), `avatar`, `circle`, `width`, `height`, `radius` | `loading`; `usa:loaded` |
|
|
96
|
+
| `<usa-progress>` | Linear progress; Fluent indeterminate animation without a value | `value`, `max` (100), `indeterminate`, `state` (`paused`, `error`), `label` | `value`, `max`, `ratio`; `usa:complete` |
|
|
97
|
+
| `<usa-toaster>` + `toast()` | Notifications that slide in, pause on hover, stack with FLIP | `position` (`bottom-right`*, `bottom-left`, `bottom-center`, `top-*`), `max` (4), `label` | `toast(msg, { type, duration, action, dismissible })` → `{ element, close() }`; `show()`, `clear()` |
|
|
98
|
+
| `<usa-check>` | Animated success / error / warning icon | `kind` (`success`*, `error`, `warning`), `size` (56), `start`, `label` | `play()`, `reset()`; `usa:complete` |
|
|
99
|
+
|
|
100
|
+
### 5. Background & decoration — `components/background`
|
|
101
|
+
|
|
102
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
103
|
+
|---|---|---|---|
|
|
104
|
+
| `<usa-aurora>` | Drifting aurora / gradient mesh behind content | `colors` (comma list), `speed` (1), `intensity` (0.7), `paused` | — (pauses off-screen) |
|
|
105
|
+
| `<usa-particles>` | Canvas constellation that avoids the pointer | `count` (60), `color`, `size`, `speed`, `links` (110, `0` = off), `interactive`, `paused` | `reset()` |
|
|
106
|
+
| `<usa-grain>` | SVG-noise film-grain overlay | `opacity` (0.12), `animated`, `blend`, `scale` | — |
|
|
107
|
+
| `<usa-marquee>` | Seamless infinite ticker | `speed` (50 px/s), `direction` (`left`*, `right`, `up`, `down`), `gap`, `pause-on-hover`, `fade`, `paused` | `pause()`, `resume()` |
|
|
108
|
+
| `<usa-acrylic>` | Fluent **Acrylic** / **Mica** materials | `kind` (`acrylic`*, `mica`), `tint`, `tint-opacity`, `blur`, `shimmer` (`hover`, `load`) | — (solid under `prefers-reduced-transparency` / forced colours) |
|
|
109
|
+
|
|
110
|
+
### 6. Transitions — `components/transitions`
|
|
111
|
+
|
|
112
|
+
| Element / helper | What it does | Key attributes / options | JS API / events |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| `<usa-dialog>` | Animated modal / drawer / sheet on the native `<dialog>` (focus trap, Esc, top layer); content is slotted, so frameworks keep owning it | `open`, `kind` (`modal`*, `drawer-start`, `drawer-end`, `drawer-bottom`, `sheet`), `label`, `no-backdrop-close`, `no-esc`; `[data-close]` children close it; `::part(panel/backdrop)`, `--usa-dialog-*` | `show()`, `close(value?)`, `open`, `returnValue`; `usa:open`, `usa:beforeclose` (cancelable), `usa:close` |
|
|
115
|
+
| `<usa-accordion>` | Smooth height animation for native `<details>` | `multiple`, `duration` (300) | `toggleItem(details, open?)`, `items`; `usa:toggle` |
|
|
116
|
+
| `<usa-view-switch>` | One view at a time with direction-aware transitions | `active` (name or index), `effect` (`slide`*, `fade`, `scale`, `drill`), `duration` | `show(view)`, `active`, `views`; `usa:change` |
|
|
117
|
+
| `viewTransition(update, opts?)` | Runs a DOM update inside `document.startViewTransition()`, cross-fade fallback | `{ fallback, duration, types }` | `Promise<void>` |
|
|
118
|
+
| `flip(targets, mutate, opts?)` | FLIP-animates any layout change | `{ duration, easing, animateEnter }` | `Promise<void>` |
|
|
119
|
+
|
|
120
|
+
### 7. Spring & physics — `components/physics`
|
|
121
|
+
|
|
122
|
+
| Element / API | What it does | Key attributes / options | JS API / events |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| `<usa-spring>` | Spring entrances (`bounce-in`, `pop`, `drop`) and attention effects (`jelly`, `rubber-band`) | `effect`, `trigger` (`view` · `hover` · `click` · `manual`), `preset` or `stiffness` / `damping` / `mass`, `delay`, `duration` (attention, 900), `repeat`, `block` | `play()`, `reset()`; `usa:complete` |
|
|
125
|
+
| `<usa-draggable>` | Drag with pointer or arrow keys, physics on release | `axis` (`both` · `x` · `y`), `spring-back`, `inertia`, `snap` (`80` grid or `0,120,240` points), `bounds="parent"`, `preset` (`wobbly`), `step` (16), `disabled` | `x`, `y`, `dragging`, `moveTo(x, y, animate?)`, `reset()`; `usa:drag-start`, `usa:drag`, `usa:drag-end`, `usa:settle`; `--usa-drag-x/-y` |
|
|
126
|
+
| `<usa-overscroll>` | Elastic scroll container (rubber-band edges) | `axis` (`y` · `x`), `max` (120), `preset`, `disabled` | `offset`; `--usa-overscroll` |
|
|
127
|
+
| `spring(el, keyframes, preset?, options?)` | WAAPI animation with spring timing | preset name or `{ stiffness, damping, mass, velocity }` | returns `Animation` (or `null` under reduced motion) |
|
|
128
|
+
| `springEasing(preset?)` | `{ easing: 'linear(…)', duration }` for CSS / WAAPI | — | cubic-bezier fallback without `linear()` |
|
|
129
|
+
| `createSpring({ value, spring, onUpdate, onRest })` | Interruptible spring value for gestures | — | `set(target, velocity?)`, `jump(v)`, `stop()`, `configure()` |
|
|
130
|
+
| `projectInertia(v, velocity)` · `snapTo(v, grid \| points)` · `rubberBand(d, dim)` | Inertia, snapping and resistance math | — | pure functions |
|
|
131
|
+
|
|
132
|
+
Presets (`SPRING_PRESETS`): `default` (170/26), `gentle` (120/14), `wobbly` (180/12), `stiff` (210/20), `bouncy` (300/10), `slow` (280/60), `molasses` (280/120) — stiffness/damping, mass 1.
|
|
133
|
+
|
|
134
|
+
### 8. Card effects — `components/cards`
|
|
135
|
+
|
|
136
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
137
|
+
|---|---|---|---|
|
|
138
|
+
| `<usa-card>` | Combinable card effects: `flip`, `holo`, `glass`, `border-glow`, `conic-border`, `lift`, `spotlight`, `sheen`, `parallax-layers`, `expand` | `effect` (space-separated), `trigger` (`hover` · `click`, flip), `axis` (`y` · `x`), `depth` (16), `color`, `flipped`, `disabled`; children `[data-front]` / `[data-back]` / `[data-detail]` / `[data-depth]` / `[data-close]` | `flip(force?)`, `expand()`, `collapse()`, `flipped`, `expanded`; `usa:flip`, `usa:expand`, `usa:collapse`; `--usa-card-x/-y/-nx/-ny`, `--usa-card-radius`, `--usa-card-bg`, `--usa-card-glow` |
|
|
139
|
+
| `<usa-card-stack>` | Swipeable deck, cards fan out behind the top one | `threshold` (90), `visible` (3), `offset` (10), `loop`, `disabled` | `top`, `swipe('left' \| 'right')`; `usa:swipe`, `usa:empty` |
|
|
140
|
+
| `<usa-sticky-stack>` | Cards stack while scrolling; covered ones shrink & dim | `top` (80), `gap` (16), `scale` (0.06) | `update()` |
|
|
141
|
+
| `<usa-carousel-3d>` | 3D ring carousel with spring rotation | `radius` (auto), `perspective` (1200), `autoplay` (ms), `index` | `index`, `next()`, `prev()`, `goTo(i)`; `usa:change` |
|
|
142
|
+
|
|
143
|
+
### 9. Click & tap — `components/click`
|
|
144
|
+
|
|
145
|
+
| Element / API | What it does | Key attributes | JS API / events |
|
|
146
|
+
|---|---|---|---|
|
|
147
|
+
| `<usa-button>` | **Button click deformation**: `squash`, `wobble`, `gooey`, `dent` (combinable); shape morph; submit morph | `deform`, `shape` (`pill` · `circle` · `icon`), `morph="submit"`, `state` (`idle` · `loading` · `success` · `error`), `reset` (1800 ms), `haptic`, `disabled`; children `[data-label]`, `[data-icon]` | `target`, `shape`, `state`, `morphTo(shape)`; `usa:submit` (`detail.done(ok)`), `usa:state`; `--usa-dent-x/-y` |
|
|
148
|
+
| `<usa-icon-morph>` | Spring icon morphs (play/pause, menu/close, plus/minus, check, arrow-right) | `icons` (`play,pause`), `index`, `size` (24), `toggle`, `labels`, `preset` | `next()`, `show(name \| i)`, `icon`; `usa:change` |
|
|
149
|
+
| `<usa-click>` | `ripple`, `burst`, `confetti`, `squish`, `press-spring`, `shake` (combinable) | `effect`, `color` (comma list), `shape`, `count`, `trigger="click"` (shake), `haptic`, `disabled` | `play(x?, y?)`, `shake()`; `usa:click-effect` |
|
|
150
|
+
| `<usa-like>` | Heart toggle with pop + burst | `liked`, `count`, `label`, `color`, `size`, `haptic` | `liked`, `count`, `toggle()`; `change`, `usa:change` |
|
|
151
|
+
| `<usa-hold>` | Hold-to-confirm ring | `duration` (1200), `label`, `color`, `haptic` | `progress`, `cancel()`; `usa:progress`, `usa:confirm`, `usa:cancel`; `--usa-hold` |
|
|
152
|
+
| `<usa-double-tap>` | Double tap → heart at the point | `icon` (♥), `color`, `delay` (300), `haptic` | `pop(x?, y?)`; `usa:double-tap` |
|
|
153
|
+
| `<usa-checkbox>` | Animated form-associated checkbox | `checked`, `indeterminate`, `name`, `value`, `label`, `shape` (`circle`) | `checked`, `toggle()`; `change`, `usa:change` |
|
|
154
|
+
| `haptic()` · `playEffect(el, 'burst' \| 'confetti' \| 'shake', …)` | Haptics; the click effects from code go through the effect registry (6.0 removed `burst()` / `confetti()` / `shake()`) | — | particles skip under reduced motion |
|
|
155
|
+
|
|
156
|
+
### 10. UI components & variants — `components/ui`
|
|
157
|
+
|
|
158
|
+
**Style variants.** `variant="minimal | neon | glass | brutalist | fluent | material"` works on every `<usa-*>` element (or `data-usa-variant` on an ancestor, or `setVariant('fluent')` page-wide). Variants only set design tokens — `--usa-accent`, `--usa-accent-text`, `--usa-surface`, `--usa-text`, `--usa-radius`, `--usa-border`, `--usa-shadow`, `--usa-blur`, `--usa-font` — which you can also set yourself. (`<usa-spinner>`, `<usa-check>`, `<usa-dialog>` and `<usa-acrylic>` pick their kind with `kind`; since 3.0 `variant` is only a style variant everywhere.)
|
|
159
|
+
|
|
160
|
+
| Element | What it does | Key attributes | JS API / events |
|
|
161
|
+
|---|---|---|---|
|
|
162
|
+
| `<usa-tabs>` | Tabs with a sliding spring indicator (`[data-tab]` + `[data-panel]`) | `selected`, `indicator` (`line` · `pill`) | `selected`, `select(i)`; `usa:change` |
|
|
163
|
+
| `<usa-drawer>` | Side panel, swipe to close | `open`, `side` (`left` · `right` · `top` · `bottom`), `label`; `[data-close]` | `open`, `show()`, `close()`; `usa:open`, `usa:close` |
|
|
164
|
+
| `<usa-bottom-sheet>` | Draggable sheet with snap points | `open`, `snap` (`0.5,0.92`), `start`, `label`; `[data-handle]` | `usa:open`, `usa:close`, `usa:snap` |
|
|
165
|
+
| `<usa-pull-refresh>` | Pull-to-refresh scroller | `threshold` (70), `label`, `disabled` | `refresh()`, `refreshing`; `usa:refresh` (`detail.done()`), `onrefresh` |
|
|
166
|
+
| `<usa-fab>` | FAB speed dial (first child = main button) | `open`, `direction` (`up` · `down` · `left` · `right` · `radial`), `position`, `gap` (56) | `open`, `toggle()`; `usa:toggle` |
|
|
167
|
+
| `<usa-navbar>` | Auto-hiding app bar | `threshold` (64), `shrink`, `target` | `show()`, `hiddenByScroll`; `usa:hide`, `usa:show` |
|
|
168
|
+
| `<usa-slider>` | Range slider (form-associated) | `value`, `min`, `max`, `step`, `name`, `label`, `bubble`, `disabled` | `value`; `input`/`change`, `usa:input`/`usa:change`; `--usa-slider` |
|
|
169
|
+
| `<usa-rating>` | Star rating | `value`, `max` (5), `icon`, `readonly`, `label`, `name` | `value`; `change`, `usa:change` |
|
|
170
|
+
| `<usa-tooltip>` | Tooltip on hover / focus | `text`, `placement` (`top`), `delay` (300) | `show()`, `hide()` |
|
|
171
|
+
| `<usa-popover>` | Click-to-open panel (`[data-popover]`) | `open`, `placement` (`bottom`) | `open`, `toggle()`; `usa:open`, `usa:close` |
|
|
172
|
+
| `<usa-badge>` | Count / dot badge | `value`, `max` (99), `dot`, `pulse`, `show-zero`, `label` | `value` |
|
|
173
|
+
| `<usa-avatar-stack>` | Overlapping avatars | `max` (5), `size` (36), `overlap` (0.35), `label` | — |
|
|
174
|
+
| `setVariant(v)` · `VARIANTS` · `adoptVariants()` | Page-wide variant / token sheet | — | — |
|
|
175
|
+
|
|
176
|
+
### 11. Page & app-wide — `components/page`
|
|
177
|
+
|
|
178
|
+
| Element / API | What it does | Key attributes / options | JS API / events |
|
|
179
|
+
|---|---|---|---|
|
|
180
|
+
| `pageTransition(update, opts)` | SPA page transition (View Transitions) | `effect` (`fade` · `slide` · `slide-left` · `slide-right` · `slide-up` · `circle` · `blinds` · `pixel` · `zoom`), `x`, `y`, `duration`, `fallback` | Promise |
|
|
181
|
+
| `enableMpaTransitions(effect)` | Cross-document (MPA) transitions | effect, duration | — |
|
|
182
|
+
| `themeTransition(apply, { x, y })` | Circle-reveal theme switch | — | Promise |
|
|
183
|
+
| `<usa-cursor>` | Custom cursor | `mode` (`dot` · `magnetic` · `glow`; 6.0 removed `trail` → `comet-trail` effect), `color`, `size`, `hide-native`, `targets` | `active` |
|
|
184
|
+
| `smoothScroll(opts)` · `scrollToTarget(to, opts)` | Wheel smoothing · spring scroll-to | `target`, `lerp` (0.12), `wheelMultiplier` · `offset`, `preset` | returns stop fn · Promise |
|
|
185
|
+
| `<usa-fullpage>` | Full-screen snapping sections | `dots`, `axis` (`y` · `x`) | `index`, `go(i)`, `next()`, `prev()`; `usa:section` |
|
|
186
|
+
| `<usa-loading-bar>` · `loadingBar` | Top loading bar | `color`, `height` (3), `position` | `start()`, `set(p)`, `done()`, `track(promise)` |
|
|
187
|
+
| `<usa-back-to-top>` | Back-to-top with progress ring | `offset` (300), `label`, `focus-target`, `position` | `visible` |
|
|
188
|
+
| `<usa-ambient>` | Page-wide ambient layer | `effect` (`particles` · `snow` · `stars` · `noise` · `gradient`), `density`, `color`, `opacity`, `layer`, `speed` | — |
|
|
189
|
+
| `<usa-splash>` | Splash / launch screen | `min` (600), `exit` (`fade` · `scale` · `slide-up` · `circle`), `manual`, `label` | `done()`; `usa:done` |
|
|
190
|
+
| `<usa-auto-skeleton>` | Automatic skeletons | `loading`; `data-no-skeleton` on children | `loading` |
|
|
191
|
+
| `<usa-motion-switch>` · `setMotionIntensity()` | Global motion intensity | `labels`, `label` · `'off' \| 'low' \| 'normal' \| 'high'`, `persist` | `usa:change`; `--usa-motion`, `data-usa-motion` |
|
|
192
|
+
|
|
193
|
+
### v2.8 additions to Text, Background & Windows
|
|
194
|
+
|
|
195
|
+
| Element / API | Category | What it does | Key attributes |
|
|
196
|
+
|---|---|---|---|
|
|
197
|
+
| `<usa-wave-text>` | text | Letters bob in a wave | `amplitude` (0.25em), `speed` (1.6s), `stagger` (0.06s) |
|
|
198
|
+
| `<usa-glitch>` | text | RGB-split glitch | `trigger` (`always` · `hover`), `intensity` (3px) |
|
|
199
|
+
| `<usa-gradient-text>` | text | Flowing gradient fill | `colors`, `speed` (6s), `angle` (90) |
|
|
200
|
+
| `<usa-handwriting>` | text | Stroke-by-stroke draw, then fill | `text`, `duration` (2400), `size` (64), `font`, `stroke`; `play()`, `usa:complete` |
|
|
201
|
+
| `<usa-scroll-highlight>` | text | Words light up while reading / marker sweep | `mode` (`words` · `marker`), `dim` (0.2), `color`; `progress` |
|
|
202
|
+
| `<usa-grid-glow>` | background | Grid lit around the pointer | `size` (32), `radius` (220), `color` |
|
|
203
|
+
| `<usa-blobs>` | background | Fluid morphing blobs | `colors`, `speed` (1), `blur` (60) |
|
|
204
|
+
| `<usa-water-ripple>` | background | Interactive water ripples (canvas) | `damping` (0.96), `strength` (1), `color` (`r,g,b`); `drop(x, y, s?)` |
|
|
205
|
+
| `<usa-dot-network>` | background | Dot grid linking to the pointer (canvas) | `gap` (28), `radius` (140), `color` (`r,g,b`) |
|
|
206
|
+
| `fluentPreset(opts)` | background | Windows 11 Fluent: variant + Mica tint + Acrylic + Reveal highlight | `reveal`, `mica`, `selector`, `root`; returns undo |
|
|
207
|
+
|
|
208
|
+
WinUI 3 / WebView2 sample app: [`examples/webview2-winui/`](../examples/webview2-winui/).
|
|
209
|
+
|
|
210
|
+
## Theme tokens
|
|
211
|
+
|
|
212
|
+
Every component reads these CSS custom properties (set them on `:root`, any ancestor, or via `variant` / `setVariant()`):
|
|
213
|
+
|
|
214
|
+
| Token | Used for |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `--usa-accent` / `--usa-accent-text` | primary colour (toggles, sliders, tabs indicator, checkbox, progress, focus rings) / text on it |
|
|
217
|
+
| `--usa-surface` / `--usa-text` | panels (drawer, sheet, popover, tooltip, back-to-top) |
|
|
218
|
+
| `--usa-radius`, `--usa-border`, `--usa-shadow`, `--usa-blur`, `--usa-font` | shape, outline, elevation, glass blur, typography |
|
|
219
|
+
| `--usa-motion` | global motion intensity (0 · 0.6 · 1 · 1.25), set by `setMotionIntensity()` |
|
|
220
|
+
|
|
221
|
+
## Framework entry points (v2.9)
|
|
222
|
+
|
|
223
|
+
| Import | What |
|
|
224
|
+
|---|---|
|
|
225
|
+
| `motionary/components/react` | `createUsaComponents(React)` typed wrappers (props, ref, `onUsa*` events) |
|
|
226
|
+
| `motionary/components/vue` | `isUsaElement`, `UsaPlugin` |
|
|
227
|
+
| `motionary/components/jsx` | `UsaIntrinsicElements` JSX types |
|
|
228
|
+
| `motionary/components/lazy` | `lazyDefine()`, `defineUsed()`, `loadCategory()` |
|
|
229
|
+
|
|
230
|
+
See [frameworks-ssr.md](./frameworks-ssr.md) and [accessibility.md](./accessibility.md).
|
|
231
|
+
|
|
232
|
+
### v3.1 Timeline & choreography (`components/timeline`)
|
|
233
|
+
|
|
234
|
+
| Element / API | What it does | Key options |
|
|
235
|
+
|---|---|---|
|
|
236
|
+
| `timeline(opts)` | One playhead for many animations | `.to(target, frames \| preset, { at, duration, easing, stagger })`, `.label()`, `.call()`, `play()`, `reverse()`, `seek()`, `progress()`, `scrub(el, { smooth })` |
|
|
237
|
+
| `<usa-timeline>` | `data-tl` children become steps | `trigger` (`view` · `click` · `manual`), `scrub`, `overlap`, `duration`, `stagger`, `repeat`; child `data-at`, `data-duration`, `data-label` |
|
|
238
|
+
|
|
239
|
+
Positions: `'>'` chain (default) · `'<'` with previous · `'-=200'` overlap · `'+=100'` gap · `'<+=50'` · `'label+=100'` · ms.
|
|
240
|
+
|
|
241
|
+
### v3.2 Gestures (`components/gesture`)
|
|
242
|
+
|
|
243
|
+
| Element / API | What it does | Key options |
|
|
244
|
+
|---|---|---|
|
|
245
|
+
| `gesture(el, handlers, opts)` | Pan · swipe · pinch · long-press · tap · double-tap | `onPan({ dx, dy, vx, vy, first, last })`, `onSwipe({ direction, velocity })`, `onPinch({ scale })`, `onLongPress`, `onTap`, `onDoubleTap`; `axis`, `threshold`, `swipeDistance`, `swipeVelocity`, `longPress`, `wheelPinch` |
|
|
246
|
+
| `<usa-swipeable>` | Swipe to dismiss, spring home | `axis`, `distance` (120), `preset`, `dismiss`; `usa:swipe`, `usa:dismiss`; `swipe(dir)`, `reset()` |
|
|
247
|
+
| `<usa-pinch-zoom>` | Pinch / Ctrl+wheel zoom + pan | `min` (1), `max` (4), `double-tap` (2), `preset`; `zoomTo(k)`, `usa:zoom` |
|
|
248
|
+
|
|
249
|
+
### v3.3 SVG (`components/svg`)
|
|
250
|
+
|
|
251
|
+
| Element / API | What it does | Key attributes |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| `<usa-draw>` | Strokes draw themselves | `trigger` (`view` · `hover` · `click` · `scrub`), `duration` (1600), `stagger` (0.2), `fill`, `repeat`; `progress`, `play()` |
|
|
254
|
+
| `<usa-morph>` | Path morph through shapes | `paths="A \| B"`, `trigger` (`click` · `hover` · `view` · `auto`), `interval` (2000), `duration` (600); `next()`, `usa:change` |
|
|
255
|
+
| `<usa-mask-reveal>` | Mask / clip-path reveal | `shape` (`circle` · `diamond` · `star` · `iris` · `wipe` · `wipe-up`), `at`, `duration` (900), `trigger`, `repeat` |
|
|
256
|
+
| `<usa-anim-icon>` | Animated stroke icons | `name` (`bell` · `heart` · `check` · `arrow` · `star` · `gear` · `search` · `download`), `size`, `label`, `trigger` (`hover` · `click` · `view` · `loop`) |
|
|
257
|
+
| `morphTo(path, d, opts)` · `interpolatePath(a, b, t)` · `drawLines(root)` | Path helpers | `duration`, `easing`; `stagger` |
|
|
258
|
+
|
|
259
|
+
### v3.4 Canvas & WebGL (`components/webgl`)
|
|
260
|
+
|
|
261
|
+
| Element / API | What it does | Key attributes |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| `<usa-shader>` | GPU shader background | `preset` (`gradient` · `plasma` · `waves` · `aurora`), `speed` (1); custom `<script type="x-shader/x-fragment">` |
|
|
264
|
+
| `<usa-distort>` | Hover distortion + RGB split on the `<img>` inside | — (fallback: CSS zoom) |
|
|
265
|
+
| `<usa-liquid>` | Click ripples + hover wobble on the `<img>` inside | `strength` (1) |
|
|
266
|
+
| `glQuad(canvas, frag)` · `supportsWebGL()` | Single-quad WebGL runner | `render({ time, mouse, hover, ripples })`, `resize()`, `texture(img)`, `dispose()` |
|
|
267
|
+
|
|
268
|
+
Fallbacks set `data-fallback` (`webgl` · `image` · `no-image`); cross-origin images need CORS headers.
|
|
269
|
+
|
|
270
|
+
### v3.5 3D & depth (`components/depth`)
|
|
271
|
+
|
|
272
|
+
| Element / API | What it does | Key attributes |
|
|
273
|
+
|---|---|---|
|
|
274
|
+
| `<usa-cube>` | CSS 3D cube, children = faces | `size` (200), `autoplay` (ms), `perspective` (900); `show(face)`, `next()`, `prev()`, `usa:change` |
|
|
275
|
+
| `<usa-depth>` | Depth parallax for `data-depth` layers | `source` (`pointer` · `orientation` · `scroll`), `strength` (40), `rotate` (0); `requestPermission()` |
|
|
276
|
+
| `deviceTilt(cb, opts)` · `requestOrientationPermission()` | Gyroscope tilt -1…1 | `range` (30°), `smooth` (0.2) |
|
|
277
|
+
|
|
278
|
+
3D ring carousel: `<usa-carousel-3d>` (cards).
|
|
279
|
+
|
|
280
|
+
### v3.6 Layout animation (`components/layout`)
|
|
281
|
+
|
|
282
|
+
| Element / API | What it does | Key options |
|
|
283
|
+
|---|---|---|
|
|
284
|
+
| `<usa-auto-animate>` · `autoAnimate(el)` | Add / remove / move / resize of children animates | `duration` (300), `no-scale` / `scale`; `enable()`, `disable()`, `stop()` |
|
|
285
|
+
| `<usa-masonry>` | Masonry grid with animated reflow | `columns` or `min` (220), `gap` (16); `layout()` |
|
|
286
|
+
| `sharedTransition(update, root?)` | Shared-element transition via `data-shared="id"` | `duration` (450), `easing`; View Transitions API or FLIP |
|
|
287
|
+
|
|
288
|
+
Also see `flip()` in `components/transitions`. (4.0 removed `<usa-flip-list>` and `connectedAnimation()` in favour of these.)
|
|
289
|
+
|
|
290
|
+
### v3.7 Visual playground
|
|
291
|
+
|
|
292
|
+
[`showcase/playground.html`](../showcase/playground.html) — stack `<usa-*>` effects around sample content, tweak every attribute live, and export HTML / ES module / React / Vue code or a share link (state in the URL hash).
|
|
293
|
+
|
|
294
|
+
### v3.8 Svelte, Solid & Angular
|
|
295
|
+
|
|
296
|
+
| Entry | API |
|
|
297
|
+
|---|---|
|
|
298
|
+
| `components/svelte` | `use:usa={{ props, on }}`, `defineUsa()` |
|
|
299
|
+
| `components/solid` | `use:usa` directive, `defineUsa()`, JSX types (`prop:` / `on:usa:*` natively) |
|
|
300
|
+
| `components/angular` | `usaInitializer()` (`APP_INITIALIZER`), `defineUsa()`, `usaDetail()`; `CUSTOM_ELEMENTS_SCHEMA` |
|
|
301
|
+
|
|
302
|
+
Hybrid / desktop hosts (MAUI, Flutter WebView, Electron, Tauri): [hybrid-apps.md](./hybrid-apps.md).
|
|
303
|
+
|
|
304
|
+
### v3.9 Effect packs (`components/packs`)
|
|
305
|
+
|
|
306
|
+
| Pack | `data-role` → effect |
|
|
307
|
+
|---|---|
|
|
308
|
+
| `ecommerce` | `product` reveal + lift · `add-to-cart` press + fly to `cart` · `cart` bump · `price` count up · `badge` pulse |
|
|
309
|
+
| `portfolio` | `project` reveal + lift · `heading` reveal · `stat` count up · `contact` press + pulse |
|
|
310
|
+
| `dashboard` | `card` reveal · `stat` count up · `alert` pulse · `action` press |
|
|
311
|
+
| `game` | `button` press · `score` count up + bump · `item` float · `hit` shake · `reward` pulse |
|
|
312
|
+
| `landing` | `hero` reveal · `feature` reveal + lift · `cta` press + pulse · `logo` float · `stat` count up |
|
|
313
|
+
|
|
314
|
+
`<usa-pack>` (e.g. `<usa-pack name="ecommerce">…</usa-pack>`) or `applyPack('ecommerce', root)`; helpers `flyToCart(from, to)`, `countUp(el)`.
|
|
315
|
+
|
|
316
|
+
**Deprecated in 3.9, removed in 4.0.0:** `sequence()`, `connectedAnimation()`, `<usa-flip-list>` — see [upgrading-4.md](./upgrading-4.md).
|
|
317
|
+
|
|
318
|
+
### v4.8 GPU particles, post-processing & adaptive quality (`components/webgl`)
|
|
319
|
+
|
|
320
|
+
- **Particle presets** for `<usa-shader preset="…">`: `snow`, `fireflies`, `stars` (warp starfield), `bokeh`, `rain` — procedural in the fragment shader, no buffers or per-particle JS.
|
|
321
|
+
- **`<usa-post-fx>`** (`definePostFx()`), e.g. `<usa-post-fx effects="vignette grain" intensity="0.6"><img …></usa-post-fx>` — chained passes `vignette` · `grain` · `chromatic` · `scanlines` · `crt` · `bloom` · `pixelate` · `duotone` · `glitch`; `postFxShader(list)` builds the same shader for your own `glQuad()`.
|
|
322
|
+
- **Unified fallback** — without WebGL every preset shows a still CSS rendering (`GL_FALLBACKS`, `glFallbackCss()`); post-fx images get an approximate CSS filter.
|
|
323
|
+
- **Adaptive quality** — every GL element measures its frame rate: after two slow seconds (< 40 fps) the drawing buffer drops to 50 % then 35 % resolution and climbs back after five good seconds; on battery saver (Battery Status API ≤ 20 % and not charging, or Save-Data) it renders at ≤ 30 fps and ≤ 60 % resolution. `quality="high"` opts out; `data-quality` shows the current scale. `glGovernor()` / `watchPowerSaver()` for your own loops; `glQuad().render({ extra })` sets any float uniform, `resize(scale)` scales the buffer.
|
|
324
|
+
|
|
325
|
+
### v5.0 Effects — unified plugin API (`components/fx`)
|
|
326
|
+
|
|
327
|
+
`<usa-fx>` (`defineFx()`, `defineFxComponents()`) plays any registered effect on its first child: `<usa-fx effect="jelly" trigger="click"><button>Go</button></usa-fx>` — `trigger` `click` · `hover` · `enter` · `load` · `loop` · `manual`, `options` (JSON), `once`, `self`.
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
import { registerEffect, playEffect, bindEffect, listEffects } from 'motionary/components/fx';
|
|
331
|
+
registerEffect({ name: 'spin-pop', kind: 'attention', run: (el, o, ctx) => ctx.animate(el, frames, { duration: 700 }) });
|
|
332
|
+
await playEffect(el, 'spin-pop');
|
|
333
|
+
const unbind = bindEffect(card, 'fade-up', { trigger: 'enter' });
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Built-ins (`BUILTIN_EFFECTS`): every timeline preset as an `enter` effect (`fade-up`, `clip-up`, `blur`…), attention seekers `pulse` · `pop` · `jelly` · `wiggle` · `heartbeat` · `bounce` · `flash` · `tada` · `shake`, click effects `burst` · `confetti` · `ripple`. `ctx.animate()` applies reduced motion, motion sensitivity, intensity and the animation budget; `loop` / `background` / `cursor` effects are skipped under reduced motion unless they declare `reduced: 'run'`.
|
|
337
|
+
|
|
338
|
+
### v5.1 Card & click effects 2.0 (`components/effects`)
|
|
339
|
+
|
|
340
|
+
The 5.x effect packs live in `motionary/components/effects` (not in `components` / `components/lite`). Register them once, then use any name with `<usa-fx>`, `playEffect()` or `bindEffect()`:
|
|
341
|
+
|
|
342
|
+
```js
|
|
343
|
+
import { registerAllEffects } from 'motionary/components/effects';
|
|
344
|
+
registerAllEffects();
|
|
345
|
+
```
|
|
346
|
+
```html
|
|
347
|
+
<usa-fx effect="holo" trigger="load"><article class="card">…</article></usa-fx>
|
|
348
|
+
<usa-fx effect="shockwave"><button>Boom</button></usa-fx>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Card: `holo` · `glare-sweep` · `book-open` · `card-fan` · `topple` · `float-tilt`. Click: `shockwave` · `ink-splash` · `star-burst` · `jelly-press` · `ring-ripple` · `emoji-rain`. Reduced motion: particles skipped, presses fade, loops don’t start.
|
|
352
|
+
|
|
353
|
+
### v5.2 Bounce & physics (`components/effects`)
|
|
354
|
+
|
|
355
|
+
`bounce-in` · `rubber-band` · `elastic-hover` · `drop-bounce` · `gravity-text` · `spring-follow` · `bell-swing` — keyframes come from a damped-spring / gravity solver and play on WAAPI.
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
import { registerAllEffects, solveSpring, springKeyframes } from 'motionary/components/effects';
|
|
359
|
+
registerAllEffects();
|
|
360
|
+
const { frames, duration } = springKeyframes((p) => ({ transform: `scale(${p})` }), { stiffness: 220, damping: 11 });
|
|
361
|
+
el.animate(frames, { duration });
|
|
362
|
+
```
|
|
363
|
+
```html
|
|
364
|
+
<usa-fx effect="drop-bounce" trigger="enter" options='{"height":160,"bounce":0.6}'><img src="badge.svg" alt="New"></usa-fx>
|
|
365
|
+
<usa-fx effect="elastic-hover" trigger="load"><article class="card">…</article></usa-fx>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### v5.3 Page-wide effects (`components/effects`)
|
|
369
|
+
|
|
370
|
+
Transitions `curtain` · `iris` · `pixel-dissolve` · `blinds` cover the viewport, await `onCovered()`, then reveal:
|
|
371
|
+
|
|
372
|
+
```js
|
|
373
|
+
import { registerAllEffects } from 'motionary/components/effects';
|
|
374
|
+
import { playEffect } from 'motionary/components/fx';
|
|
375
|
+
registerAllEffects();
|
|
376
|
+
link.addEventListener('click', (e) => {
|
|
377
|
+
e.preventDefault();
|
|
378
|
+
playEffect(link, 'iris', { onCovered: () => router.go(link.href), color: '#111' });
|
|
379
|
+
});
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Persistent: `<usa-fx effect="velocity-skew" trigger="load">`, `spotlight` (`radius`, `dim`), `edge-glow` (`color`, `size`). Reduced motion: transitions cross-fade (150 ms), persistent effects are off.
|
|
383
|
+
|
|
384
|
+
### v5.4 Scroll stories — `<usa-story>` (`components/effects`)
|
|
385
|
+
|
|
386
|
+
```js
|
|
387
|
+
import { defineStory } from 'motionary/components/effects';
|
|
388
|
+
defineStory();
|
|
389
|
+
```
|
|
390
|
+
```html
|
|
391
|
+
<usa-story template="pin">
|
|
392
|
+
<figure data-stage>…</figure>
|
|
393
|
+
<section data-step>Chapter 1</section>
|
|
394
|
+
<section data-step>Chapter 2</section>
|
|
395
|
+
</usa-story>
|
|
396
|
+
<usa-story template="gallery"><div data-sticky><div data-track>…cards…</div></div></usa-story>
|
|
397
|
+
<usa-story template="compare" label="Before / after"><div data-sticky><img data-before …><img data-after …></div></usa-story>
|
|
398
|
+
<usa-story template="counter"><strong data-count="12,480">0</strong></usa-story>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Templates `pin` · `gallery` · `zoom` (`zoom="6"`) · `compare` · `counter` · `highlight`. Each sets `--usa-story-progress`, fires `usa-story-step`, and exposes `progress`, `step`, `update()`. Reduced motion: no sliding / zooming, final counter values. Demo: `showcase/story.html`.
|
|
402
|
+
|
|
403
|
+
### v5.5 Generative backgrounds (`components/effects`)
|
|
404
|
+
|
|
405
|
+
`flow-field` · `voronoi` · `mesh-gradient` · `starfield` · `metaballs` · `contours` (kind `background`) — Canvas 2D behind the element’s content, rendering only while visible, with adaptive quality; reduced motion draws one static frame.
|
|
406
|
+
|
|
407
|
+
```html
|
|
408
|
+
<usa-fx effect="mesh-gradient" trigger="load" self class="hero" options='{"colors":["#7c5cff","#ff5c8a","#22d3ee"],"speed":0.6}'>
|
|
409
|
+
<h1>Hello</h1>
|
|
410
|
+
</usa-fx>
|
|
411
|
+
```
|
|
412
|
+
```js
|
|
413
|
+
import { registerEffect } from 'motionary/components/fx';
|
|
414
|
+
import { canvasBackground } from 'motionary/components/effects';
|
|
415
|
+
registerEffect({ name: 'pulse-bg', kind: 'background', reduced: 'run',
|
|
416
|
+
run: (el, o, ctx) => canvasBackground(el, ctx, { draw: ({ ctx: g, w, h, t }) => { g.fillStyle = `hsl(${t * 40} 70% 50%)`; g.fillRect(0, 0, w, h); } }, o) });
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### v5.6 Sound-reactive effects (`components/effects`)
|
|
420
|
+
|
|
421
|
+
`spectrum-bars` · `pulse-ring` · `wave-ring` (kind `background`) react to a Web Audio analyser; `enableAudio()` must run inside a user gesture. Beat detection plays any registered effect.
|
|
422
|
+
|
|
423
|
+
```html
|
|
424
|
+
<audio id="track" src="song.mp3" controls></audio>
|
|
425
|
+
<usa-audio source="#track" label="Play with visuals">
|
|
426
|
+
<usa-fx effect="spectrum-bars" trigger="load" self options='{"mirror":true}'><h2>Now playing</h2></usa-fx>
|
|
427
|
+
<div data-usa-beat="pop">♪</div>
|
|
428
|
+
</usa-audio>
|
|
429
|
+
```
|
|
430
|
+
```js
|
|
431
|
+
import { enableAudio, bindBeat, registerAllEffects } from 'motionary/components/effects';
|
|
432
|
+
registerAllEffects();
|
|
433
|
+
button.addEventListener('click', async () => {
|
|
434
|
+
await enableAudio('mic'); // or an <audio>/<video> element, selector or MediaStream
|
|
435
|
+
bindBeat(logo, 'pop', { threshold: 1.4, cooldown: 300 });
|
|
436
|
+
});
|
|
437
|
+
```
|
|
438
|
+
Reduced motion: visuals skipped, beats trigger nothing; audio keeps playing.
|
|
439
|
+
|
|
440
|
+
### v5.7 Cursor & gesture packs (`components/effects`)
|
|
441
|
+
|
|
442
|
+
Cursor effects (`comet-trail` · `ribbon-trail` · `sparkle-trail` · `magnetic-dots` · `spotlight-cursor`, kind `cursor`) are persistent and scoped to the element; gestures (`fling`, `twist`, `long-press`) fire any registered effect.
|
|
443
|
+
|
|
444
|
+
```html
|
|
445
|
+
<usa-fx effect="comet-trail" trigger="load" self options='{"color":"#22d3ee"}'><section class="hero">…</section></usa-fx>
|
|
446
|
+
<usa-gesture-fx gesture="long-press" effect="tada"><button>Hold me</button></usa-gesture-fx>
|
|
447
|
+
```
|
|
448
|
+
```js
|
|
449
|
+
import { bindGesture, registerAllEffects } from 'motionary/components/effects';
|
|
450
|
+
registerAllEffects();
|
|
451
|
+
bindGesture(card, 'fling', 'confetti', { velocity: 1 });
|
|
452
|
+
bindGesture(dial, 'twist', ({ direction }) => step(direction === 'cw' ? 1 : -1));
|
|
453
|
+
```
|
|
454
|
+
`--usa-charge` (0–1) lets CSS show long-press progress. Reduced motion: cursor effects off.
|
|
455
|
+
|
|
456
|
+
### v5.8 Theme packs & micro-interactions (`components/effects`)
|
|
457
|
+
|
|
458
|
+
```html
|
|
459
|
+
<usa-theme name="glass">
|
|
460
|
+
<div class="usa-surface">
|
|
461
|
+
<button data-theme-fx="click">Tap</button>
|
|
462
|
+
<usa-fx effect="like-heart" trigger="click"><button aria-pressed="false">♥ <span data-count="12">12</span></button></usa-fx>
|
|
463
|
+
<usa-fx effect="copy-success" trigger="click"><button data-copy="npm i motionary">Copy</button></usa-fx>
|
|
464
|
+
</div>
|
|
465
|
+
</usa-theme>
|
|
466
|
+
```
|
|
467
|
+
```js
|
|
468
|
+
import { applyTheme, themeCss, playEffect, registerAllEffects } from 'motionary/components/effects';
|
|
469
|
+
registerAllEffects();
|
|
470
|
+
const undo = applyTheme('neon'); // whole page: design + motion tokens + data-usa-theme
|
|
471
|
+
const css = themeCss('paper', ':root'); // static CSS for SSR
|
|
472
|
+
playEffect(passwordToggle, 'password-reveal');
|
|
473
|
+
```
|
|
474
|
+
Themes: `neon` · `paper` · `glass` · `retro` · `brutalist`. Micro effects keep working (state, labels, counts) under reduced motion.
|
|
475
|
+
|
|
476
|
+
### v5.9 `<usa-player>`
|
|
477
|
+
|
|
478
|
+
Plays JSON animations made of timeline presets, keyframes and registered effects on one clock.
|
|
479
|
+
|
|
480
|
+
```html
|
|
481
|
+
<usa-player trigger="view" controls>
|
|
482
|
+
<h1>Title</h1>
|
|
483
|
+
<a class="cta">Start</a>
|
|
484
|
+
<script type="application/json">
|
|
485
|
+
{ "format": "use-scroll-animate/animation", "version": 1,
|
|
486
|
+
"tracks": [
|
|
487
|
+
{ "target": "h1", "start": 0, "duration": 600, "preset": "fade-up" },
|
|
488
|
+
{ "target": ".cta", "start": 400, "duration": 500, "keyframes": [{ "opacity": 0, "transform": "scale(.8)" }, { "opacity": 1, "transform": "none" }] },
|
|
489
|
+
{ "target": ".cta", "start": 1000, "effect": "jelly" }
|
|
490
|
+
] }
|
|
491
|
+
</script>
|
|
492
|
+
</usa-player>
|
|
493
|
+
```
|
|
494
|
+
```js
|
|
495
|
+
import { createPlayer, registerAllEffects } from 'motionary/components/effects';
|
|
496
|
+
registerAllEffects();
|
|
497
|
+
const p = createPlayer(hero, await (await fetch('/hero.json')).json());
|
|
498
|
+
p.play(); p.seek(500); p.rate = 0.5;
|
|
499
|
+
```
|
|
500
|
+
`trigger="scroll"` scrubs the animation with the page. Reduced motion: the final state, no effects. Export JSON from the Playground (`<usa-player> JSON` tab).
|
|
501
|
+
|
|
502
|
+
### v6.2 Widgets: carousel, tab bar, accordion 2.0, stories (`components/widgets`) + GPU pack (`components/fx-gpu`)
|
|
503
|
+
|
|
504
|
+
```html
|
|
505
|
+
<usa-carousel effect="cards" loop autoplay="4000" label="Featured">
|
|
506
|
+
<img src="a.jpg" alt="…"><img src="b.jpg" alt="…"><img src="c.jpg" alt="…">
|
|
507
|
+
</usa-carousel>
|
|
508
|
+
|
|
509
|
+
<usa-tab-bar indicator="pill">
|
|
510
|
+
<button>Overview</button><button>Specs</button>
|
|
511
|
+
<div data-panel>…</div><div data-panel>…</div>
|
|
512
|
+
</usa-tab-bar>
|
|
513
|
+
|
|
514
|
+
<usa-disclosure variant="cards">
|
|
515
|
+
<details><summary>Shipping</summary><p>…</p></details>
|
|
516
|
+
</usa-disclosure>
|
|
517
|
+
|
|
518
|
+
<usa-stories duration="5000" loop><img src="1.jpg" alt="…"><img src="2.jpg" alt="…"></usa-stories>
|
|
519
|
+
|
|
520
|
+
<usa-fx effect="fluid" trigger="load" self class="hero"><h1>Hello</h1></usa-fx>
|
|
521
|
+
```
|
|
522
|
+
```js
|
|
523
|
+
import { defineWidgets } from 'motionary/components/widgets';
|
|
524
|
+
import { defineFx } from 'motionary/components/fx';
|
|
525
|
+
import { registerGpuEffects } from 'motionary/components/fx-gpu';
|
|
526
|
+
defineWidgets(); defineFx(); registerGpuEffects();
|
|
527
|
+
document.querySelector('usa-carousel').next();
|
|
528
|
+
```
|
|
529
|
+
No build: `components.umd.js` + `widgets.umd.js`. GPU effects: `fluid` · `smoke` · `fire` · `ink` · `fireflies` (WebGL2 → Canvas 2D) · `sakura` · `leaves` (Canvas 2D) · `splash` (click). Reduced motion: instant switches, no autoplay, one still frame.
|
|
530
|
+
|
|
531
|
+
## Frameworks
|
|
532
|
+
|
|
533
|
+
Custom elements work in every framework. Register once (e.g. in your entry file), then use the tags.
|
|
534
|
+
|
|
535
|
+
```jsx
|
|
536
|
+
// React 19 passes props to custom elements as properties; React 18 passes strings — both work for attributes.
|
|
537
|
+
import { defineFeedbackComponents, toast } from 'motionary/components/feedback';
|
|
538
|
+
defineFeedbackComponents();
|
|
539
|
+
|
|
540
|
+
export function Save() {
|
|
541
|
+
return <button onClick={() => toast('Saved', { type: 'success' })}>Save <usa-spinner kind="dots" size="16" /></button>;
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
```js
|
|
546
|
+
// Vue (vite.config.js): tell the compiler these are custom elements
|
|
547
|
+
vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('usa-') } } });
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
TypeScript: the entries augment `HTMLElementTagNameMap`, so `document.querySelector('usa-dialog')` is typed as `UsaDialogElement`.
|
|
551
|
+
|
|
552
|
+
## Size
|
|
553
|
+
|
|
554
|
+
Gzipped, minified (budgets enforced in CI by `npm run size:check`):
|
|
555
|
+
|
|
556
|
+
| Import | gzip |
|
|
557
|
+
|---|---:|
|
|
558
|
+
| `dist/components.umd.js` (all 30 + CSS) | ≈ 22 kB |
|
|
559
|
+
| one category (`components/text`, …) | 3.5 – 6.4 kB |
|
|
560
|
+
| one component (`defineTypewriter`, `defineReveal`, `defineRipple`, …) | ≈ 1.8 – 2.5 kB |
|
|
561
|
+
| `viewTransition` only | ≈ 0.4 kB |
|
|
562
|
+
| `dist/components.css` | ≈ 5.5 kB |
|
|
563
|
+
|
|
564
|
+
The scroll-animation core (`motionary`) is unchanged and is not pulled in by the components.
|