Skip to content

fix(AlertDialog): a released action fades on the theme's tempo, as other presses do - #8638

Merged
cixzhang merged 1 commit into
meta:mainfrom
vjeux:uikit/c19-tracker-paint
Nov 4, 2026
Merged

cixzhang merged 1 commit into
meta:mainfrom
vjeux:uikit/c19-tracker-paint

Conversation

@vjeux

@vjeux vjeux commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

User impact

Under AlertDialog's touch presentation, an action a finger or pen lifts on while the alert stays open fades its press out, but that fade ended on a fixed 200 ms timer, so under a slower motion tempo it snapped off early. A lift that closes the alert, or a loading action, is unchanged. Touch presentation only: a mouse, a keyboard and the desktop presentation are unchanged.

Before, at tempo 1.5: the release runs 300 ms, but the press came off at 200 ms. After: it stays until 300 ms. At the default tempo nothing changes.

Problem and solution fit

  • Why it occurs: AlertDialog's action-group tracker times its release fade with its own constant (PRESS_FADE_MS), while the stylesheet scales the release by the theme's --_astryx-motion-tempo (up to 1.5). The press controller's timer already reads that tempo; the tracker's never did.
  • Why it harms the task: cut short, the release reads as a flicker.
  • Why that matters: a theme's tempo is meant to slow every motion together (spec:AST-108 FR4), and this one press stayed on the old clock.

The tracker now times its release fades with the press controller's own clock, so the two can no longer drift apart.

Expected behavior and authority

spec:AST-108 FR4: the press release follows the theme's tempo, and under Reduce Motion a tempo may shorten it but never lengthens it past 200 ms. The press controller already meets it; this brings the tracker in line.

Smallest restoration

pressFeedback.ts exports its existing fade clock as pressFadeMs, unchanged. The tracker's release timer calls it instead of the constant. Nothing else changes: the tracker still paints and cuts as before, and no new API ships.

This replaces an earlier version of this pull request that rerouted every press paint through one writer; main has since taken the press controller in another form, so the change is rebuilt on it.

Evidence

  • Reproduction before the change: a tracker release under --_astryx-motion-tempo: 1.5 loses its fading paint at 200 ms.
  • Result after the change: the paint stays until 300 ms, as the press controller's does.
  • Representative unchanged path: the default tempo, and the Reduce Motion cap (a guard case passes before and after).
  • Regression test or other mutation-sensitive proof: the tempo case fails with the base's tracker.

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

Local gates at ea5342d, which differs from abde23b only in the changeset and two comment lines: the tracker and press controller tests (99 of 99), the core type check, strict lint, pnpm lint and review:pre. At abde23b: the hooks, utils, AlertDialog, Button and Tokenizer units (2,089 of 2,089), including the two new tracker cases; the core type check, strict lint, pnpm lint, the knowledge check and review:pre (no findings); and AlertDialog's Chromium interaction spec on a fresh Storybook build (11 of 11). With the tracker and press controller as on the base under these tests (NOT-FOR-LANDING arm 22f83308af), the tempo case fails: the paint is gone at 200 ms. The Reduce Motion case passes on both.

@vercel

vercel Bot commented Oct 27, 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 12:25am UTC

Request Review

@astracat-bot

astracat-bot Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

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

@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.

Changes requested. The tracker's move to paintPress is the right direction, but as opened this pull request also carries all of #8346 and #8076 (about 17,000 changed lines against its own 91), and dispose can now end a fade the tracker did not start. Please land the dependencies or retarget onto them, rebase so the diff shows only the three-file tracker change, and make dispose finish only the tracker's own fades:

  • actionGroupTracker.ts:430-436 never forgets an action when its fade ends, so dispose also removes a fade that another painter starts on that action later, which it did not do before this commit.

[Automated review]

