Repository navigation
feat(core): a theme's motion takes tempo and character #8661
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c3831c0
feat(core): a theme's motion takes tempo, character and reducedMotion
vjeux a2d7f42
fix(core): reducedMotion takes only 'system' until components follow …
cixzhang c5156c0
fix(core): resolveThemeMotion resolves references, and every motion d…
cixzhang 71d0814
docs(core): every motion doc names the three knobs, their precedence …
cixzhang 7aa40d2
Merge main into uikit/f1-theme-motion-knobs
cixzhang 72881da
fix(core): theme motion keeps reducedMotion internal, exports its typ…
cixzhang 18b09c4
fix(core): a partial duration scale beside a motion knob is refused, …
cixzhang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| --- | ||
| '@astryxdesign/core': patch | ||
| '@astryxdesign/cli': patch | ||
| --- | ||
|
|
||
| [feat] A theme's `motion` takes two knobs beside the duration scale: `tempo` (0.75–1.5) scales every motion duration, and `character` (`'crisp'`, `'standard'` or `'expressive'`) sets the new `--ease-entrance` and `--ease-move` tokens; `--ease-exit` stays the same at every character. Their types, `ThemeMotionConfig`, `ThemeMotionKnobs` and `MotionCharacter`, are exported. A theme without them renders exactly as before; a duration scale and explicit tokens win over the knobs, Spinner's and Skeleton's loops keep their timing under every tempo, and the press release fade follows tempo up to the 200 ms Reduce Motion cap under the person's setting. Springs don't read the knobs yet. The motion, token and theme-authoring docs and the theme template describe the knobs. | ||
|
|
||
| @vjeux |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,8 @@ applies_to: | |
| packages/core/src/theme/expandTypeScale.ts, | ||
| packages/core/src/theme/expandRadiusScale.ts, | ||
| packages/core/src/theme/expandMotionScale.ts, | ||
| packages/core/src/theme/themeMotion.ts, | ||
| packages/core/src/theme/motionKnobs.ts, | ||
| packages/core/src/theme/mergeComponents.ts, | ||
| packages/core/src/theme/onMediaTokens.ts, | ||
| packages/core/src/theme/localTokens.ts, | ||
|
|
@@ -33,6 +35,7 @@ verified_by: | |
| packages/core/src/theme/expandTypeScale.test.ts, | ||
| packages/core/src/theme/expandRadiusScale.test.ts, | ||
| packages/core/src/theme/expandMotionScale.test.ts, | ||
| packages/core/src/theme/themeMotion.test.ts, | ||
| packages/core/src/theme/onMediaTokens.test.ts, | ||
| scripts/check-theme-template.test.mjs, | ||
| ] | ||
|
|
@@ -52,6 +55,7 @@ deciding_specs: | |
| spec:AST-087/DEC-7, | ||
| spec:AST-087/DEC-9, | ||
| spec:AST-087/DEC-10, | ||
| spec:AST-108/DEC-1, | ||
| ] | ||
| --- | ||
|
|
||
|
|
@@ -192,6 +196,24 @@ it, typed as that theme's listed names. | |
| - **INV14 — The variant list is theme-level.** `iconVariants` lists the variant | ||
| names the whole theme supports. It is never per icon and never combined with | ||
| another theme's list. | ||
| - **INV15 — Motion is three knobs beside the duration scale.** `motion` takes | ||
| `tempo` (clamped to 0.75–1.5), `character` (`crisp`, `standard`, | ||
| `expressive`), and `reducedMotion` (`system`, `always`) beside the duration | ||
| scale. `tempo` scales every duration token and `character` sets | ||
| `--ease-entrance` and `--ease-move`; with tempo 1 and `standard` the tokens | ||
| are the defaults. A duration scale's durations win over `tempo`, and | ||
| explicit tokens win over both. An extending theme inherits motion field by | ||
| field: a duration-scale field or knob the child leaves unset keeps its | ||
| base's value. Each duration's | ||
| value before `tempo` is kept for busy-indicator loops, which never follow | ||
| `tempo`. Neither `tempo` nor `character` moves finger tracking, momentum, | ||
| the rubber band, the on-screen keyboard, the press model's onset delay, | ||
| cancel distance and tap flash, hover-intent delays, gesture thresholds, | ||
| busy-indicator loops, or the 200 ms Reduce Motion cap (`spec:AST-108` FR4). | ||
| `reducedMotion: 'always'` marks the theme's root, and what keys | ||
| reduced motion on `prefers-reduced-motion` keys it on that mark as well | ||
| (`spec:AST-108` FR6). An adaptation rule may set `tempo` and `character`, | ||
| never `reducedMotion`. | ||
|
|
||
| This record does not own: | ||
|
|
||
|
|
@@ -249,6 +271,9 @@ public surface belongs to | |
|
|
||
| ## Owning code | ||
|
|
||
| - An internal, pure `resolveThemeMotion(theme)` returns a theme's motion | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| knobs, durations, and easings for the animator and for server code; it | ||
| touches no DOM and has no import-time side effects (`spec:AST-108` FR6). | ||
| - `packages/core/src/theme/defineTheme.ts` owns the public input, normalized IR, | ||
| orchestration, and extension behavior. | ||
| - `themeAdaptations.ts` owns the fixed breakpoint/condition vocabulary, | ||
|
|
@@ -257,6 +282,9 @@ public surface belongs to | |
| adopts their tokens. | ||
| - `expandColorScale.ts`, `expandTypeScale.ts`, `expandRadiusScale.ts`, and | ||
| `expandMotionScale.ts` own their derived token/component values. | ||
| - `motionKnobs.ts` owns the motion knobs' types, defaults and clamping; | ||
| `themeMotion.ts` owns the tokens and pre-tempo durations they generate, and | ||
| `resolveThemeMotion`, the pure read the animator and server code use. | ||
| - `mergeComponents.ts` owns the shared deep-merge rule. | ||
| - `onMediaTokens.ts` owns normalization of inverted-surface overrides. | ||
| - `localTokens.ts` owns opt-in enrollment, valid CSS custom-property names, exact | ||
|
|
@@ -275,7 +303,9 @@ behavior. AST-012 decisions 1–4 establish the fixed width map, named closed co | |
| ordered rule cascade, and source/built adaptation metadata parity. AST-017 decision 1 | ||
| owns released compatibility classification and migration. AST-087 decisions 2, 7, 9, | ||
| and 10 establish function icon entries, node-valued public reads, the theme-level | ||
| `iconVariants` list, and the static public view of `componentIcons`. | ||
| `iconVariants` list, and the static public view of `componentIcons`. AST-108 | ||
| decision 1 establishes the three motion knobs and keeps per-role motion values | ||
| internal. | ||
|
|
||
| ## Known conformance and verification gaps | ||
|
|
||
|
|
@@ -285,11 +315,17 @@ classify local references. Until the implementation lands, INV8's prefix-indepen | |
| clauses are current authority but not enforcement. Existing explicit enrollment, | ||
| owner, lineage, collision, cycle, and legacy-unenrolled behavior remains shipped. | ||
|
|
||
| The motion resolver is accepted but unshipped: an internal, pure | ||
| `resolveThemeMotion(theme)` returns a theme's motion knobs, durations, easings, | ||
| and role tables for the animator and for server code, touching no DOM and with | ||
| no import-time side effects (`spec:AST-108` FR6). Until it lands, FR6's | ||
| resolution is current authority but not enforcement. | ||
| `resolveThemeMotion`'s role tables are accepted but unshipped (`spec:AST-108` | ||
| FR6): no spring reads the motion knobs yet. Until they land, that part of FR6 | ||
| is current authority but not enforcement. | ||
|
|
||
| `reducedMotion: 'always'` is accepted but unshipped (`spec:AST-108` FR6, | ||
| INV15): the public `motion` type has no `reducedMotion` field, every theme | ||
| follows each person's setting as `'system'` does, and nothing marks a | ||
| theme's root, until component styles, the animator, script readers of | ||
| `prefers-reduced-motion`, and motion-keyed adaptation rules key reduced motion | ||
| on the mark. Until then, that part of INV15 and FR6 is current authority but | ||
| not enforcement. | ||
|
|
||
| ## Verification | ||
|
|
||
|
|
@@ -304,5 +340,6 @@ resolution is current authority but not enforcement. | |
| | INV11 | `DefineThemeInput`/output diff plus runtime/build fixtures | Validation-only data enters the normalized theme, or productive input loses construction validation | | ||
| | INV12 | Core theme export diff, constructed-value evidence, and current-consumer callsite | A theme `define*` helper only checks input and returns that exact input unchanged | | ||
| | INV13, INV14 | `defineTheme.test.ts` type and normalization tests for function entries, slot functions, and the list | A public read returns a function, a child merges variant lists, or an entry sees another theme's names | | ||
| | INV15 | `themeMotion.test.ts` over tempo bounds, characters, a duration scale, explicit tokens, and extension | A token off its knob, a knob beating a scale or explicit token, a lost inherited knob, or a loop following `tempo` | | ||
| | Theme/Core compatibility | Maintained theme source/build against the minimum Core in its currently supported peer/dependency range | A theme update silently requires newer in-range Core or bypasses the `spec:AST-017` path | | ||
| | Authoring projection | `scripts/check-theme-template.test.mjs` | A supported authoring concept is missing or misstated in the template | | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
motionKnobs.tsholds the knob types, defaults and thetempoclamp thatthemeMotion.tsre-exports; worth listing it here and in the owning-code line too.