Skip to main content
View as Markdown

Calendars

The calendar component — a month, week or day view of date-bearing records.

A calendar places each record on the date its dateField names. The field mappings sit at the top level; only click handling and the time-grid settings live under calendarEvent and calendarInteraction.

Path Kind Values Default Description
dateField string Date/datetime field for calendar event position
endDateField string End date field for multi-day calendar events
defaultView enum month, week, day Calendar display mode: month grid, week view, or day view
labelField string Field to use as event label on calendar
colorField string Field whose values colour each event. A value whose option declares no colour is given one from a fixed fallback palette, hashed from the value — unlike a table’s rowColorField, which fills only from declared option colours. The hash is stable per value and distinct values may collide.
maxEventsPerDay number Max events visible per day cell before "+N more"

dataSource

Path Kind Values Default Description
dataSource object DB-table binding (DataSource) OR a system read-endpoint binding
dataSource.table string Table to bind to: a declared name (validated against app.tables), or a $param.<name> route reference declared by the page path
dataSource.fields array Specific fields to fetch from the table
dataSource.fields[] string One field name, spelled as the bound table declares it
dataSource.mode enum list, single, search Data fetching mode: 'list' (multiple), 'single' (one record), 'search' (interactive)
dataSource.filter array Filter conditions applied with AND logic
dataSource.filter[] object (truncated) Single filter condition for data source queries
dataSource.sort array Sort rules applied in order
dataSource.sort[] object (truncated) Single sort rule for data source queries
dataSource.pagination object Pagination configuration for data source
dataSource.pagination.pageSize number Number of records per page
dataSource.pagination.style enum numbered, loadMore, infinite How pagination controls are displayed (default: numbered). infinite is accepted but not implemented and pages as numbered.
dataSource.param string Route parameter name for single mode (e.g., slug, id)
dataSource.searchEngine enum client, fts, trigram, hybrid Search backend for this data source (default: 'client'). Only 'client' is dispatched today; the other three validate and search as 'client' does.
dataSource.searchFields array Fields to search across in search mode
dataSource.searchFields[] string One field name the search term is matched against
dataSource.debounceMs number Debounce delay for search input (ms)
dataSource.limit number Maximum number of results to return
dataSource.targetId string Publisher-side identifier for cross-component references — addressable by a FilterAction (targetDataSource) and by a sibling subscriber's bindTo (shared filter/period state)
dataSource.bindTo string ID of a publisher component whose value drives this data source (cross-component binding). By default a search-input whose query string drives the search; when sharedFilter is also set, a shared filter/period selector whose published params are merged into every request
dataSource.sharedFilter object Companion to bindTo: the bound publisher is a shared filter/period selector whose published params are merged into every request this data source issues. One selector can drive many sibling subscribers. Inert without bindTo.
dataSource.sharedFilter.params array (truncated) Request-param keys this subscriber consumes from the shared publisher's value bag (omit to merge the full bag verbatim)
dataSource.refreshMode enum none, poll, realtime Data refresh strategy for this binding (default: 'none'). 'poll' uses pollIntervalMs; 'realtime' subscribes to live change events.
dataSource.pollIntervalMs number 30000 Polling interval in milliseconds for refreshMode: poll (min 1000, max 300000). Defaults to 30000 when omitted, and is ignored unless refreshMode is 'poll'.
dataSource.system object Read-endpoint binding: feed a data-bound component from a system endpoint instead of a DB table
dataSource.system.endpoint string Read endpoint path to fetch rows from (e.g. /api/admin/automations/runs)
dataSource.system.rowsKey string Key of the rows array in the response envelope (default: 'items')
dataSource.system.param string Route parameter substituted into the endpoint's :param placeholder. Must be declared by the host page's path.
dataSource.system.idKey string Key of each row's unique id (default: 'id')
dataSource.system.totalKey string Key of the total-count in the envelope; falls back to rows length if absent
dataSource.system.query object Static query params merged into every request to the endpoint
dataSource.system.bindTo string ID of a sibling shared filter/period selector whose published params are merged into every request to endpoint (the dynamic counterpart to the static query)
dataSource.system.sharedFilter object (truncated) Companion to bindTo: the shared selector params merged (dynamically) into every request to endpoint, alongside the static query. Inert without bindTo.

autoSave

