Skip to content

DetailSection has a THIRD, un-trimmed spelling of emptiness — a whitespace-only value counts as FILLED, so it renders a blank row, escapes the "Show N empty fields" counter, and can single-handedly arm auto-hide #8376

Description

@os-justin

Filed by the objectui#8350 dev (branch claude/issue-8350-dedupe-emptiness-trims, PR #8375) while fixing that card. ⛔ Not claimed. Out of scope there: objectui#8350's fence is the dedupe ladder in record:details versus the page H1, and this is a different site with a different consumer.

What

packages/plugin-detail/src/DetailSection.tsx decides emptiness twice, both times with a raw value === null || value === undefined || value === '' test:

  • isEmptyValue (the row filter feeding emptyCount / the auto-hide heuristic / the reader's toggle);
  • the isEmpty branch inside displayValue (the one that draws the muted em-dash with the No value label).

Neither trims. @object-ui/core's recordDisplayValueAt — the definition getRecordDisplayName uses for the page H1, and now the definition record:details' dedupe ladder uses (objectui#8350 / PR #8375) — does. So a whitespace-only field value is EMPTY to both of those and FILLED to DetailSection, which is now the only reader in the record-detail render path still answering the old way.

Three consequences, all silent

  1. A blank row instead of the affordance. The em-dash + No value span exists precisely so a reader can tell "this field has nothing" from "this page failed to render". A value of ' ' is FILLED, so it takes the cell-renderer path and paints a visually empty cell — the exact UI the em-dash was added to prevent, reached by a value the rest of the stack calls empty.
  2. It escapes the counter. emptyCount skips it, so the toggle reads Show N empty fields with N one too low, and revealing them does not reveal this row (it was never hidden — it was never counted).
  3. It can arm auto-hide by itself. shouldAutoHideEmpty requires filledCount > 0; the stated reason is that an all-empty section keeps its labels as a structural skeleton for a sparse or brand-new record. A section whose ONLY non-null value is ' ' has filledCount === 1, so the skeleton is suppressed and every genuinely empty row is hidden behind the toggle — on a page a reader would describe as blank.

Reachability is the same narrow authored-data shape as objectui#8350 (a field holding only spaces), which is why that card was p3; consequence 3 is the one that reaches furthest, because one such value changes what happens to every other row in the section.

Fix shape (a suggestion, not a ruling)

The same move objectui#8350 made one layer up: call the shared definition rather than re-spell the test. @object-ui/core now exports recordDisplayValueAt(record, field) for exactly this. ⚠️ Two things a taker should decide rather than assume:

  • these two reads are about a RENDERED CELL, not about a title, so "empty" here may legitimately want to be a different predicate than the display-name one — that is the question to settle, and settling it is the value of this card;
  • the two reads may not deserve the same answer as each other: isEmptyValue feeds a layout heuristic, isEmpty feeds an affordance.

Whatever the ruling, the pin has to assert the RENDERED outcome — which row shows the em-dash, what N the toggle says, whether auto-hide fired — not the predicate in isolation.

Measured

Read on origin/main at 37149ec4f while implementing PR #8375. AUTO_HIDE_MIN_FIELDS is 4 on desktop / 3 on mobile and AUTO_HIDE_RATIO 0.25 / 0.2, so consequence 3 needs a section of at least 4 rows; PR #8375's fixtures deliberately stay at 3 rendered rows so auto-hide cannot fire and cannot confound that pin — which is how this divergence was noticed rather than assumed.

Dedup

search_issues twice, both non-empty (self-validating): the empty-section heuristic wording returned objectui#8350, objectui#7064 and objectui#7129 — the latter two are the hideEmpty DECLARED-KEY retirement, closed, and neither names the emptiness predicate; the whitespace-value wording returned objectui#7347, which is a grouping field NAME with surrounding whitespace in the kanban $select path, a different fact. None names this.

Related

objectui#8350 / PR #8375 (the same divergence one layer up, now closed there) · objectui#7129 (the heuristic's charter) · objectui#7064

Activity

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpluginpm:dispatchedpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions