Skip to content

fix(core): a touch press's release lasts until its fade has played - #9758

Merged
cixzhang merged 3 commits into
mainfrom
fix/press-release-ends-with-its-animation
Nov 4, 2026
Merged

cixzhang merged 3 commits into
mainfrom
fix/press-release-ends-with-its-animation

Conversation

@cixzhang

@cixzhang cixzhang commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Supersedes #8890 by @vjeux, rebased onto main now that #8360 has landed. The change is vjeux's: his commit authorship is kept, and the changeset credits him. #8890's branch carries #8360's older revision, which no longer merges, so this branch replays only the fix onto main.

User impact

This affects people who tap a control on a phone: a button, switch, checkbox, card, menu row or list row.

  • Today: after the lift, the highlight should fade out. A tap usually starts work, so the page's script often delays the fade's first frame. The release then ends on a clock that started at the lift, so the highlight is cut off mid-fade.
  • After this change: the highlight fades to the end, however late its first frame comes. A press with no release animation (an instant release, a surface without one, an engine without Web Animations) still ends on the clock, as before.

Problem and solution fit

The touch press controller removed fading on a clock that started at the lift. A delayed first frame moves the release animation's end later, but not the clock.

Now, when the clock runs out, the controller looks for the press's finite release animation that still runs or still waits for its first frame:

  • on the surface, or its ::before or ::after;
  • on a part inside it whose nearest press owner is the surface, for a component that draws its release there.

A press owner nested inside keeps its own release and never extends the outer press. While one runs, the release ends when that animation finishes or is cancelled; with none, it ends at the clock.

Changes since #8890

main changed under #8890 while it waited:

Main merge (after the phone check)

Cindy's phone check passed at 8f8f026. main then gained #8638, which renamed the release-clock helper fadeMs to an exported pressFadeMs on the line this pull request changes, so the branch merged main. The interdiff of this pull request's own change against its base, before and after the merge, is the rename alone:

-      live.timer = endAfterRelease(live.element, fadeMs(live.element), fire);
+      live.timer = endAfterRelease(
+        live.element,
+        pressFadeMs(live.element),
+        fire,
+      );

Nothing else in this pull request's diff changed. The press, AlertDialog and gesture unit suites pass on the merged head (171 tests), and lint and the core type check are clean.

Expected behavior and authority

usePressFeedback ("fades the release over 200 ms"); spec:AST-094 FR5 (the release plays the press model's duration and curve); design:user-states DR1 and DR5.

Smallest restoration

  • A longer clock: still a guess, and a long block outlasts it.
  • An animationend listener per surface: every surface has to wire it, and a surface that unmounts mid-release never fires it.
  • Chosen: read the release animation off the element when the clock runs out. One place, every surface, no new API.

Verification

  • Unit, red first: three cases in pressFeedback.test.ts ("the release ends with its animation, not its clock") fail on main's controller and pass here:
    • a release whose first frame came late;
    • one still waiting for its first frame;
    • one drawn on a part inside the surface.
  • Guards: four more cases pass on both:
    • a cancelled release ends;
    • with no release animation the release ends at the clock;
    • a nested press owner's, an endless or a finished animation is not waited for;
    • a new press on the surface keeps its paint.
  • Suites: the press surfaces' unit suites pass: utils, usePressFeedback, Button, Switch, CheckboxInput, Card, Item, List, RadioList, DropdownMenu, AlertDialog. So do the stylesheet test, lint, the core type check, check:changesets and check:knowledge. review:pre reports no findings.
  • Real Chromium: the press accessibility contracts pass 30/30 against this head's Storybook: PressedState, PressModality, CardPress and DropdownMenu's MenuPress.
  • On a phone: with fix(Item): a list row's touch press release runs on the compositor #8077 on top (its compositor row release), freeze the page for 0.7 s on the lift and press a list row. The highlight fades through the freeze to the end. On main the overlay's release runs on the main thread, so a blocked frame freezes it anyway.

Scope

  • One defect is restored.
  • No new public API, visual representation, default, or interaction model.
  • Public text and artifacts contain no internal Meta context.

Under a finger, the touch press controller ended a press's release on a
clock that starts at the lift. When script delays the first frame of the
release animation, the animation ends later, but the clock does not, so
the highlight was cut off mid-fade. When the clock runs out, the
controller now waits for a release animation that still runs or still
waits for its first frame: on the surface, its ::before or ::after, or on
a part inside it whose nearest press owner is the surface. With none, the
release ends at the clock, as before.

Rebased onto main after #8360 landed: main's theme tempo already caps the
release under Reduce Motion, so only the release-ends-with-its-animation
part remains.

Co-authored-by: Cindy Zhang <cindyxz@meta.com>
@vercel

vercel Bot commented Nov 3, 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 Nov 4, 2026 5:20am UTC

Request Review

@astracat-bot

astracat-bot Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 4, 2026, 5:30 AM UTC

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

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 633c36b

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
lab/SelectableCardGroup 50.2 kB (+272 B) · 162 B CSS (0) — — · — · —
richtext/RichTextEditorToolbar 224.9 kB (+239 B) · 454 B CSS (0) — — · — · —
ComplexSelector 55.6 kB (+236 B) · 10.4 kB CSS (0) — — · — · —
179 more components
Component Size LoC Visual · A11y · RTL
Link 42.5 kB (+235 B) · 6.9 kB CSS (0) — — · — · —
TableCell 75.4 kB (+233 B) · 15.9 kB CSS (0) — — · — · —
lab/ChatReactionBar 66.3 kB (+232 B) · 1.1 kB CSS (0) — — · — · —
LayerProvider 62.9 kB (+229 B) · 9.4 kB CSS (0) — — · — · —
lab/CommentComposer 104.5 kB (+229 B) · 1.9 kB CSS (0) — — · — · —
lab/CommentThread 253.1 kB (+229 B) · 2.4 kB CSS (0) — — · — · —
lab/ChatEmojiPicker 65.7 kB (+228 B) · 773 B CSS (0) — — · — · —
ToggleButton 46.0 kB (+227 B) · 8.8 kB CSS (0) — — · — · —
TopNavHeading 58.3 kB (+227 B) · 9.7 kB CSS (0) — — · — · —
AppShell 70.5 kB (+225 B) · 12.2 kB CSS (0) — — · — · —
AvatarGroupOverflow 38.6 kB (+225 B) · 5.5 kB CSS (0) — — · — · —
FileInput 53.6 kB (+225 B) · 9.7 kB CSS (0) — — · — · —
Table 83.7 kB (+223 B) · 16.1 kB CSS (0) — — · — · —
DropdownMenuRadioItem 18.6 kB (+222 B) · 5.9 kB CSS (0) — — · — · —
TabMenu 55.6 kB (+222 B) · 9.8 kB CSS (0) — — · — · —
lab/EmojiPicker 70.4 kB (+222 B) · 722 B CSS (0) — — · — · —
ChatLayoutScrollButton 45.6 kB (+221 B) · 8.9 kB CSS (0) — — · — · —
DateTimeInput 167.9 kB (+221 B) · 17.2 kB CSS (0) — — · — · —
TopNavMegaMenuItem 11.0 kB (+221 B) · 4.2 kB CSS (0) — — · — · —
lab/TransferList 75.1 kB (+221 B) · 1.7 kB CSS (0) — — · — · —
ChatSendButton 45.5 kB (+219 B) · 8.7 kB CSS (0) — — · — · —
CheckboxInput 48.4 kB (+219 B) · 8.7 kB CSS (0) — — · — · —
DropdownMenuCheckboxItem 18.6 kB (+219 B) · 5.9 kB CSS (0) — — · — · —
IconButton 45.1 kB (+219 B) · 8.7 kB CSS (0) — — · — · —
Toast 59.0 kB (+219 B) · 9.0 kB CSS (0) — — · — · —
TopNavItem 10.9 kB (+219 B) · 4.0 kB CSS (0) — — · — · —
Pagination 86.6 kB (+218 B) · 16.1 kB CSS (0) — — · — · —
lab/CommentPin 46.8 kB (+218 B) · 1.2 kB CSS (0) — — · — · —
lab/TransferListSelector 82.7 kB (+217 B) · 1.9 kB CSS (0) — — · — · —
CommandPaletteItem 10.3 kB (+216 B) · 3.6 kB CSS (0) — — · — · —
SideNavItem 54.6 kB (+216 B) · 9.8 kB CSS (0) — — · — · —
Switch 86.9 kB (+216 B) · 9.5 kB CSS (0) — — · — · —
Tab 11.6 kB (+216 B) · 4.2 kB CSS (0) — — · — · —
TimeInput 131.6 kB (+216 B) · 14.5 kB CSS (0) — — · — · —
lab/ListInput 82.0 kB (+216 B) · 1.6 kB CSS (0) — — · — · —
Collapsible 23.3 kB (+214 B) · 4.5 kB CSS (0) — — · — · —
Outline 22.2 kB (+214 B) · 4.2 kB CSS (0) — — · — · —
SelectableCard 15.0 kB (+214 B) · 7.2 kB CSS (0) — — · — · —
SelectorOption 16.9 kB (+214 B) · 5.4 kB CSS (0) — — · — · —
ContextMenu 74.1 kB (+213 B) · 15.5 kB CSS (0) — — · — · —
DropdownMenuItem 17.8 kB (+213 B) · 5.5 kB CSS (0) — — · — · —
SideNavHeading 58.9 kB (+213 B) · 9.9 kB CSS (0) — — · — · —
Button 45.0 kB (+212 B) · 8.7 kB CSS (0) — — · — · —
Item 13.6 kB (+212 B) · 4.9 kB CSS (0) — — · — · —
SegmentedControlItem 10.6 kB (+212 B) · 4.0 kB CSS (0) — — · — · —
Thumbnail 49.3 kB (+212 B) · 10.3 kB CSS (0) — — · — · —
TopNav 53.3 kB (+212 B) · 9.6 kB CSS (0) — — · — · —
ClickableCard 14.8 kB (+211 B) · 7.0 kB CSS (0) — — · — · —
DateInput 147.2 kB (+211 B) · 15.5 kB CSS (0) — — · — · —
Step 28.2 kB (+211 B) · 5.6 kB CSS (0) — — · — · —
TableHeaderCell 74.9 kB (+211 B) · 15.6 kB CSS (0) — — · — · —
Calendar 54.3 kB (+210 B) · 9.3 kB CSS (0) — — · — · —
Carousel 49.4 kB (+210 B) · 9.5 kB CSS (0) — — · — · —
ChatLayout 48.3 kB (+210 B) · 9.3 kB CSS (0) — — · — · —
Selector 77.8 kB (+210 B) · 15.7 kB CSS (0) — — · — · —
TextInput 52.8 kB (+210 B) · 9.9 kB CSS (0) — — · — · —
TreeList 38.9 kB (+210 B) · 5.0 kB CSS (0) — — · — · —
lab/Schedule 60.2 kB (+210 B) · 3.9 kB CSS (0) — — · — · —
DialogHeader 47.9 kB (+209 B) · 10.2 kB CSS (0) — — · — · —
DropdownMenuSubMenu 56.7 kB (+209 B) · 8.9 kB CSS (0) — — · — · —
TableSelectionToolbar 54.6 kB (+209 B) · 11.8 kB CSS (0) — — · — · —
BreadcrumbItem 67.5 kB (+208 B) · 10.8 kB CSS (0) — — · — · —
DrawerHeader 48.0 kB (+207 B) · 11.6 kB CSS (0) — — · — · —
MoreMenu 73.0 kB (+207 B) · 15.6 kB CSS (0) — — · — · —
MultiSelector 73.0 kB (+207 B) · 15.3 kB CSS (0) — — · — · —
TopNavMenu 58.2 kB (+207 B) · 9.9 kB CSS (0) — — · — · —
CommandPalette 51.1 kB (+206 B) · 12.3 kB CSS (0) — — · — · —
Typeahead 62.9 kB (+206 B) · 11.2 kB CSS (0) — — · — · —
ListItem 52.5 kB (+205 B) · 10.0 kB CSS (0) — — · — · —
Popover 51.8 kB (+205 B) · 12.8 kB CSS (0) — — · — · —
Token 25.5 kB (+205 B) · 4.8 kB CSS (0) — — · — · —
SideNav 70.2 kB (+204 B) · 10.1 kB CSS (0) — — · — · —
Stepper 46.7 kB (+204 B) · 8.9 kB CSS (0) — — · — · —
CheckboxListItem 53.1 kB (+203 B) · 10.0 kB CSS (0) — — · — · —
NumberInput 55.0 kB (+203 B) · 10.1 kB CSS (0) — — · — · —
RadioListItem 51.0 kB (+203 B) · 9.0 kB CSS (0) — — · — · —
SideNavCollapseButton 45.9 kB (+203 B) · 8.8 kB CSS (0) — — · — · —
lab/DiffViewer 70.9 kB (+203 B) · 2.1 kB CSS (0) — — · — · —
richtext/RichTextEditor 278.2 kB (+203 B) · 2.6 kB CSS (0) — — · — · —
DropdownMenu 72.7 kB (+202 B) · 15.6 kB CSS (0) — — · — · —
MobileNavToggle 45.4 kB (+202 B) · 8.7 kB CSS (0) — — · — · —
PowerSearch 236.1 kB (+202 B) · 21.8 kB CSS (0) — — · — · —
DateRangeInput 71.2 kB (+200 B) · 11.2 kB CSS (0) — — · — · —
Lightbox 52.2 kB (+200 B) · 9.1 kB CSS (0) — — · — · —
lab/Comments 258.4 kB (+200 B) · 2.5 kB CSS (0) — — · — · —
CodeBlock 58.9 kB (+199 B) · 10.0 kB CSS (0) — — · — · —
MobileNav 51.8 kB (+199 B) · 9.3 kB CSS (0) — — · — · —
ChatComposer 61.2 kB (+198 B) · 10.6 kB CSS (0) — — · — · —
ChatComposerInput 59.1 kB (+197 B) · 10.0 kB CSS (0) — — · — · —
Banner 47.0 kB (+196 B) · 9.2 kB CSS (0) — — · — · —
ChatComposerTokenElement 59.1 kB (+196 B) · 10.0 kB CSS (0) — — · — · —
lab/TourStep 57.8 kB (+196 B) · 590 B CSS (0) — — · — · —
AlertDialog 83.2 kB (+195 B) · 13.1 kB CSS (0) — — · — · —
BaseTypeahead 55.0 kB (+195 B) · 9.6 kB CSS (0) — — · — · —
ChatDictationButton 45.6 kB (+193 B) · 8.8 kB CSS (0) — — · — · —
TopNavMegaMenu 54.0 kB (+192 B) · 10.6 kB CSS (0) — — · — · —
richtext/RichTextView 258.4 kB (+192 B) · 2.3 kB CSS (0) — — · — · —
Tokenizer 69.5 kB (+191 B) · 17.1 kB CSS (0) — — · — · —
Markdown 144.8 kB (+181 B) · 18.4 kB CSS (0) — — · — · —
Timestamp 21.3 kB (+1 B) · 8.9 kB CSS (0) — — · — · —
charts/Chart 25.9 kB (0) · 20 B CSS (0) — — · — · —
charts/ChartAxis 6.7 kB (0) · 112 B CSS (0) — — · — · —
AspectRatio 3.8 kB (0) · 3.6 kB CSS (0) — — · — · —
Avatar 34.4 kB (0) · 5.4 kB CSS (0) — — · — · —
AvatarGroup 37.1 kB (0) · 5.5 kB CSS (0) — — · — · —
AvatarStatusDot 7.2 kB (0) · 3.6 kB CSS (0) — — · — · —
Badge 4.0 kB (0) · 4.0 kB CSS (0) — — · — · —
Blockquote 3.6 kB (0) · 3.5 kB CSS (0) — — · — · —
BottomSheetSwitcher 17.1 kB (0) · 3.4 kB CSS (0) — — · — · —
Breadcrumbs 16.0 kB (0) · 3.4 kB CSS (0) — — · — · —
ButtonGroup 9.0 kB (0) · 3.4 kB CSS (0) — — · — · —
Card 6.5 kB (0) · 6.4 kB CSS (0) — — · — · —
Center 4.2 kB (0) · 4.6 kB CSS (0) — — · — · —
ChatComposerDrawer 17.5 kB (0) · 4.7 kB CSS (0) — — · — · —
ChatMessage 16.7 kB (0) · 3.7 kB CSS (0) — — · — · —
ChatMessageBubble 7.1 kB (0) · 3.7 kB CSS (0) — — · — · —
ChatMessageList 22.8 kB (0) · 6.9 kB CSS (0) — — · — · —
ChatMessageMetadata 19.8 kB (0) · 4.1 kB CSS (0) — — · — · —
ChatSystemMessage 6.8 kB (0) · 3.8 kB CSS (0) — — · — · —
ChatTokenizedText 7.1 kB (0) · 4.0 kB CSS (0) — — · — · —
ChatToolCalls 25.9 kB (0) · 8.2 kB CSS (0) — — · — · —
CheckboxList 42.8 kB (0) · 7.5 kB CSS (0) — — · — · —
Citation 20.1 kB (0) · 4.4 kB CSS (0) — — · — · —
Code 3.6 kB (0) · 3.5 kB CSS (0) — — · — · —
CollapsibleGroup 6.5 kB (0) · 3.3 kB CSS (0) — — · — · —
CommandPaletteEmpty 6.2 kB (0) · 3.5 kB CSS (0) — — · — · —
CommandPaletteFooter 17.0 kB (0) · 3.7 kB CSS (0) — — · — · —
CommandPaletteGroup 3.5 kB (0) · 3.5 kB CSS (0) — — · — · —
CommandPaletteInput 26.9 kB (0) · 7.4 kB CSS (0) — — · — · —
CommandPaletteList 16.0 kB (0) · 3.4 kB CSS (0) — — · — · —
ContextMenuItem 23.5 kB (0) · 3.9 kB CSS (0) — — · — · —
Drawer 38.1 kB (0) · 8.2 kB CSS (0) — — · — · —
DropdownMenuGroup 6.2 kB (0) · 3.4 kB CSS (0) — — · — · —
DropdownMenuRadioGroup 6.1 kB (0) · 3.4 kB CSS (0) — — · — · —
FormLayout 6.4 kB (0) · 3.5 kB CSS (0) — — · — · —
Grid 4.4 kB (0) · 3.8 kB CSS (0) — — · — · —
GridSpan 3.5 kB (0) · 3.4 kB CSS (0) — — · — · —
InputGroup 41.5 kB (0) · 7.3 kB CSS (0) — — · — · —
InputGroupText 6.4 kB (0) · 3.9 kB CSS (0) — — · — · —
Kbd 16.7 kB (0) · 3.6 kB CSS (0) — — · — · —
LayoutPanel 7.6 kB (0) · 4.9 kB CSS (0) — — · — · —
MetadataList 16.7 kB (0) · 3.8 kB CSS (0) — — · — · —
MetadataListItem 6.6 kB (0) · 3.5 kB CSS (0) — — · — · —
NavHeadingMenu 14.8 kB (0) · 3.5 kB CSS (0) — — · — · —
NavIcon 3.5 kB (0) · 3.4 kB CSS (0) — — · — · —
OverflowList 8.6 kB (0) · 3.7 kB CSS (0) — — · — · —
Overlay 19.8 kB (0) · 4.0 kB CSS (0) — — · — · —
ProgressBar 10.8 kB (0) · 6.2 kB CSS (0) — — · — · —
ResizeHandle 19.5 kB (0) · 4.3 kB CSS (0) — — · — · —
Section 7.6 kB (0) · 6.3 kB CSS (0) — — · — · —
SegmentedControl 81.6 kB (0) · 6.7 kB CSS (0) — — · — · —
SideNavSection 6.6 kB (0) · 3.7 kB CSS (0) — — · — · —
Skeleton 3.8 kB (0) · 3.8 kB CSS (0) — — · — · —
Slider 88.5 kB (0) · 8.3 kB CSS (0) — — · — · —
StatusDot 22.5 kB (0) · 5.2 kB CSS (0) — — · — · —
TableBody 3.4 kB (0) · 3.3 kB CSS (0) — — · — · —
TableFooter 3.4 kB (0) · 3.3 kB CSS (0) — — · — · —
TableHeader 3.4 kB (0) · 3.3 kB CSS (0) — — · — · —
TableRow 6.5 kB (0) · 4.0 kB CSS (0) — — · — · —
TabList 35.4 kB (0) · 6.4 kB CSS (0) — — · — · —
TextArea 46.6 kB (0) · 8.8 kB CSS (0) — — · — · —
Timer 9.5 kB (0) · 5.9 kB CSS (0) — — · — · —
ToggleButtonGroup 6.4 kB (0) · 3.4 kB CSS (0) — — · — · —
Toolbar 34.8 kB (0) · 7.9 kB CSS (0) — — · — · —
TopNavMegaMenuFeaturedCard 6.9 kB (0) · 3.6 kB CSS (0) — — · — · —
TypeaheadItem 6.3 kB (0) · 3.6 kB CSS (0) — — · — · —
lab/ChartDotGL 7.4 kB (0) · 20 B CSS (0) — — · — · —
lab/ChartDotGLInteractive 8.3 kB (0) · 20 B CSS (0) — — · — · —
lab/ChartHeatmapGL 8.5 kB (0) · 20 B CSS (0) — — · — · —
lab/ChartStreamGL 7.5 kB (0) · 20 B CSS (0) — — · — · —
lab/ChatReasoning 7.0 kB (0) · 967 B CSS (0) — — · — · —
lab/ChatTypingIndicator 24.8 kB (0) · 612 B CSS (0) — — · — · —
lab/ChatUnreadDivider 3.6 kB (0) · 348 B CSS (0) — — · — · —
lab/CircularProgress 8.5 kB (0) · 1.1 kB CSS (0) — — · — · —
lab/CodeEditor 14.0 kB (0) · 743 B CSS (0) — — · — · —
lab/LogStream 8.0 kB (0) · 1.6 kB CSS (0) — — · — · —
lab/Stat 4.2 kB (0) · 646 B CSS (0) — — · — · —
lab/SVGIcon 7.6 kB (0) · 764 B CSS (0) — — · — · —
lab/ThreeDScatterGL 7.6 kB (0) · 20 B CSS (0) — — · — · —

Package size: @astryxdesign/core 6.31 MB packed (+1.6 kB); no new dependencies.

API changes: none in this pull request

Committed API report behind this build: theme-butter 1 row, theme-chocolate 1 row, theme-gothic 1 row, theme-matcha 1 row, theme-neutral 1 row, theme-stone 1 row, theme-y2k 1 row; run pnpm api:report.

Wide change (shared styles: packages/core/src/utils/interactionOverlay.stylex.ts): add ci:run-visual, ci:run-a11y or ci:run-rtl to run them.


Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks ready to approve: the controller's release now waits for its animation, which restores the release fade the Button and List records require, and the three new release cases fail against main's controller and pass here.

Optional follow-ups, none blocking:

  • An open AlertDialog's tracked action buttons still end their release on the action-group tracker's own 200 ms timer (actionGroupTracker.ts), so the same cut-off remains there.
  • pressGesture.ts still describes the PRESS_FADE_MS timer as the one that removes the attribute and fadeEnd as "PRESS_FADE_MS elapsed"; worth syncing with the new wait.
  • Two new comments in pressFeedback.ts have sentences over 25 words; suggested rewrites are inline.

[Automated review]

Comment on lines +170 to +173
* The release animations that still run for `element`'s press. A release
* animation is a finite CSS animation that has not finished, on the element,
* on its `::before` or `::after`, or on a descendant whose nearest press owner
* is the element. A component can draw its release on a part inside the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking (comment style): this sentence runs 31 words. A split keeps the same facts:

 * A release animation is a finite CSS animation that has not finished. It
 * runs on the element, on its `::before` or `::after`, or on a descendant
 * whose nearest press owner is the element.

Comment on lines +206 to +209
* clock that starts at the `fading` write can cut the release short. When
* `clockMs` runs out, a release animation that still runs, or still waits for
* its first frame, is waited for until it finishes or is cancelled (the
* surface was unmounted or restyled). With no release animation (an instant

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking (comment style): this sentence runs 32 words in the passive ("is waited for"). An active split:

 * When `clockMs` runs out, the release waits for each release animation that
 * still runs or still waits for its first frame. It ends when they finish or
 * are cancelled. A cancel means the surface was unmounted or restyled.

…animation

CodeBunny's notes on the first round: pressGesture.ts still described
PRESS_FADE_MS as the timer that removes the attribute, and two new
comments in pressFeedback.ts had sentences over 25 words.

@astracat-bot astracat-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks ready to approve: the touch press release now waits for its animation, which restores the full release fade the Button and Switch records require, and the three new release cases fail against main's controller and pass here. In Chromium, a Button's and a Switch's release after 150 ms of script on the lift is cut at about 215 ms on main and now plays to its end. The follow-up comment changes resolve the earlier notes on pressGesture.ts and the long endAfterRelease sentence.

Optional follow-ups, none blocking:

  • An open AlertDialog's tracked action buttons still end their release on the action-group tracker's own 200 ms timer (actionGroupTracker.ts), so the same cut-off remains there.
  • The rewritten releaseAnimationsOf comment now has one 34-word sentence; a split is suggested inline.
  • The pending-first-frame test models playState: 'pending', which no engine reports; a waiting animation reads 'running' with pending: true (inline).

[Automated review]

Comment on lines +171 to +174
* finite CSS animation that has not finished. It runs on the element, on its
* `::before` or `::after`, or on a descendant whose nearest press owner is
* the element, because a component can draw its release on a part inside the
* surface. A press owner nested inside plays the release of its own press,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking (comment style): this sentence now runs 34 words and carries two topics, where the animation runs and why. A split keeps both facts:

 * finite CSS animation that has not finished. It runs on the element, on its
 * `::before` or `::after`, or on a descendant whose nearest press owner is
 * the element. A component can draw its release on a part inside the
 * surface. A press owner nested inside plays the release of its own press,


it('waits for a release still waiting for its first frame when the clock ran out', async () => {
liftHeldPress();
const release = cssAnimation(rows[0], {playState: 'pending'});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking (test fidelity): 'pending' is not a Web Animations playState (it is idle, running, paused or finished). An animation still waiting for its first frame reports playState: 'running' with pending: true, so this case currently repeats the running case. Modelling it that way would show the case as an engine reports it.

Main's #8638 renamed the release clock helper fadeMs to an exported
pressFadeMs. The release call here now uses pressFadeMs; nothing else
in this pull request changes.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved pending CI: CI has not run on this head yet. The pull request is a draft, and CI runs once it is marked ready for review.

The touch press release now waits for its animation, which restores the full release fade the Button, List and Switch records require. The three new release cases fail against main's controller and pass here, and in Chromium a Button's and a Switch's release after 150 ms of script on the lift is cut at 200 ms on main and now plays to its end.

Optional follow-ups, none blocking:

  • An open AlertDialog's tracked action buttons still end their release on the action-group tracker's own timer (actionGroupTracker.ts), so the same cut-off remains there.
  • The releaseAnimationsOf comment still has one 34-word sentence; the inline suggestion splits it.
  • The pending-first-frame test models playState: 'pending', which no engine reports; a waiting animation reads 'running' with pending: true.

[Automated review]

cixzhang added a commit that referenced this pull request Nov 4, 2026
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 07:03
@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 4, 2026
@cixzhang
cixzhang marked this pull request as draft November 4, 2026 08:10
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 08:10
@cixzhang
cixzhang merged commit b206f63 into main Nov 4, 2026
165 of 166 checks passed
@github-actions
github-actions Bot deleted the fix/press-release-ends-with-its-animation branch November 5, 2026 06:03

This branch was successfully deployed

1 active deployment
Preview — 633c36bf Deployed Nov 4, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) 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