Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

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

Closed

Description

@objectstack-fleet

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

  1. 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.
  2. 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)

  1. packages/plugin-detail/src/HeaderHighlight.tsx line 113: the row is flex flex-wrap gap-y-4; lines 237–262: each chip is grow max-w-max with a basis-[16rem] min-w-[min(16rem,100%)] (wide kinds) or basis-[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 is block 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's max-w-max holds its content width while the row clips it, so the value is cut without the truncate ellipsis ever applying.
  2. packages/plugin-detail/src/DetailView.tsx line 1599 renders the strip from schema.highlightFields; the console builds that list in packages/app-shell/src/views/RecordDetailView.tsx lines 2833–2902 from objectDef.highlightFields.
  3. 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

  1. A chip that does not fit its line truncates with an ellipsis and carries the full value in title (the truncate span gets a bounded width: the chip's max-w is its share of the row, not max-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.
  2. Below sm the 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.
  3. 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

  • HeaderHighlight tests: six chips in a 1088 px row render every value whole or with an ellipsis and a title, none clipped (scrollWidth ≤ clientWidth on 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 test from the repo root green on the affected files; a changeset (patch) for @object-ui/plugin-detail.

Out of scope

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

record-1440.png

The same record at 390: two chips in a grid, then an indented list

record-390.png

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    and removed on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (priority:p1; filed on the maintainer's 「同意开卡,使用 pm-dispatch 创建卡片」)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12523-highlight-strip-clip
    Worktree: objectui-issue-12523
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/plugin-detail/src/HeaderHighlight.tsx (the row :113, the chip classes :237–:262 and the value span :358 on main 720f6d4) and its tests; one .changeset/12523-*.md. Which fields are highlights, DetailView.tsx's call site, RecordDetailView.tsx and 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/objectui names no path-derived mandate)
    Clause-②: no
    Responsibility:

    • Whose code: @object-ui/plugin-detail's HeaderHighlight. Each chip's max-w-max holds its content width while the row clips it.
    • Which platform path already covers it: none.
    • Who reaches it: every console user on a record page, and on the drawer strip that shares the component, whose highlights outgrow one line. Measured on the HotCRM lead at 1440, 1024 and 390.
      Thread-read: none
      Serial constraints cleared: read at objectui main c3de0bc73d. No pm:dispatched claim in the lane names HeaderHighlight.tsx or plugin-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

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T17:43Z

    • Merged: PR fix(plugin-detail,fields): the highlight strip ellipsizes a cut value, sizes a format-declared phone as a phone, starts every wrapped line flush, and is one layout below sm (objectui#12523) #12541 landed through the merge queue as main 518a8e3084 at 2026-10-15T17:34Z. It has one parent, 92318202a1 (objectui#12518's landing), and is an ancestor of origin/main.
    • Verified by content: all 5 files the PR changes are blob-identical on 518a8e3084 to the accepted head 28283919de.
    • Mis-close scan: the PR body's only closing keyword is Fixes objectstack-ai/objectui#12523. The only issue closed with the merge is this card, as completed.
    • What now holds:
      • The record page's highlight strip sizes a chip by the cell it draws, so a text + format: phone field gets the phone width.
      • A strip that runs out of line wraps before it cuts a value, and a wrapped line starts flush.
      • Below sm, every chip is a full-width line.
      • The email, URL and phone cells end a cut value in an ellipsis wherever a host bounds them.
      • On HotCRM's lead, Phone and Email read whole at 1440, 1024 and 390 (ACCEPT 6197776421).
    • The seat's answer to the dev's open question: keep max-w-max (A), recorded in the ACCEPT.
    • The chain: claim 6195017699, report 6196612809, ACCEPT 6197776421.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p1

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions