Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

Commit dbd1081

Browse files
fix(plugin-form): the top-level fields descriptions and the unresolved-member warning stop teaching { name } as tolerated (objectui#11550) (#11566)
Part of #11550 Clause-②: no The patch round of objectui#11550: the seat's decision A (comment `5970513384`) under triage ruling `5969880008` item 1, "the authoring faces stop teaching it". The card stays open after this merges: its governed guide PR objectui#11561 is still in flight, and the seat ends the card when both are in. ## What changes - `packages/plugin-form/src/index.tsx`: the `fields` input description of `object-form`, `view:form` and `embeddable-form` drops "; `{ name }` is tolerated" from "Bare field names to show, in order (each looked up in the object schema; …)". The `object-master-detail-form` one drops "(`{ name }` tolerated)" after "Members are bare field names". Every other sentence is unchanged. - `packages/plugin-form/src/sectionFields.ts`: the `warnUnresolvedTopLevelField` message drops "(`{ name }` is tolerated)". It still says "Top-level `fields` takes bare field-name strings", still names `sections[].fields` and `FormFieldSchema`, and still tells the author to use a bare field-name string or a `sections[].fields` entry. Its docblock now says the top level takes only bare field-name strings, and that a STORED `{ name }` entry still reads but is no authoring spelling. - `.changeset/11550-fields-tolerated-teaching-dropped.md`: `@object-ui/plugin-form` `patch`, because the text ships (measured in `dist/` below). - Not touched: the stored read (`SimpleObjectForm`'s `fieldsToShow` loop in `ObjectForm.tsx`, `buildFlatFields` in `flatFields.ts`), the section shape-3 entry, and `ObjectFormSchema`. ## Premise check, on `main` `072b7e8` - Re-grep of `is tolerated` and `tolerated)` over `packages/plugin-form/src`: 6 hits, exactly the claimed sites (three identical descriptions, the master-detail one, the warning, its docblock). After this change: 0 hits. - Repo-wide, no test, snapshot, README or docs page quotes either the description sentence or the warning sentence. The claim's lead "any test that pins that exact text" found none. The three warning pins (`objectFormFieldsMembers-8071`, `topLevelFieldsWarnCoverage-8847`, `flatFields.test.ts`) assert the substrings `{ field: 'note' }`, `sections[].fields`, `FormFieldSchema` and "top-level `fields`", and all four are kept. ## Verification, head `701ada6` - Build closure, `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-form^...' build`: 11 packages built, exit 0. - `pnpm exec vitest run --maxWorkers=2 packages/plugin-form/` (repo-root form): `Test Files 163 passed (163)`, `Tests 1889 passed, 1 skipped (1890)`. - `pnpm --filter @object-ui/plugin-form type-check`: exit 0, with the script name echoed. - `eslint .` in `packages/plugin-form` (the package's own `lint` script), JSON output: 203 files, 0 errors. The two edited files carry 22 and 10 warnings, the same counts as their `072b7e8` copies linted through stdin. The root config extends `tseslint.configs.recommended` and enables no type-aware linting, so this diff cannot move an untouched file's verdict. Repo-wide `pnpm lint` is CI's. - Shipped text: after `pnpm --filter @object-ui/plugin-form build`, no file in `dist/` contains `is tolerated`. The new warning sentence is in `dist/index.js` and `dist/index.umd.cjs`, and the new description sentence appears 3 times in `dist/index.js`. - Gates, all exit 0: `check:control-bytes` OK; `check:new-line-citations` 0 new; `check:pending-changeset-literals` OK; `check-changeset-presence` (2 source files of 1 released package, 1 changeset); `check-changeset-no-major`; `check-changeset-overwrite` (0 modified); `check-changeset-fixed`; `check:element-data-source-declaration`; `check-governed-queue-guard --test` answers NOT GOVERNED. - `check:changeset-claims` (report-only) asked for three pending paragraphs that name `sectionFields.ts` to be re-read. `9884-master-detail-fields-intersection.md` and `console-formpage-visible-predicates-5594.md` stay true. `8738-fields-warn-route1.md` stays true of the read but still says "`{ name }` tolerated": see the first acceptance note. ## Acceptance notes - `.changeset/8738-fields-warn-route1.md` is still pending, so it publishes into the same CHANGELOG release as this patch. It says "Top-level `fields` reads only bare field-name strings (`{ name }` tolerated)". That is still true of the runtime read, but it is the one remaining shipped text that calls `{ name }` tolerated. It is not edited here. It is a changeset this change does not own (`check-changeset-overwrite` reports exactly that kind of edit), and it is outside the claimed file surface. The seat decides. - `FlatFieldsContext.fields`' docblock in `flatFields.ts` still says "objects carrying one (`{ name }`)". It describes the kept read and is not exported; the seat already recorded it in `5970513384`. Not touched. - The console ledger row `object-form.fields` in `registry-inputs-spec-parity.test.ts` still calls the `{ name }` spelling "the read site's tolerance rather than a second contract". That is test prose about the pinned stored read, not an authoring face. Not touched. ## Left to CI Repo-wide `pnpm lint`, the `pnpm test` shards (the console suites included; `registry-inputs-spec-parity` only asserts each description is non-empty), e2e and the performance budget. Session: `https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2` --- _Generated by [Claude Code](https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent f624f27 commit dbd1081

3 files changed

Lines changed: 29 additions & 8 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
'@object-ui/plugin-form': patch
3+
---
4+
5+
The top-level `fields` input descriptions of `object-form`, `view:form`,
6+
`embeddable-form` and `object-master-detail-form`, and the `console.warn` a
7+
top-level `fields` member that resolves to no field name draws, no longer say
8+
that a `{ name }` object member "is tolerated" (objectui#11550). Each still says
9+
that the members are bare field names, and the warning still names the right
10+
spelling: a bare field-name string, or an entry in `sections[].fields`.
11+
12+
Write top-level `fields` members as bare field-name strings, for example
13+
`"fields": ["name", "email"]`. A per-field override (`colSpan`, a label) goes on
14+
a `sections[].fields` entry instead.
15+
16+
Behaviour is unchanged. A `{ name }` member already stored in a form view still
17+
reads at render, and the member that resolves to no name is still skipped with
18+
the same warning; only the wording that taught `{ name }` as an authoring
19+
spelling is gone.

‎packages/plugin-form/src/index.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ ComponentRegistry.register('object-form', ObjectFormRenderer, {
229229
category: 'plugin',
230230
inputs: [
231231
{ name: 'objectName', type: 'string', required: true },
232-
{ name: 'fields', type: 'array', description: 'Bare field names to show, in order (each looked up in the object schema; `{ name }` is tolerated). NOT the same vocabulary as `sections[].fields`, which also accepts the spec `FormFieldSchema` object (identity key `field`, e.g. `{ field: "note", colSpan: 2 }`) — that shape resolves to no name HERE and is silently skipped (SimpleObjectForm in ObjectForm.tsx; buildFlatFields in flatFields.ts for the drawer/modal presentations).' },
232+
{ name: 'fields', type: 'array', description: 'Bare field names to show, in order (each looked up in the object schema). NOT the same vocabulary as `sections[].fields`, which also accepts the spec `FormFieldSchema` object (identity key `field`, e.g. `{ field: "note", colSpan: 2 }`) — that shape resolves to no name HERE and is silently skipped (SimpleObjectForm in ObjectForm.tsx; buildFlatFields in flatFields.ts for the drawer/modal presentations).' },
233233
{ name: 'mode', type: 'enum', enum: ['create', 'edit', 'view'] },
234234
{ name: 'formType', type: 'enum', enum: ['simple', 'tabbed', 'wizard', 'split', 'drawer', 'modal'] },
235235
{ name: 'sections', type: 'array' },
@@ -338,7 +338,7 @@ ComponentRegistry.register('form', ObjectFormRenderer, {
338338
category: 'view',
339339
inputs: [
340340
{ name: 'objectName', type: 'string', required: true },
341-
{ name: 'fields', type: 'array', description: 'Bare field names to show, in order (each looked up in the object schema; `{ name }` is tolerated). NOT the same vocabulary as `sections[].fields`, which also accepts the spec `FormFieldSchema` object (identity key `field`, e.g. `{ field: "note", colSpan: 2 }`) — that shape resolves to no name HERE and is silently skipped (this renders through the same `ObjectFormRenderer` / `SimpleObjectForm` as `object-form` above — see its `fields` description).' },
341+
{ name: 'fields', type: 'array', description: 'Bare field names to show, in order (each looked up in the object schema). NOT the same vocabulary as `sections[].fields`, which also accepts the spec `FormFieldSchema` object (identity key `field`, e.g. `{ field: "note", colSpan: 2 }`) — that shape resolves to no name HERE and is silently skipped (this renders through the same `ObjectFormRenderer` / `SimpleObjectForm` as `object-form` above — see its `fields` description).' },
342342
{ name: 'mode', type: 'enum', enum: ['create', 'edit', 'view'] },
343343
]
344344
});
@@ -400,7 +400,7 @@ ComponentRegistry.register('embeddable-form', EmbeddableFormRenderer, {
400400
{ name: 'objectName', type: 'string', required: true },
401401
{ name: 'title', type: 'string' },
402402
{ name: 'description', type: 'string' },
403-
{ name: 'fields', type: 'array', description: 'Bare field names to show, in order (each looked up in the object schema; `{ name }` is tolerated). NOT the same vocabulary as `sections[].fields`, which also accepts the spec `FormFieldSchema` object (identity key `field`, e.g. `{ field: "note", colSpan: 2 }`) — that shape resolves to no name HERE and is silently skipped (`EmbeddableForm` passes this array straight through to `<ObjectForm>` with no `sections`, so it renders through the same `SimpleObjectForm` as `object-form` above — see its `fields` description).' },
403+
{ name: 'fields', type: 'array', description: 'Bare field names to show, in order (each looked up in the object schema). NOT the same vocabulary as `sections[].fields`, which also accepts the spec `FormFieldSchema` object (identity key `field`, e.g. `{ field: "note", colSpan: 2 }`) — that shape resolves to no name HERE and is silently skipped (`EmbeddableForm` passes this array straight through to `<ObjectForm>` with no `sections`, so it renders through the same `SimpleObjectForm` as `object-form` above — see its `fields` description).' },
404404
{ name: 'allowMultiple', type: 'boolean' },
405405
]
406406
});
@@ -491,7 +491,7 @@ ComponentRegistry.register('object-master-detail-form', MasterDetailFormRenderer
491491
// Declaring them would mint choices an authoring UI offers and this block
492492
// cannot honour.
493493
{ name: 'formType', type: 'enum', enum: ['simple', 'tabbed'], description: 'How the PARENT half of the form is presented. The detail grids below it are unaffected.' },
494-
{ name: 'fields', type: 'array', description: 'Which parent fields to show, in order — and it is NOT ignored when `sections` is given: the two INTERSECT. The parent field pool is built from this key first and every section then resolves its own members against that pool, so a section member this key does not list is dropped from the rendered form, and a section that loses EVERY member that way disappears with its heading. Each such drop is reported once via `console.warn` (objectui#9884); it is not repaired, because this key bounds what the form DRAWS and edits, not what Save writes: on a create, the submitted set is the drawn fields plus any parent value seeded through `initialValues` (or its alternate spelling `initialData`), drawn or not. A seed for an undeclared, server-owned, computed or read-only field is still stripped, as on any save. Author one or the other, or list every section member here too. Members are bare field names (`{ name }` tolerated); NOT the spec `FormFieldSchema` object `sections[].fields` accepts (identity key `field`) — that shape resolves to no name here and is silently skipped (the parent form renders through the same `ObjectForm` / `SimpleObjectForm` as `object-form` — see its `fields` description).' },
494+
{ name: 'fields', type: 'array', description: 'Which parent fields to show, in order — and it is NOT ignored when `sections` is given: the two INTERSECT. The parent field pool is built from this key first and every section then resolves its own members against that pool, so a section member this key does not list is dropped from the rendered form, and a section that loses EVERY member that way disappears with its heading. Each such drop is reported once via `console.warn` (objectui#9884); it is not repaired, because this key bounds what the form DRAWS and edits, not what Save writes: on a create, the submitted set is the drawn fields plus any parent value seeded through `initialValues` (or its alternate spelling `initialData`), drawn or not. A seed for an undeclared, server-owned, computed or read-only field is still stripped, as on any save. Author one or the other, or list every section member here too. Members are bare field names; NOT the spec `FormFieldSchema` object `sections[].fields` accepts (identity key `field`) — that shape resolves to no name here and is silently skipped (the parent form renders through the same `ObjectForm` / `SimpleObjectForm` as `object-form` — see its `fields` description).' },
495495
// The three labels are the spec's `I18nLabel` (`ComponentPropsMap
496496
// ['object-master-detail-form']`), and `MasterDetailForm` resolves a map
497497
// with `pickLocalized` against the active UI language (objectui#10935). So

‎packages/plugin-form/src/sectionFields.ts‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,11 @@ function warnOnMixedVocabulary(fd: Record<string, any>, objectName: string): voi
186186
* `field`, normalized by `normalizeSectionField` above. TOP-LEVEL `fields` —
187187
* `SimpleObjectForm`'s `fieldsToShow` loop in `ObjectForm.tsx`, and
188188
* `buildFlatFields` below in `flatFields.ts` for the drawer/modal
189-
* presentations — does NOT: it reads only bare field-name strings (`{ name }`
190-
* tolerated). The exact same `{ field: 'x', ... }` object `normalizeSectionField`
191-
* treats as canonical resolves to no `name` at the top level, and both read
189+
* presentations — does NOT: it takes only bare field-name strings. (A STORED
190+
* `{ name }` entry still reads, but it is no authoring spelling and neither
191+
* this warning nor the registrations teach it: objectui#11550.) The exact same
192+
* `{ field: 'x', ... }` object `normalizeSectionField` treats as canonical
193+
* resolves to no `name` at the top level, and both read
192194
* sites used to drop it in total silence — no throw, no warning, no
193195
* empty-state. This is the same voice and the same once-per-occurrence
194196
* discipline as `warnOnMixedVocabulary`, for the sibling mistake where a
@@ -209,7 +211,7 @@ export function warnUnresolvedTopLevelField(entry: unknown, objectName: string):
209211
warnedUnresolvedTopLevelField.add(key);
210212
console.warn(
211213
`[object-ui] top-level \`fields\` entry ${shape} resolved to no field name and was skipped. ` +
212-
`Top-level \`fields\` takes bare field-name strings (\`{ name }\` is tolerated) — it is NOT the ` +
214+
`Top-level \`fields\` takes bare field-name strings — it is NOT the ` +
213215
`same vocabulary as \`sections[].fields\`, which also accepts the spec \`FormFieldSchema\` object ` +
214216
`(identity key \`field\`, e.g. \`{ field: 'note', colSpan: 2 }\`). That shape has no \`name\` here ` +
215217
`and is silently dropped; use a bare field-name string, or move the entry into a ` +

0 commit comments

Comments
 (0)