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.

finding(react): bridgeListView's mapDensity carries four rowHeight spellings no spec-valid list view can hold #4352

Closed

Description

@yinlianghui

Found while type-checking @object-ui/react's tests for #4040 (tranche 4, PR #4351). Observation-class: nothing a user hits today, and no fix is proposed here.

What

packages/react/src/spec-bridge/bridges/list-view.ts maps a list view's rowHeight onto the renderer's density with a hand-written table of nine keys:

compact, short, comfortable, spacious, small, medium, large, tall, extra_tall

RowHeightSchema in @objectstack/spec admits five:

short | compact | medium | tall | extra_tall

So comfortable, spacious, small and large are unreachable from any spec-valid input. The bridge's own parameter type says so — it is Partial< ListView >, i.e. the spec shape — and mapDensity widens it back to rowHeight?: string to accept them.

Why it survived

SpecBridge.test.ts asserted three of the four (comfortable, spacious, small) as though they were live capability, and that file was compiled by nothing: the package's build tsconfig excludes tests and no other tsc invocation read them. Type-checking the tree is what surfaced it — the fixture would not compile against the type the function declares.

PR #4351 re-spells the fixture canonically and now covers all five spec values (gaining medium and tall, which the suite never had). It deliberately does not touch the source: deleting a lenient branch is a behaviour change for any host still passing a legacy spelling, which is a separate decision from the type-check graduation.

The decision, when someone takes it

This is AGENTS.md #0.1 territory (fix the metadata, not the renderer — one strict contract beats N dialects), so the default answer is to delete the four dead keys and let a non-spec rowHeight fall through to undefined density. The counter-consideration is empirical, not theoretical: whether any live metadata still authors comfortable/spacious, since the ADR-0087 conversions rewrote a lot of older pages. Worth a grep across the example apps and the console's own view metadata before removing.

Related: the same PR found ListColumn.link / .action asserted as { href } / { type } objects when the spec declares boolean / string; the bridge forwards them verbatim, so those assertions only ever proved pass-through. Re-spelled in #4351.

Activity

  1. self-assigned this
    on Aug 12, 2026
  2. yinlianghui commented on Aug 12, 2026

    @yinlianghui
    ContributorAuthor

    CLAIM + RULING — PM seat session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4352-mapdensity-dead-spellings, one dev agent, one PR, Fixes #4352. finding → pm:queue.

    Ruling (delegated, veto window open): the card's own default — delete the four dead spellings (comfortable/spacious/small/large), one strict contract per AGENTS.md #0.1, non-spec rowHeight falls through to undefined density — conditioned on the card's own empirical pre-check: sweep example apps, console view metadata, and any stored-metadata fixtures for legacy spellings FIRST. A live authored legacy spelling → STOP and report (the #0.1 fix is then metadata conversion, a different card). The parameter widening (rowHeight?: string) dies with the branch — mapDensity takes the spec type honestly. Red-first: a legacy spelling now yields undefined (pin the new behavior against the lenient branch), the five spec values pinned mapping (PR #4351's fixture coverage is the base). Changeset graded by whether anything published narrows (#4403 precedent if so), never major.


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions