Repository navigation
spec(ContextMenu): the context menu's three springs as motion roles, and the lift's four elements - #8830
spec(ContextMenu): the context menu's three springs as motion roles, and the lift's four elements#8830vjeux wants to merge 2020 commits into
Conversation
The morph spring moved into the springs table as the motion role springs.contextMenuMorph: the menu's growth from the finger keeps its start width in the context menu's table and plays on the role.
…t reads its end before the arena's reset) into facebook#8336
The case walked ContextMenu, DropdownMenu, useLongPress and useMenuPress's imports and failed on the UIKit gestures table: it kept that table out of the menus' bundles, the lazy design the no-lazy-load ruling and direct imports retire. The long-press numbers keep one source, still pinned by the table, recognizer and hooks case and by the hooks reaching longPress.ts.
… watcher test's tail fix) into the input hold
…xposes no ontouchstart is taken once Chromium fixes ontouchstart when the page is created, so turning touch emulation on later sends Touch Events without it: the host reads Pointer Events for the finger and must not read its Touch Events too. A one-finger long press fails here, the finger tracked twice.
…from their pointer events install() reads a finger from its pointer events when the window has no ontouchstart, but the four touch handlers still took the Touch Events a browser sends anyway (Chromium after touch emulation turns on), tracking the finger twice, so a one-finger long press never recognized. Each touch handler now returns while usesTouchEvents is false, after noting the fingers down, as install()'s comment promised.
…ter events) into meta#8320
…ter events) into meta#8293
…ter events) into meta#8356
…ter events) into meta#8358
…n before the click guard internal/motion.ts (meta#8562) re-exports UIKIT_CLICK from the barrel, so a tree carrying both fails typecheck and the Storybook build since this pull request dropped it. The barrel keeps it, with the click guard's window, and the table of every gesture group still leaves it out. Fails until the barrel exports it.
…'s window This pull request dropped UIKIT_CLICK when the click guard took the stray-click window over, but importers written before it read the barrel's UIKIT_CLICK (internal/motion.ts in meta#8562 re-exports it), so a tree carrying both failed typecheck and the Storybook build. UIKIT_CLICK stays in the barrel, deprecated, with the guard's 400 ms (CLICK_GUARD_WINDOW_MS), and UIKIT_GESTURES still leaves it out.
…ter events) into meta#8360
…ter events) into the every-pointer host # Conflicts: # packages/core/src/gestures/__tests__/GestureHost.test.ts
Bundled with the size report's esbuild options, none of Core's public entries carries a byte of gestures/ until a component imports it (architecture:react-component-runtime INV13). The click guard in utils/ imports the haptic switch's attribute from gestures/, so the root and hooks entries carry gestures/hapticSwitch.ts: both cases fail until it moves.
…blic entries carry no gesture code The click guard (utils/clickGuard.ts) imported HAPTIC_SWITCH_ATTRIBUTE from gestures/hapticSwitch.ts, which put gesture code in Core's root and hooks entries. The attribute moves to utils/hapticSwitch.ts, as the coarse-pointer query did; the click guard, the gesture host and haptics read it there, and gestures/hapticSwitch.ts re-exports it, deprecated, for importers written before the move. The module-graph case follows the new path.
…peat control owns only its hold - A pen held still requests through the hold, and the browser then fires the pen's own context menu event, during the hold or at its lift: a second request for one gesture. One request only, the hold's. - The engineering owner's ruling on meta#8670: a hold-repeat control inside a row owns only its hold; its right click and Shift+F10 still reach the row's context request. Today both are refused there. Both fail until the context request refuses the pen's echo and leaves a kept press only its hold.
…eat control owns only its hold - The context request refuses a pen's own menu event during its hold and within the menu echo after its lift, as it refuses a held finger's and a key's. (A pen's barrel button already starts no press, from meta#8665.) - A hold-repeat control inside a row keeps only its hold: the row's right click and Shift+F10 reach the request through it, as the engineering owner ruled.
… with no options a record does not need The engineering owner's ruling on meta#8670: cut the two-stage commitMs, requestMs and requestOnLift, and the allowableMovement and isPerAxis tolerance, until a record calls for them. The hold is UIKit's long press, 500 ms and 10 px as a distance, and requests as it begins; onHold reports it committed, then ended or cancelled. LongPressGestureRecognizer loses isPerAxis and geometry its axisTravel, with their tests.
…, with no stages (spec:AST-094 FR43) Red: meta#8670 cuts the context request's two-stage hold (commitMs, requestMs, requestOnLift) and its per-axis allowance, as asked there: the hold is UIKit's long press and requests as it begins. ContextMenu and the factory's menu still open a held finger at 735 ms, open at a lift after 400 ms, and allow 11.5 pt on each axis. They should open at 500 ms under any primary pointer, open nothing for a lift before it, and open nothing for a drift past 10 pt.
…press, with no options) into the headless context menu packages/core/src/utils/pressFeedback.ts and its test: meta#8670's text, with this stack's press-paint subscription (subscribePressPaint, which ContextMenu's press feedback follows) kept beside it. packages/core/src/hooks/useLongPress.ts, its test, its page and useMenuPress.ts: meta#8670's text. This stack's useLongPress `stages` and press start times served ContextMenu's two-stage hold, which no longer exists (the context request opens ContextMenu, and its hold has no stages), so they go, with their changeset and the hooks entry's LongPressStage type.
… with none of the hold options meta#8670 cut (spec:AST-094 FR43) meta#8670 cuts the context request's two-stage hold (commitMs, requestMs, requestOnLift), allowableMovement and isPerAxis, as asked there: the hold is UIKit's long press and requests as it begins. ContextMenu and the factory passed them for UIContextMenuInteraction's 400 ms commit, 735 ms menu, open at a lift and 11.5 pt on each axis. They pass none now: under any primary pointer a held finger gets the menu at 500 ms, a lift before it is a tap, and a drift past 10 pt (a distance) opens nothing. Under the touch model the commit, now the long press, plays the haptic and the press feedback plays UIKit's press curve until the menu shows. The UIKit table's per-axis drift guess has no reader left and goes. The tests, the interaction specs, the docs, the story and the changesets that described the two-stage hold describe the long press; the tests of a lift after the commit and of a drag between the commit and the menu go with that window.
…ow, and Escape returns focus to it from another row's focus (spec:AST-094 FR33, spec:AST-107 FR8) The story's Inbox row, with Drafts focused first: a held finger opens its menu with the lift up beside it, and Escape closes the menu and focuses Inbox, in Chromium and WebKit.
…and the lift's four elements spec:AST-094 FR4: springs.contextMenuLift, springs.contextMenuDismiss and springs.contextMenuMorph, measured on UIContextMenuInteraction, join the motion roles, and the registry registers them (its test reads FR4's rows). component:ContextMenu DEC-2: while a lifted menu is open the page has four more elements, each with one job, and none at rest, with their element counts. The code these records describe is in meta#8693.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Posted by Cindy's agent on her behalf. Thanks for splitting this out. Both changes are decided by current records, so this can be approved with two wording edits:
The layer-runtime INV13 line and the AST-057 reword aren't in this PR. If #8693 still carries them, they need their own spec PR. |
…heir owner, and DEC-2 is a consistency decision As asked on meta#8830: spec:AST-094 FR4 says component:ContextMenu owns the three springs.contextMenu* rows (DEC-5), and ContextMenu's record lists them. DEC-2 records its decider as consistency with current records: spec:AST-017 FR60 and DEC-29, architecture:layer-runtime INV15 and spec:AST-094 FR33.
|
Thanks, both edits are in (vjeux@5bd825809f): FR4 names |
|
/approve-spec 5bd8258 |
|
AI review status for this pull request.
|
There was a problem hiding this comment.
Requesting changes: the two spec claims here (the three springs.contextMenu* rows in spec:AST-094 FR4 and ContextMenu DEC-2) carry an engineering owner's approval for this head, but the branch also carries all of #8693, so the diff is 260 files and about 46,000 changed lines instead of the six files the two spec commits touch. Please land #8693 first and rebase this branch onto main, so this pull request contains only its own change. That rebase also removes the new FR41 sentence on claimed mouse and pen drags, which the description does not list; if it stays, it needs the reason and the fine-pointer before/after evidence spec:AST-017 FR59 asks for.
[Automated review]
| (`spec:AST-017` FR59; DEC-9). A mouse or pen drag that a recognizer claims | ||
| suppresses text selection for that drag only; an unclaimed mouse drag keeps | ||
| today's behavior. |
There was a problem hiding this comment.
This sentence changes what a claimed mouse or pen drag does, but the description's scope lists only FR4's rows and DEC-2. It comes from #8693's branch, so it leaves this pull request once #8693 lands and the branch is rebased; if it stays, spec:AST-017 FR59 asks for the reason and fine-pointer evidence before and after.
|
This PR is stacked on #8693 on purpose: the two records describe code only #8693 has, so it can't sit on |
Stacked on #8693, whose code these records describe; this PR's own change: vjeux/astryx@b9608e9...5bd8258
Exact decision needed
Part of the UIKit-parity program. #8693 lands ContextMenu's touch presentation (the lift, the menu's grow and its shrink back) without record changes, as asked there. Two of those changes are ContextMenu's own and are here, for approval at this exact head: FR4's three springs and DEC-2. The other two stay where they started: the exit copy (
architecture:layer-runtimeINV13) and thespec:AST-057reword are #8186's, and the lift module's line in the layer runtime is #8485's.Existing authority searched
spec:AST-094FR4 and FR33,component:ContextMenuFR10,architecture:layer-runtimeINV7 and INV15, and the open-layer allowance (spec:AST-017FR60, DEC-29). None names the context menu's springs or the lift's elements; the open #8186 and #8485 own the adjacent layer-runtime text.Decision
spec:AST-094FR4:springs.contextMenuLift(damping ratio 0.8, response 0.32 s),springs.contextMenuDismiss(0.85, 0.35 s) andsprings.contextMenuMorph(0.8, 0.3 s), measured on UIContextMenuInteraction in the iOS 26.2 simulator, join the motion roles, owned bycomponent:ContextMenu(DEC-5), whose record lists them. The registry's test compares its roles with FR4's rows, so the three lines that register them, and the two tests that name them, are the only code here.component:ContextMenuDEC-2, a consistency decision fromspec:AST-017FR60 and DEC-29,architecture:layer-runtimeINV15 andspec:AST-094FR33: while a lifted menu is open, the page has four more elements than under a fine pointer (the lift layer, the shadow, the box the menu is placed against, the placeholder), each with one job; none is themeable or mounted at rest, and no content is mounted twice.Rejected alternatives
DEC-2 keeps one line: a copy of the trigger above the tint, which mounts the trigger's content twice.
Claim scope and non-goals
These two claims only; no public API, prop or theme token changes.
Evidence and implementation relationship
The behavior is #8693's: the springs' measurements (iOS 26.2 simulator) for FR4; the element counts in
ContextMenuLift.interaction(Chromium and WebKit) andContextMenu.test.tsx's lift suite for DEC-2.Writing rubric results
Scope
Validation
pnpm check:knowledgepasses; Prettier andgit diff --checkare clean.vitest run packages/core/src/motionandContextMenuLift.test.tsx: 719 pass, including the registry's FR4 check.