Filter value. The accepted SHAPE depends on the operator: in / not_in take an array (any length, including []), between takes exactly [min, max], every other operator takes a scalar. The unary operators (is_empty / is_not_empty / is_null / is_not_null) take their direction from the operator name and ignore this key.
Named filter presets rendered as tabs (tabs element). Reuses ViewTabSchema
showAllRecords
boolean
optional
Show an "All records" tab before the presets (tabs element)
allowAddTab
boolean
optional
Let end users add their own tab after the presets (tabs element): the affordance asks for a name and snapshots the filters currently applied as a new tab. SESSION-SCOPED — an added tab lives only for the current mount, is never written back as metadata (ADR-0047), and carries a remove control the authored presets do not. Page lists only — object views use listViews for named presets
Allow users to reload the view data from the backend without a full page reload
rowHeight
boolean
optional (default: true)
Allow users to toggle row height/density
group
boolean
optional (default: true)
Allow users to change record grouping from the toolbar. Toggle only — the grouping itself is configured in the view-level grouping block.
addRecordForm
boolean
optional (default: false)
Add records through a form instead of inline
editInline
boolean
optional (default: false)
Allow users to edit records inline — click a cell to edit it with the field's type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in.
hideFields
boolean
optional (default: false)
Allow users to hide/show fields from the toolbar (the affordance behind the view-level hiddenFields list). Boolean toggle — distinct from the record-details component's hideFields, which is an array of field names to omit. Off by default: column hiding is opt-in.
rowColor
boolean
optional (default: false)
Allow users to configure row colouring from the toolbar. Boolean toggle — the colour rules themselves live in the view-level rowColor block. Off by default: row colouring is opt-in.
Layout regions (header, main, sidebar, footer) with their components. Optional — list pages use interfaceConfig, slotted pages use slots, and an empty full page falls back to the synthesized default layout.
Page override mode. full | slotted = structured authoring; html = author-written constrained JSX compiled (parsed, never executed) to the tree (ADR-0080; the legacy value 'jsx' is a deprecated alias), styled by the registered components' structured props plus a JSON style object with hsl(var(--token)) theme colors; react = real-React source executed at render by the runtime (ADR-0081), styled by inline style with the same token colors; it runs author JS, so it is gated by a host capability that defaults ON and is disabled server-side via the OS_PAGE_REACT=off env toggle. Do not author Tailwind classes in page source in either tier: source is runtime metadata the build-time Tailwind never scans, so utility classNames silently produce no CSS (ADR-0065; ADR-0080 amendment 2026-06-30).
Page source text. For kind==='html' (alias 'jsx') it is constrained JSX compiled to the tree by @objectstack/sdui-parser at save time (parse, never execute), styled by the registered components' structured props plus a JSON style object with hsl(var(--token)) theme colors. For kind==='react' it is real React/JSX executed at render by @object-ui/react-runtime (trusted tier), styled by inline style with the same token colors. Do not author Tailwind classes in page source in either tier: source is runtime metadata the build-time Tailwind never scans, so utility classNames silently produce no CSS (ADR-0065; ADR-0080 amendment 2026-06-30). Authoritative over regions in both.
requires
string[]
optional
Plugin namespaces the JSX source references (validated at save and load)
Accessible label for screen readers (WAI-ARIA aria-label). Plain string, or an inline locale map — no translation-bundle slot addresses this key, so a plain string is announced in the source language.
ariaDescribedBy
string
optional
ID of element providing additional description (WAI-ARIA aria-describedby)
role
string
optional
WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert")
Component Type — a standard vocabulary member, or a custom/registered component type in its own namespace (e.g. object-grid, mcp:connect-agent). The spec's own type namespaces are a closed vocabulary at author time: inside them, a type the vocabulary does not declare is refused by os validate / os build / os lint (rule component-type-unknown).
id
string
optional
Unique instance ID
label
string | Record<string, string>
optional
Display label — the default-language string, or an inline locale map ({ en, "zh-CN" }) resolved at render time
properties
Record<string, any>
optional (default: {})
Component props passed to the widget. See component.zod.ts for schemas.
Visibility predicate (CEL) — component rendered only when TRUE. Contract-bound roots: record, current_user (ADR-0068 aliases user / ctx.user — one object, three spellings), and page state as page.<var>. The shipping renderer additionally mounts app, features, os.user and binds data to the data-source ADAPTER here — renderer behaviour, NOT contract-guaranteed (ADR-0068 rules the user object only). ⚠️ data is surface-dependent: on a page:tabs item visibleWhen it is the record ROW instead. e.g. "page.selectedProjectId != ''"
[REMOVED] page.components[].responsive was removed in @objectstack/spec 17 (ADR-0049 D2) — no renderer ever read it, so per-breakpoint layout overrides (columns/order/visibility) parsed, validated, and then did nothing. Delete the key. For breakpoint behaviour that IS applied, use the sibling responsiveStyles (ADR-0065) — per-breakpoint CSS maps compiled to id-scoped CSS at render, e.g. responsiveStyles: { xsmall: { display: 'none' } } to hide a component on the narrowest screens. Run os migrate meta --from 17 to list the mechanical edits for existing sources; apply them by hand.
Accessible label for screen readers (WAI-ARIA aria-label). Plain string, or an inline locale map — no translation-bundle slot addresses this key, so a plain string is announced in the source language.
ariaDescribedBy
string
optional
ID of element providing additional description (WAI-ARIA aria-describedby)
role
string
optional
WAI-ARIA role attribute (e.g., "dialog", "navigation", "alert")
Component Type — a standard vocabulary member, or a custom/registered component type in its own namespace (e.g. object-grid, mcp:connect-agent). The spec's own type namespaces are a closed vocabulary at author time: inside them, a type the vocabulary does not declare is refused by os validate / os build / os lint (rule component-type-unknown).
id
string
optional
Unique instance ID
label
string | Record<string, string>
optional
Display label — the default-language string, or an inline locale map ({ en, "zh-CN" }) resolved at render time
properties
Record<string, any>
optional (default: {})
Component props passed to the widget. See component.zod.ts for schemas.
Visibility predicate (CEL) — component rendered only when TRUE. Contract-bound roots: record, current_user (ADR-0068 aliases user / ctx.user — one object, three spellings), and page state as page.<var>. The shipping renderer additionally mounts app, features, os.user and binds data to the data-source ADAPTER here — renderer behaviour, NOT contract-guaranteed (ADR-0068 rules the user object only). ⚠️ data is surface-dependent: on a page:tabs item visibleWhen it is the record ROW instead. e.g. "page.selectedProjectId != ''"
[REMOVED] page.components[].responsive was removed in @objectstack/spec 17 (ADR-0049 D2) — no renderer ever read it, so per-breakpoint layout overrides (columns/order/visibility) parsed, validated, and then did nothing. Delete the key. For breakpoint behaviour that IS applied, use the sibling responsiveStyles (ADR-0065) — per-breakpoint CSS maps compiled to id-scoped CSS at render, e.g. responsiveStyles: { xsmall: { display: 'none' } } to hide a component on the narrowest screens. Run os migrate meta --from 17 to list the mechanical edits for existing sources; apply them by hand.