Skip to content

fix(gestures): a selection a claimed lift's own handlers make stays - #9848

Merged
cixzhang merged 2 commits into
meta:mainfrom
vjeux:uikit/c01-kept-lift-selection
Nov 4, 2026
Merged

cixzhang merged 2 commits into
meta:mainfrom
vjeux:uikit/c01-kept-lift-selection

Conversation

@vjeux

@vjeux vjeux commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Stack: #9848 → #8657 → #8660

User impact

Part of the UIKit-parity work. With a pen on a touch screen, an AlertDialog action runs when the pen lifts. If that action selects text on the page, the selection vanishes right after the click: the drag's selection hold puts the press's selection back over it. A text field already keeps its own selection, since the hold leaves a focused field alone. The same happens for every recognizer that claims a mouse or pen press and runs a handler at its lift.

Problem and solution fit

  • Why it happens: a claimed mouse or pen press takes a drag selection hold, so the drag starts no selection and clears none (spec:AST-094 FR41). At the lift the hold puts back the selection the press began with.
  • Why it harms the task: the lift's own handlers, such as the action's click, run after that release. A selection they make is then overwritten.
  • Why it matters: the hold protects the page's selection from the drag. It is not meant to undo what the action itself does, and a native button's click keeps the selection its handler makes.

The fix: after the lift's handlers run, the hold keeps a selection they changed, or one a render they queue changes in the next microtask. When they change nothing, the press's selection comes back, as before.

Expected behavior and authority

spec:AST-094 FR41: "A mouse or pen drag that a recognizer claims takes no new text selection for that drag and never clears an existing selection." The selection an action's own click makes belongs to the click, as it does for a native button.

Smallest restoration

  • utils/selectionLock.ts: lockDragSelection returns a hold whose keepLiftSelection() keeps a selection changed since the release.
  • gestures/GestureHost.ts: at a claimed contact's lift, the host calls it after the press ends, which runs the lift's handlers.
  • No public API changes; both modules are internal.

Evidence

  • Reproduction before the change: in AlertDialog.test.tsx, "keeps the selection that the action's own click makes when a pen press lifts on it" fails on main. The selection reads "Text the page selected", not "Text the action selects".
  • Result after the change: it passes, and so do three new selectionLock.test.ts cases: a selection made after the release stays; one made by a render queued before the keep stays; the press's selection comes back when nothing changed.
  • Representative unchanged path: when the lift's handlers change nothing, the press's selection is put back, and the existing selection lock and gesture host suites pass unchanged.
  • Regression proof: all four cases fail with GestureHost.ts and selectionLock.ts at main.

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 this head (on main bb3838b), after a fresh pnpm install --frozen-lockfile:

  • Red first: with GestureHost.ts and selectionLock.ts at main, the four new cases fail. The AlertDialog case keeps "Text the page selected", and the three unit cases have no keepLiftSelection.
  • Unit: the utils, gestures, AlertDialog, hooks, Slider and Carousel suites pass; the full test:ui passes (19,445 tests).
  • Browser, Storybook built at this head, Chromium and WebKit (container, CI settings): AlertDialog's interaction spec 11/11 and the gesture system's own gestures.interaction (66 passed in Chromium, 58 in WebKit; the rest are that file's engine gates).
  • Static: core typecheck, review:pre and check:knowledge pass.

When a recognizer claims a mouse or pen press, its drag's selection hold
puts the press's selection back after the lift. A selection that the
lift's own handlers made, such as the click an action runs, was put
back over too. Now the hold keeps a selection the lift's handlers
change, or a render they queue changes. When they change nothing, the
press's selection comes back as before.
@vercel

vercel Bot commented Nov 4, 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:47am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 4, 2026
@astracat-bot

astracat-bot Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

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

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 57210f3

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
SegmentedControl 81.7 kB (+114 B) · 6.7 kB CSS (0) — — · — · —
PowerSearch 236.1 kB (+110 B) · 21.8 kB CSS (0) — — · — · —
Slider 88.6 kB (+102 B) · 8.3 kB CSS (0) — — · — · —
7 more components
Component Size LoC Visual · A11y · RTL
lab/Comments 258.3 kB (+100 B) · 2.5 kB CSS (0) — — · — · —
AlertDialog · Storybook 83.1 kB (+99 B) · 13.1 kB CSS (0) 215 (0) ✓ · ✓ · ✓
DateTimeInput 167.8 kB (+99 B) · 17.2 kB CSS (0) — — · — · —
lab/CommentThread 253.0 kB (+99 B) · 2.4 kB CSS (0) — — · — · —
Switch 86.8 kB (+90 B) · 9.5 kB CSS (0) — — · — · —
TimeInput 131.5 kB (+90 B) · 14.5 kB CSS (0) — — · — · —
DateInput 147.1 kB (+83 B) · 15.5 kB CSS (0) — — · — · —

Package size: @astryxdesign/core 6.30 MB packed (+705 B); 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.

Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.


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.

Recommendation: approve. No blocking findings: keeping a text selection that a claimed mouse or pen lift's own handlers make matches spec:AST-094 FR41, and the new AlertDialog pen test fails before the change and passes after it.

  • Optional: in packages/core/src/utils/selectionLock.ts, renaming atLift to selectionAtRelease would let you drop the comment above it.

CI for this head stopped at the step that waits for a maintainer's ci:run label, before any lint or test ran, so it still needs to run before this lands.

[Automated review]

Comment on lines +157 to +159
// The selection when the lift released the hold, until the lift's
// handlers ran.
let atLift: ReadonlyArray<AbstractRange> | null = null;

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.

Optional naming suggestion: selectionAtRelease says what this holds, and atLift = null in keepLiftSelection already shows when it ends, so the comment could go.

@vjeux
vjeux marked this pull request as ready for review November 4, 2026 01:40
@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 02:44
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 02:44
@cixzhang
cixzhang marked this pull request as draft November 4, 2026 04:08
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 04:08

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

Recommendation: request changes. The code change is correct: keeping a selection that a claimed mouse or pen lift's own handlers make matches spec:AST-094 FR41. The new AlertDialog pen test fails before the change and passes after it, and Chromium shows the same for both a mouse and a pen. Only the description needs a fix.

  • Miss: the User impact example "for example a field's contents for copying" describes a bug that does not exist, because a lift handler that selects a text field's contents already keeps that selection before this change (the hold skips restoring while a text field has focus, packages/core/src/utils/selectionLock.ts lines 162-165), so please reword it to the page-text case your tests reproduce.

This pull request was reviewed on its own, not as a stack: #8657 is built on an earlier commit of this branch, not on its current head, so the declared stack does not hold until #8657 is rebased onto it.

[Automated review]

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

Recommendation: approve. Keeping a text selection that a claimed mouse or pen lift's own handlers make restores spec:AST-094 FR41 ("never clears an existing selection"). The new AlertDialog pen test and the three selection-hold cases fail before the change and pass after it, and CI passed on this head. The description's field example that held up the last review is gone, and the new wording matches what the tests reproduce.

  • Optional: renaming atLift to selectionAtRelease in packages/core/src/utils/selectionLock.ts would let you drop the comment above it.

[Automated review]

@cixzhang
cixzhang marked this pull request as draft November 4, 2026 06:40
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 06:41
@cixzhang
cixzhang merged commit 7b87c5c into meta:main Nov 4, 2026
122 of 123 checks passed
@vjeux
vjeux deleted the uikit/c01-kept-lift-selection branch November 4, 2026 11:42

This branch was successfully deployed

1 active deployment
Preview — 57210f3f 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