Skip to content

fix(core): a control in an opening layer keeps its settled touch insets - #9957

Merged
cixzhang merged 1 commit into
meta:mainfrom
vjeux:c04/hit-area-layout-boxes
Nov 4, 2026
Merged

cixzhang merged 1 commit into
meta:mainfrom
vjeux:c04/hit-area-layout-boxes

Conversation

@vjeux

@vjeux vjeux commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

User impact

Under a finger, a Switch or InfoTip measured while an ancestor is scaled keeps the scaled frame's touch insets until the next resize. On the open touch presentation, a popover growing out of its trigger leaves a switch a 21.8 px left inset and a 0.44 px right one, not the settled 2 px.

Problem and solution fit

  • watchHitArea measures a control from client rects once it is on screen, and during the opening the layer's scale is in them.
  • A transform changes neither layout size nor visibility, so nothing measures again when the layer settles.
  • The hit area lets a finger reach 44 px without taking a neighbour's taps.
  • Insets are lengths in the control's own box, so the pass now measures in layout px: each rect's offset from the control is divided by its scale, client size over computed size. A scale within 0.001 of 1 changes nothing.

Expected behavior and authority

spec:AST-094 FR42: under a coarse pointer, touch targets meet 44 px through an invisible hit area, clamped to half the gap to a neighbour.

Smallest restoration

measureOne computes insets from layout-px rects; a touch's distance checks keep screen rects. No new observer, listener or timer; a mouse still measures nothing.

Evidence

  • Reproduction before the change: on the open touch growth stack (feat(Popover): under a finger, it grows out of its trigger and shrinks back into it #8187 → test(Popover): browser proofs of the touch presentation's grow and shrink #9823, at 77983a3), the Popover "Settings" story's switches got 2.23 0.44 0.05 21.8, 0.07 0.44 0.05 21.8 and 0.07 0.44 21.95 21.8 px (top, right, bottom, left) in Chromium on the phone profile, 3 of 3 runs.
  • Result after the change: 10 2 10 2 px for all three, 3 of 3 runs, as measured at rest.
  • Representative unchanged path: on main, the Popover's CSS entry animation never reaches getBoundingClientRect in Chromium (rect 280 px while the transform reads matrix(0.95…)), so main is right there: 10 2 10 2 px either way. The defect shows wherever the scale reaches the rects.
  • Regression tests: a watchHitArea case at half size hears {top: 16, right: 2, …} on main and the full-size {top: 10, right: 4, …} here. A browser case holds the Switch story at scale 0.5 for the first pass: on main its settled insets stay 16px 12px 16px 12px against 10px 2px 10px 2px at rest; here they match, 3 of 3 runs. A mouse context writes none.

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

At 47ec35b on main fbb81c6:

  • vitest run --project ui on hitArea.test.ts, Switch, InfoTip, SideNav.test.tsx and ResizeHandle.test.tsx: 10 files, 530 tests passed.
  • playwright test packages/core/src/utils/__tests__/hitArea.interaction.browser.spec.ts --config playwright.interaction.config.ts --project=chromium, on a Storybook built at this commit: 2 passed in 3 runs. On main's build the first case fails.
  • Switch.interaction.browser.spec.ts in Chromium: 44 passed on main's build and on this one.
  • The growth-stack numbers come from a one-off probe that wraps setProperty, with a positive control on its filter. It is not part of this change.
  • Core tsc --noEmit, pnpm lint, eslint (CI=true), Prettier and check:changesets pass. pnpm review:pre: 0 findings.

Overlap with open pull requests

@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 2:43pm UTC

Request Review

@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review 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, 2:51 PM UTC

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 47ec35b

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC
InfoTip 37.2 kB (+321 B) · 5.0 kB CSS (0) —
Switch 87.3 kB (+293 B) · 9.5 kB CSS (0) —

Package size: @astryxdesign/core 6.39 MB packed (+1.8 kB); no new dependencies.

API changes: none in this pull request

Committed API report behind this build: cli 8 rows, core 2 rows; 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

@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 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 layout-px measurement looks right, but the release note describes a defect that main does not have.

  • The changeset's "Before, a popover growing out of its trigger left the insets its first, scaled frame gave." does not hold on main, where the Popover's switches already settle at 10px 2px 10px 2px (as the pull request's own evidence notes), so reword it to what the tests prove, for example "Before, a control measured while an ancestor was scaled kept that frame's insets until the next resize."

The new unit case and browser spec fail on main and pass here, and the Switch and InfoTip suites stay green. One non-blocking inline suggestion splits a source comment into one topic per sentence.

[Automated review]

'@astryxdesign/core': patch
---

[fix] Under a finger, a Switch or InfoTip in a layer that opens from a smaller scale keeps the touch insets of the size the layer settles at. Before, a popover growing out of its trigger left the insets its first, scaled frame gave.

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 the Popover's switches already settle at 10px 2px 10px 2px (the pull request's own evidence says so too), so "Before, a popover growing out of its trigger…" describes a defect released versions do not have. Suggested wording, matching what the tests prove:

[fix] Under a finger, a Switch or InfoTip measured while an ancestor is scaled keeps the touch insets of its unscaled layout. Before, that measurement kept the scaled frame's insets until the next resize.

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.

Done in 47ec35b: the release note now uses this wording.

Comment thread packages/core/src/utils/hitArea.ts Outdated
Comment on lines +471 to +474
// The insets are in the control's layout px; the rects stay on screen for
// a touch's distances. Neighbours map by the control's scale, as if in its
// layer. One outside an opening layer then reads farther away; a touch
// re-measures at once and counts 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.

Non-blocking: the first and third sentences each join two topics with a semicolon. A rewrite with one topic per sentence:

// The insets are in the control's layout px. The returned rects stay in
// screen px for a touch's distance checks. A neighbour maps by the
// control's scale, as if it is in the same layer. A neighbour outside that
// layer then reads farther away. A touch compares screen distances, so it
// still counts that neighbour.

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.

Done in 47ec35b: the comment now has one topic per sentence, as suggested.

utils/hitArea measured a control's hit insets from client rects. A
layer that opens from a smaller scale scales those rects, so a pass
during the opening left the insets of a scaled frame. A popover growing
out of its trigger left a switch's left inset at 21.8 px instead of
2 px, and nothing measured it again. The insets are lengths in the
control's own box, so a pass now measures in its layout px: each rect's
offset from the control is divided by the control's scale on screen,
its client size over its layout size.

@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 release note now describes what the tests prove, and the layout-px measurement holds up: the new unit case and the Chromium spec fail on main and pass here, and the existing Switch and InfoTip hit-area suites stay green.

Next step: mark the pull request ready for review, and a maintainer adds the ci:run label so CI runs.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 4, 2026 15:00
@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 15:06
@cixzhang
cixzhang marked this pull request as ready for review November 4, 2026 15:06
@cixzhang
cixzhang merged commit 0f05928 into meta:main Nov 4, 2026
162 of 167 checks passed
@vjeux
vjeux deleted the c04/hit-area-layout-boxes branch November 4, 2026 15:56

This branch was successfully deployed

1 active deployment
Preview — 47ec35b6 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. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants