Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/6397-partial-schema-collapse-pin.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ Once #5155 removes the root index signature, the alias starts working as written
with no edit at all. What this ships is the removal of the one impermissible
state — *declared, published, collapsed, and unpinned*.

⚠️ **Dated note, 2026-09-28 — a generic re-spelling of this `Omit` does not collapse —
objectui#9256.** Later in this same release objectui#9256 declared a key-remapping
`OmitDeclared` (`{ [P in keyof T as P extends K ? never : P]: T[P] }`, in
`packages/types/src/form.ts`) and re-spelled the heritage of `InputShorthandSchema` and
`UiCalendarSchema` with it. Such a mapped type iterates the named members and the index
signature separately, so it drops exactly `K`, keeps every other named member with its
modifiers, and keeps the index signature. The same spelling of this alias declares 28
properties at `ButtonSchema` and 62 at `ObjectGridSchema` in this release, where the
shipped alias declares 1 at each; at this change's own commit, under the same TypeScript,
it declares 27 and 61, the source counts in the table above. So "every generic re-spelling
collapses" was not true when it was written. The alias is still left as written:
re-spelling it would narrow what every instantiation accepts, a contract change and not a
pin's business. The `PartialSchema` docblock and `partial-schema-collapse-pin.test.ts`
carry the correction. The rest of this entry is kept as the reading of this change.

No runtime code, no type declaration and no accepted value changes; a consumer's
`PartialSchema<X>` means exactly what it meant before. Declared `patch` rather
than as a no-release so the doc-comment warning actually reaches the published
Expand Down
7 changes: 7 additions & 0 deletions .changeset/8499-node-slot-registered-arms.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ from 107 to 154:
`renderers/form/input.tsx` registers onto the `input` renderer with `inputType`
pinned. `inputType` is deliberately NOT declared on this arm: the wrapper spreads
its own value last, so an authored one is overwritten.
⚠️ **Dated note, 2026-09-28 — `inputType` is now declared on this arm, as a refusal —
objectui#8762.** Later in this same release the arm declares `inputType` on both faces
and refuses it by name (`?: never` on the TypeScript face, a `retirementTombstone` on
the zod mirror, at path `inputType`), with guidance pointing at
`{ "type": "input", "inputType": "email" }`. So "`inputType` is deliberately NOT declared
on this arm" no longer holds; the reason does, since the wrapper still spreads its own
value last. The rest of this entry is kept as the reading of this change.
- `UiCalendarSchema` (`zod/form.zod.ts`) — `ui:calendar`, the date-picker primitive
`renderers/form/calendar.tsx` registers under exactly that key (`skipFallback`,
because bare `calendar` belongs to the plugin-calendar view).
Expand Down
19 changes: 19 additions & 0 deletions .changeset/9256-content-channel-family-d.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,25 @@ twins are unchanged and go on inheriting `body` as the content slot, and the rea
held the key out — it was a naming collision to rule on, not a family-D read-site verdict —
is the part that stayed true.

⚠️ **Dated note, 2026-09-28 — the two twins no longer take `body` — objectui#6771.** Later
in this same release objectui#6771 retired `body` as a child-list spelling on `BaseSchema`
itself, so the `body` slot `chatbot-enhanced` and `chatbot-floating` inherited is gone. Both
now refuse `body` on both faces: the TypeScript face through `BaseSchema`'s `body?: never`,
and each mirror by name, with a message pointing at `requestBody`, the key the registration
forwards to the chat runtime. So "The two twins are unchanged and go on inheriting `body` as
the content slot" no longer holds. The paragraph above is kept as the reading of that
amendment.

