Uh oh!
There was an error while loading. Please reload this page.
fix(components): the static table renderer reads only the declared TableColumn contract, and §TableSchema is corrected to match - #5475
Merged
Conversation
…ontract Retire the undeclared `col.label` header alias and `col.name` accessor alias in renderers/complex/table.tsx, the fourth site of the column-alias family, and correct content/docs/api/schema-reference.md TableSchema to publish the declared `header`/`accessorKey` spelling it contradicted. Family ruling recorded on objectui#5120 (2026-08-20). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
os-support-ai
marked this pull request as ready for review
August 21, 2026 01:59
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#5350
The static
tablerenderer was the fourth site of the undeclared column-alias family. It resolved a heading ascol.header || col.labeland a cell asrow[col.accessorKey || col.name], whilepackages/types/src/data-display.tsdeclaresTableColumnwith requiredheaderandaccessorKeyand neither alias. Both aliases are retired here, and the published reference page that contradicted the type is corrected in the same PR.The ruling this applies, verbatim
Recorded on #5120, 2026-08-20 — maintainer accepted the batch verbatim: 「其他接受你的建议。」
Triage's unlock note on #5350 applies the same words to this card: "
packages/types' declared contract stands;schema-reference.md§TableSchema corrects to match."Both halves, one PR
This site is not a mechanical follow-on of its three siblings, and that is the whole point: the alias here was not merely tolerated, it was published. §TableSchema shipped a copyable
{ "name": "id", "label": "#" }example plus a property row reading "Column definitions withname,label, …". Retiring the alias without correcting the page would have converted a documented, working example into a silently broken one.packages/components/src/renderers/complex/table.tsx—col.header || col.labelbecomescol.header;row[col.accessorKey || col.name]becomesrow[col.accessorKey].content/docs/api/schema-reference.md§TableSchema — the example authorsaccessorKey/header; the property row states the declared contract.Per-shape before/after, measured by rendering
Measured with a temporary probe that renders each shape through
SchemaRendererand reads back the actualthead/tbodytext, run on both legs. Row data is{ name: 'Ada', role: 'Engineer' }. The probe was removed before commit; the same shapes are pinned permanently intable-column-contract.test.tsx.{ accessorKey }""Ada""Ada{ name }""Ada""""{ header, accessorKey }NameAdaNameAda{ label, accessorKey }NameAda""Ada{ name, label }— the retired docs spellingNameAda""""{ label, accessorKey }— the skills-guide spellingNameAda""AdaThe two shapes that move nothing are exactly the two spelled the declared way. Legibility of a now-unresolvable column, pinned as measured behaviour rather than endorsed: the column keeps its slot, neighbours are unaffected, nothing throws, and because this renderer keys cells by index rather than by accessor it does not even emit React's generic missing-key warning that
data-tableproduces. It is fully silent. Whether that should become a diagnostic is #5349's question; none is implemented here.Census, with its counter-probe
Question: every authored
type: "table"column using thename/labelspelling, across docs, skills, examples, fixtures, catalogs, apps, e2e and package READMEs.Two independent methods over the same corpus (4174 files:
content/docs,skills,examples,apps,e2e,packages):type: "table"occurrences repo-wide, then read each one'scolumns.columns:array in the corpus (194 found), classify each by spelling and by the nearest enclosingtype.Both agree. Exactly four
columnsarrays sit on atype: "table"node and carrynameorlabel:content/docs/api/schema-reference.md:402§TableSchemaskills/objectui/guides/schema-expressions.md:500content/docs/api/schema-reference.md:1131§DetailViewSchemarelated[]content/docs/core/report-schema.mdx:327The two exclusions are textual near-misses on a different declared contract, and both were checked by reading the render path rather than the spelling:
related[]is a related-list descriptor (api-backed).DetailView.tsx:1526-1533forwardsrelated.columnsinto a RelatedList component, never the component-registrytablekey.packages/plugin-detail/README.mdauthors the same array as bare strings.report-schema.mdx:327is a report section, rendered byReportViewer.tsx:345, which emits its own markup readingcol.label || col.nameagainstReportField— andpackages/types/src/reports.ts:57-66declaresnameandlabelonReportField. It is correctly spelled for its own contract. This refines the premise in finding(components): the statictablerenderer is a fourth site of the undeclared column-alias family, and its published docs declarename/labelasTableColumnwhilepackages/typesdeclaresheader/accessorKey#5350's body, which cited it as evidence of the same defect; it is not.Counter-probe. The zero-beyond-the-known-docs claim is only meaningful if the same method can see the spelling that is present, so the run reports both buckets. Method 2 found 39 column arrays spelled the declared
header/accessorKeyway in the same pass, six of them ontype: "table"nodes:apps/site/app/playground/page.tsx:751,examples/schema-catalog/src/schemas/components-complex-table/basic-table.json:3,packages/plugin-dashboard/README.md:496,packages/types/examples/data-display-examples.json:70,packages/plugin-dashboard/src/__tests__/StaticTableWidget.test.tsx:131, and this renderer's owndefaultProps. So the method demonstrably findstable-enclosed column arrays and reads their spelling correctly, and the alias bucket was non-empty in the same run.e2e/holds notype: "table"node at all; the catalog holds exactly one, already declared-spelled.Blast radius — reported, not migrated
skills/objectui/guides/schema-expressions.mddepends on both retired aliases: its prose at L493 documents the accessor fallback as contract ("accessorKey, falling back toname"), and its worked example at L500 authors{ "label": "Name", "accessorKey": "name" }, which renders an empty heading after this change.skills/**is a governed, customer-published surface outside this card's declared file surface, so it is filed as #5473 rather than silently migrated. Sequencing is triage's call.Scope fences held
data-table.tsx,ObjectDataTable.tsx,ObjectGrid.tsxand theobject-griddoc examples — finding(components/plugin-dashboard): data-table 的访问键归一化读一个自身类型未声明的col.name别名,而唯一在交付前解析列身份的生产者只有 RelatedList #5120+finding(components): data-table's column normalization also reads an undeclaredcol.labelalias forheader— the sibling alias on the same two lines ascol.name#5351 is in flight on those.type: "crud"examples in the same file spellname/labeltoo and are not touched. Checked againsttype: 'crud'has four declaration faces and no renderer —api/schema-reference.mddocuments it as reference material, so a reader who copies it gets OBJUI-001 #5373 before deciding, as instructed: its maintainer ruling (2026-08-20) is "retireCRUDSchemaunder ADR-0049 enforce-or-remove … delete all four declaration faces, rewriteapi/schema-reference.mdaround shapes that render". That section is scheduled for deletion, not re-spelling, andcrudhas no renderer at all — so re-spelling its columns would be work that gets deleted and a collision in the one file both cards edit. Left alone deliberately.One bounded in-place fix, named rather than slipped in
The §TableSchema property row also advertised a
renderproperty.TableColumnhas never declared one — the renderer hook iscell(data-display.ts:277). Correctingname/labelin that sentence while leavingrenderstanding would have republished a false claim in a line already being rewritten, so the row now states only what is both declared and honoured here:accessorKey,header,width,className,cellClassName. For the same reason"align": "right"is dropped from the example —alignis declared onTableColumn, but this renderer never reads it, so keeping it would have contradicted the corrected sentence one line below.alignis not alone in that, and the broader gap is not fixed here: 11 of the 20 keysTableSchema/TableColumndeclare are inert on this renderer, includinghoverableandstriped, which the page documents as working and which the example still sets. That is an ADR-0049 enforce-or-remove decision rather than a re-spelling, so it is filed as #5474 and the example keeps them.Finally, the two
columns.mapcallbacks are typedTableColumninstead ofany, so reintroducing an undeclared alias on this renderer is now a type error rather than a reviewer's catch.Verification
All at final commit
455bbec9c, the tree this PR ships.packages/components/src/renderers/complex/__tests__/table-column-contract.test.tsx— 5 tests, all passing.pnpm exec vitest run packages/components --maxWorkers=2->Test Files 172 passed (172) / Tests 1565 passed (1565).shadowed-renderer-behaviour.test.tsxauthors its columns the declared way and stays green — behaviour the retirement must not move, and does not.pnpm --filter @object-ui/components type-check-> exit 0, afterpnpm build(43/43 tasks). The run echoestsc --noEmit && tsc -p tsconfig.test.json, so this is a real pass and not a zero-match filter exiting 0.check-control-bytesOK (4526 files),check-doc-component-typesOK,check-doc-linksOK,check-changeset-presence/check-changeset-no-major/check-changeset-fixedOK, andcheck-doc-snippet-typesOK — "Semantic phase: 88 of 88 block(s) judged, 0 failed" (it hard-fails on an unbuilt workspace, so the build above is a precondition, not an optimisation).Reverse verification
Prediction was recorded before the run. No build artifact sits between the edit and the test:
vitest.config.mts:264aliases@object-ui/componentstopackages/components/src, so both legs transform source and neither leg needs a rebuild — checked, not assumed.Ablating the fix (
git checkout origin/main -- table.tsx, tests kept) was predicted to flipname-only cells back toAda,label-bearing headers back toName, and to turn exactly 3 of the 5 new tests red — the three alias assertions — leaving the declared-spelling test and the legibility test green, since the latter asserts only slot counts and its neighbour column.Observed:
Tests 3 failed | 3 passed (6)(6 = 5 contract tests + the probe), the three failures being preciselydoes NOT resolve a cell through the retired name alias,does NOT resolve a header through the retired label alias, andrenders nothing for a fully alias-spelled column. Every shape in the matrix flipped as predicted. Predicted and observed match exactly.The tree was then restored with
git checkout HEAD -- table.tsxand proven clean:git status --shortempty,git diff --stat HEADempty, and both retired lines confirmed back to their post-fix bytes.Changeset
.changeset/table-renderer-declared-column-contract-5350.md,@object-ui/components: minor— declared as the behaviour change it is, including the silent failure mode of a retired-spelling column.Generated by Claude Code