From 1dd672dc6369865dd833ccc632292be153c88339 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 01:15:12 +0000 Subject: [PATCH 1/3] fix(types,components,docs): correct the texts objectui#6771 left false about `body` (objectui#8284) objectui#6771 retired `body` as a child-list spelling; `children` is the one child-list key and `BaseSchema` refuses `body` by name. Several texts still described the two-channel world. Prose and strings only: no key, value, refusal behaviour or rendered result moves. - The nine `aliasKeyRefusal('body', 'children', ...)` detail strings on box, span, container, flex, stack, grid, scroll-area, form and toggle no longer say `body` "is inherited from BaseSchema, so an authored body parsed green here"; they say it is the retired spelling, refused by name. - A dated note on the pending 8284 changeset corrects its two-channel sentence and the alert / badge / tooltip row that objectui#6771 inverted. - The header of content-channel-per-component-8284.test.ts describes what the file pins today; the test code is byte-identical. - card.tsx's JSX comment no longer describes a `children || body` alias. - div.mdx and page.mdx interface blocks teach `children` only; div.mdx's callout and caveat, the DIV_DEPRECATION_NOTICE body bullet and the docblock above it no longer say `card` reads `body`. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk --- .../8284-content-channel-per-component.md | 13 ++++ .changeset/8284-refusal-and-notice-text.md | 20 ++++++ content/docs/components/basic/div.mdx | 16 ++--- content/docs/components/layout/page.mdx | 3 +- .../components/src/renderers/basic/div.tsx | 7 +- .../components/src/renderers/layout/card.tsx | 17 +++-- ...content-channel-per-component-8284.test.ts | 65 +++++++++++-------- packages/types/src/zod/form.zod.ts | 8 +-- packages/types/src/zod/layout.zod.ts | 28 ++++---- 9 files changed, 113 insertions(+), 64 deletions(-) create mode 100644 .changeset/8284-refusal-and-notice-text.md diff --git a/.changeset/8284-content-channel-per-component.md b/.changeset/8284-content-channel-per-component.md index 95b655bc81..1859ec7f9d 100644 --- a/.changeset/8284-content-channel-per-component.md +++ b/.changeset/8284-content-channel-per-component.md @@ -27,6 +27,19 @@ that names the channel to write instead: | `children` | `box`, `span`, `container`, `flex`, `stack`, `grid`, `scroll-area`, `form`, `toggle` | `body` | | `body` (at the time of this change; objectui#6771 has since retired that spelling and these three read `children`) | `alert`, `badge`, `tooltip` (which reads `content` first, the child list as its fallback) | the other channel | +⚠️ **Dated note, 2026-09-28 — `BaseSchema` declares one content channel, and the +`alert` / `badge` / `tooltip` row is inverted at release — objectui#6771.** Later in this same +release objectui#6771 retired `body` as a child-list spelling: `BaseSchema.body` is `never` on +the TypeScript face and refused by name on the zod mirror, and `children` is the one +child-list key. So the paragraph that opens "`BaseSchema` declares two optional content +channels" no longer describes `BaseSchema`, and for all twelve components in the table the +renderer reads `children` and the refused channel is `body`. That includes `alert`, `badge` +and `tooltip`, which accept `children` and refuse `body`, not the other way round. For those +three the Migration paragraph below does not hold as written: in the previous release their +renderers drew an authored `body`, and this release refuses it. objectui#6771's entry states +that migration: author `children`. The rest of this entry is kept as the reading of this +change. + Which channel each renderer reads was measured with the TypeScript type checker over every `ComponentRegistry.register(...)` call in `packages/components` — a read site is a property access filed under the type of the object it is read from, so a docblock mention diff --git a/.changeset/8284-refusal-and-notice-text.md b/.changeset/8284-refusal-and-notice-text.md new file mode 100644 index 0000000000..c80300dd3d --- /dev/null +++ b/.changeset/8284-refusal-and-notice-text.md @@ -0,0 +1,20 @@ +--- +'@object-ui/types': patch +'@object-ui/components': patch +--- + +Correct author-facing text that objectui#6771's retirement of the `body` child-list spelling +left false (objectui#8284). Only wording moves; no key, value or rendered result does. + +- `@object-ui/types` — the `body` refusal on `box`, `span`, `container`, `flex`, `stack`, + `grid`, `scroll-area`, `form` and `toggle` explained that `body` "is inherited from + `BaseSchema`, so an authored `body` parsed green here". Since objectui#6771, `BaseSchema` + refuses `body` by name itself, so that explanation no longer holds. The message now says + that `body` is the child-list spelling objectui#6771 retired, refused by name, and that + `children` is the one child-list key. The refused key, the replacement it names, the issue + code and the issue path are unchanged; the same string is still the `.describe()` metadata. +- `@object-ui/components` — the `div` deprecation notice said that every replacement except + `card` reads `children` only, so a blind retype drops `body` content. Since objectui#6771, + `card` and `div` itself read `children` only as well. The notice now says that validation + refuses `body` by name and that neither `div` nor any replacement draws it. The replacements + it offers are unchanged. diff --git a/content/docs/components/basic/div.mdx b/content/docs/components/basic/div.mdx index 54cfc1aeed..808f5f4374 100644 --- a/content/docs/components/basic/div.mdx +++ b/content/docs/components/basic/div.mdx @@ -13,9 +13,9 @@ description: "Generic container element - use Shadcn components instead"
  • When you want their layout: use card, flex, container, stack, or grid — each injects classes of its own, and card also moves children into an extra element
  • - Move any content authored under the legacy body key into children first: every - replacement listed above except card reads children only, so a blind retype drops - that content silently, at an unchanged element count. + Move any content authored under the retired body key into children first: + objectui#6771 retired that child-list spelling, so validation refuses it by name, and neither + div nor any replacement listed above draws it.

    @@ -47,9 +47,10 @@ the page; a `div` → `box` swap does not. One caveat for a node still authored in the retired `body` spelling: every option reads `children` and never `body` (objectui#6771 retired it across the -protocol, `card` included). Such a node must move that content into `children` -as part of the swap, or it disappears from the page without changing the element -count — silently. +protocol, `card` included), and so does `div` itself. Such a node must move that +content into `children` as part of the swap. Until it does, validation refuses +the key by name, and the content is missing from the page under `div` and under +every replacement alike. ### For a Plain Wrapper → Use `box` @@ -83,8 +84,7 @@ interface DivSchema { type: 'div'; // Content - children?: SchemaNode | SchemaNode[]; // Child components - body?: SchemaNode[]; // Alternative content prop + children?: SchemaNode | SchemaNode[]; // Child components (the child key this component reads) // Styling className?: string; // Tailwind CSS classes diff --git a/content/docs/components/layout/page.mdx b/content/docs/components/layout/page.mdx index 94c6c34f97..6c20db41a3 100644 --- a/content/docs/components/layout/page.mdx +++ b/content/docs/components/layout/page.mdx @@ -25,8 +25,7 @@ interface PageSchema { description?: string; // Page description // Content - body?: SchemaNode | SchemaNode[]; // Main content — one node or a list - children?: SchemaNode | SchemaNode[]; // Alternative content prop + children?: SchemaNode | SchemaNode[]; // Main content — one node or a list // Styling className?: string; // Tailwind CSS classes diff --git a/packages/components/src/renderers/basic/div.tsx b/packages/components/src/renderers/basic/div.tsx index 6f2443f32f..a5587e5b79 100644 --- a/packages/components/src/renderers/basic/div.tsx +++ b/packages/components/src/renderers/basic/div.tsx @@ -80,7 +80,10 @@ function warnDeprecatedOnce(type: string, message: string): void { * and four of those five — `flex`, `container`, `stack`, `grid` — read * `children` ONLY, so a node that authored `body` loses its content SILENTLY, * at an unchanged element count. `box` is the one class-transparent swap, and - * the old text never named it. + * the old text never named it. (That was the measurement at the time. Since + * objectui#6771 retired the `body` spelling, `card` and `div` itself read + * `children` only as well, so `body` content is drawn by none of them and the + * notice's `body` bullet says so.) * * That is why this is worth a re-ruling rather than a nice-to-have. Deprecation * guidance is followed LITERALLY, by humans and by generating models reading @@ -116,7 +119,7 @@ const DIV_DEPRECATION_NOTICE = '[ObjectUI] The "div" component is deprecated on every authoring surface. Please use Shadcn components instead:\n' + ' - For a plain wrapper the drop-in swap is "box": same element, your `className` verbatim, no layout of its own.\n' + ' - Reach for "card", "flex", "container", "stack", or "grid" only when you want their layout — each injects classes of its own, and "card" also moves children into an extra element.\n' + - ' - Move any `body` content into `children` first: every replacement above except "card" reads `children` only, so a blind retype drops it silently at an unchanged element count.\n' + + ' - Move any `body` content into `children` first: `body` is the child-list spelling objectui#6771 retired, so validation refuses it by name, and neither this component nor any replacement above draws it.\n' + ' This applies to JSON-authored nodes and to kind:\'html\' pages alike: an html page refuses the\n' + ' tag when it compiles, naming the same replacement.\n' + 'See documentation at https://www.objectui.org/docs/components for alternatives.'; diff --git a/packages/components/src/renderers/layout/card.tsx b/packages/components/src/renderers/layout/card.tsx index d427e62d4a..2d0a0df624 100644 --- a/packages/components/src/renderers/layout/card.tsx +++ b/packages/components/src/renderers/layout/card.tsx @@ -62,13 +62,16 @@ const CardRenderer = forwardRef )} - {/* `||` here is ALIAS RESOLUTION — `body` is the legacy spelling of - `children` — and ⛔ it is no longer the guard. That distinction is - the whole point: `children: 0` used to be converted away by the - accident of `0 || undefined === undefined`, which protected nothing, - because the sibling `body: 0` went through `undefined || 0 === 0` - and leaked. `renderNodeSlot` covers both; the alias order is - unchanged. */} + {/* `children` is the one child-list key: this slot used to read + `schema.children || schema.body`, and objectui#6771 dropped the + `body` arm when it retired that spelling (the callback's `body` + below is only a local name for the slot's content). ⛔ No `||` is + the guard here. That distinction was the point of objectui#9162: + `children: 0` used to be converted away by the accident of + `0 || undefined === undefined`, which protected nothing, because + the sibling `body: 0` went through `undefined || 0 === 0` and + leaked. `renderNodeSlot` is the guard, so an empty slot, `0` + included, renders no `CardContent` at all. */} {renderNodeSlot(schema.children, (body) => ( {renderChildren(body)} ))} diff --git a/packages/types/src/__tests__/content-channel-per-component-8284.test.ts b/packages/types/src/__tests__/content-channel-per-component-8284.test.ts index da736bba6c..f80ad850a2 100644 --- a/packages/types/src/__tests__/content-channel-per-component-8284.test.ts +++ b/packages/types/src/__tests__/content-channel-per-component-8284.test.ts @@ -7,37 +7,45 @@ */ /** - * objectui#8284 — the `body` / `children` duality on `BaseSchema` is resolved - * PER COMPONENT: each component schema narrows to the channel its renderer - * actually reads and TOMBSTONES the other, on both published faces + * objectui#8284 — each component schema narrows to the content channel its + * renderer actually reads and TOMBSTONES the other, on both published faces * (maintainer ruling, summon #17 decision batch #2, 2026-09-07, verbatim - * 「同意」). + * 「同意」). This file pins that rule on the twelve dedicated declarations + * listed in `ROWS`. * * ## The defect this pins closed * - * `BaseSchema` declares TWO optional content channels and its own docblock - * admits that "some components use `children` instead of `body`" WITHOUT - * saying which. The zod base is `.passthrough()` and both keys are optional, + * `BaseSchema` used to declare TWO optional content channels, and its docblock + * admitted that "some components use `children` instead of `body`" WITHOUT + * saying which. The zod base is `.passthrough()` and both keys were optional, * so a node carrying the WRONG channel type-checked, parsed green, was * PRESERVED by the parse, and then rendered an EMPTY element — no error at * authoring time, none at validation time, none at render time. Seven cards * repaired one page of that each (#5027 · #3900 · #6773 · #6806 · #8197 · * #8234 · #6939) before the declaration itself was named. * + * objectui#6771 has since retired `body` as a child-list spelling on every + * node: `BaseSchema.body` is `never` on the TypeScript face and refused by name + * on the zod mirror, and `children` is the one child-list key. So on every row + * below the renderer reads `children` and the refused channel is `body`. What + * this file still pins is objectui#8284's own refusal on each row's DEDICATED + * declaration: it is installed there, it names both keys and this card, it is + * the `.describe()` metadata too, and it reaches a nested node. + * * ## The population here is FAMILY A + B of the measured table, not "all" * * The table posted on objectui#8284 is derived from every * `ComponentRegistry.register(...)` call under - * `packages/components/src/renderers/**` (114 registrations) and the read side - * is measured with the TypeScript TYPE CHECKER — each `body` / `children` - * property access is filed under the TYPE of the object it is read from, so a - * docblock mention cannot score. + * `packages/components/src/renderers/**` (114 registrations when it was taken) + * and the read side is measured with the TypeScript TYPE CHECKER — each + * `body` / `children` property access is filed under the TYPE of the object it + * is read from, so a docblock mention cannot score. * * ⚠️ THE CONTROL MOVED, because objectui#6771 SPENT the one that stood here. * It read: the `BoxSchema` docblock in `renderers/layout/box.tsx` SAYS * `schema.body` in prose and `grep -l` counts it, the checker does not — and - * the card's own `17 / 17` figure came from that query. This card rewrote that - * docblock, so `box.tsx` now answers 0 to BOTH halves and a reader replaying it + * the card's own `17 / 17` figure came from that query. objectui#6771 rewrote + * that docblock, so `box.tsx` now answers 0 to BOTH halves and a reader replaying it * gets no divergence at all. ⛔ A control that cannot fire is worse than none: * it reads as evidence and is not. * @@ -51,24 +59,27 @@ * `renderers/action/action-icon.tsx` is a REAL property access and survives * stripping at 1, so the 0 above is a reading and not a blanked file. * - * The twelve rows below are the ones where the renderer reads EXACTLY ONE - * channel, the component owns a dedicated declaration, and exactly one - * registration claims its `type`. `sidebar` is measured into family B and held - * BACK from it, because two registrations claim `sidebar` and the second types - * its schema prop `any`. Families C (reads both — a live `children || body` - * fallback), D (reads neither) and E (no dedicated declaration) are named on - * the card with the measurement each still needs. + * The twelve rows below are the ones that table measured as reading EXACTLY ONE + * channel, owning a dedicated declaration, and claimed by exactly one + * registration. `sidebar` was measured into family B and held BACK, because two + * registrations claim `sidebar` and the second types its schema prop `any`; it + * is not a row here. The other families are not pinned in this file: + * family C (read both, through a live `children || body` fallback) lost its + * `body` arm to objectui#6771 and reads the `children` channel only; family D + * (reads neither) is pinned by `content-channel-family-d-9256.test.ts` + * (objectui#9256); family E (no dedicated declaration) was ruled done or + * superseded by objectui#6771 and objectui#9910, with its residual moved to + * objectui#9256 (ruling 5861449497 on objectui#8284). * * ## What is NOT pinned here, and why * - * ⛔ Not the renderers. Nothing about rendering changes: a document that - * authors the channel its renderer reads is byte-identical through both faces, - * and a document that authors the other one rendered nothing before and - * renders nothing now — it is merely REFUSED first. The counter-probes in + * ⛔ Not the renderers. This file pins the two authoring faces only: a + * document that authors the channel its renderer reads parses and compiles, + * and a document that authors `body` is refused by both. + * The render side is pinned elsewhere, by counter-probes that deliberately + * author the dead channel (`body`) and assert the empty render: * `examples/schema-catalog/test/badge-demo-label-6829.test.tsx` and - * `packages/components/src/__tests__/span-children-rendering.test.tsx`, which - * deliberately author the dead channel and assert the empty render, therefore - * keep passing. + * `packages/components/src/__tests__/span-children-rendering.test.tsx`. * * ## ⚠️ Half of this file is a COMPILE-TIME assertion and vitest CANNOT read it * diff --git a/packages/types/src/zod/form.zod.ts b/packages/types/src/zod/form.zod.ts index 37ad00032f..e152dc47c0 100644 --- a/packages/types/src/zod/form.zod.ts +++ b/packages/types/src/zod/form.zod.ts @@ -435,8 +435,8 @@ export const ToggleSchema = BaseSchema.extend({ 'children', 'this toggle node', '`toggle` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/form/toggle.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -995,8 +995,8 @@ export const FormSchema = BaseSchema.extend({ 'children', 'this form node', '`form` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/form/form.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); diff --git a/packages/types/src/zod/layout.zod.ts b/packages/types/src/zod/layout.zod.ts index b23db79a32..543d91a202 100644 --- a/packages/types/src/zod/layout.zod.ts +++ b/packages/types/src/zod/layout.zod.ts @@ -82,8 +82,8 @@ export const BoxSchema = BaseSchema.extend({ 'children', 'this box node', '`box` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/layout/box.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -99,8 +99,8 @@ export const TextSpanSchema = BaseSchema.extend({ 'children', 'this span node', '`span` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/basic/span.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -315,8 +315,8 @@ export const ContainerSchema = BaseSchema.extend({ 'children', 'this container node', '`container` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/layout/container.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -342,8 +342,8 @@ export const FlexSchema = BaseSchema.extend({ 'children', 'this flex node', '`flex` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/layout/flex.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -363,8 +363,8 @@ export const StackSchema = BaseSchema.extend({ 'children', 'this stack node', '`stack` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/layout/stack.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -399,8 +399,8 @@ export const GridSchema = BaseSchema.extend({ 'children', 'this grid node', '`grid` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/layout/grid.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -485,8 +485,8 @@ export const ScrollAreaSchema = BaseSchema.extend({ 'children', 'this scroll-area node', '`scroll-area` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/complex/scroll-area.tsx`). ' - + '`body` is inherited from `BaseSchema`, so an authored `body` parsed green here and rendered ' - + 'an EMPTY element — no error, no warning. objectui#8284.', + + '`body` is the child-list spelling objectui#6771 retired — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); From 5a82fb771a29ff562a26d98cdacd21c16d0b7fa7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 01:35:14 +0000 Subject: [PATCH 2/3] fix(components): describe card's retired fallback without spelling the expression node-slot-numeric-falsy.test.tsx pins card.tsx's SOURCE against the literal `||` chain between the two channels, so the comment now describes that fallback in words instead of quoting it. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk --- packages/components/src/renderers/layout/card.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/src/renderers/layout/card.tsx b/packages/components/src/renderers/layout/card.tsx index 2d0a0df624..e54a96b1ec 100644 --- a/packages/components/src/renderers/layout/card.tsx +++ b/packages/components/src/renderers/layout/card.tsx @@ -62,9 +62,9 @@ const CardRenderer = forwardRef )} - {/* `children` is the one child-list key: this slot used to read - `schema.children || schema.body`, and objectui#6771 dropped the - `body` arm when it retired that spelling (the callback's `body` + {/* `children` is the one child-list key: this slot used to fall back + from `children` to `body` through an `||`, and objectui#6771 dropped + that `body` arm when it retired the spelling (the callback's `body` below is only a local name for the slot's content). ⛔ No `||` is the guard here. That distinction was the point of objectui#9162: `children: 0` used to be converted away by the accident of From e5823aef7236126b5eb7f3736b31637aa9f225c6 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 02:09:42 +0000 Subject: [PATCH 3/3] fix(types): alert and badge body refusals, and dated notes on three pending changesets Round 2 of the same closing dispatch, prose and strings only. - The AlertSchema and BadgeSchema `body` refusal details said an authored `body` "now parses green through .passthrough()", which the refusal they sit in contradicts. They now say it is refused by name and that `children` is the one child-list key; the history clause is kept. - Dated notes in the objectui#10533 form on the pending 6877, 6773 and 6788 changesets, whose `children || body` descriptions objectui#6771 made false. Frontmatter and original text are unchanged. - The new 8284 changeset names the alert and badge strings. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk --- .changeset/6773-aspect-ratio-demo-content.md | 7 +++++++ .changeset/6788-context-menu-demo-content.md | 7 +++++++ .changeset/6877-div-guidance-names-box.md | 8 ++++++++ .changeset/8284-refusal-and-notice-text.md | 11 +++++++---- packages/types/src/zod/data-display.zod.ts | 8 ++++---- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/.changeset/6773-aspect-ratio-demo-content.md b/.changeset/6773-aspect-ratio-demo-content.md index 67468c5502..e78167d0dd 100644 --- a/.changeset/6773-aspect-ratio-demo-content.md +++ b/.changeset/6773-aspect-ratio-demo-content.md @@ -14,6 +14,13 @@ nested `card` never read `content` either, so moving only the outer key would ha an empty box for an empty card. The page's Schema block published `content` as contract while omitting `image`/`alt`; it now documents what the renderer reads. +⚠️ **Dated note, 2026-09-28 — the child list is `children` alone — objectui#6771.** Since +this change, objectui#6771 dropped the `body` arm of that read, in `aspect-ratio.tsx` and in +the nested `card` alike: both read `children` and never `body`, both zod mirrors refuse an +authored `body` by name, and both TypeScript faces declare it `never`. The four card demos +already author `children` at both levels, so they are unaffected. The rest of this entry is +kept as the reading of this change. + Nothing publishes from this change — a docs page plus `@object-ui/example-schema-catalog` fixtures, both outside the release — hence the empty frontmatter. The regression control is `examples/schema-catalog/test/aspect-ratio-demo-content-6773.test.tsx`: category scope, not diff --git a/.changeset/6788-context-menu-demo-content.md b/.changeset/6788-context-menu-demo-content.md index 127c80a63c..dd6df9ef72 100644 --- a/.changeset/6788-context-menu-demo-content.md +++ b/.changeset/6788-context-menu-demo-content.md @@ -18,4 +18,11 @@ dialect, and objectui#6773 authored `children` in the four sibling `aspect-ratio` card demos. The renderer was NOT widened to read `content` — that would add a second dialect for one slot to a published surface. +⚠️ **Dated note, 2026-09-28 — `card` reads `children` alone — objectui#6771.** Since this +change, objectui#6771 retired `body` as a child-list spelling: the `children || body` read +above is now `children` alone, `CardSchema` declares `body` as `never` and its zod mirror +refuses it by name, and `BaseSchema.body` is `never` rather than a legacy member. So the +demo's `children` is the one spelling that renders, not the preferred one of two. The rest +of this entry is kept as the reading of this change. + No package source changed, so this declares no release. diff --git a/.changeset/6877-div-guidance-names-box.md b/.changeset/6877-div-guidance-names-box.md index dde8cc89bf..e4497a7a98 100644 --- a/.changeset/6877-div-guidance-names-box.md +++ b/.changeset/6877-div-guidance-names-box.md @@ -15,3 +15,11 @@ exactly the conversions objectui#3965 measured and rejected. Both statements now name `box` first for the mechanical swap, keep the layout components for the cases where their layout is actually wanted, and state the `body` → `children` move that every option except `card` requires. `span`'s guidance is deliberately unchanged. + +⚠️ **Dated note, 2026-09-28 — every option, and `div` itself, reads `children` only — +objectui#6771.** Later in this same release objectui#6771 retired `body` as a child-list +spelling, and `card` and `div` dropped their `body` arms with it. So the `body` → `children` +move is one every option requires, `card` included. A retype no longer drops `body` content +either: `div` does not draw it, and validation refuses the key by name. The notice's `body` +bullet now says that (objectui#8284); `deprecated.replacement` is unchanged. The rest of this +entry is kept as the reading of this change. diff --git a/.changeset/8284-refusal-and-notice-text.md b/.changeset/8284-refusal-and-notice-text.md index c80300dd3d..65935f3720 100644 --- a/.changeset/8284-refusal-and-notice-text.md +++ b/.changeset/8284-refusal-and-notice-text.md @@ -9,10 +9,13 @@ left false (objectui#8284). Only wording moves; no key, value or rendered result - `@object-ui/types` — the `body` refusal on `box`, `span`, `container`, `flex`, `stack`, `grid`, `scroll-area`, `form` and `toggle` explained that `body` "is inherited from `BaseSchema`, so an authored `body` parsed green here". Since objectui#6771, `BaseSchema` - refuses `body` by name itself, so that explanation no longer holds. The message now says - that `body` is the child-list spelling objectui#6771 retired, refused by name, and that - `children` is the one child-list key. The refused key, the replacement it names, the issue - code and the issue path are unchanged; the same string is still the `.describe()` metadata. + refuses `body` by name itself, so that explanation no longer holds. The message now says that + `body` is the child-list spelling objectui#6771 retired, refused by name, and that `children` + is the one child-list key. The same refusal on `alert` and `badge` said that an authored + `body` "now parses green through `.passthrough()`", which that refusal itself contradicts; + like the other nine, it now says that `body` is refused here by name and that `children` is + the one child-list key. The refused key, the replacement it names, the issue code and the + issue path are unchanged; the same string is still the `.describe()` metadata. - `@object-ui/components` — the `div` deprecation notice said that every replacement except `card` reads `children` only, so a blind retype drops `body` content. Since objectui#6771, `card` and `div` itself read `children` only as well. The notice now says that validation diff --git a/packages/types/src/zod/data-display.zod.ts b/packages/types/src/zod/data-display.zod.ts index 638c54348e..c74374e06d 100644 --- a/packages/types/src/zod/data-display.zod.ts +++ b/packages/types/src/zod/data-display.zod.ts @@ -77,8 +77,8 @@ export const AlertSchema = BaseSchema.extend({ 'children', 'this alert node', '`alert` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/data-display/alert.tsx`). ' - + '`body` was this node\'s only child-list key until objectui#6771 retired the spelling; an authored `body` now parses green through ' - + '`.passthrough()` and renders an EMPTY element — no error, no warning. objectui#8284.', + + '`body` was this node\'s only child-list key until objectui#6771 retired the spelling — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), }); @@ -124,8 +124,8 @@ export const BadgeSchema = BaseSchema.extend({ 'children', 'this badge node', '`badge` reads `children`, never `body` (READ SITE, measured with the TypeScript type checker: `packages/components/src/renderers/data-display/badge.tsx`). ' - + '`body` was this node\'s only child-list key until objectui#6771 retired the spelling; an authored `body` now parses green through ' - + '`.passthrough()` and renders an EMPTY element — no error, no warning. objectui#8284.', + + '`body` was this node\'s only child-list key until objectui#6771 retired the spelling — one concept, one spelling — so it is ' + + 'refused here by name; write the content under `children`, the one child-list key. objectui#8284.', ), });