Repository navigation
record page header: the highlight strip clips its last values at 1440 ("+1-555-0") and at 390 mixes a two-column grid with an indented list — values truncate with a tooltip or wrap, and the phone strip keeps one layout #12523
Description
Filing gate ① (a product defect, measured on main), filed on the maintainer's word (chat, 2026-10-15, session session_019YFzJp4o8Ck4NsT1toC4UP, seat account os-bill): the seat ran a functional audit of the HotCRM console on objectui main 720f6d4 (report, private to the maintainer: https://claude.ai/artifact/XPrn5eZMsQaKUgasMJEMmR, findings F4 and F11, figures 6 and 15), and the maintainer answered 「同意开卡,使用 pm-dispatch 创建卡片」. Quota note: the audit's cards exceed the filing gate's three-per-fire quota on that word, which approved the report's card list as a set.
Parent: objectstack-ai/objectstack#25945. The record-page sibling of #11684 (closed by PR #11719, which fixed the drawer's fixed-basis chips). Blocks nothing; nothing blocks it.
Reader who acts: the domain:ui lane's next dispatch (seat post #9800), one dev round in @object-ui/plugin-detail (HeaderHighlight.tsx), size S.
Dedupe (MCP search_issues, scope objectstack-ai/objectui, all states, read 2026-10-15T14:14Z): "record page header highlight fields strip truncates phone email value clipped key fields mobile layout" → 7, all closed: #12188 (a lookup title at phone width), #11684 (the drawer's chips truncating short values; fixed by PR #11719: chips share the row's free width), #7245, #6083, #2249 (the 2026-07 strip layout pass), #1034 (the 2026-03 phone layout), #1006. None is this card: #11684's fix is in place and this card measures what is left on the record page.
What happens
- Desktop (1440, HotCRM lead "Mira Costa"): the highlight strip under the title shows Status · Lead Score · Lead Source · Lead Owner · Email · Phone; Phone reads "+1-555-0" and Email reads "mira.costa@atlasconstruction" — the last two values are clipped at the cell's edge with no ellipsis and no title. The anchor itself is not truncated (its scroll width equals its client width); the cell clips it. The same at 1024 and in the dark theme and zh locale.
- Phone (390, the same record): the first two highlights (Status, Lead Score) sit side by side in a two-column grid; the next four (Lead Source, Lead Owner, Email, Phone) become a single-column list with a left rule and an indent. Two layouts in one strip; the email is clipped at its end there too.
Readings (objectui origin/main 720f6d4, read 2026-10-15T14:15Z)
packages/plugin-detail/src/HeaderHighlight.tsxline 113: the row isflex flex-wrap gap-y-4; lines 237–262: each chip isgrow max-w-maxwith abasis-[16rem] min-w-[min(16rem,100%)](wide kinds) orbasis-[9rem] min-w-[min(9rem,100%)]floor (record drawer: header highlight fields truncate short values ("QA Wid…") with most of the row empty #11684); line 358: the value isblock min-w-0 truncate text-sm font-semibold. With six chips at the record page's content width (about 1088 px at 1440) the floors sum past the row, the last chip'smax-w-maxholds its content width while the row clips it, so the value is cut without thetruncateellipsis ever applying.packages/plugin-detail/src/DetailView.tsxline 1599 renders the strip fromschema.highlightFields; the console builds that list inpackages/app-shell/src/views/RecordDetailView.tsxlines 2833–2902 fromobjectDef.highlightFields.- The phone reading is the same component at 390: the first line of the wrap holds two chips, the rest wrap one per line with the chip's own left border, which reads as a different layout.
What to build
- A chip that does not fit its line truncates with an ellipsis and carries the full value in
title(thetruncatespan gets a bounded width: the chip'smax-wis its share of the row, notmax-content); the last chip of a line is never clipped by the row. When the chips' floors exceed the row, the strip wraps to a second line before any value is cut. - Below
smthe strip is one layout: either every chip is a full-width "label · value" row, or a two-column grid throughout; the per-chip left border goes where it no longer separates columns. - The existing record drawer: header highlight fields truncate short values ("QA Wid…") with most of the row empty #11684 behaviour (chips share free width, a short value renders whole) is kept.
Acceptance
HeaderHighlighttests: six chips in a 1088 px row render every value whole or with an ellipsis and atitle, none clipped (scrollWidth≤clientWidthon each chip); the record drawer: header highlight fields truncate short values ("QA Wid…") with most of the row empty #11684 pins unchanged; at a 358 px row every chip has the same layout class.- Browser reading by the landing seat at 1440 on the HotCRM lead above: Phone reads "+1-555-0117-1119" whole or ends in an ellipsis with the full number in its tooltip; at 390 the strip's six chips share one layout.
pnpm testfrom the repo root green on the affected files; a changeset (patch) for@object-ui/plugin-detail.
Out of scope
- Which fields are highlights (HotCRM's
highlightFields); the record drawer's strip beyond what the shared component fixes; the page header's title chip (RecordTitleChip: the record title collapses to ~30px ("S…") when the header carries three wide action buttons at ~800px #7244).
Attribution: written by the domain:ui seat in session session_019YFzJp4o8Ck4NsT1toC4UP (account os-bill) on the maintainer's words quoted above.
Screenshots (added 2026-10-15T14:39Z, on the maintainer's word 「专用分支存图,卡里嵌 raw 链接」)
The images live on the attachment branch claude/ui-audit-2026-10-15-shots of objectstack-ai/objectui (commit 918a251, never merged; index at https://github.com/objectstack-ai/objectui/blob/918a2510a54bd6875b90eb6996d098c3ec0451dd/docs/design/console-audit-2026-10-15/README.md). Full set and figure numbers: the audit report linked above.
Lead record page at 1440: Phone reads "+1-555-0", Email cut at the cell's edge
The same record at 390: two chips in a grid, then an indented list


Activity
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 1 (
priority:p1; filed on the maintainer's 「同意开卡,使用 pm-dispatch 创建卡片」)Session:
session_01JZnppgHRp4sREcouhkQYDBAccount:
sunhaolinBranch:
claude/issue-12523-highlight-strip-clipWorktree:
objectui-issue-12523Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/plugin-detail/src/HeaderHighlight.tsx(the row:113, the chip classes:237–:262and the value span:358onmain720f6d4) and its tests; one.changeset/12523-*.md. Which fields are highlights,DetailView.tsx's call site,RecordDetailView.tsxand the title chip (objectui#7244) are outside the surface (stop on breach; explain in the report).Container & model:
S,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuinames no path-derived mandate)Clause-②: no
Responsibility:
@object-ui/plugin-detail'sHeaderHighlight. Each chip'smax-w-maxholds its content width while the row clips it.Thread-read: none
Serial constraints cleared: read at objectui
mainc3de0bc73d. Nopm:dispatchedclaim in the lane namesHeaderHighlight.tsxorplugin-detail(scanned in this act). The other two in flight are this seat's objectui#12518 (plugin-view) and objectui#12520 (SidebarItemMenu.tsx), both disjoint.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 12523,
"status": "done",
"branch": "claude/issue-12523-highlight-strip-clip",
"pr": "#12541",
"session": "session_01JZnppgHRp4sREcouhkQYDB — this run's harness-stamped id (Claude-Session trailer on commit 2828391; subagent of the domain:ui seat, so the parent's id)",
"premise_still_valid": true,
"summary": "Premise holds, and its mechanism was corrected by a Chromium measurement. The harness renders the real HeaderHighlight markup with the console's compiled Tailwind sheet, and it reproduced the card's 1440 reading. A1 is FALSIFIED. Each chip in the 1088px row sat at its floor (144/144/144/256/256/144, summing to exactly 1088), and no chip ever passed its line. Phone was on the 9rem floor because HotCRM declares it text + format: phone, and isWide read the declared type. The value span did clip, but its only child was the link cell's inline-flex box, and the first atomic inline on a line is clipped, never ellipsed. Shipped: (1) @object-ui/fields: the email, url and phone cells now fit a bounded slot with an ellipsis, using the TruncatedText single-line convention (the producer, under the dispatch's producer clause; outside the predicted file surface). (2) HeaderHighlight: isWide's display half reads the drawn renderer type (drawnType), so a format-declared phone gets the objectui#11659 16rem floor. The floors then exceed the row and Phone wraps before any cut. (3) Every chip carries the separator. From sm up, the row is pulled left by one separator and a left-only clip-path hides every line-start rule, so wrapped lines start flush. (4) Below sm, one layout: every chip is a full-width line (max-sm:basis-full max-sm:max-w-full max-sm:border-l-0 max-sm:px-0). Harness after the change: at 1088, Email reads whole on line 1 and Phone whole on line 2, flush left. At 358, six full-width lines, all whole. Long values each end in an ellipsis drawn by the cell itself. The objectui#11684 product strip is unchanged. Ruling 1 deviation, flagged (see open_questions): max-w-max is KEPT. The parenthetical "max-w is its share of the row, not max-content" rests on A1's falsified mechanism, and swapping to max-w-full would reverse the objectui#11684 distribution. So the #11684 pin file is byte-identical and green, and the suggested "put max-w-max back" ablation does not apply. A2: class and structure pins. Stubbed widths would only measure the stub, and the #11684 pins stub none either. The pixel half is the harness reading plus the landing seat's reading. A3: full-width lines. Two columns of a 358 row leave a value about 179px or less, while the phone cell measures 167 and the email 322. The cost is one more line at 390, about 56px. A4: the callers are DetailView, the record:highlights renderer (record page and drawer) and RecordPreviewCard, all covered. Card assignee was already sunhaolin, and I did not touch it.",
"tests": "All test runs are from the repo root through os-verify-lock, at final head 2828391. pnpm exec vitest run --maxWorkers=2 packages/plugin-detail/ packages/fields/: Test Files 528 passed | 2 skipped (530); Tests 6707 passed | 21 skipped (6728); VERDICT command-exit 0. New pins: - HeaderHighlight.lineFitAndPhoneLayout-12523 (9 tests); - cellRenderers.linkEllipsis-12523 (5 tests). Unchanged pins, 6 files / 52 tests green before the commit: HeaderHighlight.shareRowWidth-11684 (the #11684 pins, file untouched), RecordHighlightsRenderer.phoneWidth-11659, RecordHighlightsRenderer.percentClip, expandableFamily.identity-5874. Consumers, 15 files / 100 tests passed, VERDICT command-exit 0: - the seven RecordDetailView.* tests that render highlights (childWriteRefreshesParent-12244, expandFls-7230, lookupDependsOn-7190, oneProvenanceFooter-12307, pageHeaderTitleFls-10499, recordOpenRequests-11699, sectionHeadingsRenderPath-6190); - RecordPreviewCard and record-pointer-card-renderer; - ObjectGrid.linkCellNoNestedAnchor-11817 and formatHintedColumnRenderer-8920; - ObjectDataTable.cells and recordFields.formatHintNotDatePattern-10220; - ObjectGallery.cells and ReportViewer.cells. Census tests whose subject the diff touches ran in the package suites: summaryChip.badgeFitCensus-8464, cellRenderers.fabricatedValue-8490 / objectLiteral-8596 / valueIndependent-8678 / childlessContainer-8580, RecordPickerDialog.layout-11903. Type-check: - closure build pnpm --workspace-concurrency=2 --filter @object-ui/plugin-detail^... build: BUILD_EXIT=0; - pnpm --filter @object-ui/plugin-detail type-check: TC_DETAIL_EXIT=0; - pnpm --filter @object-ui/fields type-check: TC_FIELDS_EXIT=0. Each type-check exit was captured to its own file. Both scripts echoed tsc --noEmit and tsc -p tsconfig.test.json, which includes the tests. Ablation: every leg ran through ablation-replace, with the anchor-hit and blob-moved checks and a restore proved by blob == HEAD and an empty git diff HEAD. Source resolves via the vitest alias, so no dist is involved. - leg 1, isWide back on resolvedType: 2 red (the format-phone and format-email floor pins), 7 green; - leg 2, max-sm class line deleted: 2 red (both one-layout pins); - leg 3, first:border-l-0 first:pl-0 restored: 1 red (every-chip separator); - leg 4a, email anchor reverted: 1 red; - leg 4c, url anchor reverted: 1 red; - leg 4b, phone truncate span removed: the first attempt was REFUSED by the tool before running, because the replacement text occurs elsewhere and its count could not move. Re-run with a two-line anchor: 1 red. Pixel evidence: a Chromium 1194 harness, before and after, on the lead at row widths 1088 / 800 / 358 and on long values; the readings are in the PR body. Deviation: the very first single-file harness render (about 15s) ran outside the lock; every run after it went through the lock.",
"gates": "objectui has no dispatch-gates.mjs, so the gate list was hand-derived from package.json check:* and lint.yml, ci.yml, changeset-guard.yml and performance-budget.yml. No --ran reconciliation is possible. Local, each exit captured before any pipe: - eslint --no-inline-config on the 4 changed source and test files: exit 0, 0 errors; - check:control-bytes: exit 0; - check:new-line-citations: exit 0, 0 new citations; - check-changeset-presence: exit 0; - check-changeset-no-major: exit 0; - check-changeset-overwrite: exit 0; - check-changeset-claims: exit 0; - check-vi-mock-override-shape: exit 0; - check-test-path-roots: exit 0. CI at 2828391, read once right after the PR opened: 36 check-runs. success: Changeset Bump Policy, Changeset Fixed Group Check, label. skipped: dependabot, Test (coverage), Test (coverage shard matrix). in_progress (honest value, not waited on): Lint, Type Check, Test shards 1-16/16, Test (dist pins), Build & E2E, Build Docs, Changeset Declaration, Changeset Claim Re-read, Changeset Overwrite Report, Line Citation Gate, Repo Gates, Spec Main Shape Gate, Governed Surface Queue Guard, Bundle Analysis, Live E2E (informational). Left to CI and not run locally: repo-wide pnpm lint / pnpm check, the sharded pnpm test, Build & E2E, and the performance budget. Known red, not chased: objectui#12422's plugin-list / plugin-detail build-order race may red Type Check.",
"mcp_calls": "0 — no MCP GitHub calls. Reads went through the REST proxy: issue 12523 and its comments, issue 4054, PR 12541, and the check-runs.",
"api_writes": "2 — fleet-write relay strokes, each sent as POST /repos/objectstack-ai/objectstack/dispatches: (1) pr_create, which the relay executed as POST /repos/objectstack-ai/objectui/pulls (draft) plus POST /repos//issues/12541/assignees [sunhaolin]; (2) this os-dev-report comment, POST /repos//issues/12523/comments. Also two git pushes of the branch (not REST). No label writes, no PATCH.",
"open_questions": [
{
"question": "Ruling 1 says "its max-w is its share of the row, not max-content". The measurement shows max-w-max never lets a chip exceed its line, so I kept it and met the ruling's intent by other means: an ellipsis drawn by the cell, a title on the clip box, the correct phone floor, and a wrap before any cut. Accept the kept max-w-max?",
"options": [
"A: keep max-w-max (as shipped). The #11684 pins stay byte-identical, and a fitting chip keeps passing its free width to the chips that need it.",
"B: swap to max-w-full as the ruling worded it. Nothing changes at the measured row, which has zero free width. On rows with free width, fitting chips grow past their content and take width from chips that need it: the #11684 distribution reversed, its pins red, and the hover pencil drifting away from short values."
],
"recommendation": "A, because the parenthetical describes A1's mechanism, which the Chromium reading falsified, and B regresses ruling 3 (keep #11684) for no gain at the measured row."
}
],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted in the PR Acceptance notes, not filed · the location / geolocation and color-swatch cells keep an atomic multi-element inline root, so a squeezed chip can still cut them without an ellipsis. This is the residue objectui#4054 described, and that card ended as not planned. No user-hit instance was reproduced, so it is an observation.",
"carrier: none (承接者:无) · noted, not filed · isKpi reads the declared type, so a text + format: currency / percent chip misses tabular-nums. Cosmetic."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Landed ·
domain:uiseat 1 ·session_01JZnppgHRp4sREcouhkQYDB· 2026-10-15T17:43Zmain518a8e3084at 2026-10-15T17:34Z. It has one parent,92318202a1(objectui#12518's landing), and is an ancestor oforigin/main.518a8e3084to the accepted head28283919de.Fixes objectstack-ai/objectui#12523. The only issue closed with the merge is this card, ascompleted.text+format: phonefield gets the phone width.sm, every chip is a full-width line.6197776421).max-w-max(A), recorded in the ACCEPT.6195017699, report6196612809, ACCEPT6197776421.Generated by Claude Code
fix(plugin-detail,fields): the highlight strip ellipsizes a cut value…