feat(plugin-form): derive the inline grid default columns through the spec rule deriveInlineGridColumns (objectui#11345) - #11623
Merged
objectstack-fleet[bot] merged 4 commits intoOct 4, 2026
Conversation
…he spec's deriveInlineGridColumns (objectui#11345) `deriveColumns` now takes which columns an inline master-detail grid draws, their order and their `defaultHidden` flag from `@objectstack/spec`'s `deriveInlineGridColumns`, and builds each column from its child field with the per-column builder it already had (extracted as `deriveColumn`). The local budget (`curateColumns`, `NAME_LIKE_FIELDS`, `TYPE_FILL_PRIORITY`), the local column filter (`NON_EDITABLE_TYPES`) and the module's own `DEFAULT_MAX_INLINE_COLUMNS = 6` are deleted; the budget is the spec's `DEFAULT_MAX_INLINE_GRID_COLUMNS`. Signature and output of the public `deriveColumns` are unchanged. A new pin holds a corpus to both answers: the spec's names / order / defaultHidden, and the full output the replaced implementation returned. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL
`@object-ui/plugin-form`'s published `dist/index.js` now imports `deriveInlineGridColumns` and `DEFAULT_MAX_INLINE_GRID_COLUMNS` from `@objectstack/spec/data`, which the spec first exports in 17.6.0. The declared `^17.0.0` admitted 17.0.0 to 17.5.x, none of which carries either name. `pnpm-lock.yaml` follows the specifier; the resolved version (17.6.0) does not move. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL
…columns (objectui#11345) Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL
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
|
objectstack-fleet
Bot
deleted the
claude/issue-11345-derive-inline-grid-columns
branch
October 4, 2026 18:39
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 free
to 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 #11345
Clause-②: no
What this PR is
deriveColumns, the default columns of a master-detail inline grid whose author listed none, now takes which columns it draws, their order and theirdefaultHiddenflag from@objectstack/spec'sderiveInlineGridColumns, and its visible budget from the spec'sDEFAULT_MAX_INLINE_GRID_COLUMNS. objectui's own per-column builder stays over the returned names (extracted asderiveColumn), so each column's label, cell type, options, lookup target, conditional rules and computed expression are built exactly as before, including the plain text column for a falsy field definition.Deleted from
packages/plugin-form/src/deriveMasterDetail.ts:curateColumns,NAME_LIKE_FIELDS,TYPE_FILL_PRIORITY,fillPriority,NON_EDITABLE_TYPES, and the module-levelDEFAULT_MAX_INLINE_COLUMNS = 6, which the package entry never re-exported.SYSTEM_FIELDSandSORT_FIELD_NAMESstay, becausederiveFormFieldsand the sort-field pick inderiveDetailstill read them.The direction is triage's first grade (comment 5926478449): names and
defaultHiddenfrom the spec, objectui's builder over the names, the budget imported asDEFAULT_MAX_INLINE_GRID_COLUMNS, no second6.The fence
deriveColumnskeeps its signature, and its output is unchanged on every input the evidence below reached.@object-ui/*package. The one declaration-file change is the module-levelDEFAULT_MAX_INLINE_COLUMNSleavingdist/deriveMasterDetail.d.ts. The package entrysrc/index.tsxnever re-exported it, and the packageexportsmap exposes only..Landing site, and one addition to the claimed file surface
The landing site is the dispatched one:
packages/plugin-form/src/deriveMasterDetail.tsand a test beside it.packages/plugin-form/package.json(@objectstack/specgoes from^17.0.0to^17.6.0) and the one matching specifier line inpnpm-lock.yaml. The resolved version stays 17.6.0. They are in commit399fc03, kept separate so it can be judged on its own. The reason: the publisheddist/index.jsnow importsderiveInlineGridColumnsandDEFAULT_MAX_INLINE_GRID_COLUMNSfrom@objectstack/spec/data. The old floor admitted 17.0.0 to 17.5.x, which carry neither name, so a consumer that resolves one of those versions could not link the entry. PR #11552 and PR #11555 raised floors the same way, with the lockfile specifier.Evidence (head
fe06e31, after merging mainc096f03)The pin.
deriveMasterDetail.inlineGridColumns-11345.test.tsholds one 14-entry corpus to two answers:defaultHiddenequal (toStrictEqual) the spec'sderiveInlineGridColumnsanswer;toStrictEqual) the arrays the replaced implementation returned. These were generated fromderiveColumnsat6e9090c.The corpus covers both sides of the budget edge,
maxColumns3, 0 and -1,excludewith and without a relationship field, the filters, more required columns than the budget, a computed required column, falsy definitions, and four shapes with no field map. One more test checks that an omittedmaxColumnsleaves exactlyDEFAULT_MAX_INLINE_GRID_COLUMNScolumns visible.Ablations on committed code (
b879c7c). Each ran through objectstack'sscripts/ablation-replace.mjs. In each, the anchor went from 1 hit to 0, the blob changed, and the restore was proven (blob equals HEAD,git diff HEADempty).defaultHiddencarry. Predicted 13 red. ObservedTests 13 failed | 16 passed (29).{ name }, the hydrate route the card warns about. Predicted 1 red (pin 2, falsy entry). ObservedTests 1 failed | 28 passed (29).One-off differential. Not committed; a historical reading at
fe06e31. It comparesderiveColumnsat BASE (6e9090c) with this branch over 80,014 cases: the 14 corpus entries, 50,000 random cases and 30,000 budget-heavy ones.relationshipField,excludeandmaxColumns, including NaN and Infinity.util.inspectrendering (so key order and undefined-valued keys count) plus deep equality.hydrateColumns, gives 68,522 mismatches on the same cases, so the instrument can fire.Floor. This is objectui's
scripts/check-spec-range-floors.mjsverdict (itsanalyze()), scoped to@object-ui/plugin-formover its built dist:^17.0.0: red,floor-too-lowon exactlyDEFAULT_MAX_INLINE_GRID_COLUMNSandderiveInlineGridColumns;^17.5.0(in memory): red, on the same two names;^17.6.0: green.pnpm exec vitest run packages/plugin-form/Test Files 164 passed (164),Tests 1918 passed / 1 skipped (1919)pnpm --filter @object-ui/plugin-form type-check, afterturbo run build --filter=@object-ui/plugin-form. Bothtsclegs ran, and--listFilesshows the test program reads the new pinpnpm --filter @object-ui/plugin-form lintcheck:spec-symbols,check:phantom-deps,check:unused-deps,check:lockfile-integrity,check:lockfile-dedupe,check:new-line-citations,check:control-bytes,check:test-path-roots,check:unreferenced-sources,check:installed-pin-claims,check:pending-changeset-literals,check:changeset-claims,check:esm-specifiers,check:self-import,check:vi-mock-specifiersscripts/check-changeset-presence.mjs,scripts/check-changeset-no-major.mjsscripts/check-governed-queue-guard.mjs --testover the five changed pathsNOT MEASURED locally. These need every published package built, and CI or the release path runs them:
check:spec-floors(the scoped verdict above stands in);check:readme-exports(refused here with 24 packages unbuilt; this diff touches no README and no export);check:dist-completeness,check:node-esm-loadandcheck:published-dist;pnpm lintandpnpm test.Measured answers to the dispatch's open points
@objectstack/spec17.6.0dist/datadeclaresDEFAULT_MAX_INLINE_GRID_COLUMNS = 6and exportsderiveInlineGridColumns. 17.5.0 lacks both, as the scoped floor verdict shows.be5211522412. The differential above was taken on this base, after PR feat(types,plugin-form,plugin-charts,app-shell)!: dashboard widgets bind a dataset in the catalog and docs; FormulaFieldMetadata takes the spec's expression; three display-pointer readers read displayField alone (objectui#11070, round 6) #11333 and PR feat(types)!: a form view'ssubforms[].columnsentry is the spec'sInlineGridColumnSchema, by reference (objectui#11266) #11618.deriveMasterDetail.tsreadDEFAULT_MAX_INLINE_COLUMNS.6exists: themaxColumns = 6default ofRelatedListinpackages/plugin-detail. That is a different budget: a related-list card that slices columns away, not an inline grid that collapses them into a chooser. It is left as is.GridField's doc comment namesderiveColumnsand gives no number. No docs page states the budget.Acceptance notes
SYSTEM_FIELDSandSORT_FIELD_NAMES(used by the row form and the sort-field pick) hold the same names as the spec's module-privateINLINE_GRID_SYSTEM_FIELDSandINLINE_GRID_SORT_FIELDS, which@objectstack/spec/datadoes not export. This is an observation only: the row-form rule is not spec-owned, and nothing here judges it. Carrier: none.Changeset
.changeset/11345-inline-grid-columns-spec-rule.mddeclares@object-ui/plugin-formpatchand includes the floor sentence.Session:
https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL(os-dev, dispatched by thedomain:uiseat 1).Generated by Claude Code