Skip to content

fix(Layer): under a finger with Reduce Motion, a layer fades in instead of appearing at once - #8322

Merged
cixzhang merged 2 commits into
meta:mainfrom
vjeux:uikit/c26-touch-reduced-motion
Oct 25, 2026
Merged

cixzhang merged 2 commits into
meta:mainfrom
vjeux:uikit/c26-touch-reduced-motion

Conversation

@vjeux

@vjeux vjeux commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Supersedes #8214, which #8272's merge closed through its closing keyword; same branch, plus the 200 ms cap that design:reduced-motion asks for.

User impact

With Reduce Motion on, a Tooltip, HoverCard, menu or other layer that opens under a finger appeared in a single frame: the shared layer entrance dropped its whole animation, fade included. On a touch screen Reduce Motion replaces motion with a cross-fade, never a jump.

Evidence

iOS 26.2 Safari with Reduce Motion on, a tap on the Tooltip's term (a grey dot drawn by the test page marks the finger); before (main), then after:

Before After

  • Before: the tooltip appears in a single frame of the 60 fps recording.
  • After: it fades in where it lands, opacity only, over the theme's fast duration (165 ms with the default motion scale; most of the change in the first 115 ms on the standard ease). Under a mouse with Reduce Motion it still appears at once; under a finger without it the entrance still animates opacity and transform.
  • Regression proof: the Chromium contract's fade cases fail on main's build, and its slow-theme case (--duration-fast-max: 400ms) fails without the cap (0.4 s) and passes with it (0.2 s).

Problem and solution fit

layerAnimations (the entrance every layer applies through layer.render) set animation-name: none under prefers-reduced-motion: reduce. That suits a mouse. Under a coarse pointer it is a jump where iOS fades.

Under a coarse pointer with Reduce Motion the entrance now keeps its opacity ramp, drops the slide and the scale, and lasts min(--duration-fast-max, 200ms). Under a mouse it still appears at once; without Reduce Motion nothing changes. Components with their own touch presentation (DropdownMenu, Popover in the open stacks) override this entrance inline, so this reaches layers that have none: Tooltip, HoverCard, Selector, ContextMenu and the like.

Expected behavior and authority

  • design:reduced-motion (current): under reduced motion nothing moves, scales or springs (DR1); on a coarse pointer it cross-fades, opacity only, in 200 ms or less (DR2); on other pointers it changes at once (DR3); no theme value keeps motion (DR4).

Smallest restoration

One added media condition per placement in layerAnimations.stylex.ts (a fade keyframe, and the capped duration), and a real-engine contract with its own pr-a11y step. A UIKit-timed touch entrance for tooltips is an open owner question (D7), not built here.

Scope

  • One defect is restored.
  • Separable contradictory or unsettled tagalongs were removed or split.
  • No new public API, visual representation, default, or interaction model is hidden under the bug-fix label.
  • Public text and artifacts contain no internal Meta context.

Testing

  • pnpm exec playwright test packages/core/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts --project chromium after pnpm storybook:build: 8/8 (Tooltip and HoverCard: an opacity-only fade of 200 ms or less under a finger with Reduce Motion, also with a slow theme; unchanged without it; still instant under a mouse). The fade cases fail against main; the slow-theme case fails against fix(Layer): under a finger with Reduce Motion, a layer fades in instead of appearing at once #8214's head.
  • pnpm vitest run .github/scripts/ci-test-routing.test.mjs .github/scripts/release-check-workflow.test.mjs: 101 pass.
  • pnpm vitest run packages/core/src/Layer packages/core/src/Tooltip packages/core/src/HoverCard packages/core/src/Popover packages/core/src/DropdownMenu packages/core/src/Selector packages/core/src/ContextMenu: 983 pass.
  • iOS 26.2 simulator in Safari with Reduce Motion on, before and after, 60 fps recordings with a page log; the cap changes nothing at the default theme's 165 ms.
  • Core typecheck, eslint, prettier.

vjeux added 2 commits October 24, 2026 04:28
…ad of appearing at once

The shared layer entrance (layerAnimations) dropped its animation under
prefers-reduced-motion, so a Tooltip, HoverCard or menu opened by a tap
appeared in one frame. On a touch screen Reduce Motion replaces motion with
a cross-fade, never a jump: under a coarse pointer the entrance now keeps
its opacity ramp and drops only the travel and the scale. Under a mouse it
still appears at once, and without Reduce Motion nothing changes.

LayerReducedMotion.a11y.chromium.spec.ts proves the three cases in a real
engine (media queries), with its own pr-a11y step.
The current design:reduced-motion record (DR2) asks a core component under
Reduce Motion on a coarse pointer to cross-fade, opacity only, in 200 ms or
less, and DR3 asks other pointers to change at once. The touch fade took the
theme's --duration-fast-max, 165 ms with the default motion scale but 230 ms
without one and longer in a slower theme. Under a coarse pointer with Reduce
Motion it is now min(--duration-fast-max, 200ms); everything else is
unchanged.

The Chromium contract checks the fade's duration, and a slow-theme case
(--duration-fast-max: 400ms) proves the cap: 0.4 s before, 0.2 s now.
@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Oct 24, 2026 11:00pm UTC

Request Review

@astracat-bot

astracat-bot Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Oct 24, 2026, 11:46 PM UTC

@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review label Oct 24, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 24, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review recommends approval. Under Reduce Motion on a touch screen, layers that use the shared entrance now fade in place, opacity only and within 200 ms, as design:reduced-motion DR2 requires; mouse and no-preference entrances stay as they were. The new Chromium contract fails against main's build and passes on this head, and the 200 ms cap holds for slower themes in Chromium and WebKit. Nothing further is needed from you.

[Automated review]

@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR

🧪 Sandbox Preview

View Sandbox for this PR

No new or modified components detected.

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.9KB 1.2KB

Accessibility Audit

Status: No accessibility violations detected.

Visual Regression

46 of 494 shot(s) changed.

A change here is a question, not a failure: check whether the after is the
picture you intended. Record that review on the PR. Baseline maintenance is an
explicit dispatch of CI; this report never rewrites the baseline or adds a release gate.

component story theme mode pixels
Selector Indicator Space Bottom Sheet Narrow End RTL neutral light 753,933
Selector Indicator Space Bottom Sheet Wide Start neutral light 740,072
Chat Full AI Chat probe light 230,823
Chat Full AI Chat probe dark 229,805
RichTextEditor Markdown parity: side by side probe dark 94,866
RichTextEditor Markdown parity: side by side probe light 89,762
Collapsible Dividers probe dark 66,445
Collapsible Dividers probe light 66,445
Chat Default neutral dark 36,304
Chat Default neutral light 35,767
Chat Empty State probe light 23,531
Chat Empty State probe dark 22,622
ChatAutoScroll Scroll Behavior Comparison neutral dark 15,378
ChatAutoScroll Scroll Behavior Comparison neutral light 14,107
Chat With Attachments probe light 13,406
Chat With Attachments probe dark 11,232
ProgressBar With Target Mark probe dark 7,895
ProgressBar With Target Mark probe light 7,895
Markdown Default neutral dark 7,573
Markdown Default neutral light 7,566

and 26 more.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

@cixzhang
cixzhang merged commit 216ad57 into meta:main Oct 25, 2026
64 checks passed
@vjeux
vjeux deleted the uikit/c26-touch-reduced-motion branch October 25, 2026 02:58

This branch was successfully deployed

1 active deployment
Preview — 9aa86cfd Deployed Oct 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants