Repository navigation
fix(core): under a finger a pressable highlights at touch-down, and waits only inside a scroller - #9765
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
Requesting changes. The touch-down highlight follows the touch-presentation spec's press profiles, and the new unit tests fail before the change and pass after it. Two things need fixing first:
isInsideScroller,allowedPansandrootScrollsinutils/pressFeedback.tscopy the gesture core's scroll-view probe ingestures/nativeScroll.ts, so move that test into autils/module (asutils/flatTree.tsalready does forparentAcrossShadow) and use it from both, so a Button and a grouped action keep one definition of "inside a scroll view".- The changeset says a pressable now highlights at touch-down, but a page that scrolls still counts as a scroller (a button on a 3000 px page still paints 151 ms after touch-down), so the changeset and the description should say that a scrolling page keeps the delay.
The inline comment suggestions are optional.
[Automated review]
| * gesture core stays out of Core's public entries until a component | ||
| * imports it. | ||
| */ | ||
| function isInsideScroller(element: Element): boolean { |
There was a problem hiding this comment.
This walk, with allowedPans and rootScrolls above it, repeats parseTouchAction, rootOverflow and the chain behind NativeScrollProbe.isInsideScroller in gestures/nativeScroll.ts, which PressTracker and useActionGroupTracking already use for the same decision. The controller can't import gestures/, but the shared test can move to a utils/ module that both import, as utils/flatTree.ts does for parentAcrossShadow. Then one fix reaches every pressable.
| '@astryxdesign/core': patch | ||
| --- | ||
|
|
||
| [fix] Under a finger, a pressable (a button, card, link, list row or any other surface) now highlights in the frame the finger lands, as UIKit's controls do, instead of after a 150 ms delay. Inside a scroller it still waits that delay, so a flick paints nothing, and a scroll that takes a held press cancels it with no fade. A mouse on a desktop keeps `:active`. |
There was a problem hiding this comment.
A page that scrolls counts as a scroller here (pressFeedback.ts:170-177), so a button on a long page still waits 150 ms. Suggested: "Under a finger, a pressable that no scroll can take (in a fixed bar, a dialog, a menu that fits, or a page that does not scroll) now highlights in the frame the finger lands … Inside a scroller, a page that scrolls included, it still waits that delay."
| /** | ||
| * Whether the browser could scroll something under this element: a box above | ||
| * it (the page included) that overflows on an axis it scrolls and that | ||
| * `touch-action` leaves to the browser. That is UIKit's question for a | ||
| * touch: is it inside a scroll view? It lives here, not in the gesture core's | ||
| * scroll probe, because every pressable carries this controller and the | ||
| * gesture core stays out of Core's public entries until a component | ||
| * imports it. | ||
| */ |
There was a problem hiding this comment.
Optional: two sentences here run past 25 words, and the last one explains where the function lives. Suggested: "Whether a scroll can take a touch on this element. A box above it counts when it overflows on an axis that touch-action leaves to the browser. The page counts too."
| // The flat tree the browser scrolls: a slotted node goes to its slot, a | ||
| // shadow root to its host. |
There was a problem hiding this comment.
Optional: this repeats parentAcrossShadow's own comment in utils/flatTree.ts, so it can go.
There was a problem hiding this comment.
Recommending approval. Under a finger, a pressable now highlights at touch-down outside a scroll view and keeps the 150 ms delay inside one, as the touch-presentation spec's press profiles (FR11, DEC-14) require, and the new unit tests fail before the change and pass after it. Both earlier requested changes are addressed: the press controller and the gesture core now share one scroll-view test in utils/scrollView.ts, and the changeset says a page that scrolls keeps the delay. Two optional follow-ups are in the inline comments.
[Automated review]
| ]); | ||
|
|
||
| /** How far a box must overflow, in px, before it counts as scrolling. */ | ||
| const OVERFLOW_TOLERANCE_PX = 1; |
There was a problem hiding this comment.
Optional: EDGE_TOLERANCE in gestures/nativeScroll.ts:56 holds the same 1 px threshold for the probe's canMoveY and canMoveX, while its isInsideScroller now reads this one. Exporting this constant and using it there keeps the two answers from drifting.
| // Only a finger inside a scroller waits. The controller tells the machine | ||
| // which touch waits (`down`'s `delayed`), and a touch that does not wait goes | ||
| // straight to `pressed`. After that the machine is the same. |
There was a problem hiding this comment.
Optional: the last two sentences narrate the code, and delayed's JSDoc already says which touch waits. Suggested: keep "Only a finger inside a scroller waits." and delete the rest. The unchanged comment at line 193, "A new touch always starts armed and painting nothing", is no longer true for an undelayed touch; "A delayed touch starts armed" would fit.
Under a coarse primary pointer, Button (and IconButton and ToggleButton) paints its touch press on its own ::before layer, present only while a press is on or fading, with isolation only then. ClickableCard, SelectableCard and Thumbnail fade their ::after. Each release is an opacity animation, which engines run on the compositor, so it keeps fading while the page's script runs. Any other pointer is unchanged. Rebased onto main and #9765 (which supersedes #8117), on Specs' direction: the layers play the strength's own press clock and curve (main's tempo clock) for now, and a pen follows the touch presentation. Button FR15's release length waits on an owner decision. So this drops #8118's UIButton table, its mouse and key input marker, its #8350 CLI files and #8338's reduced-motion arms. The press layer styles live in the press attribute's owner module. Co-authored-by: Cindy Zhang <cindyxz@meta.com>
There was a problem hiding this comment.
Recommending approval. Under a finger, a pressable now highlights at touch-down outside a scroll view and keeps the 150 ms delay inside one, as the touch-presentation spec's press profiles require (FR11, with DEC-14 for menus whose rows fit), and the new unit cases fail before the change and pass after it.
- Worth a follow-up: with
height="auto", AppShell's phone top bar isposition: sticky, so the walk inutils/scrollView.tspasses it and its controls still wait 150 ms on a long page, although FR11 lists a top bar among the bars that are not inside a scroll view. - Optional: trim the narrating comment at the top of
utils/pressGesture.ts(and the "always starts armed" sentence the change makes untrue), and share one overflow tolerance betweenutils/scrollView.tsandgestures/nativeScroll.ts.
[Automated review]
There was a problem hiding this comment.
Approved pending CI: CI has not run on this head yet.
Under a finger, a pressable now highlights at touch-down outside a scroll view and keeps the 150 ms delay inside one, as the touch-presentation spec's press profiles require (FR11, with DEC-14 for menus whose rows fit), and the new unit cases fail before the change and pass after it.
Non-blocking follow-ups:
- With
height="auto", AppShell's phone top bar isposition: sticky, so the walk inutils/scrollView.tspasses it and its controls still wait 150 ms on a long page, although FR11 lists a top bar among the bars that are not inside a scroll view. - The earlier inline suggestions still apply: trim the narrating comment at the top of
utils/pressGesture.tsand the "always starts armed" sentence the change makes untrue, and share one overflow tolerance betweenutils/scrollView.tsandgestures/nativeScroll.ts.
[Automated review]
6128ad5 to
e2f2ed7
Compare
…de scroll views A touch on a pressable that is not inside a scroll view paints its press in the frame the finger lands, as a UIControl does; inside a scroll view the content-touch delay still applies. The press controller and the gesture core's scroll probe share one scroll-view test (utils/scrollView). The WebKit interaction proofs now run when that module changes. Co-authored-by: Cindy Zhang <cindyxz@meta.com>
1b6a265 to
3b74202
Compare
|
/approve-spec 3b74202 |
There was a problem hiding this comment.
Approved pending CI: CI has not run on this head yet; it starts once the pull request is marked ready for review.
Under a finger, a pressable now highlights at touch-down outside a scroll view and keeps the 150 ms delay inside one, as the touch-presentation spec's press profiles require (FR11, with DEC-14 for menus whose rows fit), and the new unit cases fail before the change and pass after it.
Non-blocking follow-ups:
- With
height="auto", AppShell's phone top bar isposition: sticky, so the walk inutils/scrollView.tspasses it and its controls still wait 150 ms on a long page, although FR11 lists a top bar among the bars that are not inside a scroll view. - The earlier inline suggestions still apply: trim the narrating comment at the top of
utils/pressGesture.tsand the "always starts armed" sentence the change makes untrue, and read one 1 px overflow tolerance inutils/scrollView.tsandgestures/nativeScroll.ts.
[Automated review]
PR Analysis Report🔎 Preview ·
|
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| Button · Storybook | 45.8 kB (+529 B) · 8.7 kB CSS (0) | 628 (0) | ✓ · ✓ · ✗ |
| TableSelectionToolbar | 55.4 kB (+552 B) · 11.8 kB CSS (0) | — | — · — · — |
| TabMenu | 57.0 kB (+546 B) · 9.9 kB CSS (0) | — | — · — · — |
115 more components
| Component | Size | LoC | Visual · A11y · RTL |
|---|---|---|---|
| lab/TourStep | 58.5 kB (+546 B) · 590 B CSS (0) | — | — · — · — |
| MultiSelector | 73.6 kB (+543 B) · 15.3 kB CSS (0) | — | — · — · — |
| Pagination | 88.4 kB (+543 B) · 16.5 kB CSS (0) | — | — · — · — |
| BaseTypeahead | 55.9 kB (+542 B) · 9.7 kB CSS (0) | — | — · — · — |
| Selector | 79.6 kB (+541 B) · 16.2 kB CSS (0) | — | — · — · — |
| Stepper | 47.3 kB (+539 B) · 8.9 kB CSS (0) | — | — · — · — |
| SideNavCollapseButton | 46.6 kB (+537 B) · 8.8 kB CSS (0) | — | — · — · — |
| Tokenizer | 70.4 kB (+537 B) · 17.1 kB CSS (0) | — | — · — · — |
| ChatComposerInput | 59.9 kB (+533 B) · 10.0 kB CSS (0) | — | — · — · — |
| ChatComposerTokenElement | 59.9 kB (+533 B) · 10.0 kB CSS (0) | — | — · — · — |
| ToggleButton | 46.7 kB (+530 B) · 8.8 kB CSS (0) | — | — · — · — |
| Calendar | 54.9 kB (+529 B) · 9.3 kB CSS (0) | — | — · — · — |
| TopNavMegaMenuItem | 11.5 kB (+529 B) · 4.2 kB CSS (0) | — | — · — · — |
| Banner | 47.7 kB (+528 B) · 9.2 kB CSS (0) | — | — · — · — |
| TopNavItem | 11.4 kB (+528 B) · 4.0 kB CSS (0) | — | — · — · — |
| ChatLayoutScrollButton | 46.3 kB (+527 B) · 8.9 kB CSS (0) | — | — · — · — |
| ContextMenuItem | 21.3 kB (+527 B) · 6.0 kB CSS (0) | — | — · — · — |
| DialogHeader | 48.6 kB (+527 B) · 10.2 kB CSS (0) | — | — · — · — |
| CheckboxListItem | 54.5 kB (+526 B) · 10.4 kB CSS (0) | — | — · — · — |
| CodeBlock | 59.7 kB (+526 B) · 10.0 kB CSS (0) | — | — · — · — |
| Tab | 12.1 kB (+526 B) · 4.2 kB CSS (0) | — | — · — · — |
| DrawerHeader | 48.8 kB (+525 B) · 11.6 kB CSS (0) | — | — · — · — |
| Link | 43.2 kB (+525 B) · 6.9 kB CSS (0) | — | — · — · — |
| Popover | 52.5 kB (+525 B) · 12.8 kB CSS (0) | — | — · — · — |
| RadioListItem | 52.3 kB (+525 B) · 9.4 kB CSS (0) | — | — · — · — |
| ChatDictationButton | 46.3 kB (+523 B) · 8.8 kB CSS (0) | — | — · — · — |
| IconButton | 45.8 kB (+523 B) · 8.7 kB CSS (0) | — | — · — · — |
| MobileNavToggle | 46.1 kB (+523 B) · 8.7 kB CSS (0) | — | — · — · — |
| TopNavMenu | 59.6 kB (+522 B) · 9.9 kB CSS (0) | — | — · — · — |
| ChatSendButton | 46.2 kB (+521 B) · 8.7 kB CSS (0) | — | — · — · — |
| TopNavMegaMenu | 54.8 kB (+521 B) · 10.6 kB CSS (0) | — | — · — · — |
| TreeList | 39.9 kB (+520 B) · 5.3 kB CSS (0) | — | — · — · — |
| ListItem | 53.8 kB (+518 B) · 10.4 kB CSS (0) | — | ✓ · ✓ · ✓ |
| lab/Schedule | 61.1 kB (+518 B) · 3.9 kB CSS (0) | — | — · — · — |
| lab/SelectableCardGroup | 50.9 kB (+518 B) · 162 B CSS (0) | — | — · — · — |
| Carousel | 50.2 kB (+517 B) · 9.5 kB CSS (0) | — | — · — · — |
| ChatLayout | 48.9 kB (+517 B) · 9.3 kB CSS (0) | — | — · — · — |
| SelectableCard | 15.6 kB (+516 B) · 7.2 kB CSS (0) | — | — · — · — |
| ChatComposer | 62.0 kB (+515 B) · 10.6 kB CSS (0) | — | — · — · — |
| DropdownMenu | 74.5 kB (+515 B) · 16.0 kB CSS (0) | — | — · — · — |
| TableHeaderCell | 76.6 kB (+515 B) · 16.1 kB CSS (0) | — | — · — · — |
| DropdownMenuRadioItem | 19.6 kB (+514 B) · 6.4 kB CSS (0) | — | — · — · — |
| SideNavHeading | 60.3 kB (+514 B) · 10.0 kB CSS (0) | — | — · — · — |
| Step | 28.7 kB (+514 B) · 5.6 kB CSS (0) | — | — · — · — |
| Token | 26.1 kB (+514 B) · 4.8 kB CSS (0) | — | — · — · — |
| TopNavHeading | 59.7 kB (+514 B) · 9.8 kB CSS (0) | — | — · — · — |
| CommandPaletteItem | 10.8 kB (+512 B) · 3.6 kB CSS (0) | — | — · — · — |
| DropdownMenuItem | 18.9 kB (+512 B) · 6.0 kB CSS (0) | — | — · — · — |
| NumberInput | 55.6 kB (+512 B) · 10.2 kB CSS (0) | — | — · — · — |
| lab/EmojiPicker | 71.2 kB (+512 B) · 722 B CSS (0) | — | — · — · — |
| TableCell | 77.0 kB (+511 B) · 16.3 kB CSS (0) | — | — · — · — |
| BreadcrumbItem | 69.8 kB (+508 B) · 11.3 kB CSS (0) | — | — · — · — |
| MoreMenu | 74.8 kB (+508 B) · 16.0 kB CSS (0) | — | — · — · — |
| Table | 85.2 kB (+508 B) · 16.6 kB CSS (0) | — | — · — · — |
| SideNavItem | 55.3 kB (+507 B) · 9.8 kB CSS (0) | — | — · — · — |
| Lightbox | 53.0 kB (+505 B) · 9.1 kB CSS (0) | — | — · — · — |
| SegmentedControlItem | 11.1 kB (+505 B) · 4.0 kB CSS (0) | — | — · — · — |
| Thumbnail | 50.1 kB (+504 B) · 10.3 kB CSS (0) | — | — · — · — |
| Collapsible | 23.8 kB (+503 B) · 4.5 kB CSS (0) | — | — · — · — |
| MobileNav | 52.7 kB (+502 B) · 9.3 kB CSS (0) | — | — · — · — |
| richtext/RichTextEditor | 278.8 kB (+502 B) · 2.6 kB CSS (0) | — | — · — · — |
| ContextMenu | 75.8 kB (+500 B) · 15.9 kB CSS (0) | — | — · — · — |
| TopNav | 54.2 kB (+500 B) · 9.6 kB CSS (0) | — | — · — · — |
| DropdownMenuCheckboxItem | 19.6 kB (+499 B) · 6.4 kB CSS (0) | — | — · — · — |
| SelectorOption | 17.8 kB (+499 B) · 5.8 kB CSS (0) | — | — · — · — |
| FileInput | 54.3 kB (+496 B) · 9.7 kB CSS (0) | — | — · — · — |
| Typeahead | 63.6 kB (+496 B) · 11.2 kB CSS (0) | — | — · — · — |
| AvatarGroupOverflow | 39.3 kB (+495 B) · 5.5 kB CSS (0) | — | — · — · — |
| lab/DiffViewer | 71.7 kB (+494 B) · 2.1 kB CSS (0) | — | — · — · — |
| richtext/RichTextView | 259.2 kB (+494 B) · 2.3 kB CSS (0) | — | — · — · — |
| ClickableCard | 15.4 kB (+492 B) · 7.0 kB CSS (0) | — | — · — · — |
| DropdownMenuSubMenu | 58.3 kB (+492 B) · 9.3 kB CSS (0) | — | — · — · — |
| Item | 14.5 kB (+491 B) · 5.2 kB CSS (0) | — | — · — · — |
| Markdown | 146.5 kB (+488 B) · 18.8 kB CSS (0) | — | — · — · — |
| TextInput | 53.4 kB (+487 B) · 9.9 kB CSS (0) | — | — · — · — |
| ComplexSelector | 56.2 kB (+486 B) · 10.5 kB CSS (0) | — | — · — · — |
| CheckboxInput | 49.1 kB (+477 B) · 8.7 kB CSS (0) | — | — · — · — |
| Outline | 22.6 kB (+477 B) · 4.2 kB CSS (0) | — | — · — · — |
| SideNav | 71.9 kB (+477 B) · 10.1 kB CSS (0) | — | — · — · — |
| AppShell | 71.6 kB (+476 B) · 12.2 kB CSS (0) | — | — · — · — |
| lab/CommentComposer | 105.3 kB (+474 B) · 1.9 kB CSS (0) | — | — · — · — |
| Toast | 60.0 kB (+466 B) · 9.0 kB CSS (0) | — | — · — · — |
| LayerProvider | 63.8 kB (+464 B) · 9.4 kB CSS (0) | — | — · — · — |
| lab/CommentPin | 47.5 kB (+464 B) · 1.2 kB CSS (0) | — | — · — · — |
| CommandPalette | 51.5 kB (+444 B) · 12.3 kB CSS (0) | — | — · — · — |
| lab/TransferList | 76.1 kB (+435 B) · 1.7 kB CSS (0) | — | — · — · — |
| lab/ChatReactionBar | 66.8 kB (+429 B) · 1.1 kB CSS (0) | — | — · — · — |
| richtext/RichTextEditorToolbar | 226.4 kB (+424 B) · 454 B CSS (0) | — | — · — · — |
| lab/ChatEmojiPicker | 66.3 kB (+423 B) · 773 B CSS (0) | — | — · — · — |
| DateRangeInput | 71.7 kB (+415 B) · 11.2 kB CSS (0) | — | — · — · — |
| lab/TransferListSelector | 83.7 kB (+412 B) · 1.9 kB CSS (0) | — | — · — · — |
| lab/ListInput | 82.3 kB (+408 B) · 1.6 kB CSS (0) | — | — · — · — |
| Switch | 87.7 kB (+290 B) · 9.5 kB CSS (0) | — | — · — · — |
| TimeInput | 137.5 kB (+286 B) · 14.5 kB CSS (0) | — | — · — · — |
| lab/CommentThread | 257.0 kB (+275 B) · 2.4 kB CSS (0) | — | — · — · — |
| lab/Comments | 262.3 kB (+262 B) · 2.5 kB CSS (0) | — | — · — · — |
| Slider | 90.3 kB (+259 B) · 8.3 kB CSS (0) | — | — · — · — |
| AlertDialog | 84.1 kB (+258 B) · 13.1 kB CSS (0) | — | — · — · — |
| DateInput | 151.2 kB (+199 B) · 15.5 kB CSS (0) | — | — · — · — |
| SegmentedControl | 82.2 kB (+191 B) · 6.7 kB CSS (0) | — | — · — · — |
| PowerSearch | 242.1 kB (+190 B) · 22.2 kB CSS (0) | — | — · — · — |
| DateTimeInput | 173.4 kB (+182 B) · 17.2 kB CSS (0) | — | — · — · — |
| InputGroup | 43.1 kB (+29 B) · 7.3 kB CSS (0) | — | — · — · — |
| RadioList | 43.5 kB (+29 B) · 6.9 kB CSS (0) | — | — · — · — |
| Field | 42.0 kB (+28 B) · 6.9 kB CSS (0) | — | — · — · — |
| Overlay | 21.1 kB (+28 B) · 4.0 kB CSS (0) | — | — · — · — |
| CheckboxList | 44.6 kB (+27 B) · 7.5 kB CSS (0) | — | — · — · — |
| FieldLabel | 38.0 kB (+25 B) · 5.4 kB CSS (0) | — | — · — · — |
| TextArea | 48.2 kB (+25 B) · 8.8 kB CSS (0) | — | — · — · — |
| BottomSheet | 55.0 kB (+5 B) · 7.5 kB CSS (0) | — | — · — · — |
| BottomSheetSwitcher | 17.1 kB (+3 B) · 3.4 kB CSS (0) | — | — · — · — |
| List | 5.4 kB (0) · 435 B CSS (0) | — | ✓ · ✓ · — |
| Timestamp | 21.3 kB (0) · 8.9 kB CSS (0) | — | — · — · — |
| Dialog | 19.1 kB (−1 B) · 6.7 kB CSS (0) | — | — · — · — |
| Drawer | 38.2 kB (−1 B) · 8.2 kB CSS (0) | — | — · — · — |
Package size: @astryxdesign/core 6.40 MB packed (+2.6 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.
Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.
CI impact: +8.7 job-min per update · pool +9.4% · standard runners · 1 CI action or script file changed (not measured)
| Before | After | Change | |
|---|---|---|---|
| Job-minutes per PR update | 92.7 | 101.4 | +8.7 |
| Runner pool, runner-minutes a day | 32,717 | 35,778 | +3,061 (+9.4%) |
| Average concurrent jobs | 22.7 | 24.8 | +2.1 |
| Time to green (median → this run) | — | 18.2 min | — |
| Runs a day | 353 | 353 | 0 |
Changed jobs: pr-interaction-webkit changed: standard
Not measured (the jobs that use these keep their recent minutes above): .github/scripts/ci-interaction-webkit.test.mjs.
Assumptions: before is each job's average over the last 20 pull-request runs; after keeps that for unchanged jobs and uses this run's minutes for added or changed ones, weighted by how often each changed job ran in those runs; runs a day averages the seven whole days before today; time to green compares this run with the median of those runs that ran the same jobs.
Generated by PR Enrichment workflow | View full report
Supersedes #8117 by @vjeux, rebased onto
mainafter #9758 and #9762 (which supersede #8890 and #8077) merged. The change is vjeux's: his commit authorship is kept, and the changeset credits him.User impact
This affects people who tap a control on a phone: a button, card, link, list row, or any other pressable outside a scrolling list.
:active.Rebase onto main (card 28 pass carry-over)
Cindy passed card 28 at 14f7ca4. This branch is now one commit on
main. The range-diff of this pull request's own change, before (on #9762's branch) and after (onmain), is three lines and no product code:ButtonPress.interaction.browser.spec.tsimports from@astryxdesign/a11y-spec/playwright, asmainnow requires for browser specs..github/workflows/ci.yml:scrollViewjoins thepr-interaction-webkitscope'sutils/(…)alternation, so the WebKit touch proofs run when the shared scroll-view test changes, as they do for the press controller that reads it. CI & Release reviewed this line..github/scripts/ci-interaction-webkit.test.mjslistspackages/core/src/utils/scrollView.tsamong the paths that run the WebKit proofs.Every product file (
pressFeedback.ts,pressGesture.ts,scrollView.ts,nativeScroll.ts,usePressFeedback, the stories and the tests) is byte-identical to the passed head's change.Expected behavior and authority
spec:AST-094FR11 (current): "A control (UIControl) highlights on touch-down outside scroll views".mainwaits 150 ms everywhere, so this restores the current record.design:user-statesDR4.Problem and solution fit
UIKit delays a touch only inside a scroll view (
delaysContentTouches). Atpointerdownthe controller walks up the flat tree from the touched surface for a box that can scroll on an axistouch-actionleaves to the browser, or an overflowing page. Aposition: fixedancestor ends the walk, because a fixed bar does not move with the page. The result setsdown'sdelayed, and an undelayed touch goes straight topressed. After that the press machine is unchanged.The walk is one function,
isInsideScrollViewin a newutils/scrollView.ts. The press controller and the gesture core's native-scroll probe (gestures/nativeScroll.ts, whoseisInsideScrollerPressTracker reads for a grouped action) both use it, so a Button and a grouped action share one definition of "inside a scroll view". It sits inutils/because Core's main entry must stay free of the gesture core.parseTouchActionand the root-overflow test moved there with it.Changes since #8117
utils/scrollView.ts(see above).mainchanged under #8117 while it waited:mainshortened thepressFeedback.tsandpressGesture.tsheaders. This keepsmain's headers and adds the scroller rule in short sentences, with no record citations.mainthe controller wrote the press attribute on every step, even when the paint stayed the same. feat(core): under a finger a pressable highlights at touch-down, and waits only inside a scroller #8117's base wrote only on a change, and its new button test checks for exactly one change per paint. The controller now skips a write that keeps the paint. Nothing on screen changes.Verification
pressFeedback.test.tsandpressGesture.test.tsfail on fix(Item): a list row's touch press release runs on the compositor #9762's controller and pass here:usePressFeedback, Button, Item, List, TreeList and Card pass (1,299 tests), as do strict lint on the changed files and the core type check.PressedState,PressModality,CardPressandMenuPresspass 28/30.PressModality's "a finger's press on a control highlights as the finger lands" fails on fix(Item): a list row's touch press release runs on the compositor #9762's head and passes here.MenuPress's "a finger that lands on Edit and lifts on Delete" fails in my local rig onmain+ fix(core): a touch press's release lasts until its fade has played #9758 too, so it isn't this change. CI runs it.PressModality's menu-drag case failed once under parallel load and passed 4/4 when rerun.Scope
usePressFeedbackkeeps its signature.