Skip to content

spec(AST-094): every touch presentation holds pointer input while it enters (FR35) - #8618

Merged
cixzhang merged 10 commits into
mainfrom
spec/ast094-fr35-every-entrance
Oct 27, 2026
Merged

cixzhang merged 10 commits into
mainfrom
spec/ast094-fr35-every-entrance

Conversation

@cixzhang

@cixzhang cixzhang commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Decided (Cindy, 2026-10-26, D30 = A).

User impact

On a phone, a tap that lands while an alert, a sheet, or a dialog is still entering no longer closes it or reaches the page beneath. It's absorbed, as it already is for a popover or menu growing out of its trigger. Keyboard and screen-reader users are never held, and a mouse is unchanged.

Change: spec:AST-094

  • FR35 covers every touch presentation's entrance (Popover and anchored menus, alerts, sheets, dialogs). It holds pointer input only: keys and assistive technology stay live and the content stays in the accessibility tree. A pinch still zooms, and a mouse is unchanged. During an entrance FR35 wins over FR6's catch.
  • The scope line now says FR35 applies to every touch presentation's entrance. Current-state impact names the members (AlertDialog, Dialog, BottomSheet, BottomSheetSwitcher, Drawer, MobileNav, Lightbox) and the entrance-time exception to BottomSheet FR7, BottomSheetSwitcher FR6 and overlay-dismissal AV4. Toast isn't held, because the page behind it stays live.
  • The input-hold mechanism is recorded separately (layer-runtime INV16, architecture(layer-runtime): the runtime owns the one input hold (INV16) #8595).
  • The FR34/FR35 verification row gains alert, sheet, and dialog entrances, keys and a screen reader during an entrance, and a pinch. It fails any tap or drag during an entrance that closes, scrolls, moves focus, or reaches beneath.
  • DEC-16 records the decision. Its number assumes DEC-15 in spec(AST-108): theme motion is three knobs — tempo, character, reducedMotion #8613.

Writing rubric results

  • R1 present tense: pass. R2 research: none. R3 verification: row extended.
  • R4 rejected alternatives: one line in DEC-16. R5 change references: none in the record. R6 open questions: none.

@vercel

vercel Bot commented Oct 26, 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 27, 2026 8:35am UTC

Request Review

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 21fc4c1

@astracat-bot

astracat-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Oct 27, 2026, 9:12 AM UTC

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

Previews ready: Storybook and Sandbox were built with this PR's docsite. CI evidence will be added when available.

View Storybook for this PR · View Sandbox for this PR

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

Requesting changes: the FR35 direction has spec-owner approval for this head, but the record now cites a mechanism and overrides member contracts that the current specs don't reflect yet.

  • Land the layer-runtime input-hold amendment (#8595) first or together and add architecture:layer-runtime to affects_architecture and Current-state impact, or drop "The hold is the layer runtime's input hold" until it is current.
  • Name in Current-state impact each presentation FR35 now governs, with its entrance exception to component:BottomSheet FR7, component:BottomSheetSwitcher FR6 and family:overlay-dismissal AV4, and say whether Drawer, MobileNav, Toast and Lightbox are in scope.
  • Say whether FR6's "catch any animation mid-flight" applies to an entering sheet, and extend the FR35 verification row to fail a tap or drag during the new entrances that scrolls, moves focus or reaches the page.

[Automated review]

Comment on lines +394 to +395
in the accessibility tree. A pinch still zooms the page (FR10). The hold is
the layer runtime's input hold (`architecture:layer-runtime`). A mouse keeps

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 names an input hold that the current architecture:layer-runtime doesn't define. INV14 lists top-layer mounting, close-request delivery, the presentation hold, the exit copy and the backdrop tint, and main has no input-hold module in packages/core/src/Layer. Please land this with or after the layer-runtime amendment (INV16 in #8595) and add architecture:layer-runtime to affects_architecture and Current-state impact. Otherwise drop the sentence until that record is current.

Comment on lines +389 to +391
tap or a drag that lands while a touch presentation is still entering, a
Popover or an anchored menu growing out of its trigger, an alert, a sheet, or
a dialog, MUST NOT close it, scroll the page, move focus, or reach anything

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

FR35 now governs alerts, sheets and dialogs, but Current-state impact still applies FR35 only to DropdownMenu, ContextMenu and Popover. The current component:BottomSheet FR7 and component:BottomSheetSwitcher FR6 also still let a scrim tap close at any time. Please add a Current-state impact line for each governed member with its entrance exception, and say which record "an alert" is. Also say whether Drawer, MobileNav, Toast and Lightbox count as "every touch presentation".

tap or a drag that lands while a touch presentation is still entering, a
Popover or an anchored menu growing out of its trigger, an alert, a sheet, or
a dialog, MUST NOT close it, scroll the page, move focus, or reach anything
beneath it; the presentation finishes entering and stays open. Only pointer

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For a sheet this collides with FR6 ("A finger MUST be able to catch any animation mid-flight at the value on screen"). A drag on an entering sheet can't both catch it and be held until it finishes entering. Please state which rule applies during an entrance.

| FR29 | Trigger tests with explicit timestamps | a press in a fixed bar; a press in scrolling content held 149 and 150 ms; a quick tap in scrolling content; a scroll taking the touch before 150 ms; a drift of 12 and 14 pt; moves before and after the handoff; `presentation="popover"` | a fixed-bar press that waits, a held finger's scroll-view open before 150 ms or after a scroll, a quick tap that does not open at its lift, an open past the drift allowance, a lift that acts before the handoff, or a `popover` trigger that opens on press fails |
| FR31–FR33 | Browser tests and storyboards under a finger | a menu, a Popover and a ContextMenu lift: open, close, a pan outside, a tap outside, a pinch over the surface; a mouse | a surface that does not grow from and shrink into its trigger, a pan outside that leaves a menu open, a Popover whose dismissal changed, a pinch blocked other than by the author's `touch-action`, a tap outside that reaches the page, or a changed mouse path fails |
| FR34, FR35 | Browser tests and storyboards under a finger | a sub-menu drilling in and its Back row returning; a tap and a drag during a popover's and a menu's growth; a pinch during growth; a mouse | a drill-in that leaves the parent's rows in place, a change between levels that does not play on its roles, a tap during growth that closes, scrolls or moves focus, a pinch blocked other than by the author's `touch-action`, or a changed mouse path fails |
| FR34, FR35 | Browser tests and storyboards under a finger | a sub-menu drilling in and its Back row returning; a tap and a drag during a popover's and a menu's growth; a pinch during growth; a mouse; a tap and a drag during an alert's, a sheet's, and a dialog's entrance; a key and a screen reader during an entrance | a drill-in that leaves the parent's rows in place, a change between levels that does not play on its roles, a tap during growth that closes, scrolls or moves focus, a pinch blocked other than by the author's `touch-action`, or a changed mouse path, or a held key, a hidden content tree, or an entrance that a tap closes, fails |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For the alert, sheet and dialog entrances, this row fails only "an entrance that a tap closes". A tap or drag during those entrances that scrolls the page, moves focus or reaches beneath fails nothing, and the row has no pinch during an entrance. Please fail "a tap or drag during an entrance that closes, scrolls, moves focus or reaches anything beneath" and add a pinch case.

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec a601083

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

Requesting changes: the FR35 direction has spec-owner approval for this head, but the record overrides a current MobileNav claim without naming it and leaves two smaller gaps.

  • Add component:MobileNav FR4 ("A click on the overlay outside the Drawer requests close") to the entrance exceptions in Current-state impact, with spec:AST-003 FR10 and architecture:layer-runtime INV14, which leave dismissal to the component just as AV4 does.
  • Make the FR34/FR35 verification row fail an assistive-technology activation held during an entrance, since FR35 keeps assistive technology live.
  • Scope the "every touch presentation" line to the entrances FR35 lists, since a Toast is not held.

These are small edits to the same record; after the new commit, an engineering owner records approval again with /approve-spec <full head SHA>.

[Automated review]

Comment on lines +526 to +528
entrance is held (FR35), an exception during the entrance to
`component:BottomSheet` FR7, `component:BottomSheetSwitcher` FR6 and
`family:overlay-dismissal` AV4, which otherwise let a scrim tap close at any

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MobileNav is listed as held, but its current FR4 ("A click on the overlay outside the Drawer requests close") isn't among these exceptions. By the same reasoning as AV4, spec:AST-003 FR10 and architecture:layer-runtime INV14 also leave dismissal to the component. architecture:knowledge-contracts INV9 rules out a silent override, so please add these three here, and architecture:layer-runtime to affects_architecture. AV4 itself leaves outside dismissal to each member rather than letting a scrim tap close at any time.

| FR29 | Trigger tests with explicit timestamps | a press in a fixed bar; a press in scrolling content held 149 and 150 ms; a quick tap in scrolling content; a scroll taking the touch before 150 ms; a drift of 12 and 14 pt; moves before and after the handoff; `presentation="popover"` | a fixed-bar press that waits, a held finger's scroll-view open before 150 ms or after a scroll, a quick tap that does not open at its lift, an open past the drift allowance, a lift that acts before the handoff, or a `popover` trigger that opens on press fails |
| FR31–FR33 | Browser tests and storyboards under a finger | a menu, a Popover and a ContextMenu lift: open, close, a pan outside, a tap outside, a pinch over the surface; a mouse | a surface that does not grow from and shrink into its trigger, a pan outside that leaves a menu open, a Popover whose dismissal changed, a pinch blocked other than by the author's `touch-action`, a tap outside that reaches the page, or a changed mouse path fails |
| FR34, FR35 | Browser tests and storyboards under a finger | a sub-menu drilling in and its Back row returning; a tap and a drag during a popover's and a menu's growth; a pinch during growth; a mouse | a drill-in that leaves the parent's rows in place, a change between levels that does not play on its roles, a tap during growth that closes, scrolls or moves focus, a pinch blocked other than by the author's `touch-action`, or a changed mouse path fails |
| FR34, FR35 | Browser tests and storyboards under a finger | a sub-menu drilling in and its Back row returning; a tap and a drag during a popover's and a menu's growth; a pinch during growth; a mouse; a tap and a drag during an alert's, a sheet's, and a dialog's entrance; a key and a screen reader during an entrance; a pinch during an alert's and a sheet's entrance | a drill-in that leaves the parent's rows in place, a change between levels that does not play on its roles, a tap during growth that closes, scrolls or moves focus, a pinch blocked other than by the author's `touch-action`, or a changed mouse path, a held key, a hidden content tree, or a tap or drag during an entrance that closes the presentation, scrolls the page, moves focus or reaches anything beneath, fails |

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 row lists "a key and a screen reader during an entrance" but fails only "a held key, a hidden content tree". Since FR35 keeps assistive technology live, please also fail "an assistive-technology activation held during an entrance" (spec:AST-009 FR8, FR10).

Comment on lines +315 to +316
FR31 applies to anchored menus and to Popover under a finger, and FR35 to
every touch presentation's entrance; FR32 and

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 line says FR35 applies to every touch presentation's entrance, but FR35 names a Popover or anchored menu, an alert, a sheet and a dialog, and Current-state impact says a Toast is not held. Please scope this to the entrances FR35 lists, or move the Toast exclusion into FR35.

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 240b223

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

Requesting changes: FR35's wider entrance hold has engineering-owner approval for this head, but Current-state impact still overrides two current claims without naming them.

  • Add component:Popover DEC-8 ("The sheet always light-dismisses: a tap outside it or a swipe down closes it") to the entrance-time exceptions, since a Popover presented as a sheet follows the sheet and FR35 now holds that tap and swipe while it enters.
  • Name component:BottomSheetSwitcher FR5 and its Non-modal state ("leaves the page interactive") there too, or say in FR35 that a non-modal sheet's page is not held, as the record already says for Toast.

After the new commit, an engineering owner records approval again with /approve-spec <full head SHA>, which the author may do as one.

[Automated review]

Comment on lines +526 to +528
entrance is held (FR35), an exception during the entrance to
`component:BottomSheet` FR7, `component:BottomSheetSwitcher` FR6,
`component:MobileNav` FR4 and `family:overlay-dismissal` AV4, which otherwise

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

FR35 now holds a Popover sheet's entrance too (a popover presented as a bottom sheet follows the sheet, FR31), but this list doesn't name CURRENT component:Popover DEC-8: "The sheet always light-dismisses: a tap outside it or a swipe down closes it, whatever hasLightDismiss says, so a finger always has a way out." architecture:knowledge-contracts INV9 rules out a silent override, so please add DEC-8 to these entrance-time exceptions.

`component:BottomSheetSwitcher`, `component:Drawer`, `component:MobileNav`
and `component:Lightbox`: under a finger, a tap or a drag during the
entrance is held (FR35), an exception during the entrance to
`component:BottomSheet` FR7, `component:BottomSheetSwitcher` FR6,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Besides FR6, FR35 also holds the page around a non-modal flow while it enters ("MUST NOT close it, scroll the page, move focus, or reach anything beneath it"), which component:BottomSheetSwitcher FR5 says stays interactive ("hasScrim=false uses show() without a backdrop or scroll lock and leaves the page interactive") and its Non-modal state requires ("background content remains interactive"). Please name FR5 and that state here, or say in FR35 that a non-modal sheet's page is not held, as the Toast sentence below does for Toast.

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 33e2608

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

Requesting changes: FR35's wider entrance hold has engineering-owner approval for this head, but the record now says two different things about the page beside an entering non-modal sheet. FR35 and the FR34/FR35 verification row hold that page ("MUST NOT close it, scroll the page, move focus, or reach anything beneath it"), while Current-state impact says "the page behind them stays live", as component:BottomSheet FR11 and component:BottomSheetSwitcher FR5 keep it. Please state the non-modal carve-out in FR35 itself and add a passing case for the page beside an entering non-modal sheet to the row; after the new commit, an engineering owner records approval again with /approve-spec <full head SHA>, which the author may do as one.

[Automated review]

Comment on lines +396 to +398
(`component:AlertDialog`), a sheet, a dialog, a Drawer, MobileNav, or
Lightbox, MUST NOT close it, scroll the page, move focus, or reach anything
beneath it; the presentation finishes entering and stays open. Only pointer

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

FR35 lists "a sheet" without qualification, so a tap or a drag on the page beside an entering non-modal sheet "MUST NOT close it, scroll the page, move focus, or reach anything beneath it". Current-state impact (lines 537-539) says that page stays live, as component:BottomSheet FR11 and component:BottomSheetSwitcher FR5 keep it. Please state the carve-out here, for example: "Around a non-modal sheet only a tap or a drag on the sheet is held; the page stays live (component:BottomSheet FR11, component:BottomSheetSwitcher FR5)."

| FR29 | Trigger tests with explicit timestamps | a press in a fixed bar; a press in scrolling content held 149 and 150 ms; a quick tap in scrolling content; a scroll taking the touch before 150 ms; a drift of 12 and 14 pt; moves before and after the handoff; `presentation="popover"` | a fixed-bar press that waits, a held finger's scroll-view open before 150 ms or after a scroll, a quick tap that does not open at its lift, an open past the drift allowance, a lift that acts before the handoff, or a `popover` trigger that opens on press fails |
| FR31–FR33 | Browser tests and storyboards under a finger | a menu, a Popover and a ContextMenu lift: open, close, a pan outside, a tap outside, a pinch over the surface; a mouse | a surface that does not grow from and shrink into its trigger, a pan outside that leaves a menu open, a Popover whose dismissal changed, a pinch blocked other than by the author's `touch-action`, a tap outside that reaches the page, or a changed mouse path fails |
| FR34, FR35 | Browser tests and storyboards under a finger | a sub-menu drilling in and its Back row returning; a tap and a drag during a popover's and a menu's growth; a pinch during growth; a mouse | a drill-in that leaves the parent's rows in place, a change between levels that does not play on its roles, a tap during growth that closes, scrolls or moves focus, a pinch blocked other than by the author's `touch-action`, or a changed mouse path fails |
| FR34, FR35 | Browser tests and storyboards under a finger | a sub-menu drilling in and its Back row returning; a tap and a drag during a popover's and a menu's growth; a pinch during growth; a mouse; a tap and a drag during an alert's, a sheet's, and a dialog's entrance; a key and a screen reader during an entrance; a pinch during an alert's and a sheet's entrance | a drill-in that leaves the parent's rows in place, a change between levels that does not play on its roles, a tap during growth that closes, scrolls or moves focus, a pinch blocked other than by the author's `touch-action`, or a changed mouse path, a held key or assistive-technology activation, a hidden content tree, or a tap or drag during an entrance that closes the presentation, scrolls the page, moves focus or reaches anything beneath, fails |

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 row fails "a tap or drag during an entrance that closes the presentation, scrolls the page, moves focus or reaches anything beneath", which the live page beside a non-modal sheet (lines 537-539) would fail. Please add "a tap and a scroll on the page beside an entering non-modal sheet" as a state that must pass, and limit the page failures to presentations that hold the page.

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 24bf068

vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
…s open is held

spec:AST-094 FR35 as proposed in meta#8618 (cixzhang's decision on meta#8373): every
touch presentation holds pointer input while it enters, and names Lightbox.
The touch opening (the zoom out of the thumbnail, after at most the decode
wait, or its Reduce Motion fade) now takes the Layer module's input hold
(meta#8342, scope 'viewport') from showModal until the opening settles; a close
(an Escape mid-opening) or an unmount ends it. Keys and assistive technology
stay live and nothing turns inert; a pinch still zooms the page (FR10). A
mouse, or a viewer with no source, opens at once as before, with nothing to
hold.

Red first, on the same build without the hold: a tap above the photo closed
the viewer, a double tap zoomed it to 1017 px instead of the fitted 402, and
a drag down dismissed it. With the hold, all three finish the opening and
stay (Chromium and WebKit), Tab still moves focus within the dialog, the
controls and the photo showing are not inert, and the existing Escape
mid-opening case still closes it.
vjeux added a commit to vjeux/astryx that referenced this pull request Oct 27, 2026
…nters, on the layer runtime's input hold

spec:AST-094 FR35 and DEC-16, as proposed in meta#8618: every touch presentation
holds pointer input while it enters; keys and assistive technology stay
live; a mouse is unchanged. The standalone sheet's own overlay moves onto
meta#8342's shared hold (useInputHold, viewport scope), and a switcher's step,
which enters on the stylesheet, now holds too: the panel reports its
entrance under a finger until the entrance's transition ends (its opacity
under the reduced-motion cross-fade).

Tests: the hold covers the sheet and the scrim until the sheet lands, keys
and focus stay live, and a switcher's steps are held as they enter (3 fail
on the old sources); with a mouse nothing is held (2 guards). The browser
spec checks that Escape during the entrance closes the sheet once it lands.

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

Recommending approval: the wider FR35 entrance hold has engineering-owner approval for this head, and the record now agrees with every current claim it names, including the live page beside a non-modal sheet (component:BottomSheet FR11, component:BottomSheetSwitcher FR5). The changes requested on earlier heads are all addressed, so nothing further is needed from you.

[Automated review]

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec db4c10d

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

Recommending approval. Every change here carries engineering-owner approval for this exact head, and Current-state impact names each current dismissal rule the entrance hold pauses, with the page beside a non-modal sheet left live as component:BottomSheet FR11 and component:BottomSheetSwitcher FR5 require. Nothing further is needed from you; a new commit would need a fresh /approve-spec <full head SHA> from an engineering owner.

[Automated review]

@cixzhang

Copy link
Copy Markdown
Contributor Author

/approve-spec 8d09803

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

Recommending approval: every change to spec:AST-094 here carries engineering-owner approval for this exact head, and Current-state impact names each current dismissal rule the entrance hold pauses, with the page beside a non-modal sheet left live. Nothing further is needed from you; a new commit would need a fresh /approve-spec <full head SHA> from an engineering owner. If holding the page beside an entering non-modal Drawer (hasScrim={false}) is not intended, FR35's non-modal carve-out could name it alongside the non-modal sheet.

[Automated review]

@cixzhang
cixzhang merged commit 2f49219 into main Oct 27, 2026
54 checks passed
@github-actions
github-actions Bot deleted the spec/ast094-fr35-every-entrance branch October 28, 2026 06:17

This branch was successfully deployed

1 active deployment
Preview — 8d098033 Deployed Oct 27, 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. spec-auto-merge Auto-merge was enabled by the spec owner gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant