Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .changeset/grid-column-declared-spelling-only-5068.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
---
"@object-ui/plugin-grid": minor
---

fix(plugin-grid): `ObjectGrid` reads the declared column spelling, and only it

`ObjectGridSchema.columns` is declared `string[] | ListColumn[]`, and
`ListColumnSchema` in `@objectstack/spec/ui` is a **strict** object: `field` is
required, and `accessorKey` / `header` are refused **by name** —
`unrecognized_keys`, with a prescriptive message. The renderer accepted that
refused spelling anyway, through a branch that sniffed `columns[0]` for an
`accessorKey` and synthesized a `ListColumn` from it. One key, two spellings:
one the schema admits, one only the runtime did.

That branch retires (inheriting the disposition of objectui#3951 together with
its reason — unify at the producer, no consumer-side tolerance alias, AGENTS.md
#0.1). It is also why the fictional `{ header, accessorKey }` column interface
in the plugin README (objectui#5013) read as credible: it rendered, so nothing
signalled that the contract refuses it.

**Affected input.** A column authored `{ accessorKey, header }` no longer
resolves; it is dropped, and a grid whose columns are all mis-spelled renders as
the row-number column alone. Write columns the declared way — `{ field, label }`
— which is what the spec has always accepted and what the docs have always said
(`content/docs/plugins/plugin-grid.mdx`: "The field this column reads. There is
no `accessorKey`."). No authored usage of the retired spelling exists in this
repo's examples, docs, apps or fixtures; every in-repo occurrence of the name
belongs to the `table` / `data-table` component, which legitimately owns it.

The `columns[0]` sniff goes with the branch. Column identity is a per-column
property, and one filter now judges it: a mis-spelled column is dropped alone,
where the sniff let the first entry decide the fate of the whole array — a
declared column standing behind an undeclared one was lost with it, and the
reverse order threw a `TypeError` mid-render.

`accessorKey` keeps its job on the way **out**: it is the data-table adapter's
column key, which `@object-ui/core` deliberately holds outside the metadata
identity fold (`TABLE_ADAPTER_COLUMN_KEY`) and which `ObjectGrid` still writes
when it hands columns to the adapter. Metadata vocabulary in, adapter vocabulary
out, one translation at one boundary.
33 changes: 33 additions & 0 deletions .changeset/spec-bridge-list-view-canonical-columns-5068.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
---
"@object-ui/react": minor
---

fix(react): `bridgeListView` emits the column spelling the spec declares

`mapColumn` took a spec-canonical `ListColumn` — whose columns are **already**
spelled `field` / `label` — and down-translated every one of them to
`{ accessorKey, header }` before emitting the `object-grid` node, which
`ObjectGrid` then translated back. A round trip through a spelling
`ListColumnSchema` refuses by name, on a value that arrived canonical. The
bridge now forwards the declared shape, and the tolerance branch on the other
side retires in the same release (see `@object-ui/plugin-grid`).

**Output shape.** `bridgeListView` / `SpecBridge.transformListView` emit
`columns: [{ field, label?, … }]`. Code reading `node.columns[i].accessorKey`
off a bridged node reads `field` instead; `header` becomes `label`. The bare
string shorthand `columns: ['name']` now maps to `{ field: 'name' }`.

**No label is invented any more.** `header: col.label ?? col.field` turned "the
author declared no label" into "the author declared the machine name", and that
synthesized value pre-empted `ObjectGrid`'s own header chain — the column's
label, then the **object field's** label, then the prettified machine name —
whose middle step exists so a localized field label wins on a non-English app.
A bridged view therefore rendered raw machine names where a directly authored
`object-grid` rendered the field's real label. A bare `{ field }` column now
reaches that chain intact.

Speaking the declared spelling also routes bridged views through the renderer's
full ListColumn path rather than its type-inference-only one: object-schema
field enrichment, `hidden` filtering, primary-field auto-linking, and per-column
`link` / `action` handling now apply to a bridged `ListView` exactly as they do
to an authored grid.
Loading
Loading