Path Kind Values Default Description
autoSave object Configuration for automatic persistence of edits. Applies to table, form, kanban, and calendar components.
autoSave.saveMode enum auto, onBlur, manual Save trigger strategy: 'auto' (debounced), 'onBlur' (field blur), 'manual' (button). Default: 'manual'.
autoSave.autoSaveDebounceMs number Debounce delay for auto-save in milliseconds (default: 500, min: 100)
autoSave.showSaveIndicator boolean Display a save status indicator (Saving... / Saved / Error). Default: true when saveMode is auto or onBlur.
autoSave.saveIndicatorPosition enum inline, toast, toolbar Where the save status indicator appears
Path Kind Values Default Description
search object Shared search bar configuration for data-bound components (table, kanban, calendar)
search.enabled boolean Enable search bar (default: true)
search.placeholder string Search input placeholder text
search.debounceMs number Debounce delay for search input in ms (default: 300)
search.highlight boolean Highlight matched search terms in results (default: false)

calendarEvent

Path Kind Values Default Description
calendarEvent object Configuration for how events are displayed and interacted with on the calendar
calendarEvent.onEventClick object Component action. Discriminated by type: auth (authentication), crud (data operations), automation (invoke workflow), filter (cross-component filtering), navigate (pure URL navigation), toast (transient notification), fetch (client-side HTTP with toast response). Open-drawer is discriminated by action: openDrawer instead of type (PG-04 quick-edit drawer pattern).
calendarEvent.onEventClick.type enum auth, crud, automation, filter, navigate, toast, fetch Which kind of action this is. It decides which of the other keys apply.
calendarEvent.onEventClick.method enum login, signup, logout, resetPassword, setNewPassword, verifyEmail, GET, POST, PUT, PATCH, DELETE What the action performs: the authentication operation under type: auth, or the HTTP verb under type: fetch (default GET).
calendarEvent.onEventClick.strategy enum email, magicLink, oauth Authentication strategy to use
calendarEvent.onEventClick.provider string OAuth provider name (e.g., google, github)
calendarEvent.onEventClick.submitLabel string Submit-button label for the form this action embeds. Defaults to the localized built-in label for the method or operation. Supports key translation references.
calendarEvent.onEventClick.pendingLabel string Custom in-flight (pending) submit-button label for the auth form. Defaults to the localized built-in pending label for the method. Supports key translation references.
calendarEvent.onEventClick.fields array (truncated) Per-field label/placeholder overrides for the form this action embeds. Targets fields by name. Additive — the default fields are used when omitted.
calendarEvent.onEventClick.onSuccess object (truncated)
calendarEvent.onEventClick.onError object (truncated)
calendarEvent.onEventClick.operation enum create, update, delete Data operation to perform
calendarEvent.onEventClick.table string Table to perform the operation on
calendarEvent.onEventClick.confirm boolean If true, shows a confirmation prompt before executing the action
calendarEvent.onEventClick.confirmMessage string Custom confirmation message. Defaults to a generic confirmation prompt.
calendarEvent.onEventClick.data object Field values to apply in bulk update operations
calendarEvent.onEventClick.name string Automation name (must match an automation defined in app.automations)
calendarEvent.onEventClick.inputData object Key-value pairs passed to the automation as input. Supports $variable references.
calendarEvent.onEventClick.await boolean Wait for completion before triggering response (default: false = fire-and-forget)
calendarEvent.onEventClick.targetDataSource string ID of the data source to filter (matches dataSource.targetId)
calendarEvent.onEventClick.field string Field name to apply the filter to
calendarEvent.onEventClick.operator enum eq, neq, contains, gt, lt, gte, lte Comparison operator (defaults to eq)
calendarEvent.onEventClick.path string Destination URL path (supports $record.X substitution)
calendarEvent.onEventClick.message string Toast notification message. Supports $variable references.
calendarEvent.onEventClick.variant enum success, error, warning, info Visual style of the toast notification
calendarEvent.onEventClick.duration number Auto-dismiss duration in milliseconds (default: 5000)
calendarEvent.onEventClick.url string Target URL (any absolute path or fully-qualified URL; not prefix-restricted). e.g. /api/tables/contacts/records, /api/auth/admin/ban-user, /api/buckets/default/files/<key>
calendarEvent.onEventClick.mode enum fetch, navigate, download, oauth Dispatch mode: fetch (default, client fetch + toast), navigate (browser navigation, e.g. ?format=csv export), download (native file download), oauth (authorize → provider → callback round-trip)
calendarEvent.onEventClick.headers object Request headers. Content-Type defaults to application/json when body is set.
calendarEvent.onEventClick.body object JSON request body (serialized with JSON.stringify). String values support $record.<field> and the $session.<field> token (resolved client-side from the caller session, e.g. { confirm: "$session.email" }).
calendarEvent.onEventClick.filename string Suggested download filename. Only meaningful when mode is "download".
calendarEvent.onEventClick.redirectKey string Response field holding the OAuth provider redirect URL (default "url"). Only meaningful when mode is "oauth".
calendarEvent.onEventClick.callbackPath string OAuth provider return path (the registered redirect_uri). Only meaningful when mode is "oauth".
calendarEvent.onEventClick.responseEnvelope enum sovrium, better-auth, raw sovrium Response-envelope interpretation: sovrium (default), better-auth (always-200 enumeration-safe envelope at /api/auth/admin/*), raw (status-only, no body assumptions)
calendarEvent.onEventClick.action enum openDrawer Set to openDrawer to open a sibling drawer instead of running one of the type actions.
calendarEvent.onEventClick.component string ID of the drawer page-component to open (matches a sibling { type: 'drawer', id })
calendarEvent.onEventClick.props object (truncated) Per-trigger overrides applied to the referenced drawer component

calendarInteraction

Path Kind Values Default Description
calendarInteraction object Configuration for calendar user interactions (date clicks, drag, time slots)
calendarInteraction.onDateClick object Component action. Discriminated by type: auth (authentication), crud (data operations), automation (invoke workflow), filter (cross-component filtering), navigate (pure URL navigation), toast (transient notification), fetch (client-side HTTP with toast response). Open-drawer is discriminated by action: openDrawer instead of type (PG-04 quick-edit drawer pattern).
calendarInteraction.onDateClick.type enum auth, crud, automation, filter, navigate, toast, fetch Which kind of action this is. It decides which of the other keys apply.
calendarInteraction.onDateClick.method enum login, signup, logout, resetPassword, setNewPassword, verifyEmail, GET, POST, PUT, PATCH, DELETE What the action performs: the authentication operation under type: auth, or the HTTP verb under type: fetch (default GET).
calendarInteraction.onDateClick.strategy enum email, magicLink, oauth Authentication strategy to use
calendarInteraction.onDateClick.provider string OAuth provider name (e.g., google, github)
calendarInteraction.onDateClick.submitLabel string Submit-button label for the form this action embeds. Defaults to the localized built-in label for the method or operation. Supports key translation references.
calendarInteraction.onDateClick.pendingLabel string Custom in-flight (pending) submit-button label for the auth form. Defaults to the localized built-in pending label for the method. Supports key translation references.
calendarInteraction.onDateClick.fields array (truncated) Per-field label/placeholder overrides for the form this action embeds. Targets fields by name. Additive — the default fields are used when omitted.
calendarInteraction.onDateClick.onSuccess object (truncated)
calendarInteraction.onDateClick.onError object (truncated)
calendarInteraction.onDateClick.operation enum create, update, delete Data operation to perform
calendarInteraction.onDateClick.table string Table to perform the operation on
calendarInteraction.onDateClick.confirm boolean If true, shows a confirmation prompt before executing the action
calendarInteraction.onDateClick.confirmMessage string Custom confirmation message. Defaults to a generic confirmation prompt.
calendarInteraction.onDateClick.data object Field values to apply in bulk update operations
calendarInteraction.onDateClick.name string Automation name (must match an automation defined in app.automations)
calendarInteraction.onDateClick.inputData object Key-value pairs passed to the automation as input. Supports $variable references.
calendarInteraction.onDateClick.await boolean Wait for completion before triggering response (default: false = fire-and-forget)
calendarInteraction.onDateClick.targetDataSource string ID of the data source to filter (matches dataSource.targetId)
calendarInteraction.onDateClick.field string Field name to apply the filter to
calendarInteraction.onDateClick.operator enum eq, neq, contains, gt, lt, gte, lte Comparison operator (defaults to eq)
calendarInteraction.onDateClick.path string Destination URL path (supports $record.X substitution)
calendarInteraction.onDateClick.message string Toast notification message. Supports $variable references.
calendarInteraction.onDateClick.variant enum success, error, warning, info Visual style of the toast notification
calendarInteraction.onDateClick.duration number Auto-dismiss duration in milliseconds (default: 5000)
calendarInteraction.onDateClick.url string Target URL (any absolute path or fully-qualified URL; not prefix-restricted). e.g. /api/tables/contacts/records, /api/auth/admin/ban-user, /api/buckets/default/files/<key>
calendarInteraction.onDateClick.mode enum fetch, navigate, download, oauth Dispatch mode: fetch (default, client fetch + toast), navigate (browser navigation, e.g. ?format=csv export), download (native file download), oauth (authorize → provider → callback round-trip)
calendarInteraction.onDateClick.headers object Request headers. Content-Type defaults to application/json when body is set.
calendarInteraction.onDateClick.body object JSON request body (serialized with JSON.stringify). String values support $record.<field> and the $session.<field> token (resolved client-side from the caller session, e.g. { confirm: "$session.email" }).
calendarInteraction.onDateClick.filename string Suggested download filename. Only meaningful when mode is "download".
calendarInteraction.onDateClick.redirectKey string Response field holding the OAuth provider redirect URL (default "url"). Only meaningful when mode is "oauth".
calendarInteraction.onDateClick.callbackPath string OAuth provider return path (the registered redirect_uri). Only meaningful when mode is "oauth".
calendarInteraction.onDateClick.responseEnvelope enum sovrium, better-auth, raw sovrium Response-envelope interpretation: sovrium (default), better-auth (always-200 enumeration-safe envelope at /api/auth/admin/*), raw (status-only, no body assumptions)
calendarInteraction.onDateClick.action enum openDrawer Set to openDrawer to open a sibling drawer instead of running one of the type actions.
calendarInteraction.onDateClick.component string ID of the drawer page-component to open (matches a sibling { type: 'drawer', id })
calendarInteraction.onDateClick.props object (truncated) Per-trigger overrides applied to the referenced drawer component
calendarInteraction.timeSlotInterval number Time slot interval in minutes for week/day views (default: 60)
calendarInteraction.showCurrentTimeIndicator boolean Show a horizontal line at the current time in week/day views

dateField supplies each event's start and endDateField its end, for events that span time. labelField is rendered as the event's label, and defaultView is month, week or day. maxEventsPerDay caps a day cell before it collapses into a "+N more" affordance.

calendarEvent.onEventClick runs when an event is clicked and calendarInteraction.onDateClick when an empty date or slot is. calendarInteraction.timeSlotInterval is the slot length in minutes for week and day views, and showCurrentTimeIndicator draws a line at the current time.

app.yaml
tables:
  - name: bookings
    fields:
      - { name: customer_name, type: single-line-text }
      - { name: starts_at, type: datetime }
      - { name: ends_at, type: datetime }
pages:
  - name: Bookings
    path: /bookings
    components:
      - type: calendar
        dataSource: { table: bookings }
        dateField: starts_at
        endDateField: ends_at
        labelField: customer_name
        defaultView: week
        calendarInteraction: { timeSlotInterval: 30, showCurrentTimeIndicator: true }

A coloured event is a block, not a dot

A calendar reads colorField at the top level — the record-view colour rules are the same ones a kanban board follows, including where the hue comes from and what happens when a value declares none.

In month view a calendar renders a timed event as a small dot by default. A dot is mostly empty space, so a colour applied to it is close to invisible. An event that carries a colour therefore renders as a filled block instead; an event with no colour keeps the default dot.

Expect that as a visible layout change on any month-view calendar that sets colorField — day cells that used to hold lines of dots now hold bands of filled blocks.

Behaviour

Data Calendar

  • type: 'calendar' is a valid component type in page components
  • dataSource.table binds the calendar to a table
  • dateField maps a record's date/datetime field to calendar position
  • endDateField enables multi-day events spanning across cells
  • defaultView sets the initial view mode (month, week, day)
  • Navigation buttons (previous, next, today) change the visible period
  • labelField renders the record field value as the event label
  • colorField maps field values to event background colors
  • Multi-day events span across date cells from dateField to endDateField
  • maxEventsPerDay limits visible events with a "+N more" overflow
  • onEventClick triggers a navigation or modal action on event click
  • onDateClick triggers a create action with the clicked date pre-filled
  • Dragging an event to a different date updates the dateField
  • Week/day views show time slots based on timeSlotInterval
  • showCurrentTimeIndicator renders a line at the current time
  • The week and day views render rather than throwing on a slot duration
  • A timed view honours the slot interval and the now-indicator
  • User can complete full calendar workflow end-to-end (regression)

System read-endpoint data source

  • A system-source calendar whose dateField/labelField are NOT app.tables fields boots successfully (field cross-validation is skipped)
  • With dataSource.system, the calendar fetches system.endpoint and never falls through to /api/tables/:t/records
  • The { items: [...] } envelope is normalized to calendar events; total falls back to rows length when totalKey is absent
  • dateField positions and labelField labels each event against endpoint rows (config drives rendering, not a table schema)
  • dataSource.system.query static params are merged into the endpoint request
  • A system-source calendar offers no record-write affordances (no drag-to-reschedule, no onDateClick create, no event edit)
  • A system-source calendar offers no saved/user views and no user-preferences (read-only, endpoint-shaped)
  • View switching (month/week/day) stays ON for a system source — a read-side control that re-reads the endpoint, never the records API
  • The existing dataSource.table binding still positions table rows on the date grid unchanged (discriminated-union regression)
  • A system-source calendar validates, fetches its endpoint, normalizes the envelope into events, gates writes off, keeps view switching, leaves DB intact

Last updated September 23, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium