Repository navigation
fix(plugin-grid): on a phone, each list card offers its row's actions through one 44 px menu - #29301
Merged
Merged
Conversation
…e 44 px menu Each card in ObjectGrid's phone card face ends with the row's own RowActionMenu (inline budget 0) when the row offers an action, so the desktop row's actions are reachable from the list on a phone and a tap on the card still opens the record. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jVMaEeoiKQgHPaTy3Z
Contributor
Author
|
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu 席位核对 · ACCEPT · 2026-11-02T11:37ZHead-sha:
|
This was referenced Nov 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Steedos · project thread
Fixes #29150
Clause-②: no
Metadata-protocol: none
维护者速读
list_item)根本够不到。ObjectGrid.tsx卡片渲染里一处:复用桌面行的RowActionMenu和rowActionMenuProps(row)(同一套权限、谓词、处理函数和确认框),内联预算设为 0,所以所有操作都在一个菜单里。按钮外层用-my-2,实测卡片高度不变(62 px)。不加键、不加 prop、不加导出、不加文案。回滚即回退本 PR。ui/packages/plugin-grid/src/ObjectGrid.tsx的buildMobileCardRenderer末尾grid-card-actions那一段(只在rowOffersAction(row)时绘制);新测试ui/packages/plugin-grid/src/__tests__/phoneCardRowActions-29150.test.tsx。pnpm --dir ui exec vitest run packages/plugin-grid/src/__tests__/phoneCardRowActions-29150.test.tsx,预期 4 个用例全部通过;在main上同一文件 3 个失败。Claim: issuecomment-6574754357.
What changes
Below the 768 px card breakpoint,
ObjectGriddraws each row as a card (the #28484 layout: title, one subtitle line, one status chip). A card had no action control, so a phone reader had to open each record to edit, delete or run a declared row action, and an action offered only on the list (list_item) could not be reached at all.ObjectGrid(plugin-grid),buildMobileCardRenderer: each card whose row offers an action ends with the row's ownRowActionMenu, rendered fromrowActionMenuProps(row), the props the desktop row's "⋮" cell and its context menu already read. So it applies the same capability gate, per-record predicates, record-level verdicts, handlers and confirm steps.0(maxInlineActions={0}), the value the desktop row's context menu passes: every action sits in the one menu, in the plan's order (Edit, Delete, primary actions, other actions, legacy actions). On desktop the same set shows in the same order, except that up to one primary action is drawn as a button left of the "⋮".RowActionMenu's existing one, 44×44 belowsm. Its wrapper stops the click, so a tap on the control does not open the record, and a tap anywhere else on the card still does. The card's wrapper box takes-my-2, so the 44 px target does not make the card taller.rowOffersAction(row)false) draws no control.The desktop table, the row context menu and the metadata are unchanged. No key, prop, export or locale string is added; the trigger's screen-reader label is the existing
grid.openMenu.Tests
phoneCardRowActions-29150.test.tsx(new), on the realObjectGridwith Edit, Delete and threelist_itemactions (one primary, one gated byvisible):onEditwith that row and does not callonRowClick. A tap on another card's title callsonRowClickwith that row.main(0c0d3b6): the first three cases fail ("Unable to find an element by: [data-testid="row-action-trigger"]"), the control passes.maxInlineActions={0}changed tomaxInlineActions={1}throughscripts/ablation-replace.mjsreds the order case (the primary moves onto the card as an inline button). The restore leftgit diff HEADempty. A first attempt replaced the anchor with a string that already occurred 41 times; the tool refused it as a no-op, so it did not run.phoneCardRow-28484.test.tsxandrowContextMenu-28434.test.tsxpass unchanged (29/29 with the new file).Acceptance notes
Live measurement, Console production build of this branch (
pnpm console:buildat 49c4abf), served at/_consolebypnpm dev:crm -- --seed-admin --fresh. Chromium withisMobileandhasTouch, DPR 2, at 390×844 and 375×812; desktop reference at 1280×900. Script and readings:/mnt/project-files/issue-29150/measure.cjs,after/measure.json(crm_lead) andafter/measure-account.json(crm_account).crm_lead, which declares thelist_itemaction Convert Lead)crm_account(Edit and Delete only) reads the same: 44×44 control, card 62 px either way, menu equal to the desktop menu, the card tap opens the record. Before this change (maina4015ab, #29074's run record, check L06) a card held no control and a long press opened the record.Out of scope, reported to the seat: the menu's items are 32 px tall at phone width. That is the shared dropdown item, the same in every phone menu, not this card's control.
Verification
All local readings are on head 49c4abf.
Touched package and neighbours
pnpm --dir ui exec vitest run packages/plugin-grid/src/__tests__/phoneCardRowActions-29150.test.tsx packages/plugin-grid/src/__tests__/phoneCardRow-28484.test.tsx packages/plugin-grid/src/__tests__/rowContextMenu-28434.test.tsx: 3 files, 29 tests passed.ObjectGrid(git grepset, 163 files) at--maxWorkers=2in four batches: 41 + 41 + 41 + 40 files passed, 269 + 372 + 286 + 360 = 1287 tests passed. CI's Test UI runs the rest of the package.pnpm exec turbo run type-check --filter=@object-ui/plugin-grid: exit 0 (tsc --noEmit && tsc -p tsconfig.test.json;--listFilesOnlyon the test project lists the new file).eslinton the two changed ui files: 0 errors (warnings only, the file's existingany).pnpm --dir ui run check:new-line-citations: 0 new citations.Derived gates
node scripts/pm/dispatch-gates.mjs --commandsderived 35 families for this diff; each ran locally on 49c4abf and exited 0.dispatch-gates --ranreconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN.vitest run scripts/read 169 files passed, 2 skipped (4900 tests passed). The type-check lanes and the wide-population families are CI's.Human Minimum
packages/specholds no runtime logic. (packages/specnot touched.)main, one pull request.packages/specnot touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code