Repository navigation
fix(Layer): the touch cross-fade uses the motion foundation's Reduce Motion values #8355
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| '@astryxdesign/core': patch | ||
| --- | ||
|
|
||
| [fix] With Reduce Motion on, a layer that opens under a finger fades in over 200 ms on easeInOut, the motion foundation's Reduce Motion values, instead of the theme's fast duration and curve. Under a mouse it still appears at once. | ||
|
|
||
| @vjeux |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,14 +89,22 @@ const fadeIn = stylex.keyframes({ | |
| to: {opacity: 1}, | ||
| }); | ||
|
|
||
| // Reduce Motion follows the motion foundation's policy | ||
| // (design:reduced-motion): under a coarse pointer an opacity-only fade of | ||
| // 200 ms on easeInOut that no theme value lengthens, under any other pointer | ||
| // no animation. The media keys stay literal, spelled as the policy's queries | ||
| // (a test pins them): the StyleX build gives an imported at-rule key another | ||
| // priority. The values become `reducedMotionFadeConsts` once it is on main. | ||
| const animationBase = { | ||
| animationDuration: { | ||
| default: durationVars['--duration-fast-max'], | ||
| // The cross-fade is 200 ms or less, whatever the theme's duration | ||
| // (design:reduced-motion DR2). | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': `min(${durationVars['--duration-fast-max']}, 200ms)`, | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': '200ms', | ||
| }, | ||
| animationTimingFunction: { | ||
| default: easeVars['--ease-standard'], | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': | ||
| 'cubic-bezier(0.42, 0, 0.58, 1)', | ||
|
Comment on lines
+103
to
+106
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. This curve is the open question for an owner: |
||
| }, | ||
| animationTimingFunction: easeVars['--ease-standard'], | ||
| animationFillMode: 'backwards' as const, | ||
| }; | ||
|
|
||
|
|
@@ -106,27 +114,27 @@ const animationBase = { | |
| * Keyed by LayerPlacement ('above' | 'below' | 'start' | 'end') | ||
| * for easy lookup: `layerAnimations[placement]`. | ||
| * | ||
| * Each entry disables its keyframe animation under | ||
| * `prefers-reduced-motion: reduce` so the layer appears instantly instead of | ||
| * translating/scaling in (infra-6). Under a finger (the primary pointer is | ||
| * coarse) it fades in instead, opacity only and in 200 ms or less: on a touch | ||
| * screen Reduce Motion replaces motion with a cross-fade rather than a jump | ||
| * (design:reduced-motion DR2, DR3), as iOS does for its menus, popovers and | ||
| * tips. | ||
| * Under `prefers-reduced-motion: reduce` each entry drops its travel and | ||
| * scale. Under a finger (the primary pointer is coarse) the layer fades in, | ||
| * opacity only, in 200 ms on easeInOut: on a touch screen Reduce Motion | ||
| * replaces motion with a cross-fade rather than a jump; under any other | ||
| * pointer it appears at once (design:reduced-motion DR1 to DR4). | ||
| */ | ||
| export const layerAnimations = stylex.create({ | ||
| below: { | ||
| animationName: { | ||
| default: enterBelow, | ||
| '@media (prefers-reduced-motion: reduce)': 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (not (pointer: coarse))': | ||
| 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': fadeIn, | ||
| }, | ||
| ...animationBase, | ||
| }, | ||
| above: { | ||
| animationName: { | ||
| default: enterAbove, | ||
| '@media (prefers-reduced-motion: reduce)': 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (not (pointer: coarse))': | ||
| 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': fadeIn, | ||
| }, | ||
| ...animationBase, | ||
|
|
@@ -135,7 +143,8 @@ export const layerAnimations = stylex.create({ | |
| animationName: { | ||
| default: enterEnd, | ||
| ':is([dir="rtl"] *)': enterEndRtl, | ||
| '@media (prefers-reduced-motion: reduce)': 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (not (pointer: coarse))': | ||
| 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': fadeIn, | ||
| }, | ||
| ...animationBase, | ||
|
|
@@ -144,7 +153,8 @@ export const layerAnimations = stylex.create({ | |
| animationName: { | ||
| default: enterStart, | ||
| ':is([dir="rtl"] *)': enterStartRtl, | ||
| '@media (prefers-reduced-motion: reduce)': 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (not (pointer: coarse))': | ||
| 'none', | ||
| '@media (prefers-reduced-motion: reduce) and (pointer: coarse)': fadeIn, | ||
| }, | ||
| ...animationBase, | ||
|
|
||
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.
Chromium reports this value as
cubic-bezier(0.42, 0, 0.58, 1)(computed on a Storybook dev server, and the core package'sdist/astryx.cssships it that way); it readsease-in-outhere only because the production Storybook build rewrites it. If the curve stays, accept both spellings and say the build, not the engine, renames it. The same applies at line 153.