Skip to content

refactor(Toast): a moved toast's card runs no hidden transition - #10223

Merged
cixzhang merged 1 commit into
meta:mainfrom
vjeux:uikit/c18-toast-card-still
Nov 6, 2026
Merged

cixzhang merged 1 commit into
meta:mainfrom
vjeux:uikit/c18-toast-card-still

Conversation

@vjeux

@vjeux vjeux commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Maintainer impact

When a Dialog, a modal Drawer or a bottom sheet with a scrim opens or closes while a toast is on screen, the top-layer ToastViewport moves its host into the modal or back out, and each toast card that has already entered runs a hidden transform transition. Since #10086 it runs from the identity to the identity, so nothing moves on screen, but the card fires transitionrun and transitionend at every move, and its entrance depends on two private custom properties that the row sets only so that the replayed starting values match the resting ones. AlertDialog's touch exit (#8084) moves a toast twice for each alert. Code and tests that watch a toast's transitions see one start per move that changes nothing.

Intended invariant

  • component:Toast FR5: "A new card slides in from its edge and fades in". A toast's first entrance stays the same.
  • component:Toast FR12: a top-layer viewport moves into the latest open modal and back, "keeping each toast, its timer, and focus inside the viewport".
  • Nothing visible changes: an entered card keeps its transform, opacity and box across a move, as it does on main.

Change

  • The card's starting style moves into its own style, applied only until the toast's row starts to open: the same gate as the row's, from the same state, which the row now passes to the card. A standalone Toast card keeps its entrance.
  • A move then renders an entered card with no starting style, so no transition starts.
  • This replaces the two private custom properties the row set on the card (--_toast-start-opacity and --_toast-start-slide), so they also leave the docs and the derived-variable registry's list.
  • No API change. It belongs in maintenance because the transition it removes changes nothing on screen.

The host still moves as a DOM node, and React sees nothing. Moving the toasts through a React portal instead would remount them: a portal whose container changes is a new portal to React, so every toast would enter again. A toast left outside an open modal cannot take a tap or focus, so it has to live inside the modal.

Evidence

  • Failure before the change: on main's "App toast over dialog" and "App toast over drawer" stories, each move of a toast already on screen starts a transform transition on its card: one when a Dialog closes, one when it opens, two when a Drawer closes and opens again. Chromium and WebKit show the same. On a Storybook built from main, the three cases for a toast already shown fail three runs out of three in each engine, each listing card transform.
  • Success after the change: all five cases pass in both engines. With the new gate removed, four cases fail, the move during an entrance included. In the iOS 26.2 Simulator (Mobile Safari), on a local build of feat(AlertDialog): under a finger the alert appears and leaves the way iOS's does #8084 with this change, repeating "Delete item", then "Delete", three times, the four moves after the first entrance start no transition on the toast's row or card; on feat(AlertDialog): under a finger the alert appears and leaves the way iOS's does #8084 without this change, each starts one on the card.
  • Product/runtime behavior verified unchanged: the moved cases check that the card's opacity stays above 0.99 on every frame, as on main. A new toast still slides and fades in, and the first case asserts that the recorder sees its row and card transitions start, so the empty lists in the other cases count. A dismissed toast still collapses.
  • CI impact: no workflow, action or CI script changes.

Scope

  • No intended public API, product behavior, visual direction, or policy change.
  • Product changes discovered during the work were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

Local gates at c048c03, on main add0516; this head changes only the changeset, now an [internal] entry:

  • Toast/__tests__/ToastViewport.hostMove.interaction.browser.spec.ts (it also records every transition or animation that starts on the toast's row or card, and a new case covers a modal Drawer): Chromium twice and pinned to 2 cores three times, 5 of 5 each; WebKit in CI's container five times, 25 of 25. The bottom sheet's and the drawer's toast outlet accessibility contracts (6) and the Toast, Layer, Dialog, Drawer, BottomSheet and theme units (3,050) pass.
  • CI=true pnpm lint (no errors), the build, pnpm typecheck, Storybook, pnpm test:ui (21,545), pnpm test:node (16,817), check:knowledge, check:repo, specs:for --diff and review:pre pass. api:report --check reports drift already on main (the CLI's ComponentDeprecation and search types), none of it in Toast.
  • This change adds no conflict with the open Toast pull requests. AlertDialog's own case comes with feat(AlertDialog): under a finger the alert appears and leaves the way iOS's does #8084, whose story it needs.

@vercel

vercel Bot commented Nov 6, 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 6, 2026 6:43am UTC

Request Review

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

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · a3c7630

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
Toast · Storybook 88.9 kB (+71 B) · 9.6 kB CSS (−14 B) 1,644 (+1) — · — · —

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

API changes: none in this pull request

Committed API report behind this build: cli 19 rows, core 21 rows; run pnpm api:report.

Wide change (shared styles: packages/core/src/theme/derivedVarRegistry.test.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 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 6, 2026, 6:48 AM UTC

@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec c048c03

@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 code change looks right, but the changeset describes a visible defect that main does not have.

  • .changeset/toast-moved-card-still.md says a moved toast "restarts its card's slide", but on main the moved card's transform transition runs from the identity to the identity (in Chromium its transform, opacity and position stay unchanged on every frame when a Dialog or a modal Drawer opens or closes over it, and the 0.7.9 notes already say a moved toast stays where it is), so please reword it to what changes, for example "A toast's card no longer runs a hidden transform transition, with its transitionrun and transitionend events, when a Dialog, a modal Drawer or a scrim sheet opens or closes over it. The toast already stayed still, and nothing on screen changes."

Please make the description's User impact match that wording. The card's new entry gate, the private-property cleanup and the new Drawer case look good, and a toast's first entrance is unchanged.

[Automated review]

Comment thread .changeset/toast-moved-card-still.md Outdated
'@astryxdesign/core': patch
---

[fix] A toast already on screen no longer restarts its card's slide when a Dialog, a modal Drawer or a scrim sheet opens or closes over it. Its card now enters only once, as its row does.

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 describes a visible restart that main does not have. Since the 0.7.9 fix, a moved card's restarted transform transition runs from translateY(0px) to its resting translateY(0px) scale(1), the identity on every frame, so the card neither slides nor fades. In Chromium its transform, opacity and box stay unchanged through each Dialog and Drawer move. Suggested wording: "A toast's card no longer runs a hidden transform transition, with its transitionrun and transitionend events, when a Dialog, a modal Drawer or a scrim sheet opens or closes over it. The toast already stayed still, and nothing on screen changes."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reworded at d873097: the changeset now says the card no longer runs a hidden transform transition, with its events, and that the toast already stayed in place. The description says the same.

@vjeux
vjeux force-pushed the uikit/c18-toast-card-still branch from c048c03 to d873097 Compare November 6, 2026 06:09
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec d873097

@vjeux vjeux changed the title fix(Toast): a moved toast's card starts no transition refactor(Toast): a moved toast's card runs no hidden transition Nov 6, 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.

Approved pending CI: CI has not run on this head yet. The required checks wait for a maintainer to add the ci:run label; CI runs once it is added.

The changeset and description now match the change: on main a moved toast's card runs an identity-to-identity transform transition, with its events, that moves nothing on screen, and this change removes it. The host-move browser spec fails its three already-shown cases on main and passes on this head, and a toast's first entrance is unchanged.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 6, 2026 06:25
A top-layer ToastViewport moves its host into the latest open modal and
back out. Each move renders the toast's card again, and the card's
starting style applied once more. So a toast already on screen started
a transform transition at every move: a Dialog, a modal Drawer or a
scrim sheet that opened or closed over it.

The card's starting style now applies only until the toast's row starts
to open, as the row's own does, and the row passes that state to the
card. A move then renders an entered card at rest and starts nothing.
This replaces the two private start properties the row set on the card,
so they leave the docs and the registry's list too.
@vjeux
vjeux marked this pull request as draft November 6, 2026 06:32
@vjeux
vjeux force-pushed the uikit/c18-toast-card-still branch from d873097 to a3c7630 Compare November 6, 2026 06:32
@cixzhang

cixzhang commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

/approve-spec a3c7630

@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 still a draft, and its required checks run once it is marked ready for review and a maintainer adds the ci:run label.

The [internal] changeset and the description match the change: on main a moved toast's card runs an identity-to-identity transform transition, with its events, that moves nothing on screen, and this change removes it. The host-move browser spec fails its three already-shown cases on main and passes on this head, and a toast's first entrance is unchanged.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 6, 2026 06:48
@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 6, 2026
@cixzhang
cixzhang marked this pull request as draft November 6, 2026 06:50
@cixzhang
cixzhang marked this pull request as ready for review November 6, 2026 06:50
@cixzhang
cixzhang merged commit 6d8e4c3 into meta:main Nov 6, 2026
162 of 167 checks passed
cixzhang added a commit to vjeux/astryx that referenced this pull request Nov 6, 2026
@vjeux
vjeux deleted the uikit/c18-toast-card-still branch November 6, 2026 07:18

This branch was successfully deployed

1 active deployment
Preview — a3c76308 Deployed Nov 6, 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