diff --git a/packages/plugin-calendar/README.md b/packages/plugin-calendar/README.md index 69692e2d8..56ca775fc 100644 --- a/packages/plugin-calendar/README.md +++ b/packages/plugin-calendar/README.md @@ -156,23 +156,40 @@ reads (objectui#5667). Two of them — `data` and `className` — refine common any node. ```typescript -{ - type: 'calendar-view', - data?: any, // records rendered as events (array, or a binding expression) - titleField?: string, // default 'title' - startDateField?: string, // default 'start' - endDateField?: string, // default 'end' - allDayField?: string, // default 'allDay' - colorField?: string, // default 'color' - view?: CalendarViewMode, // 'month' | 'week' | 'day' (default 'month') - currentDate?: string | Date, // ISO string authored; Date from a React host - allowCreate?: boolean, // default false — shows the "New event" button - className?: string, // Tailwind classes for the container - onEventClick?: (event: CalendarEvent) => void, // HOST-ONLY (see below) - onViewChange?: (view: CalendarViewMode) => void // HOST-ONLY (see below) -} +import type { CalendarViewSchema, CalendarViewMode, CalendarEvent } from '@object-ui/types'; + +type CalendarViewNode = { + type: 'calendar-view'; + data?: any; // records rendered as events (array, or a binding expression) + titleField?: string; // default 'title' + startDateField?: string; // default 'start' + endDateField?: string; // default 'end' + allDayField?: string; // default 'allDay' + colorField?: string; // default 'color' + view?: CalendarViewMode; // 'month' | 'week' | 'day' (default 'month') + currentDate?: string | Date; // ISO string authored; Date from a React host + allowCreate?: boolean; // default false — shows the "New event" button + className?: string; // Tailwind classes for the container + onEventClick?: (event: CalendarEvent) => void; // HOST-ONLY (see below) + onViewChange?: (view: CalendarViewMode) => void; // HOST-ONLY (see below) +}; + +// The listing above is held to the shipped type BY THE COMPILER, both +// directions, rather than by this paragraph: a key whose type here disagrees +// with what `CalendarViewSchema` declares is a compile error. +declare const authored: CalendarViewNode; +declare const shipped: CalendarViewSchema; +const forwards: CalendarViewSchema = authored; +const backwards: CalendarViewNode = shipped; ``` +> **What those two assignments do and do not buy.** They check every key's +> **type**, in both directions. They do **not** check a key's **spelling**: +> `CalendarViewSchema` extends `BaseSchema`, whose `[key: string]: any` accepts +> any name, so a key invented or misspelled here is `any` rather than an error +> (objectui#7927). Key-level validity is the strict `@objectstack/spec` twin's +> question, not TypeScript's. + There is deliberately **no authorable `events` key**: the renderer computes its events from `data` plus the field-name keys, and drops an authored `events` (objectui#4433). Nine formerly declared keys — `events`, `defaultView`, @@ -256,11 +273,16 @@ The handlers are host-only — a function can only come from a React host building the node in code, never from authored JSON: ```typescript -const schema = { +import type { CalendarViewSchema } from '@object-ui/types'; + +// The annotation is what types the two handler parameters: `event` is +// `CalendarEvent` and `view` is `CalendarViewMode`, read off the shipped +// schema. Without it both are implicitly `any`. +const schema: CalendarViewSchema = { type: 'calendar-view', data: [], onEventClick: (event) => { - console.log('Event clicked:', event); + console.log('Event clicked:', event.title); // Open event details modal }, onViewChange: (view) => { @@ -304,10 +326,12 @@ const schema = { Style the calendar with Tailwind classes: ```typescript -const schema = { +import type { CalendarViewSchema } from '@object-ui/types'; + +const schema: CalendarViewSchema = { type: 'calendar-view', className: 'border rounded-lg shadow-lg', - data: [...] + data: [] // your records }; ``` diff --git a/scripts/check-doc-snippet-types.mjs b/scripts/check-doc-snippet-types.mjs index 32cd6533d..9cef5e007 100644 --- a/scripts/check-doc-snippet-types.mjs +++ b/scripts/check-doc-snippet-types.mjs @@ -729,8 +729,6 @@ const UNGATED_DOCS = { '12 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2322x4 TS2345x1 TS2353x1 — candidate real defects, un-triaged', 'packages/plugin-ai/README.md': '5 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2322x3 — candidate real defects, un-triaged', - 'packages/plugin-calendar/README.md': - '9 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 2 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines', 'packages/plugin-charts/README.md': '6 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies', 'packages/plugin-chatbot/README.md':