Comment on lines +430 to +436
dispose() {
for (const element of fading) {
// Only a fade still running: a later paint is its painter's.
paintPress(element, 'none', {onlyFrom: ['fading']});
}
fading.clear();
reset();

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.

fading is never pruned when the writer's timer ends a fade, so this loop also ends a fading written later by another painter on an action the tracker faded earlier. Fade, wait 200 ms, paintPress(button, 'fading'), then dispose(): the attribute is gone. The same case passes against the previous tracker, whose timers deleted their own entries. Could dispose end only fades the tracker started, for example through a handle paintPress returns for the fade it starts, or by dropping the action once the writer ends that fade? It would be worth adding that case.

Comment on lines +241 to +242
// The document's press controller faded this button a moment ago (its
// fade's clock runs in the one writer).

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 comment names the document's press controller, but the case fades with paintPress. The controller fades through writePress on its own timer in pressFeedback.ts, so this case covers another paintPress painter rather than the controller. Worth rewording, or adding a controller case if that interplay is meant to be covered.

vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
…ntPress) into the AlertDialog tracking base
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 27, 2026

@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.

Changes requested. Routing the tracker through paintPress is the right direction, but against main this pull request still carries all of #8076 (about 15,600 changed lines against its own 91), and dispose can end a fade the tracker did not start. Please land #8076 and merge main so the diff shows only the three-file tracker change, and make dispose finish only the tracker's own running fades, with a test for that case.

  • actionGroupTracker.ts:430-437 never forgets an action once the writer ends its fade, so dispose also removes a fade another painter starts on that action later.

[Automated review]

vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · ea5342d

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC
SegmentedControl 82.6 kB (+116 B) · 7.8 kB CSS (0) —
AlertDialog 84.6 kB (+10 B) · 13.1 kB CSS (0) —
Carousel 51.3 kB (+4 B) · 10.6 kB CSS (0) —
102 more components
Component Size LoC
lab/CommentThread 254.3 kB (+2 B) · 2.4 kB CSS (0) —
Button 45.8 kB (+1 B) · 9.8 kB CSS (0) —
DropdownMenuItem 17.5 kB (+1 B) · 5.5 kB CSS (0) —
LayerProvider 63.7 kB (+1 B) · 10.5 kB CSS (0) —
AppShell 70.9 kB (0) · 12.2 kB CSS (0) —
AvatarGroupOverflow 39.3 kB (0) · 6.6 kB CSS (0) —
Banner 47.8 kB (0) · 10.3 kB CSS (0) —
BaseTypeahead 55.8 kB (0) · 10.3 kB CSS (0) —
BreadcrumbItem 68.4 kB (0) · 11.5 kB CSS (0) —
Calendar 54.8 kB (0) · 10.4 kB CSS (0) —
ChatComposer 61.9 kB (0) · 11.2 kB CSS (0) —
ChatComposerInput 59.9 kB (0) · 10.7 kB CSS (0) —
ChatComposerTokenElement 59.9 kB (0) · 10.7 kB CSS (0) —
ChatDictationButton 46.4 kB (0) · 9.9 kB CSS (0) —
ChatLayout 49.0 kB (0) · 10.3 kB CSS (0) —
ChatLayoutScrollButton 46.4 kB (0) · 10.0 kB CSS (0) —
ChatSendButton 46.3 kB (0) · 9.8 kB CSS (0) —
CheckboxInput 49.2 kB (0) · 9.8 kB CSS (0) —
CheckboxListItem 53.9 kB (0) · 11.1 kB CSS (0) —
ClickableCard 14.6 kB (0) · 7.1 kB CSS (0) —
CodeBlock 59.8 kB (0) · 11.1 kB CSS (0) —
Collapsible 22.7 kB (0) · 4.5 kB CSS (0) —
CommandPalette 50.8 kB (0) · 12.3 kB CSS (0) —
CommandPaletteItem 10.1 kB (0) · 3.6 kB CSS (0) —
ComplexSelector 56.3 kB (0) · 11.1 kB CSS (0) —
ContextMenu 75.9 kB (0) · 15.4 kB CSS (0) —
ContextMenuItem 26.2 kB (0) · 5.0 kB CSS (0) —
DateInput 147.9 kB (0) · 15.4 kB CSS (0) —
DateRangeInput 72.2 kB (0) · 11.9 kB CSS (0) —
DialogHeader 48.9 kB (0) · 10.2 kB CSS (0) —
DrawerHeader 49.0 kB (0) · 11.6 kB CSS (0) —
DropdownMenu 74.1 kB (0) · 15.5 kB CSS (0) —
DropdownMenuCheckboxItem 18.3 kB (0) · 5.9 kB CSS (0) —
DropdownMenuRadioItem 18.3 kB (0) · 5.9 kB CSS (0) —
DropdownMenuSubMenu 56.5 kB (0) · 10.0 kB CSS (0) —
FileInput 54.3 kB (0) · 10.8 kB CSS (0) —
IconButton 45.9 kB (0) · 9.8 kB CSS (0) —
Item 13.3 kB (0) · 4.9 kB CSS (0) —
Lightbox 52.8 kB (0) · 10.2 kB CSS (0) —
Link 43.3 kB (0) · 8.0 kB CSS (0) —
ListItem 53.2 kB (0) · 11.1 kB CSS (0) —
Markdown 146.3 kB (0) · 18.4 kB CSS (0) —
MobileNav 52.5 kB (0) · 10.4 kB CSS (0) —
MobileNavToggle 46.2 kB (0) · 9.8 kB CSS (0) —
MoreMenu 74.4 kB (0) · 15.5 kB CSS (0) —
MultiSelector 73.7 kB (0) · 15.3 kB CSS (0) —
NumberInput 55.7 kB (0) · 11.3 kB CSS (0) —
Outline 21.9 kB (0) · 4.2 kB CSS (0) —
Pagination 87.3 kB (0) · 16.1 kB CSS (0) —
Popover 53.3 kB (0) · 12.7 kB CSS (0) —
PowerSearch 236.1 kB (0) · 21.7 kB CSS (0) —
RadioListItem 51.7 kB (0) · 10.1 kB CSS (0) —
SegmentedControlItem 10.4 kB (0) · 4.0 kB CSS (0) —
SelectableCard 14.8 kB (0) · 7.3 kB CSS (0) —
Selector 78.4 kB (0) · 15.7 kB CSS (0) —
SelectorOption 16.6 kB (0) · 5.4 kB CSS (0) —
SideNavCollapseButton 46.7 kB (0) · 9.9 kB CSS (0) —
SideNavHeading 59.7 kB (0) · 10.6 kB CSS (0) —
SideNavItem 55.3 kB (0) · 10.5 kB CSS (0) —
Step 27.9 kB (0) · 5.6 kB CSS (0) —
Stepper 47.6 kB (0) · 10.0 kB CSS (0) —
Switch 87.7 kB (0) · 10.6 kB CSS (0) —
Tab 11.4 kB (0) · 4.2 kB CSS (0) —
Table 85.3 kB (0) · 16.1 kB CSS (0) —
TableCell 77.1 kB (0) · 15.9 kB CSS (0) —
TableHeaderCell 76.7 kB (0) · 15.6 kB CSS (0) —
TableSelectionToolbar 55.7 kB (0) · 11.8 kB CSS (0) —
TabMenu 56.3 kB (0) · 10.5 kB CSS (0) —
TextInput 53.5 kB (0) · 11.0 kB CSS (0) —
Thumbnail 50.1 kB (0) · 11.4 kB CSS (0) —
TimeInput 132.7 kB (0) · 14.4 kB CSS (0) —
Timestamp 21.3 kB (0) · 10.0 kB CSS (0) —
Toast 59.7 kB (0) · 10.1 kB CSS (0) —
ToggleButton 46.7 kB (0) · 9.9 kB CSS (0) —
Token 25.3 kB (0) · 4.8 kB CSS (0) —
Tokenizer 71.4 kB (0) · 17.1 kB CSS (0) —
TopNav 54.1 kB (0) · 10.7 kB CSS (0) —
TopNavHeading 59.1 kB (0) · 10.4 kB CSS (0) —
TopNavItem 10.7 kB (0) · 4.0 kB CSS (0) —
TopNavMegaMenu 54.8 kB (0) · 11.2 kB CSS (0) —
TopNavMegaMenuItem 10.8 kB (0) · 4.2 kB CSS (0) —
TopNavMenu 58.9 kB (0) · 10.5 kB CSS (0) —
TreeList 38.2 kB (0) · 5.0 kB CSS (0) —
Typeahead 63.6 kB (0) · 11.8 kB CSS (0) —
lab/ChatEmojiPicker 66.9 kB (0) · 773 B CSS (0) —
lab/ChatReactionBar 67.5 kB (0) · 1.1 kB CSS (0) —
lab/CommentComposer 105.5 kB (0) · 1.9 kB CSS (0) —
lab/CommentPin 47.5 kB (0) · 1.2 kB CSS (0) —
lab/DiffViewer 71.8 kB (0) · 2.1 kB CSS (0) —
lab/EmojiPicker 71.2 kB (0) · 722 B CSS (0) —
lab/ListInput 83.7 kB (0) · 1.6 kB CSS (0) —
lab/Schedule 62.0 kB (0) · 3.9 kB CSS (0) —
lab/TourStep 58.6 kB (0) · 590 B CSS (0) —
lab/TransferList 76.7 kB (0) · 1.7 kB CSS (0) —
lab/TransferListSelector 83.2 kB (0) · 1.9 kB CSS (0) —
richtext/RichTextEditor 278.7 kB (0) · 2.6 kB CSS (0) —
richtext/RichTextEditorToolbar 225.6 kB (0) · 454 B CSS (0) —
richtext/RichTextView 259.2 kB (0) · 2.3 kB CSS (0) —
lab/Comments 259.4 kB (−1 B) · 2.5 kB CSS (0) —
lab/SelectableCardGroup 50.9 kB (−1 B) · 162 B CSS (0) —
SideNav 70.2 kB (−2 B) · 11.2 kB CSS (0) —
DateTimeInput 168.6 kB (−24 B) · 17.1 kB CSS (0) —

Package size: @astryxdesign/core 6.30 MB packed (+212 B); no new dependencies.

API changes: none in this pull request

Committed API report behind this build: core 1 row; run pnpm api:report.

Not run on this PR: 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.

Changes requested. Routing the tracker through paintPress is the right direction, but against main this pull request still carries all of #8076 (about 15,800 changed lines against its own 91), and dispose can end a fade the tracker did not start. Please land #8076 and merge main so the diff shows only the three-file tracker change, and make dispose finish only the tracker's own running fades, with a test for that sequence.

  • actionGroupTracker.ts:430-437 never forgets an action once the writer ends its fade, so dispose also removes a fade another painter starts on that action later, which the tracker did not do before this commit.

[Automated review]

vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
@vjeux
vjeux force-pushed the uikit/c19-tracker-paint branch from 30e0d10 to 6471d4c Compare November 3, 2026 22:55

@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.

Changes requested. Routing the tracker through one press writer is a reasonable direction, but this branch was built on copies of #8076 and #8360 that have since landed on main in a different form, so it cannot merge as it stands.

  • The branch conflicts with main in 87 files, including actionGroupTracker.ts, actionGroupTracker.test.ts and pressFeedback.ts.
  • paintPress, which the tracker now imports (actionGroupTracker.ts:65), does not exist on main, because #8076 and #8360 landed without it, writePress or the held paint.
  • Resolving the merge toward this branch would re-add 27 changesets already released in v0.7.5 and v0.7.6 and modules main dropped or moved, such as gestures/useAttachment.ts.
  • The changeset's "No component uses the tracker yet" no longer holds on main, where AlertDialog drives the tracker with its paint on.
  • Against main the diff is 27,382 authored lines, of which the tracker change is 164.

