Repository navigation
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.
This can't be approved yet. The selection lock rests only on spec:AST-094, a draft that main does not have, and none of its requirements (FR19 included) says that a held finger or pen turns off text selection and the callout on press-tracked elements or on recognizers with preventsTextSelection. An engineering owner needs to approve that requirement, for example by adding it to AST-094, and records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. Whatever that decision, these changes are needed:
- Land the stacked predecessors first and rebase, so this pull request carries the 296-line lock commit instead of 28,738 lines across 167 files.
- The new
platformadaptation condition (themeAdaptations.ts:82) conflicts with the theme authoring contract's fixed condition vocabulary, and the new adaptive query (utils/touchPresentation.ts:78-79) conflicts with Selector DEC-1's width-and-pointer query. - Draft FR4 says touch motion is not themable, while the branch ships
defineThememotion roles that retune it; one of the two has to change. lockSelection(GestureHost.ts:614-621) also locks for a disabled or pointer-excluded recognizer; skip those, as a declined press already is.
[Automated review]
| for (const recognizer of recognizers) { | ||
| if ( | ||
| recognizer.preventsTextSelection && | ||
| recognizer.view instanceof Element | ||
| ) { | ||
| elements.add(recognizer.view); | ||
| } | ||
| } |
There was a problem hiding this comment.
This adds every recognizer on the path that has preventsTextSelection, including one whose isEnabled is false or whose allowedPointerTypes excludes this contact. Both make acceptsTouch decline the touch (GestureRecognizer.ts:428-437), so a disabled slider would still turn selection off under a finger, unlike a declined press, which you deliberately leave unlocked. Consider skipping recognizers that would decline this contact, and adding a unit case for a disabled recognizer.
| * is everything else. Pair `ios` with `pointer: 'coarse'` for a touch | ||
| * profile, such as touch motion tuned per platform. | ||
| */ | ||
| platform?: 'ios' | 'other'; |
There was a problem hiding this comment.
platform adds an axis to the adaptation condition vocabulary. The theme authoring contract on main says "An adaptation change preserves the fixed condition vocabulary" (docs/architecture/theme-authoring-contract.md, line 241). This needs an owner amendment of that contract (and of AST-012's closed conditions) before it ships, or it should come out of the stack.
| export const COMPACT_TOUCH_QUERY = | ||
| '(width < 744px) and (pointer: coarse), (height < 500px) and (pointer: coarse)'; |
There was a problem hiding this comment.
This query feeds COMPACT_TOUCH_PRESENTATION_QUERY, so Selector's default presentation and four other components change surface: coarse-pointer viewports 744-768px wide (and at least 500px tall) move from the sheet to the popover, and landscape phones wider than 768px move to the sheet. Selector DEC-1 on main says "adaptive keeps its width-and-pointer query", and the height branch is outside that text.
With the press tracker in place no recognizer claimed the touch, and iOS Safari's long-press text selection started on the held segment's title (the per-path simulator recording showed the selection handles and the loupe). The horizontal pan now sets preventsTextSelection, so the gesture host turns text selection and the touch callout off on the track while a finger is down (meta#8270; the press tracker's element gets the same lock) and gives them back at the lift. At rest, and under a mouse, titles stay selectable. The tap slide's test now holds the lens's animations at their birth, so a slow engine cannot reach the hold after the lift's own curves have ended.
PR Analysis Report
Component Size
Sizes are gzip. Import counts the JavaScript the import loads eagerly; CSS counts the package stylesheet rules referenced by the modules it can load from its own package, lazily loaded ones included. Bundle Size SummaryGzip figures measure each package's entry file, not the code an import pulls in.
Accessibility AuditStatus: No accessibility violations detected. Visual Regression55 of 502 shot(s) changed. A change here is a question, not a failure: check whether the after is the
and 35 more. Generated by PR Enrichment workflow | View full report |
With the press tracker in place no recognizer claimed the touch, and iOS Safari's long-press text selection started on the held segment's title (the per-path simulator recording showed the selection handles and the loupe). The horizontal pan now sets preventsTextSelection, so the gesture host turns text selection and the touch callout off on the track while a finger is down (meta#8270; the press tracker's element gets the same lock) and gives them back at the lift. At rest, and under a mouse, titles stay selectable. The tap slide's test now holds the lens's animations at their birth, so a slow engine cannot reach the hold after the lift's own curves have ended.
With the press tracker in place no recognizer claimed the touch, and iOS Safari's long-press text selection started on the held segment's title (the per-path simulator recording showed the selection handles and the loupe). The horizontal pan now sets preventsTextSelection, so the gesture host turns text selection and the touch callout off on the track while a finger is down (meta#8270; the press tracker's element gets the same lock) and gives them back at the lift. At rest, and under a mouse, titles stay selectable. The tap slide's test now holds the lens's animations at their birth, so a slow engine cannot reach the hold after the lift's own curves have ended.
3e9cf5f to
009f2c8
Compare
There was a problem hiding this comment.
This can't be approved yet: the selection lock, including the new extension to checkboxes, radios and switch inputs, rests only on spec:AST-094, a draft that main does not have, and none of its requirements (FR19 included) says that a held finger or pen turns off text selection and the callout. An engineering owner needs to approve that requirement, for example by adding it to AST-094, and records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner. Whatever that decision, these changes are needed:
- Land the stacked predecessors first and rebase, so this pull request carries the 401-line lock commit instead of 28,843 lines across 167 files.
- The compact-touch query hard-codes 744px (
utils/touchPresentation.ts:75-79), whilespec:AST-012FR9 and the public component API record (INV17) onmaindefine compact as width below the theme'smdpoint (768 by default) or height below 500 with no numbers of its own, and the presentation Changeset should namepresentationas the way to keep a surface. - The new
platformadaptation condition (themeAdaptations.ts:82) is outside the closed condition vocabulary of AST-012 FR2. - The
defineThememotion roles are documented as retuning touch motion that no component plays yet, and their validation runs only when the experimental motion tables happen to be loaded, so a misspelled role id passes silently. lockSelection(GestureHost.ts:617-624) still locks for a disabled or pointer-excluded recognizer, and theuseGestureRecognizerenable effect callsonGesturefrom inside the effect.- Draft FR4 says touch motion is not themable while the branch ships themable motion roles, so one of the two has to change.
[Automated review]
| export const COMPACT_QUERY = '(width < 744px), (height < 500px)'; | ||
|
|
||
| /** Both: presentations such as a sheet in place of a popover. */ | ||
| export const COMPACT_TOUCH_QUERY = | ||
| '(width < 744px) and (pointer: coarse), (height < 500px) and (pointer: coarse)'; |
There was a problem hiding this comment.
This width is the resolver's own number. spec:AST-012 FR9 on main makes a screen compact while its width is below the theme's effective md point (768 by default) or its height is below 500, and says the web touch presentation resolver keeps no size numbers of its own; architecture:public-component-api INV17 says the same. At 744-767 px wide with a coarse pointer, adaptive Selector, MultiSelector, DropdownMenu, ContextMenu and MoreMenu now open the popover where FR9 asks for the sheet. The height edge matches FR9; the width edge should come from the theme's md point.
| useIsomorphicLayoutEffect(() => { | ||
| recognizer.setEnabled(isEnabled); | ||
| }, [recognizer, isEnabled]); |
There was a problem hiding this comment.
Turning isEnabled off mid-gesture cancels the recognizer here, and its listeners run synchronously (GestureRecognizer.ts:569-574, :603-606), so the consumer's onGesture fires from inside this layout effect. architecture:react-component-runtime INV2 keeps consumer callbacks out of effects, and INV3 asks each effect to name the external system it synchronizes; a comment naming the recognizer and justifying the cancellation callback, or delivering it outside the effect, would settle it.
| const registered = motionRole(id); | ||
| if (registered !== undefined && registered.kind !== kind) { | ||
| throw new Error( | ||
| `${location}: "${id}" is a ${registered.kind}; set it under the matching group.`, | ||
| ); | ||
| } |
There was a problem hiding this comment.
This check only runs when the motion tables are registered, and they register themselves from motion/uikit/*.ts on import, which the defineTheme path never does. Through defineTheme alone, a spring role under durations passes and a misspelled id such as springs.sheetPresnt becomes --motion-springs-sheet-presnt with no error, while an app where the tables happen to be loaded (for example through the uikit namespace of @astryxdesign/core/motion/experimental) gets the error. Validating against the registered roles in this path, and rejecting ids no table registers, would make the same theme behave the same everywhere.
With the press tracker in place no recognizer claimed the touch, and iOS Safari's long-press text selection started on the held segment's title (the per-path simulator recording showed the selection handles and the loupe). The horizontal pan now sets preventsTextSelection, so the gesture host turns text selection and the touch callout off on the track while a finger is down (meta#8270; the press tracker's element gets the same lock) and gives them back at the lift. At rest, and under a mouse, titles stay selectable. The tap slide's test now holds the lens's animations at their birth, so a slow engine cannot reach the hold after the lift's own curves have ended.
…ond route around ./internal/* Lab's per-module tsconfig paths (core's motion, gestures and touchPresentation) and the Sandbox/docsite resolver that served them opened a route around architecture:react-component-runtime INV13's ./internal/* subpath exports. Nothing in Lab imports those paths here; they're dropped, and the import guard now fails on any Lab import core doesn't export and on any Lab tsconfig alias for core. Co-authored-by: Christopher Chedeau <vjeux@users.noreply.github.com>
… detaches The deferred unmount demotes the detached node, and demote asks for a fresh will-change read; the detached node now gets none, so no timer outlives the element (architecture:react-component-runtime INV5). Co-authored-by: Christopher Chedeau <vjeux@users.noreply.github.com>
…core's exports) into meta#8270
… that finger until it lifts (spec:AST-094 FR14) A recognition that claimed its touches and was then cancelled gave them back to the browser unless another recognition owned them, so a finger resting there could pinch-zoom the page. A gesture that cancels itself on a finger's move, a long press dragged past its tolerance after it began, gave back a finger that was dragging: the host stopped cancelling its moves and the page scrolled the rest of the drag, a hand change FR14 forbids and UIKit never makes (its scroll view never takes a touch another recognizer had). A cancel during a finger's move now keeps that finger claimed until it lifts; a resting finger is given back as before, and a waiting recognition that fails still gives its claim back. The new arena case fails on the previous code: the dragging finger reads unclaimed right after the cancel.
…edge-zone strip decides at UIKit's 15 px The host's arena environment had no viewSize, so under the real host a screen-edge pan never saw its edge zone while a touch was down and decided at 10 px, while its attach-time touch-action (read through the default environment) had already claimed the axis (spec:AST-094 FR18). Co-authored-by: Christopher Chedeau <vjeux@users.noreply.github.com>
…fter layout rounding Lane 0's real-host browser spec found a strip authored at the 40.2 px edge region lays out at 40.203 px (layout snaps to 1/64 px), so the strict comparison read it as off the zone and the pan decided at 10 px instead of UIKit's 15 (spec:AST-094 FR18). The zone takes half a pixel of tolerance: the rounded strip is the zone, a view a pixel wider still is not. Failing-first test at 40.203 px: it claims pan-x and decides at 15. Co-authored-by: Christopher Chedeau <vjeuxx@gmail.com>
There was a problem hiding this comment.
Changes requested: the selection lock itself follows spec:AST-094 FR41 and DEC-9, but the comparison with main still carries the content of 13 open predecessor pull requests, so please land that stack first or rebuild this branch on it, leaving only the lock’s 21 files. The stacked gesture host also contradicts two current claims, which should be fixed before anything attaches it:
GestureHost.ts:477-508writes the derivedtouch-actionover the element’s own value instead of intersecting with it (FR18).GestureHost.ts:1584-1618lets any scroll event take a still finger’s touch without the 10 px of travel FR20 requires.
[Automated review]
| const style: GestureHostStyle = this.isPrimaryPointerCoarse() | ||
| ? gestureHostStyle(registration.recognizers.filter(r => r.isEnabled)) | ||
| : {}; | ||
| for (const key of Object.keys( | ||
| STYLE_PROPERTIES, | ||
| ) as (keyof GestureHostStyle)[]) { | ||
| const property = STYLE_PROPERTIES[key]; | ||
| const value = style[key]; | ||
| if (value != null) { | ||
| if (!registration.savedStyle.has(property)) { | ||
| registration.savedStyle.set( | ||
| property, | ||
| element.style.getPropertyValue(property), | ||
| ); | ||
| } | ||
| element.style.setProperty(property, value); |
There was a problem hiding this comment.
This writes the derived touch-action over the element’s own value: the saved inline value only comes back at detach, and gestureHostStyle derives from the recognizers alone. An element whose author narrowed touch-action (none on a drawing surface, pan-x on a carousel) is widened once a recognizer attaches. spec:AST-094 FR18: “The derived value is intersected with the element’s own author touch-action and is never wider than it (DEC-8)”. Please intersect with the author’s value before writing, with the verification row’s narrower-author case.
| const taken: number[] = []; | ||
| for (const touch of this.arena.touches) { | ||
| if ( | ||
| touch.takenByBrowser || | ||
| touch.phase === 'ended' || | ||
| touch.phase === 'cancelled' || | ||
| touch.pointerType !== 'touch' || | ||
| this.arena.isClaimed(touch.id) | ||
| ) { | ||
| continue; | ||
| } | ||
| if (touch.target instanceof Node && scroller.contains(touch.target)) { | ||
| taken.push(touch.id); | ||
| } | ||
| } | ||
| if (taken.length > 0) { | ||
| this.arena.browserTookOver(taken, time); | ||
| } |
There was a problem hiding this comment.
Every live, unclaimed finger whose target is inside the scrolling node is handed to browserTookOver here, whatever distance it has moved, so a still finger on a tappable row loses its tap to sub-pixel or programmatic scrolling; the case at __tests__/GestureHost.test.ts:817-826 asserts exactly that. spec:AST-094 FR20: “a native scroll only once that finger has moved the scroll take distance (FR2)”, and DEC-8 rejects “cancelling at the first scroll event”. Please count a scroll only once the finger’s own travel reaches 10 px.
Main's meta#8521 is its head 25b468c squashed, which this pull request already carries: every file it touches is byte-identical to 25b468c. In the two files that conflicted (the motion README and animator.ts), the resolution is this side's version, main's merged meta#8521 with this pull request's later work on top. Nothing of main is dropped.
An attach reads the element's own will-change in a task of its own. A shared animator (animatorFor) is never detached, so its node can leave the document with that read still waiting, and the read then forces a style pass on a node with no style: a test run that mounts and unmounts many pagers piled up such reads until a later wait timed out. The read now skips a node out of the document; a promotion that needs it reads it then, as one on a node attached in the same task does. A detach and dispose already cancel it. The new test fails on the previous code (one read of a removed node); the in-task read test now puts its element in the document, where the read happens.
There was a problem hiding this comment.
Changes requested: the touch selection lock itself matches AST-094 FR41 and DEC-9, but this pull request still carries the content of 12 open predecessor pull requests, 16,991 changed lines of which 1,735 are the lock’s. Please land the predecessors first, or rebuild this branch on them, so it carries only the lock’s 21 files.
- The stacked gesture host writes its derived
touch-actionover the element’s own value (packages/core/src/gestures/GestureHost.ts:486-517), where FR18 requires intersecting it with the author’s value. - Its scroll handler hands every unclaimed finger inside a scroller to the browser with no travel check (
GestureHost.ts:1593-1627), where FR20 allows that only after 10 px of movement, so the fixes reported in #8309 need to land before anything attaches the host.
[Automated review]
| element.style.getPropertyValue(property), | ||
| ); | ||
| } | ||
| element.style.setProperty(property, value); |
There was a problem hiding this comment.
This writes the derived touch-action over the element’s own value and keeps that value only to restore it at detach, so an author’s narrower touch-action (none, pan-x) is widened. Current spec:AST-094 FR18: “The derived value is intersected with the element’s own author touch-action and is never wider than it (DEC-8)”.
| } | ||
| } | ||
| if (taken.length > 0) { | ||
| this.arena.browserTookOver(taken, time); |
There was a problem hiding this comment.
Every live, unclaimed finger inside the scrolling node is handed to the browser here whatever distance it has moved, so a still finger loses its tap to sub-pixel or programmatic scrolling (the case at __tests__/GestureHost.test.ts:838-847 asserts it). Current spec:AST-094 FR20 counts a native scroll only “once that finger has moved the scroll take distance (FR2)”, 10 px.
…of the document) into meta#8270
…sture system (spec:AST-094 FR24, FR43) utils/pressFeedback.ts reaches gestures/coarsePointer.ts, so a page whose only touch work is press feedback carries a gesture module, and a bundle check that counts gestures/ code finds it in the root and hooks entries. The coarse-pointer query belongs with the environment queries. This test walks the controller's import graph and fails until it reaches no module under gestures/.
…ries in utils/ (spec:AST-094 FR43) gestures/coarsePointer.ts becomes utils/coarsePointer.ts, beside utils/touchQueries.ts, with its test; the gesture host's selection lock, the press controller and the pointer test helper import it from there. The press controller's import graph now reaches no module under gestures/, so a page whose only touch work is press feedback carries none of the gesture system. No behavior changes.
There was a problem hiding this comment.
Changes requested: the touch selection lock itself matches AST-094 FR41 and DEC-9, but this pull request still carries the content of 12 open predecessor pull requests, 17,093 changed lines of which 1,790 are the lock's. Please land the predecessors first, or rebuild this branch on them, so it carries only the lock's 22 files.
- The stacked gesture host writes its derived
touch-actionover the element's own value (packages/core/src/gestures/GestureHost.ts:486-517), where FR18 requires intersecting it with the author's value. - Its scroll handler hands every unclaimed finger inside a scroller to the browser with no travel check (
GestureHost.ts:1593-1627), where FR20 allows that only after 10 px of movement, so the fixes reported in #8309 need to land before anything attaches the host. packages/core/src/utils/pressFeedbackImports.test.ts:8cites AST-094 FR43, which the current record does not have; cite FR24 alone until it does.
[Automated review]
| * @input The source of utils/pressFeedback.ts and every module it imports | ||
| * @output The press feedback controller's import graph reaches no module | ||
| * under gestures/: a page whose only touch work is press feedback carries | ||
| * none of the gesture system (`spec:AST-094` FR24, FR43: pointer queries |
There was a problem hiding this comment.
spec:AST-094 on main has no FR43; an FR43 is only proposed in the open spec pull request #8646. Citing it here presents a draft as the requirement behind this import boundary. FR24 ("no touch-only listener, observer or timer is active" where the primary pointer is fine) is the current claim; please cite it alone, or drop the FR43 reference until a current record states it.
…(spec:AST-094 FR18, DEC-13) A screen-edge pan attached to a stack container, as wide as the screen, with a touch 4 px from its edge: inside the 40.2 px band the pan decides at UIKit's 15 px whatever the element's width, and then tracks the travel past it. From several edges too. Both fail while a wider element decides at FR19's 10 px.
…'s width (spec:AST-094 FR18, DEC-13) FR18: inside the 40.2 px band a screen-edge pan decides at UIKit's 15 px screen-edge hysteresis; outside it the author's scrolling is untouched and FR19's 10 px governs every other claim. The pan decided at 10 px on any element wider than the band, so NavigationStack's edge pan, attached to the stack container, began 5 px early. The edge zone still decides only the touch-action; a touch outside every band still fails at once. The two cases that pinned the 10 px decision go.
…than the band (spec:AST-094 FR18, DEC-22) FR18 as amended in meta#8631 (DEC-22): the band's pan-x claim and 15 px start hold only where the screen-edge pan is attached to an element within the band; on an element that reaches beyond it, whose touch-action cannot claim per touch, a touch in the band decides at FR19's 10 px like every other claim. This restores the 10 px decision 3d85c30 removed and keeps 15 px on an element within the band. The cases pin DEC-22 both ways (a wide element with a touch at x=4 begins at 10, an in-band strip at 15, and from several edges at 10 on a wide element); the 10 px cases fail on 3d85c30.
There was a problem hiding this comment.
Changes requested: the touch selection lock itself matches AST-094 FR41 and DEC-9, but this pull request still carries the content of 13 open predecessor pull requests, 17,214 authored changed lines of which 1,790 are the lock's, so please land the predecessors first, or rebuild this branch on them, so it carries only the lock's 22 files.
- The stacked gesture host writes its derived
touch-actionover the element's own value (packages/core/src/gestures/GestureHost.ts:486-517, against FR18) and hands every unclaimed finger inside a scroller to the browser with no travel check (GestureHost.ts:1593-1627, against FR20), so the fixes reported in #8309 need to land before anything attaches the host. - New at this head, the arena keeps a finger claimed after its gesture cancels on a move (
packages/core/src/gestures/GestureArena.ts:643), so the host keeps cancelling that finger'stouchmove, which FR19 forbids for a touch no recognizer owns; please settle that in #8641. packages/core/src/utils/pressFeedbackImports.test.ts:8cites AST-094 FR43, which the current record does not have; cite FR24 alone until it does.
[Automated review]
| } | ||
| if (next === 'cancelled' || next === 'failed') { | ||
| if (next === 'cancelled') { | ||
| this.releaseClaim(recognizer, this.movingIds); |
There was a problem hiding this comment.
When a claiming recognizer cancels itself during a move, this keeps the moving finger claimed, and the host's blocking listener keeps calling preventDefault() on that finger's touchmove until the lift (GestureHost.ts:898-903), though no recognizer owns it any more; arena.test.ts:526 asserts it. Current spec:AST-094 FR19: "A touchmove of a touch no recognizer owns MUST NOT be cancelled, with three exceptions", and none of them is a cancelled gesture (FR14 governs a drag that starts inside a scroll area). Give the finger back on cancel, as before, or have an engineering owner amend FR19 first.
…xperimental touch exports The motion README's Files table is the union: main's rows, with meta#8663's resolveSnapPoint.ts and selectPage.ts, plus this branch's, in main's order. # Conflicts: # packages/core/src/motion/README.md
There was a problem hiding this comment.
Changes requested: the touch selection lock itself matches AST-094 FR41 and DEC-9, but this pull request still carries the content of 13 open predecessor pull requests (17,218 authored changed lines, of which 1,790 are the lock's), so please land the predecessors first, or rebuild this branch on them, so it carries only the lock's 22 files.
- The stacked gesture host writes its derived
touch-actionover the element's own value (packages/core/src/gestures/GestureHost.ts:486-517, against FR18) and hands every unclaimed finger inside a scroller to the browser with no travel check (GestureHost.ts:1593-1627, against FR20), so the fixes reported in #8309 need to land before anything attaches the host. - The stacked arena keeps a finger claimed after its gesture cancels on a move (
packages/core/src/gestures/GestureArena.ts:643), so the host keeps cancelling that finger'stouchmove, which FR19 forbids for a touch no recognizer owns; please settle that in #8641. packages/core/src/utils/pressFeedbackImports.test.ts:8cites AST-094 FR43, which the current record does not have; cite FR24 alone until it does.
[Automated review]
| element.style.getPropertyValue(property), | ||
| ); | ||
| } | ||
| element.style.setProperty(property, value); |
There was a problem hiding this comment.
This writes the derived touch-action over the element's own value, so an author who narrowed it (none on a drawing surface, pan-x on a carousel) gets a wider value once a recognizer attaches. AST-094 FR18 requires the derived value to be intersected with the author's touch-action and never wider than it (DEC-8); the fix reported in #8309 needs to land before anything attaches the host.
| if (touch.target instanceof Node && scroller.contains(touch.target)) { | ||
| taken.push(touch.id); | ||
| } |
There was a problem hiding this comment.
Any scroll above an unclaimed finger counts as the browser taking it, whatever that finger's travel, so a still finger loses its tap to sub-pixel or programmatic scrolling (the case 'reads a scroll above an unclaimed touch as the browser taking it' asserts this). AST-094 FR20 counts a native scroll only once the finger has moved the 10 px scroll take distance, and DEC-8 rejects cancelling at the first scroll event.
| } | ||
| if (next === 'cancelled' || next === 'failed') { | ||
| if (next === 'cancelled') { | ||
| this.releaseClaim(recognizer, this.movingIds); |
There was a problem hiding this comment.
Keeping the claim on the touches that moved when this recognizer cancelled leaves that finger claimed with no active recognizer owning it, so the host keeps cancelling its touchmove until the lift. AST-094 FR19 forbids cancelling the moves of a touch no recognizer owns outside its three exceptions, and FR14 decides who takes a drag that starts inside a scroll area rather than this case; please settle it in #8641.
| * @input The source of utils/pressFeedback.ts and every module it imports | ||
| * @output The press feedback controller's import graph reaches no module | ||
| * under gestures/: a page whose only touch work is press feedback carries | ||
| * none of the gesture system (`spec:AST-094` FR24, FR43: pointer queries |
There was a problem hiding this comment.
Current AST-094 ends at FR42 and has no FR43, so this citation points at nothing; cite FR24 alone until a current claim states the rule.
|
Closing: carried by #8360 (this head, 170162d, is in it by hash). The review items:
|
Depends on #8076. Review only this pull request's change: vjeux/astryx@3fb31dd...170162d
Why
On a phone, a finger resting on a slider's thumb or a switch starts a text selection or the loupe, and a long press on a context-menu trigger can bring up the iOS callout over the menu. UIKit never selects text under a control whose hold does something.
What led to it
This is part of the UIKit-parity work on Astryx's touch components. The approved gesture spec says a held finger does what the hold does, not a selection, and that anything whose hold does nothing keeps the browser's long-press selection (
spec:AST-094FR41).Options and tradeoffs
selectionLockoption on the recognizers whose drag acts (a slider's thumb, a switch's drag), and the long press bringing its own.Why this choice
Only elements whose hold does something lose selection, and only for that press, lifted at the lift or a cancel. A plain control, a row or a label keeps native selection. Where iOS WebKit runs (it sends no
selectstartfor a long press), the lock usesuser-selectand the callout over the held elements; elsewhere it cancelsselectstartand writes no style, so nothing repaints. A non-text input inside a locked element locks too; text fields never do. At this pull request it applies where the primary pointer is coarse; #8665 extends it to every primary pointer, as the merged FR41 now reads, with a mouse always excluded.How to check it
Evidence
test-ui (4/4)fails on the CodeBlockHeaderPlugin race that test(richtext): the code block header tests wait for the copy button's tooltip #8569 fixes; it is unrelated to this change.