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
2 changes: 2 additions & 0 deletions .changeset/8026-objectcalendar-alldayfield-honoured.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ the `CalendarConfig` mirror in `@object-ui/types`, whose comment names it: "the
renderers grow config knobs ahead of the protocol (calendar's `allDayField`, for
one), and stripping them here would silently disable a shipped capability." Nothing
in this change widens any accept set.

**Correction, 2026-10-01 (objectui#8831).** The "Not spec surface" paragraph above is false against `@objectstack/spec` 17.5.0, which this same release installs. That release's `CalendarConfigSchema` declares five keys, `allDayField` among them, and accepts it. It still refuses `defaultView`. The key no longer rides the `.passthrough()` of the `CalendarConfig` mirror in `@object-ui/types`: that mirror derives from the spec schema, so `allDayField` is now a declared member of it. objectui#11073's bump to 17.5.0 made the paragraph false, not this entry and not objectui#8831. The paragraphs about the renderer still hold: `object-calendar` takes no default field name for `allDayField`, and a declared one is the whole answer.
2 changes: 2 additions & 0 deletions .changeset/8466-calendar-color-allday-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ reason.
The `BaseSchema` index-signature ceiling measured by
objectstack-ai/objectui#7927 is unchanged — a MISSPELLED key is still admitted on
both faces, and the accompanying pin asserts that rather than claiming otherwise.

⚠️ **Dated note, 2026-10-01 — the README no longer teaches the flat spelling on `object-calendar` (objectui#8831).** The first two paragraphs above say the package README teaches all five flat keys. That was true when this entry was written, and the same release changes it. `@objectstack/spec` refuses the five flat on an `object-calendar` node and prescribes the `calendar` block, so the README now writes them inside `calendar` and calls the flat spelling the runtime handoff `ObjectView` and `ListView` emit. It keeps the five-key sentence for `calendar-view` only. The declarations this entry adds are unchanged: they record that the renderer reads the flat spelling, not that an author should write it. Separately, `@objectstack/spec` 17.5.0 (objectui#11073) declares `allDayField` on `CalendarConfigSchema`, so `calendar.allDayField` now has the spec twin that this entry says it lacks.
2 changes: 2 additions & 0 deletions .changeset/8830-calendar-doc-key-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ load-bearing since objectui#8026 — and neither objectui authoring face rejects
fifth key in the `calendar` block. The page now separates the spec face from the
renderer face, and `packages/types/src/__tests__/calendar-doc-key-set-8830.test.ts`
derives both sets on every run so the enumeration cannot drift again.

**Correction, 2026-10-01 (objectui#8831).** "the four plus objectui's own `allDayField`" is false against `@objectstack/spec` 17.5.0, which this same release installs. That release's `CalendarConfigSchema` declares all five, so `allDayField` is a spec key like the other four. objectui#11073's bump made the phrase false, not this entry and not objectui#8831. The rest of this entry holds: the renderer still reads five keys, neither objectui face rejects an extra key in the `calendar` block, and `calendar-doc-key-set-8830.test.ts` still derives both sets on every run.
13 changes: 13 additions & 0 deletions .changeset/8831-calendar-flat-teaching-face.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@object-ui/types': patch
'@object-ui/plugin-calendar': patch
---

`object-calendar` is taught with its `calendar` block, not with flat field-name keys (objectstack-ai/objectui#8831).

`@objectstack/spec` refuses `startDateField`, `endDateField`, `titleField`, `colorField` and `allDayField` written flat on an `object-calendar` node, and its diagnostic prescribes `calendar: { startDateField, endDateField, titleField, colorField, allDayField }`. Since 17.5.0 the spec's `CalendarConfigSchema` declares all five, `allDayField` included. objectui's published faces still taught the flat spelling as something to write, so an author who followed them was refused at publish.

- `@object-ui/plugin-calendar`: both `object-calendar` examples in the README write the five keys inside `calendar`, and the README says what the flat spelling is: the runtime handoff `ObjectView` and `ListView` emit, which `getCalendarConfig` reads only when the node has no `calendar` block. The five-key sentence for `calendar-view` stays and now says it is about that element: `CalendarViewSchema` has no `calendar` block, so the flat keys are its only spelling.
- `@object-ui/types`: the `.describe()` text and the TypeScript docblocks of `ObjectCalendarSchema`'s five flat members call them the read-only handoff and point at `calendar.KEY`. The `calendar` member's text calls the block the authored spelling. The `allDayField` member of the `calendar` block no longer calls the key objectui-local, because 17.5.0 declares it.

Descriptions and documentation only. No accept set moves: the flat members stay declared on both faces, with the same types, because the renderer still reads them.
5 changes: 5 additions & 0 deletions .changeset/olive-buckets-scream.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ fix(plugin-calendar): type `ObjectCalendar` at the published `object-calendar` s
- `ObjectCalendarSchema.calendar` is declared on both published faces. The spec declares the KEY; it does **not** declare its shape — `ComponentPropsMap['object-calendar'].calendar` is `z.unknown().optional()` and accepts anything at that position — so the member list is objectui's own: the four `CalendarConfigSchema` names plus objectui's `allDayField`, which is what the renderer reads out of the block. The container keeps `.passthrough()`, so no KEY that parsed before is refused — an unexamined key inside the block still parses, and so do `calendar.dateField` and `calendar.defaultView`. What is new is VALUE validation: `calendar: 42` and `calendar: { startDateField: 42 }` are refused where both were admitted unexamined.
- `@object-ui/types` now exports the type `ObjectCalendarBlockConfig`, so that published member has a name an importer can write.
- ⚠️ The `dateField` / `endField` alias rungs in `getCalendarConfig` are **kept**, and routed to the producer. An earlier revision of this change retired them on a census that was false: `ListView` flattens an authored `calendar` block onto the node it emits, and `resolveTimelineDateBinding` in that same file documents `dateField` as the pre-#2231 alias for `startDateField` and honours it — so a view authored that way renders today and would have drawn "Calendar configuration required". (objectui's own `ListViewSchema` also accepts `calendar.dateField`, but only weakly: that block is `.passthrough()` and admits nonsense too, so the load-bearing half is the producer and the read site, not the accept.) No behaviour changes for either spelling. The alias question already has a carrier — objectui#8355, open and undecided — and the producer-side remedy belongs in `ListView`'s calendar branch.

**Correction, 2026-10-01 (objectui#8831).** Two statements in this entry are false against the tree this release ships, for two different reasons.

- "the four `CalendarConfigSchema` names plus objectui's `allDayField`": `@objectstack/spec` 17.5.0, which this same release installs, declares all five on `CalendarConfigSchema`, so the container's members are the spec's five. objectui#11073's bump made this false, not this entry and not objectui#8831. What the same bullet says about the spec at this position still holds on 17.5.0: `ComponentPropsMap['object-calendar'].calendar` declares the key but not its shape, and accepts `calendar: 42`.
- "and so do `calendar.dateField`", and the ⚠️ bullet's "The `dateField` / `endField` alias rungs in `getCalendarConfig` are **kept**": objectui#8355 retired both rungs in this same release. `getCalendarConfig` no longer reads either spelling, and the container refuses `calendar.dateField` and `calendar.endField` by name (see objectui#8355's own entry). objectui#8355 made these false, not objectui#11073 and not objectui#8831. An unexamined key and `calendar.defaultView` still parse inside the block, and the value validation this entry adds (`calendar: 42` and `calendar: { startDateField: 42 }` are refused) still holds.
16 changes: 11 additions & 5 deletions content/docs/plugins/plugin-calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,17 @@ before the spec declared it; the spec declares it since `@objectstack/spec`
never declares it draws exactly as before, with the all-day flag inferred from
the absence of an end date.

Nor is a sixth key rejected on the way in. Neither published face of
`ObjectCalendarSchema` declares the `calendar` container, so whatever you write
inside it reaches the renderer unexamined; on the list-view path the container
*is* declared — as objectui's own mirror of the spec schema, which keeps
`.passthrough()` for exactly this. Annotating the block `CalendarConfig` is what
Nor is a sixth key rejected on the way in. Both published faces of
`ObjectCalendarSchema` declare the `calendar` container (objectui#8651), with
the five keys above as its members. Their values are checked, so
`calendar: { startDateField: 42 }` is refused, and the retired `dateField` /
`endField` are refused by name (objectui#8355). The container keeps
`.passthrough()`, though, so any other key you write inside it still parses and
reaches the renderer unexamined. `@objectstack/spec` does not judge it there
either: on an `object-calendar` node it declares the `calendar` key but not that
key's shape. On the list-view path the container is objectui's own mirror of
`CalendarConfigSchema`, kept `.passthrough()` in the same way, while the spec's
own list-view block is strict. Annotating the block `CalendarConfig` is what
narrows it to the spec's five.

## Configuration
Expand Down
77 changes: 46 additions & 31 deletions packages/plugin-calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,46 +259,59 @@ const schema = {
```

The records above already use the default field names (`title`, `start`, `end`,
`color`), so no field-name keys are needed; point `titleField` /
`startDateField` / `endDateField` / `allDayField` / `colorField` at your own
fields when they differ.
`color`), so no field-name keys are needed; on a `calendar-view` node, point
`titleField` / `startDateField` / `endDateField` / `allDayField` / `colorField`
at your own fields when they differ. They sit flat on this node because
`CalendarViewSchema` has no `calendar` block: here the flat keys are the only
spelling. An `object-calendar` takes the same five inside its `calendar` block
instead (next section).

### With ObjectQL Integration

Every key below is one `ObjectCalendarSchema` declares. Spelling the start-date
key anything else is not a partial failure: `getCalendarConfig` gates the whole
configuration on it, so a calendar whose title and end keys are spelled correctly
still renders the "Calendar configuration required" refusal screen and never
reads them.

`startDateField` is the only key that gate asks for — `titleField` is optional,
and an event with no explicit title resolves one through the ADR-0079 record
display-name chain. The refusal screen says so, and it also names where the key
belongs: the view's `calendar` block. That matters on an **interface page**,
whose `interfaceConfig` has no calendar slot of its own — the only lever there
is `sourceView`, pointed at a view that declares the block (objectui#8170).
Every key below is one `ObjectCalendarSchema` declares. The five field-name keys
go inside the `calendar` block: `getCalendarConfig` reads that block first and
returns it whole. A misspelt start-date key inside it is therefore not a partial
failure either: no record has a date to be placed by, so every one is counted
as unscheduled under the calendar instead of drawn.

`startDateField` is the only one of the five the calendar needs — `titleField`
is optional, and an event with no explicit title resolves one through the
ADR-0079 record display-name chain. A calendar authored with no `calendar`
block renders the "Calendar configuration required" refusal screen, which says
so and also names where the key belongs: the view's `calendar` block. That
matters on an **interface page**, whose `interfaceConfig` has no calendar slot
of its own — the only lever there is `sourceView`, pointed at a view that
declares the block (objectui#8170).

The same five keys written flat on the node are **not** a second way to author
this. That flat spelling is the runtime handoff — `ObjectView` and `ListView`
emit it on the node they build, and `getCalendarConfig` falls back to it only
when the node has no `calendar` block — so `ObjectCalendarSchema` declares it
because the renderer reads it. `@objectstack/spec` refuses it at authoring with
`unrecognized_keys` and names the `calendar` block in the same diagnostic (one
key per concept, its Prime Directive #12).

```typescript
import type { ObjectCalendarSchema } from '@object-ui/types';

// What this annotation buys, and what it does not - measured, objectui#7925.
// It type-checks the VALUES of the declared keys: `defaultView: 'agenda'` and
// `titleField: 42` are both compile errors, and `check:doc-snippets` re-runs
// that check on every commit. Since objectui#8466 that cover reaches all five
// flat field-name keys - `allDayField` and `colorField` were reachable only
// through `BaseSchema`'s index signature until then, so this block is also
// what proves they are declared. It does NOT check key NAMES - this interface
// extends `BaseSchema`, whose `[key: string]: any` admits any spelling, so a
// `calendar: { titleField: 42 }` are both compile errors, and
// `check:doc-snippets` re-runs that check on every commit. It does NOT check
// key NAMES - this interface extends `BaseSchema`, whose `[key: string]: any`
// admits any spelling, and the `calendar` block is open the same way, so a
// misspelt key still compiles clean. Read the block as type-checked values,
// never as a guarded key set.
const schema: ObjectCalendarSchema = {
type: 'object-calendar',
objectName: 'events',
titleField: 'name',
startDateField: 'startDate',
endDateField: 'endDate',
allDayField: 'isAllDay',
colorField: 'statusColor',
calendar: {
titleField: 'name',
startDateField: 'startDate',
endDateField: 'endDate',
allDayField: 'isAllDay',
colorField: 'statusColor'
},
defaultView: 'month',
navigation: { mode: 'modal' } // what an event click opens - see below
};
Expand Down Expand Up @@ -348,8 +361,8 @@ Authored JSON reacts to clicks through the node's action channel instead
When using with ObjectStack, the calendar can automatically fetch and display
events. The adapter is **not** a schema key: `ObjectCalendarRenderer` reads it
from the renderer context that `SchemaRendererProvider` supplies. The schema
names the object and its fields with the same flat keys as above - there is no
`fields` container.
names the object with `objectName` and its fields inside the same `calendar`
block as above - there is no `fields` container.

```typescript
import { createObjectStackAdapter } from '@object-ui/data-objectstack';
Expand All @@ -365,9 +378,11 @@ const dataSource = createObjectStackAdapter({
const schema: ObjectCalendarSchema = {
type: 'object-calendar',
objectName: 'calendar_events',
titleField: 'title',
startDateField: 'start_time',
endDateField: 'end_time',
calendar: {
titleField: 'title',
startDateField: 'start_time',
endDateField: 'end_time'
},
defaultView: 'month'
};
```
Expand Down
Loading
Loading