⚠️ **Dated note, 2026-09-28 — most of the hold-outs above have since been narrowed —
objectui#9256.** Later in this same release, under the same card: `text`, `image`, `icon`,
`tabs`, `accordion` and `calendar`, six of the nine names, once `check:registry-bare-names`
(objectui#9264) measured one owner for each; `list` and `timeline`; `DetailViewSchema` and
the `email` / `password` shorthand faces (`InputShorthandSchema`), whose TypeScript heritage
was re-spelled from a collapsing `Omit` to `OmitDeclared`; and `InputSchema` itself. Each
now refuses both channels on both faces, and each is its own entry in this release.
`button` and `AppComponentSchema` still accept `children`. The rest of this entry is kept as
the reading of this change.

Four published documents in the schema catalog and three component reference pages were
authoring `children` on `dialog`, `drawer`, `popover` and `collapsible`, all of which
read `content`. They rendered empty boxes and are corrected here.
5 changes: 3 additions & 2 deletions .changeset/9256-e3-residual-content-channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
content channels by name — `object-grid`, `object-form`, `object-kanban`,
`object-map`, `object-tree`, `object-view`, `object-gantt`, `object-calendar`,
`object-chart`, `detail-view`, `email` and `password`. None of their renderers
reads `body` or `children`, so an authored child list on them rendered nothing:
no error, no warning, no element. Both keys are now `?: never` on the TypeScript
reads `body` or `children`, so an authored child list on them rendered nothing,
with no render-time error or warning and no element; only the parser tier's
`not-a-container` warning (objectui#9910) noticed it. Both keys are now `?: never` on the TypeScript
face and a by-name refusal on the zod mirror, each kept a member of the mirror
shape.

Expand Down
36 changes: 36 additions & 0 deletions .changeset/9256-input-content-channels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
'@object-ui/types': minor
---

**BREAKING (shipped as `minor` — see below):** the `input` node type now refuses
both content channels by name. Its renderer reads neither `body` nor `children`,
so an authored child list on it rendered nothing, with no render-time error or
warning and no element; only the parser tier's `not-a-container` warning
(objectui#9910) noticed it. Both keys are now `?: never` on the TypeScript face (`InputSchema`) and
a by-name refusal on the zod mirror, each kept a member of the mirror shape.

What moves for an author:

- `children` on `input` type-checked and parsed green before; it is now refused
at authoring time and at `safeParse` time, at its own path.
- `body` on `input` was already refused on both faces, by `BaseSchema`. Its
refusal message now names what `input` renders instead, where it used to
point at `children`, which `input` does not read either.
- `email` / `password` (`InputShorthandSchema`) accept and refuse exactly what
they did before, with the same message. They already refused both channels
with their own pair, which names those two nodes. They now also inherit
`input`'s pair: on the TypeScript face it is the same `?: never`, and on the
zod mirror their own members override it, so the message an author reads
there does not change.

No render behaviour changes: nothing read these keys, which is the whole reason
they could be refused.

Migration: `input` renders one field from its own keys, so there is no channel
to move the content to. Put label or help text in `label`, `placeholder` or
`description`; place anything else beside the `input` in a container that reads
`children`, or drop it.

`minor` rather than `major` because this repo's version policy forbids `major`
in any changeset — one `fixed` group — and records `minor` plus an explicit
breaking note as the spelling for a breaking change here.
36 changes: 25 additions & 11 deletions packages/types/src/__tests__/content-channel-family-d-9256.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@
* `icon`, `tabs` and `accordion` each have ONE claimant of the bare key
* because every rival passes `skipFallback: true`, while `calendar`'s
* several claimants name ONE full type. `ui:calendar` rides along on
* `calendar`'s tombstone by declaration (`Omit` on the TS face, `.extend()`
* on the mirror) and is pinned as its own row so the propagation is
* measured and not assumed.
* `calendar`'s tombstone by declaration (`.extend()` on the mirror, and on
* the TS face `OmitDeclared` since objectui#9256's E3 slice — the plain
* `Omit` it replaced collapsed into `BaseSchema`'s index signature and
* carried no member, the tombstone included). Its mirror half is pinned as
* its own row here; its TS half lives in
* `content-channel-e3-residual-9256.test.ts`.
* - ⭐ `list` and `timeline` are narrowed HERE, by objectui#9256 slice 3. They
* were held for a SERIAL constraint and ⛔ never for a verdict: both declare
* in `data-display.ts`, which another slice was editing. That constraint is
Expand Down Expand Up @@ -85,14 +88,23 @@
* to tombstone at all — it does not extend `BaseSchema` and carries only
* `bodyExtra` / `bodyShape`, the prefix keys grep confuses for the channel.
* A LIVE CONTROL below keeps `button` parsing both channels.
* - `InputSchema`: `InputShorthandSchema` is declared as an `Omit` of it, so a
* tombstone here would propagate onto the `email` / `password` shorthand
* face, whose registrations are `any`-typed — family E, frozen.
* - `InputSchema` is narrowed, but NOT in this file. It was held out here while
* `InputShorthandSchema` inherited from it through a plain `Omit`, which
* collapsed into `BaseSchema`'s index signature: a tombstone on `input`
* reached neither the `email` nor the `password` face. objectui#9256's E3
* slice re-spelled that heritage as `OmitDeclared` and narrowed the two
* shorthand faces (`content-channel-e3-residual-9256.test.ts`); its `input`
* slice then narrowed `input` itself, measured to read neither channel
* (`content-channel-input-9256.test.ts`).
* - `AppComponentSchema`: it declares the `app` type literal, and `app` is
* served by `PageNodeSchema`, which reads BOTH channels — family C, with the
* maintainer.
* - `DetailViewSchema`: its own literal is `detail-view`, and that name is
* registered with an `any`-typed renderer whose reads are unattributable.
* - `DetailViewSchema` is narrowed, but NOT in this file. The `detail-view`
* registration's `any`-typed hop hands the node to `DetailView`, typed
* `DetailViewSchema`, whose `SchemaRenderer` calls render sub-keys (`header`,
* `footer`, a tab's `content`) and never the node's own channel. The E3 slice
* attributed those reads directly and narrowed it there
* (`content-channel-e3-residual-9256.test.ts`).
* - the `body` channel of the three chatbot faces: the parity ledger already
* records that key as "two different meanings of one key — a naming
* collision to rule on". Their `children` channel is narrowed here, and the
Expand Down Expand Up @@ -317,9 +329,11 @@ const ROWS: ReadonlyArray<readonly [
// Each name's owner is MEASURED (`pnpm check:registry-bare-names --table`,
// objectui#9264) rather than guessed, which is the whole reason these six
// could move while `list`, `timeline`, `input` and `app-schema-renderer`
// could not. `ui:calendar` rides along because its declaration is an `Omit`
// of `calendar`'s on the TypeScript face and a `.extend()` of it on the
// mirror — the propagation is pinned here rather than assumed.
// could not. `ui:calendar` rides along because its mirror is a `.extend()` of
// `calendar`'s, which this row pins rather than assumes. Its TypeScript face
// inherits through `OmitDeclared` since objectui#9256's E3 slice (a plain
// `Omit` until then, which carried no member), and that half is pinned in
// `content-channel-e3-residual-9256.test.ts`.
['text', TextMirror as unknown as Mirror, ['body', 'children'], {}],
['image', ImageMirror as unknown as Mirror, ['body', 'children'], {"src":"/a.png"}],
['icon', IconMirror as unknown as Mirror, ['body', 'children'], {"icon":"check"}],
Expand Down
Loading
Loading