Repository navigation
fields(RecordPickerDialog): one picker, one dialog layout — recompose from the design system's primitives (header rhythm, one search border, Checkbox rows, width by columns, one footer bar, confirm disabled at zero, no link cells) #11903
Description
Filing gate: ① a product defect with a named landing spot and a reproduction, filed on the maintainer's word. Filed by the director seat (objectstack seat post objectstack-ai/objectstack#12708, summon #35, session_01VYToj6PQehTEKNrjGM9akg). The maintainer opened a role's Assigned Users section, pressed Assign user, and sent the screenshot with 「我发现了很丑的界面」; after the seat's analysis below the maintainer answered 「同意,立卡」.
Reader: the ui lane dev. Landing spot: packages/fields/src/widgets/RecordPickerDialog.tsx (@object-ui/fields), plus a wrapper under packages/components/src/custom/ if a primitive needs composing (⛔ never packages/components/src/ui/**, the Shadcn no-touch zone, AGENTS.md rule #7).
Reproduction: console → a role → Assigned Users → Assign user (AssignedUsersSection renders RecordPickerDialog with multiple, object sys_user, three columns: name, email, email verified). The same dialog opens from every multi-select lookup field and related list.
Reach: ten call sites import the dialog — LookupField, PeoplePicker, lookupColumnDisplay, the @object-ui/fields index, plugin-list ListView, plugin-detail RelatedList and its index, app-shell AccessExplainPanel and AssignedUsersSection. One fix changes all of them; that is also why the fix is a contract, not a patch.
What the screenshot shows, and the override behind each
| seen | cause in the component |
|---|---|
| the title sits on the search box with no space | the DialogContent wrapper sets gap-0, which removes the spacing the design system gives the header |
| the search box shows a doubled, pill-shaped outline | a hand-rolled bordered wrapper div around an Input whose own border is switched off; two style sets stack |
| the leading column is blank; nothing says the list is multi-select | the header renders an empty w-10 cell and a row shows a Check icon only after it is selected; the Checkbox primitive is imported but not used in rows |
| three columns stretched to about a thousand pixels | the dialog width is fixed at lg:max-w-5xl whatever the column count |
| "3 records" and "0 selected" on two lines, a few pixels out of line with each other | the pagination bar carries its own horizontal padding, the DialogFooter does not; two status texts live in two bars that do not know about each other |
| Confirm enabled with nothing selected | the confirm button has no disabled binding to the pending selection |
| the email column renders as blue links inside a picker | the cell renderer follows the field type; inside a picker a link is a click target competing with row selection |
Each fix in this file's history was correct for its issue (the file pins at least five of them in comments). The whole is wrong because nothing states what the whole must look like. This card states it.
The contract (acceptance; each point is checkable)
- Header rhythm.
DialogContentkeeps the design system's header and footer spacing; nogap-0or equivalent override at the container. The title-to-search distance is whatDialogHeadergives every other dialog. - One search border. The search field is the
Inputprimitive with a leading icon in the design system's own pattern; at rest exactly one border, on focus exactly one ring. No wrapper carrying a second border. - Checkbox rows. In
multiplemode each row's leading cell renders theCheckboxprimitive reflecting the selected state; the header cell renders the design system's table-selection pattern (a select-all for the page, or an accessible empty head — the dev picks what the Table primitive supports and says which). Row click still toggles; keyboard behaviour (arrow keys, Enter) unchanged. - Width by columns. The dialog's max width follows the column count: a three-column picker is not wider than it needs; a ladder of width classes keyed on column count is acceptable, so is a measured width. The
lg:max-w-5xlceiling may remain as the ceiling. - One footer bar. The record count, the page controls and the selected count sit on one bar with one horizontal padding, Cancel and Confirm right-aligned on that same bar in
multiplemode. Single-select mode keeps its one bar without buttons. - Confirm disabled at zero. The confirm control carries
disabledwhile the pending selection is empty. - No link cells. Inside the picker a cell never renders as a navigational link: email, url and lookup values render as text (the row is the only click target). The inline
LookupFielddropdown and the grid slot (renderGrid) keep their own rendering — out of scope here. - Reviewable by eye and by test. The console preview gallery (
apps/console/src/preview-gallery.tsx) shows the dialog inmultiplemode with three columns so a human can look at it; one pin per DOM-checkable point (3, 6, 2's single border, 5's single bar) in the package's test suite; the existing two-surface agreement pin (objectui#5492) and the keyboard pin (objectui#7154) stay green.
⛔ Out of scope
- The inline lookup dropdown, the filter bar and panel, the external grid slot, the
ui/primitives themselves. - Any new primitive or theme token; the fix uses what
@object-ui/componentsalready ships. - Other surfaces with the same class of defect: the coverage-sweep angle filed in objectstack (titled "qa(checklist): the coverage sweep gains an angle — surface kinds vs the one design system") enumerates them; each gets its own card.
Priority: p2 — the picker is on the North Star path (records · lookup-picker-create-new; identity · admin-lifecycle-operations) and it runs but renders wrong (priority rule 2, 「能跑但出错 ⇒ P2」). The North Star sentence this card is the first application of is the companion objectstack card "docs(north-star): priority rule 4 gains the human-facing standard".
Dedupe: the 59 open objectui issues were listed through the repository endpoint and scanned (title and body) for RecordPickerDialog / record picker / lookup picker / dialog layout / design system / 美观 / 视觉 / Assign user: 0.
Related: packages/fields/src/widgets/RecordPickerDialog.tsx · packages/app-shell/src/views/metadata-admin/AssignedUsersSection.tsx · packages/components/src/custom/ · apps/console/src/preview-gallery.tsx · AGENTS.md rules #3 and #7 · objectui#5492 · objectui#7154.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 8, 2026
Claim: PM loop round 3
Session:
session_01CGZy1BGCjdN5cXqL9cnvB8Account:
os-support-aiBranch:
claude/issue-11903-record-picker-layoutWorktree:
objectui-issue-11903Domain:
domain:uiSeat:
domain:ui#3File surface (on
3683591):packages/fields/src/widgets/RecordPickerDialog.tsx: the dialog's container spacing, search field, row selection cells, width, footer bar, confirm binding and cell rendering (the card's contract points 1–7);packages/components/src/custom/, only if a primitive needs composing (the card names this as allowed);apps/console/src/preview-gallery.tsx: one entry showing the dialog inmultiplemode with three columns (contract point 8);.changeset/11903-*.md.⛔ Not on it:
packages/components/src/ui/**(objectui AGENTS.md #7); the inline lookup dropdown, the filter bar and panel, the external grid slot (renderGrid); any new primitive or theme token; the ten call sites (they change nothing). Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate; default tier)Clause-②: no
Responsibility:
objectui fields: RecordPickerDialog stacks overrides on the design system (gap-0 header, a doubled search border, a blank selection column, a fixed 5xl width, two footer bars, Confirm live at zero, link cells) — the maintainer's 「我发现了很丑的界面」 | the platform path: @object-ui/components already ships the Dialog, Input, Checkbox and Table primitives the contract names | every user of a multi-select lookup, a related list's add, or a role's Assign user (ten call sites)Thread-read: none
Serial constraints cleared:
noneblocking. No in-flight claim in the lane namesRecordPickerDialog.tsxorpreview-gallery.tsx, and no open objectui PR touches them (read 2026-10-08T06:36Z).Why
Clause-②: no: layout and rendering inside an existing published component, with no prop, export or type change. A new or changed published prop, export, type member or language-pack key is a stop: the dev reports it before opening the PR, and the seat amends this line.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{ "issue": 11903, "status": "done", "branch": "claude/issue-11903-record-picker-layout", "pr": "https://github.com/objectstack-ai/objectui/pull/11936", "session": "session_01CGZy1BGCjdN5cXqL9cnvB8 — subagent mode, the parent's id", "premise_still_valid": true, "summary": "RecordPickerDialog now meets the card's eight-point contract using only the Dialog, Input, Checkbox and Table primitives already shipped. 1: no gap-0 and no per-section margins, so the container keeps gap-4. 2: the search is the Input primitive with a leading icon, one border and one ring. 3: every row in multiple mode leads with a Checkbox, and the header is a page select-all. I chose select-all because the Table primitive's has-checkbox cell rule is built for it. Row click and the arrow/Enter/Space keys are unchanged. 4: the width follows a max-width ladder keyed on the drawn column count, with lg:max-w-5xl as the ceiling; multiple mode floors at the three-column rung because measurement showed its footer wrapping below it. 5: one DialogFooter bar. 6: Confirm is disabled at zero. 7: self-linking types (email, url, phone, file, video, audio) are drawn with the text face, and the rows render under the host with recordHref and openRecord withheld. 8: the console preview gallery gains a record_picker entry, and 13 pins cover it. Browser readings before and after, three ablations, and how each earlier fix's intent survives are all in the PR body. No export, prop, type member or language-pack key changed (existing table.selectRow and table.selectAllRows keys are used).", "tests": "All at head 94eb111, heavy runs under os-verify-lock. pnpm exec vitest run packages/fields/src/widgets/ -> Test Files 114 passed (114), Tests 1068 passed (1068); this includes the new RecordPickerDialog.layout-11903.test.tsx (13 cases) and the objectui#5492 agreement pin. pnpm exec vitest run packages/fields/src/__tests__/ plus the 9 top-level fields tests -> Test Files 128 passed | 1 skipped (129), Tests 2888 passed | 7 skipped. Together those are all 243 fields test files. Consumers (lookupPickerKeys-7154, gridDependentValues-7165, ObjectGrid.linkCellNoNestedAnchor-11817, countLabels.ruAr-10425, AssignedUsersSection x2, AccessExplainPanel, RelatedList.addPickerFilter, console preview-samples-registry-resolvable) -> Test Files 9 passed (9), Tests 92 passed (92). Baseline at 3683591 before any edit (widgets dir plus those consumers) -> 118 files / 1126 tests passed. type-check: pnpm --filter @object-ui/fields type-check and pnpm --filter @object-ui/console type-check, each after building its dependency closure -> exit 0; the fields second leg (tsconfig.test.json) covers tests and caught one census typing error, which I fixed. Ablation at 2381af5 via ablation-replace, each leg restored with blob == HEAD 7be98824 and git diff HEAD empty, vitest resolving src through the root alias so no dist was involved. A: Confirm's disabled binding replaced -> 1 failed | 12 passed, point 6 'Received element is not disabled'. B: text-face substitution removed -> census red with 6 anchors (mailto, url, tel, 3 download). C: host recordHref not withheld -> census red with 3 record anchors (lookup, master_detail, tree). Real browser (console preview gallery, Chromium 1440x900): before -> 1024px wide, row-gap 0, title-to-search 1px, a bordered wrapper plus a ring shadow on the input, an empty header cell, two footer bars (y 696 / 730), Confirm enabled at 0, 10 mailto anchors. After -> 672px, row-gap 16, title-to-search 16px, one bordered element (the input) with no ring at rest and one ring focused, header select-all plus a row checkbox on every row, one bar (count and selected both at y 723), Confirm disabled at 0, 0 anchors. Rungs measured: 576 (1-2 cols, single), 672 (3 cols; 1 col multiple), 768 / 896 / 1024 (4 / 5 / 6 cols). A phone reading at 390px shows the footer stacking like any DialogFooter.", "mcp_calls": "0 — none", "api_writes": "3 — all through scripts/pm tools via the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches each): pr_create of objectstack-ai/objectui#11936 (draft; read-back 13081 bytes identical); label-write.mjs assign os-support-ai on #11936 (read-back MATCHES; labeler had already set apps, tests, package: fields); comment os-dev-report on #11903 (this report). git push is not counted.", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — the card's reproduction says a role's Assign user (AssignedUsersSection) draws three columns, but in this repo it passes no columns and draws one (Name). The three-column shape with email links is plugin-detail RelatedList's Add picker. Both shapes are measured in the PR. Dedupe words: AssignedUsersSection columns, Assign user picker, RelatedList add picker", "carrier: none · noted, not filed — the card and brief call objectui#7154 'the keyboard pin'. lookupPickerKeys-7154.test.tsx pins the four picker METADATA keys (multiple, allowCreate, lookupPageSize, dependsOn) and stays green. No keyboard pin for this dialog existed; the PR adds one (point 3). Dedupe words: lookupPickerKeys-7154, picker keyboard pin, RecordPickerDialog keyboard", "carrier: none · noted, not filed — a consequence of point 6 (ruled): a multi-value lookup can no longer be emptied by unticking every row in the dialog and confirming; the field's chip remove buttons remain the path. Dedupe words: Confirm disabled zero, clear multi lookup, chip remove", "carrier: none · noted, not filed — SELF_LINKING_CELL_TYPES (fields RecordPickerDialog) re-states plugin-grid's module-internal SELF_LINKING_RENDERER_TYPES. Each package's census over listCellRendererTypes() goes red on its own surface; there is no shared home because a new export is off this claim. Dedupe words: self-linking renderer types, linkCellRenderer, text face census", "carrier: none · noted, not filed (inference, not measured) — measured in this dialog: with Tailwind v4, an Input given focus-visible:ring-0 still carries a ring-colored 2px box-shadow, because ring-0 is calc(0px + ring-offset-width) and the primitive keeps ring-offset-2. packages/components/src/custom/input-group.tsx applies [&_input]:focus-visible:ring-0 too; I did not measure that surface. Dedupe words: focus-visible ring-0 ring-offset, InputGroup double ring, search double outline" ], "gates": [ {"command": "pnpm exec vitest run packages/fields/src/widgets/", "exit": 0, "verdict": "Test Files 114 passed (114) · Tests 1068 passed (1068)"}, {"command": "pnpm exec vitest run packages/fields/src/__tests__/ + 9 top-level fields test files", "exit": 0, "verdict": "Test Files 128 passed | 1 skipped (129) · Tests 2888 passed | 7 skipped (2895)"}, {"command": "pnpm exec vitest run (9 consumer pins incl. 7154, 10425, 11817, console preview-samples)", "exit": 0, "verdict": "Test Files 9 passed (9) · Tests 92 passed (92)"}, {"command": "pnpm --filter @object-ui/fields type-check", "exit": 0, "verdict": "os-verify-lock VERDICT command-exit 0 (script name echoed: @object-ui/fields type-check)"}, {"command": "pnpm --filter @object-ui/console type-check", "exit": 0, "verdict": "os-verify-lock VERDICT command-exit 0 (script name echoed: @object-ui/console type-check)"}, {"command": "pnpm exec eslint RecordPickerDialog.tsx RecordPickerDialog.layout-11903.test.tsx preview-gallery.tsx", "exit": 0, "verdict": "39 problems (0 errors, 39 warnings); RecordPickerDialog.tsx 35 warnings before and after"}, {"command": "pnpm check:control-bytes", "exit": 0, "verdict": "check-control-bytes: OK (scanned 7951 tracked text file(s); skipped 85 binary)"}, {"command": "pnpm check:test-path-roots", "exit": 0, "verdict": "check-test-path-roots: OK"}, {"command": "pnpm check:changeset-claims", "exit": 0, "verdict": "No pending changeset names a file this change touches."}, {"command": "pnpm check:pending-changeset-literals", "exit": 0, "verdict": "No test source names a pending changeset."}, {"command": "node scripts/check-changeset-presence.mjs", "exit": 0, "verdict": "3 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/11903-record-picker-layout.md."}, {"command": "pnpm check:i18n-keys", "exit": 0, "verdict": "Every in-scope call-site key resolves against the en pack (3300 keys), every literal inline defaultValue matches the value the pack serves"}, {"command": "pnpm check:new-line-citations", "exit": 0, "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0"}, {"command": "pnpm check:i18n-dead-keys", "exit": 0, "verdict": "report-only; exit 0"}, {"command": "pnpm check:doc-types", "exit": 0, "verdict": "Every documented component type is registered."}, {"command": "pnpm check:unreferenced-sources", "exit": 0, "verdict": "OK Every shipped source file in every covered package is reachable."}, {"command": "pnpm check:lint-rule-coverage", "exit": 0, "verdict": "OK 6631 file(s) walked by ESLint"}, {"command": "pnpm check:element-data-source-declaration", "exit": 0, "verdict": "OK — 14 gate-consuming file(s) checked"}, {"command": "pnpm check:component-surface-parity", "exit": 0, "verdict": "exit 0 (report lines only)"}, {"command": "pnpm check:eager-closure", "exit": 2, "verdict": "NOT MEASURED: needs apps/console/dist/eager-closure.json from a console production build (prerequisite missing); preview-gallery.html is not a build input; CI owns it"}, {"command": "CI on #11936 at 94eb111", "exit": null, "verdict": "in_progress at report time: 20 success, 3 skipped, 19 in progress, 0 failed"} ], "deviations": [ "Point 1 also removed the filter-bar OUTER wrapper's py-2, along with the search's mb-3 and the pagination's mt-2 pt-3. These were the per-section stand-ins for gap-0. The filter bar and panel markup is untouched (the card puts it out of scope).", "Point 4: the ladder adds a multiple-mode floor at the three-column rung, because at the one-column rung (576px) the one footer bar wrapped to two lines (measured).", "The changeset declares '@object-ui/console': patch for the dev-only gallery file, because check-changeset-presence counts every src/ file of a released package.", "Local narrowing, declared: no repo-wide pnpm lint or pnpm test (CI). check:eager-closure is NOT MEASURED (needs a console production build). The i18n pack gates other than i18n-keys and i18n-dead-keys and check:readme-exports were not run, because no pack or export changed.", "Not measurements, re-run: four os-verify-lock queue-timeouts (exit 99), and one full-package fields run killed by my own timeout 590 wrapper (exit 124), re-run as two halves that cover all 243 files.", "The brief's 'keyboard pin (objectui#7154)' does not match what that file pins; see out_of_scope_findings. I ran it before and after anyway.", "Harness hygiene: the card body was first fetched into the scratchpad root, then moved into issue-11903/ (no other agent's file was touched)." ], "files_changed": [ "packages/fields/src/widgets/RecordPickerDialog.tsx", "packages/fields/src/widgets/RecordPickerDialog.layout-11903.test.tsx", "apps/console/src/preview-gallery.tsx", ".changeset/11903-record-picker-layout.md" ], "line_budget": "not applicable (no skills/** surface)" }Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
ACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T09:17Z. PR objectui#11936, heada373c4e.PR shape:
main, with no rebase.git merge-treeof the currentmain(19a7348) and this head is clean; the queue tests that merge.Fixes #11903, with no other closing keyword.Clause-②: noat line start.os-support-ai.Scope: 4 files, +860/−99, all on the claim's surface (
6053993445):packages/fields/src/widgets/RecordPickerDialog.tsx;apps/console/src/preview-gallery.tsx(one entry);patchon@object-ui/fields, andpatchon@object-ui/consolefor the dev-only gallery file, whichcheck-changeset-presencecounts.Untouched:
packages/components/src/ui/**; the inline lookup dropdown, the filter bar and panel markup, andrenderGrid; the ten call sites. No export, prop, type member, primitive, token or language-pack key changes; the existingtable.selectRowandtable.selectAllRowskeys are used. No governed path.The card's contract, point by point (the seat's own diff read):
DialogContentkeeps the primitive'sgap-4.gap-0is gone, and so are the per-section margins that stood in for it.Inputprimitive with a leading icon. The bordered wrapper and theborder-0/ring-0overrides are gone, so one border and one ring are drawn.multiplemode every row leads with aCheckboxreflecting its state. It is not a tab stop, and its click toggles the row once. The header is a page select-all, and its keys stay its own. Row click, the arrows and Enter / Space are unchanged.dialogWidthClassmaps the drawn column count onto a max-width ladder, withlg:max-w-5xlas the ceiling.multiplefloors at the three-column rung, because the footer wrapped below it (measured).DialogFooterbar.disabledat zero.textface. The built-in table renders under the host withrecordHrefandopenRecordwithheld, so a reference value is plain text.record_pickerentry, with 13 pins. The objectui#5492 agreement pin stays green.Reverse verification (dev report
6056279217), three ablations, each restore proven (blob equals HEAD):disabledreplaced: point 6 red.recordHrefnot withheld: the census red, with 3 record anchors.Tests and checks:
@object-ui/fieldstest files pass, plus 9 consumer pins.@object-ui/fieldsand@object-ui/consoletype-checks pass.Review round 2 (seat-requested): three new comments named the three-column shape "a role's Assign user". The dev's own reading is that
AssignedUsersSectiondraws one column and the three-column shape isRelatedList's Add. Fixed ata373c4e, which is comment-only (diff read); the pin file re-ran 13 of 13. The same slip in the PR body was corrected by the seat; read back identical.Gates: CI on
a373c4e(head_shaequals the PR head): 43 runs: 39 success, 3 skipped (Test (coverage), its shard template,dependabot), and 1 failure,Bundle Analysis(see Landing).LintandType Checkare success. Mergeable stateunstable, from that one non-required red.Contract review: not required (
Clause-②: no).Findings:
Acceptance notesAcceptance notesAcceptance notes(a consequence of the ruled contract)SELF_LINKING_CELL_TYPESrestates@object-ui/plugin-grid's module-internal set. Each package's census overlistCellRendererTypes()holds its own copy to the registry. A shared home would be a new export →Acceptance notesfocus-visible:ring-0may still draw the ring offset inInputGroup. That is an inference, not measured → dropped — no measured reachLanding: held — waits on objectui#11937 (since 2026-10-08T09:12Z).
Bundle Analysisis red onmainsince19a7348. The eager closure is over its 3307.0 KB ceiling (MAX_EAGER_CLOSURE_GZIP_BYTES), with the same failing step as this PR (Check console performance budget). objectui#11937 is the p0 anchor, and seat 2 is fixing it forward.main's 3307.0 KB. Landing it now would widen the gap that fix has to close.Bundle Analysisis not required and does not run in the merge group, so the queue would admit it anyway.maininto this branch and lands it when every check on that head is green,Bundle Analysisincluded. If the fix leaves too little headroom for this PR's bytes, the seat comes back here with a measured option.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
ACCEPT, landing head —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T12:25Z. PR objectui#11936, headd0c33818. It extends ACCEPT6056704842(heada373c4e), whose landing was held for the eager budget.d0c33818, with parentsa373c4e2andmain70e3d772. It is a pure merge: the seat measured that its tree equalsgit merge-treeof the two parents (2cafd4346f). None of the 191 files it brings in is underpackages/fields/,preview-gallery.tsxorpackages/components/src/ui|custom/. This PR's four files are byte-for-byte what was accepted.mainis green after the rollback3c888c6(objectui#11956).1c51e97(objectui#11949, ruling6056819248step 2) is in.d0c33818the budget bot reads 3308.5 KB across 337 chunks against 3312.0 KB: PASS.d0c33818:packages/fields/src/widgets/, 114 files and 1068 tests passed; the layout pin, 13 of 13; the@object-ui/fieldstype-check passed.d0c33818(head_shaequals the PR head): 43 runs, 40 success, 3 skipped (Test (coverage), its shard template,dependabot), 0 failure. Mergeable stateclean. 4 files, +860/−99. No governed path.Landing: ready + auto-merge through the queue, now.
Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Landed —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T12:46Z. PR objectui#11936 merged through the queue as5ab2f19at 2026-10-08T12:44Z.45d58536(objectui#11930's merge), an ancestor oforigin/main.git merge-treeof that parent and the landing headd0c33818(treefd299b65on both). That head's ACCEPT extension is6059822988.45d58536→5ab2f19, inpackages/fields/src/widgets/RecordPickerDialog.tsx:dialogWidthClass: 0 → 3.SELF_LINKING_CELL_TYPES: 0 → 3.WithoutRecordLinks: 0 → 3.gap-0: 1 → 1. Read by line, it moved out of the class list: before, it was inDialogContent'sclassName(:1061); after, only a comment saying there is nogap-0names it (:1192). Contract point 1 holds.packages/fields/src/widgets/LookupField.tsx(the inline dropdown, out of scope) is byte-identical on both sides.Fixes #11903, and this merge closed only objectui#11903, ascompletedat 12:44Z.pm:dispatchedis removed in this pass.Generated by Claude Code
fix(fields): one record picker, one dialog layout, recomposed from th…