Options
Everything useCalendar and Calendar accept.
useCalendar(() => options) and the Calendar component take the core calendar's options, the same ones
createCalendar takes. useCalendar takes them through an accessor, so signals read inside it keep them current.
createCalendar<TData, TResourceData, TViews, TFeatures>(options);TData is the type of each event's data payload and TResourceData that of each resource's. TViews and
TFeatures are inferred from views and features, so view and onNavigate only accept your view keys, and the
configuration, state and actions of the registered features appear on the calendar.
Let TypeScript infer all four. Passing some explicitly, as in createCalendar<Booking>(…), turns off inference for
the others, and view keys widen to string. Type events as Calendar_EventInput<Booking>[] instead.
| Option | Type | Default | Tracked |
|---|---|---|---|
id | string | none | No |
timeZone | string (IANA zone) | required | Yes |
views | calendarViews({ features, views }) | required | Yes |
features | calendarFeatures({ … }) | required | Read once |
view | keyof TViews | required | Yes |
date | Temporal.PlainDate | required | Yes |
onNavigate | (next: Calendar_Navigation) => void | required | No |
events | Calendar_EventInput<TData>[] | required | Yes |
resources | Calendar_Resource<TResourceData>[] | [] | Yes |
firstDayOfWeek | 1 to 7, or DayOfWeek.* | 7 (Sunday) | Yes |
eventOrder | (a, b, context) => number | see below | No |
clock | Calendar_Clock | one-minute tick | No |
initialNow | Temporal.Instant | clock's now() | No |
state | Controlled feature state slices | none | Yes, per slice |
atoms | External stores for feature state slices | none | Read once |
Tracked options re-derive the layout when they change through ~update. Others are read when needed: changing
eventOrder alone does not re-order until a tracked input changes. Read once options are read at creation and
fixed afterwards. Changing feature definitions throws; create a new instance to change them.
views, events, resources and each state slice are compared by reference. Pass a new array or object to signal
a change and keep the same reference otherwise, or every update re-derives. Feature options go to their factories and
per-view overrides to the view definitions; see features.
timeZone
The IANA zone every timed event is converted to and laid out in, for example 'Europe/Paris'. It also sets which day
counts as today.
id
Identifies this calendar. Ordinary calendars can omit it; event transfers need distinct, nonempty IDs on both sides.
It does not name a peer, register a feature or join a drag scope; transfer configures acceptance and relocation.
Changing an ID invalidates the calendar's prepared sources and revalidates its active receiving draft.
views, view and date
views maps your own keys to views, usually through calendarViews. view
selects one, and date is any day inside the period to show. Both are controlled: see
actions. An unknown view key throws.
features
Configured feature definitions, keyed by aliases you choose:
const features = calendarFeatures({ background: backgroundFeature(defaultBackgrounds) });
const views = calendarViews({ features, views: { week: timeGridView({ weeks: 1 }) } });
createCalendar({ ...options, views, features });Every view inherits the registered features. A view can override a feature through features: { background: layers }.
Unknown keys and invalid override types are rejected. Feature definitions are captured at creation; view overrides
update through a new views reference. See features.
onNavigate
Every navigation action calls it with the next view, date, range, period and inputRange. Store view and
date and pass them back in.
events and resources
See events and resources. Event ids must be unique.
eventOrder
Sorts the events of the visible range before layout. It receives the view context (view, kind, date, range,
period), so the order can differ per view. Without it, events sort by
the default order.
clock and initialNow
See now and today and server rendering.
state and atoms
Where feature state lives; see feature state.
Interaction options
Each field exists only when its feature is registered:
| Feature | Live settings | Callback |
|---|---|---|
dateSelectionFeature | selection | onSelectionChange(range) |
eventMoveFeature | movement | onEventMove({ before, after }) |
eventResizeFeature | resizing | onEventResize({ before, after, edge }) |
constraintsFeature | constraints | Custom validation through constraints.allow |
pointerFeature, touchFeature, autoScrollFeature | pointer, touch, autoScroll | None |
externalDropFeature | externalDrop | onExternalDrop({ after, metadata }) |
eventTransferFeature | transfer | onEventTransfer({ sourceId, destinationId, before, after }) on the source |
interactionFeature | interactionOwnership, eventRelocationPolicy | Controlled ownership uses its onChange |
Callbacks and proposal results preserve the event input's data type. Apply accepted event proposals to your input array; the runtime does not mutate events. Feature factories can supply setting defaults, and per-view overrides take precedence over live settings. Keep rule arrays and predicate functions stable between changes.
eventRelocationPolicy supplies calendar-wide conversion and resource defaults. Movement, external creation and
transfer receiving can override individual fields through their relocationPolicy settings. Effective policy
changes revalidate the active draft and preview without re-deriving the base event layout. Defining defaults does
not register any of these operations.
See selection and editing, policies, and external drops and transfers.
The accessible-label locale is a prop of the framework's CalendarProvider or Calendar, not a calendar option.