Skip to content

fix(Toast): a quick flick dismisses a toast of any height - #8047

Draft
vjeux wants to merge 1 commit into
meta:mainfrom
vjeux:uikit/c25-flick
Draft

vjeux wants to merge 1 commit into
meta:mainfrom
vjeux:uikit/c25-flick

Conversation

@vjeux

@vjeux vjeux commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

User impact

A quick flick toward a toast's edge snaps back on any toast up to 120 px tall (every one-line toast); only a 48 px drag dismisses it.

Problem and solution fit

  1. The flick needed 48 px. A release dismisses past max(40% of the height, 48 px), or as a flick (over 1.2 px/ms) that also travelled 48 px: up to 120 px tall, the flick never decides.
  2. The flick was timed by its handlers, which run a frame or two late: in Chromium, input spanning 33 ms is handled over 55 ms, so 1.4 px/ms reads as 0.84.

Expected behavior and authority

  • Toast.spec.md FR4 and spec:AST-094 FR36 (current): a release decides on projected travel (travel plus the release velocity times a projection) past the commit point, with no travel floor of its own for a flick.
  • Toast.doc.mjs: toasts "swipe-dismiss toward their configured top or bottom edge"; spec:AST-003 FR16 (a toast swipe dismisses only the toast) is kept.
  • iOS 26.2: a notification banner dismisses on a 15 pt flick.

Smallest restoration

Evidence

Mobile Safari, iOS 26.2 simulator; each path has a named test (ring drawn by the test page).

Path Clip
Before (main): a 46 px flick (about 20 ms) on a 56 px toast snaps back (real time, then ¼ speed) before
After: the same flick dismisses; the exit is Toast's existing one, unchanged here (over within a frame on this simulator) after
After: a slow 36 px drag still snaps back (cancel) cancel

Chromium phone emulation, CDP touch, 56 px toast: 46 px / 33 ms and 30 px / 23 ms flicks snapped back and now dismiss; slow 40 px and 60 px drags are unchanged.

Regression tests: pen and touch flicks on a one-line toast fail on main; a late-handled 30 ms flick fails with only the floor change.

Rebased onto main, which carries #8050, as one commit.

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 32035ec:

@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 30, 2026 11:15pm UTC

Request Review

@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 commented Oct 24, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

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

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

Current run: The current CI run concluded skipped. Current analysis is unavailable.

The exact-head preview is not available yet.


Generated by PR Enrichment workflow | View current CI run

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

The change works as described: a quick flick now dismisses a one-line toast, slow drags behave as before, and the new tests fail on main and pass here. Approval waits on one decision, because no current record settles Toast's swipe thresholds (spec:AST-003 leaves them to the component): should a swipe toward the edge dismiss as a flick at any travel past the 8 px slop, timed by the input events' timestamps, instead of also needing 48 px of travel? Any engineering owner, the author included, records that decision by commenting /approve-spec 6c39f1425a58b4693bf944d170732c5271e00017 on this pull request, or can point to the record that already governs it.

[Automated review]

@cixzhang

Copy link
Copy Markdown
Contributor

Posted by Cindy's agent on her behalf.

Parts of this PR re-implement behavior that already exists, or is being specified, as a shared part of core. Converging keeps one implementation per behavior:

  • Commit or spring back on release. core/src/Toast/useToastGesture.ts:25 decides on its own whether a release finishes or springs back. A shared release rule is being specified (AST-057 FR5 covers row swipe today); avoid a component-specific threshold model.

This is about where the behavior lives, not about the PR's intent.

@vjeux

vjeux commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

Agreed: one implementation.

@vjeux

vjeux commented Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

The release speed moved to the shared velocity tracker in #8121 (a0dfe79), which stacks on the foundation that provides it; this PR stays on main's estimator so it can land on its own.

vjeux added a commit to vjeux/astryx that referenced this pull request Oct 25, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 25, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 25, 2026
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 26, 2026
@vjeux
vjeux marked this pull request as draft October 29, 2026 22:29
A release toward the edge dismissed past max(40% of the card's height,
48 px), or as a flick only when it had also travelled 48 px. On any toast
up to 120 px tall the two floors are the same distance, so a flick could
never dismiss a one-line toast. The flick now needs no travel of its own
beyond the slop the swipe already passed.

The flick's speed was also timed with Date.now() in the handlers. Browsers
deliver touch and pointer moves on the next frame, so the handlers trail the
finger by up to two frames (measured in Chromium: a 33 ms flick handled over
55 ms), which halved the speed of a short flick. It is now timed by the input
events' own timeStamp.
@vjeux

vjeux commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

Current records now cover the threshold: Toast.spec.md FR4 and spec:AST-094 FR36 decide a release on projected travel past the commit point, with no travel floor of its own for a flick, so this removes the 48 px floor (at 32035ec); the rest of the shipped rule stays the gap FR4 lists.

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

Approval recommended: a quick flick now dismisses a one-line toast, slow drags behave as before, and the flick's speed is read from the input events' own timestamps. This follows the Toast component record's release rule (FR4, through spec:AST-094 FR36, which sets no travel floor for a flick) and spec:AST-100 FR4, and the new tests fail on main and pass here. The other gaps FR4 lists, the shared tracker's release velocity and cancelling a release that moves back, stay for the follow-up the description names.

[Automated review]

This branch was successfully deployed

1 active deployment
Preview — 32035ec9 Deployed Oct 30, 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants