From 1066b1cdff37323a77b51533accaf6137b456dda Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Aug 2026 11:51:36 +0000 Subject: [PATCH] docs(plugin-form): state the field-level className rule as contract, not reader count (#5131) `packages/plugin-form/README.md`'s "Not a `FormField` key" table claimed a field-level `className` is "read on exactly one pseudo-field, `type: 'section-divider'`". That quantifier holds only for the renderer's explicit read; the same renderer forwards every key it did not destructure, so `className` rides the props spread onto whichever control the field resolves to and lands visibly on built-in controls. The cell now describes the contract (undeclared, promised nothing, honoured by a registered widget only if it spreads its leftover props) instead of counting readers, matching the wording the docs site already ships. The advice in the row is unchanged, and the explicit `section-divider` read is kept, now named as explicit. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012u2pRjcqAYtoEjgr3wwhnK --- ...n-form-readme-classname-quantifier-5131.md | 28 +++++++++++++++++++ packages/plugin-form/README.md | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .changeset/plugin-form-readme-classname-quantifier-5131.md diff --git a/.changeset/plugin-form-readme-classname-quantifier-5131.md b/.changeset/plugin-form-readme-classname-quantifier-5131.md new file mode 100644 index 000000000..112411d63 --- /dev/null +++ b/.changeset/plugin-form-readme-classname-quantifier-5131.md @@ -0,0 +1,28 @@ +--- +'@object-ui/plugin-form': patch +--- + +`README.md`'s "Not a `FormField` key" table said a field-level `className` is +"read on exactly one pseudo-field, `type: 'section-divider'`". That quantifier +holds only for the renderer's *explicit* read — `className={fp.className}` on +the `section-divider` branch of +`packages/components/src/renderers/form/form.tsx`. The same renderer forwards +every key it did not destructure, and `className` is not among the names taken +off the field config, not among the ones `stripRendererOnlyProps` removes, and +so rides `{...fieldProps}` into `renderFieldComponent`, whose built-in `input` +branch spreads it onto ``. A field-level `className` therefore lands +visibly on ordinary built-in controls, and a reader taking "exactly one" +literally concludes the opposite of what the code does (objectui#5131). + +The cell now describes the contract rather than the reader count: an undeclared +key still rides the props spread down to whichever component the field resolves +to, nothing in the contract promises that, and a registered widget honours it +only if it happens to spread its leftover props — the wording the docs site +already ships, so the two sources agree again. The advice in the row is +unchanged and was never wrong (`span` / `colSpan` for width, +`FormSchema.fieldContainerClass` for the grid), and the explicit +`section-divider` read is kept, now named as explicit. + +This is a documentation fix to a file `plugin-form` publishes to npm, which is +why it carries a version: the npm landing page only picks up the correction on a +release. No behaviour, export, type, or `dist` byte changes. diff --git a/packages/plugin-form/README.md b/packages/plugin-form/README.md index 1873030de..5d79d267a 100644 --- a/packages/plugin-form/README.md +++ b/packages/plugin-form/README.md @@ -224,7 +224,7 @@ here too. Two that a reader might expect, and that are **not** declared: | Not a `FormField` key | Write this instead | |---|---| | `defaultValue` | `FormSchema.defaultValues` at form level. An object-bound form seeds from the object field's own declared `defaultValue` — see [What a create form opens with](#what-a-create-form-opens-with) | -| `className` | `span` / `colSpan` for width, `FormSchema.fieldContainerClass` for the grid. (A field-level `className` is read on exactly one pseudo-field, `type: 'section-divider'`, where it styles the inline section header.) | +| `className` | `span` / `colSpan` for width, `FormSchema.fieldContainerClass` for the grid. (An undeclared key still rides the props spread down to whichever component the field resolves to, so a field-level `className` can visibly land on a built-in control — but nothing in the contract promises that, and a registered widget honours it only if it happens to spread its leftover props. The renderer reads it *explicitly* on exactly one pseudo-field, `type: 'section-divider'`, where it styles the inline section header.) | There is no `ValidationRule` type in this repo, under any spelling.