Next: merge main keeping main's version of every carried file, rebuild the tracker change on main's press controller, and update the changeset and description. A few new comments could also be shorter; see the inline notes.

[Automated review]


import {PRESSED_ATTRIBUTE} from '../utils/pressFeedback';
import {PRESS_FADE_MS} from '../utils/pressGesture';
import {paintPress} from '../utils/pressFeedback';

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.

main has no paintPress to import: #8076 and #8360 landed without it, writePress or the held paint, and main's press controller writes the attribute through a private paintElement. After merging main, this change needs rebuilding on that controller, or the one-writer design has to come to main with every painter it covers.

'@astryxdesign/core': patch
---

[chore] The internal action-group tracker paints its highlight through the one press writer in `utils/pressFeedback.ts`, as the document's press controller does, so neither cuts the other's fade short, a `held` paint is left alone, and its unmount ends only the fades it started that are still running. No component uses the tracker yet, and no package entry point exports it.

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.

On main, AlertDialog drives the tracker with its paint on (hooks/useActionGroupTracking.ts), so "No component uses the tracker yet" would be false in the release that ships this. Once the change is rebuilt on main, could this say what changes for AlertDialog's actions?

Comment on lines +36 to +40
* The highlight is painted through `paintPress`, the one writer of the press
* attribute (utils/pressFeedback.ts), as the document's press controller
* paints: a write ends any fade another painter left running on that action,
* so neither cuts the other's fade short, and a paint the tracker did not
* write (a `held` row) is left alone.

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: this is one sentence of about 50 words with several topics. A shorter version: "The tracker paints through paintPress, the press attribute's one writer. A write ends a fade that another painter left running. A held paint stays with its owner."

element.removeAttribute(PRESSED_ATTRIBUTE);
}
for (const element of fading) {
// Each is the tracker's own fade, still running.

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: this repeats what the comment on the fading set (line 242) already says, so it can go.

const PAINTS: ReadonlySet<string> = new Set(['on', 'held', 'fading']);
/** A `fading` paint's own release clock, per element (paintPress). */
const fadeTimers = new WeakMap<Element, ReturnType<typeof setTimeout>>();
/** A `fading` paint's end callback, per element (paintPress's onFadeEnd). */

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: this restates the name and type of fadeEnds, so it can go.

@vjeux
vjeux force-pushed the uikit/c19-tracker-paint branch from 6471d4c to abde23b Compare November 3, 2026 23:40
@vjeux vjeux changed the title fix(core): the action-group tracker paints through the one press writer fix(AlertDialog): a released action fades on the theme's tempo, as other presses do Nov 3, 2026
@github-actions github-actions Bot removed the needs:design-review Affects visuals — Design should review label Nov 3, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
meta#8638's own change. The tracker paints its groups' presses through
paintPress, the one writer, which now takes an `onFadeEnd` for a `fading`
paint: the writer calls it once, when that fade stops being the element's
paint, on its release's end (meta#8890's endAfterRelease) or when a later
write replaces it. The tracker forgets an action there, so `dispose` ends
only its own running fades.

Absorbs meta#8638.
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
meta#8638's own change. The tracker paints its groups' presses through
paintPress, the one writer, which now takes an `onFadeEnd` for a `fading`
paint: the writer calls it once, when that fade stops being the element's
paint, on its release's end (meta#8890's endAfterRelease) or when a later
write replaces it. The tracker forgets an action there, so `dispose` ends
only its own running fades.

Absorbs meta#8638.
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
meta#8638's own change. The tracker paints its groups' presses through
paintPress, the one writer, which now takes an `onFadeEnd` for a `fading`
paint: the writer calls it once, when that fade stops being the element's
paint, on its release's end (meta#8890's endAfterRelease) or when a later
write replaces it. The tracker forgets an action there, so `dispose` ends
only its own running fades.

Absorbs meta#8638.
vjeux added a commit to vjeux/astryx that referenced this pull request Nov 3, 2026
meta#8638's own change. The tracker paints its groups' presses through
paintPress, the one writer, which now takes an `onFadeEnd` for a `fading`
paint: the writer calls it once, when that fade stops being the element's
paint, on its release's end (meta#8890's endAfterRelease) or when a later
write replaces it. The tracker forgets an action there, so `dispose` ends
only its own running fades.

Absorbs meta#8638.

The gestures README says so: the tracker paints its groups' presses with
paintPress.

@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.

Changes requested: the timer change is correct and brings the tracker's release fade onto the theme's tempo, but the release note claims more than the change does.

  • The changeset (and the User impact section) says every action a finger or pen lifts on now fades for the theme's full release time, but a lift that closes the alert (Cancel, or an action that closes it at once) still ends its fade at the close and a loading action paints no overlay, so please reword it to cover an action lifted while the alert stays open and enabled.

Optional: the new sentence in pressFadeMs's doc comment repeats the reason the tracker's own comment gives, and the pressFeedback.ts header's @output list does not name pressFadeMs yet.

[Automated review]

'@astryxdesign/core': patch
---

[fix] AlertDialog: under the touch presentation, the action a finger or pen lifts on now fades for the theme's full release time, as every other press does, instead of cutting off at 200 ms under a slower motion tempo.

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 promises the longer fade for every lifted action, but a lift that closes the alert (Cancel, or an action that closes it at once) still ends its fade at the close, and a loading action paints no overlay. Suggested wording:

[fix] AlertDialog: under the touch presentation, an action lifted while the alert stays open now ends its release fade on the theme's tempo-scaled clock, as the stylesheet's fade does, instead of at a fixed 200 ms.

* The release fade's clock on `element`, read once, at the release, from the
* property its stylesheet reads: the theme's `--_astryx-motion-tempo`. Under
* Reduce Motion a tempo may shorten the fade, never lengthen it past 200 ms.
* A group's tracker times its own release fades with it too.

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: this sentence names a caller, which the import already shows, and the tracker's own comment gives the reason. Consider dropping it, and adding pressFadeMs to the header's @output list instead.

…her presses do

Under the touch presentation, AlertDialog's action-group tracker took the
press off an action lifted while the alert stays open on a fixed 200 ms
timer. The stylesheet's
release runs 200 ms times the theme's tempo (up to 1.5), and the press
controller's own timer follows it, so under a slower tempo the fade
snapped off before it ended.

The tracker now times its release fades with the press controller's clock
(pressFadeMs, exported from pressFeedback.ts), which also keeps the
Reduce Motion cap.

@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.

Recommending approval: the action-group tracker now ends a lifted action's release fade on the press controller's tempo-scaled clock, so under a non-default theme tempo AlertDialog's action keeps its press paint for the whole release, as component:Button FR15 and spec:AST-108 FR1 and FR4 require.

The new tempo test fails against the previous tracker and passes here, the Reduce Motion cap is covered, and the reworded changeset now matches what changes. CI's test jobs were skipped while the pull request is a draft, so they still need to run once it is marked ready.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 4, 2026 00:39
@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 01:44
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 01:44
@cixzhang
cixzhang merged commit 787b696 into meta:main Nov 4, 2026
151 of 156 checks passed
@vjeux
vjeux deleted the uikit/c19-tracker-paint branch November 4, 2026 04:40
cixzhang added a commit that referenced this pull request Nov 4, 2026
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.
cixzhang added a commit that referenced this pull request Nov 4, 2026
…9758)

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

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>

* docs(core): the press clock's comments say the release waits for its 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.

* Merge main into the press release change

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.

Co-authored-by: Christopher Chedeau <vjeuxx@gmail.com>

This branch was successfully deployed

1 active deployment
Preview — ea5342df 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants