Skip to content

finding(plugin-grid): a standalone ObjectGrid still renders an off-spec rowHeight as medium, the third answer to the question #4440 unified #4443

Description

@yinlianghui

Found while implementing #4440. Observation-class: nothing a user hits today, and no fix is proposed here.

What

#4440 made two surfaces agree that an off-spec rowHeight gets no density — @object-ui/core's rowHeightToDensityMode and @object-ui/react's mapDensity. A third surface answers the same question without consulting either.

packages/plugin-grid/src/ObjectGrid.tsx:371 takes the value straight into state:

const [rowHeightMode, setRowHeightMode] =
  useState<'compact' | 'short' | 'medium' | 'tall' | 'extra_tall'>(schema.rowHeight ?? 'compact');

and renders it through a ternary chain whose final else is the medium styling (ObjectGrid.tsx:1834-1841, and again for cellClassName at 2370-2377):

rowHeightMode === 'compact'   ? 'px-3 py-1 h-9 text-[13px] leading-tight'
  : rowHeightMode === 'short'      ? 'px-3 py-1 h-9 text-[13px] leading-normal'
  : rowHeightMode === 'tall'       ? 'px-3 py-2.5 h-14 text-sm'
  : rowHeightMode === 'extra_tall' ? 'px-3 py-3.5 h-16 text-sm leading-relaxed'
  : 'px-3 py-1.5 h-11 text-[13px] leading-normal'   // ← medium, and everything unrecognized

So for the same garbage rowHeight, the system now says: ListView → compact (32px), the spec bridge → no density at all, a standalone ObjectGrid → medium (44px). Note the ?? on line 371 makes ABSENT resolve to compact while OFF-SPEC resolves to medium — the same absent-vs-off-spec split #4440 removed from ListView.

Only the standalone path is affected: when ListView owns the grid it overwrites the prop with a value derived from density.mode (ListView.tsx:1676-1698, one of compact/medium/tall), so nothing off-spec survives that hop.

Why it is observation-class and not a defect today

Unreachable by any metadata that exists. The three-repo sweep run for #4352 (PR #4439), re-run at newer HEADs for #4440, found zero authored off-spec rowHeight values across objectui, the objectstack example apps and one downstream app; every authored value is one of the five RowHeightSchema admits.

It is also a materially weaker case than #4440 was. This is not a mapping table with a catch-all branch — it is a rendering ternary whose default is a style, and a component's own last-resort styling default is a legitimate thing to have. What is odd is only that the default it picks (medium) differs from the default the same component picks when the key is absent (compact).

The decision, when someone takes it

  1. Narrow at the boundary — validate schema.rowHeight into the state exactly as ListView now does, so off-spec and absent both land on compact. This is the finding(core): rowHeightToDensityMode coerces an off-spec rowHeight to comfortable, the opposite of what the spec bridge now does with the same input #4440 answer applied to the third surface, and it makes the ?? on line 371 mean one thing.
  2. Leave it and write down why — a leaf renderer's terminal else is not a vocabulary bridge, and forcing every styling ternary to pre-validate its input has a cost. If that is the intended position, say so at line 371 and name the two surfaces that decided otherwise, so the next reader does not file this twice.

Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions