Calendar
A full calendar with month, week, day, agenda, timeline and year views.
SourcePackage @weft-js/warp
Preview
tsx
import { state } from '@weft-js/core'import { Calendar } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function Week() { const s = useEvents() return <Calendar events={s.events.value} calendars={CALENDARS} defaultView="week" defaultDate={CAL_TODAY} today={CAL_TODAY} now={CAL_NOW} locale="en-US" firstDayOfWeek={1} workingHours={[540, 1080]} onMove={s.change} onResize={s.change} onCreate={s.create} onEdit={s.edit} onDelete={s.remove} />}const CAL_TODAY = '2026-11-02'const CAL_NOW = '2026-11-04T10:40'const CALENDARS = ['Releases', 'On-call', 'Team', 'Customers'].map((name, i) => ({ id: i + 1, name }))const EVENTS: CalEvent[] = [ { id: 'e1', title: 'Standup', start: '2026-11-02T09:30', end: '2026-11-02T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e2', title: 'Standup', start: '2026-11-03T09:30', end: '2026-11-03T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e3', title: 'Standup', start: '2026-11-04T09:30', end: '2026-11-04T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e4', title: 'Standup', start: '2026-11-05T09:30', end: '2026-11-05T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e5', title: 'Standup', start: '2026-11-06T09:30', end: '2026-11-06T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e6', title: 'Ship checkout to production', start: '2026-11-02T11:00', end: '2026-11-02T12:00', cal: 1, location: 'Room Atlas', attendees: ['Tomás Oliveira', 'Mara Lindqvist'], resource: 'atlas' }, { id: 'e7', title: 'Search ranking review', start: '2026-11-03T14:00', end: '2026-11-03T15:30', cal: 3, attendees: ['Lena Fischer', 'Noor Haddad'], video: true, resource: 'birch' }, { id: 'e8', title: 'Acme onboarding', start: '2026-11-04T10:00', end: '2026-11-04T11:00', cal: 4, video: true, attendees: ['Priya Raman'] }, { id: 'e9', title: 'Incident review: mobile-bff', start: '2026-11-04T10:30', end: '2026-11-04T11:30', cal: 2, attendees: ['Sam Okafor', 'Jun Tanaka'], resource: 'cedar' }, { id: 'e10', title: 'Rotate edge certificates', start: '2026-11-05T13:00', end: '2026-11-05T14:00', cal: 2, locked: true, location: 'Do not move' }, { id: 'e11', title: 'Northwind renewal', start: '2026-11-05T15:00', end: '2026-11-05T16:00', cal: 4, tentative: true, location: 'Waiting on Inés' }, { id: 'e12', title: 'Release retro', start: '2026-11-06T11:00', end: '2026-11-06T12:00', cal: 1, video: true, resource: 'atlas' }, { id: 'e13', title: 'Design crit', start: '2026-11-04T09:00', end: '2026-11-04T10:00', cal: 3, resource: 'atlas' }, { id: 'e14', title: 'Hiring sync', start: '2026-11-04T13:00', end: '2026-11-04T14:30', cal: 3, resource: 'atlas' }, { id: 'e15', title: 'Billing walkthrough', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 4, resource: 'birch' }, { id: 'e16', title: 'Roadmap', start: '2026-11-04T15:00', end: '2026-11-04T16:30', cal: 3, resource: 'cedar' }, { id: 'a1', title: 'Jun on call', start: '2026-11-02', end: '2026-11-04', allDay: true, cal: 2 }, { id: 'a2', title: 'Release 2026.11', start: '2026-11-06', end: '2026-11-06', allDay: true, cal: 1 },]type Event = (typeof EVENTS)[number]function useEvents() { const events = state<Event[]>(EVENTS) const change = (e: Event, to: Partial<Event>) => { events.value = events.value.map(x => (x.id === e.id ? { ...x, ...to } : x)) } return { events, change, create: (e: Event) => (events.value = [...events.value, e]), edit: (e: Event) => change(e, e), remove: (e: Event) => (events.value = events.value.filter(x => x.id !== e.id)), }}Installation
npm install @weft-js/warpUsage
tsx
import { Calendar } from '@weft-js/warp'Views
Read-only month
views limits the tabs and readOnly turns off every edit.
tsx
import { Calendar } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function Month() { return ( <Calendar events={EVENTS} calendars={CALENDARS} views={[...COMPACT_VIEWS]} defaultView="month" defaultDate={CAL_TODAY} today={CAL_TODAY} now={CAL_NOW} locale="en-US" firstDayOfWeek={1} readOnly /> )}const CAL_TODAY = '2026-11-02'const CAL_NOW = '2026-11-04T10:40'const CALENDARS = ['Releases', 'On-call', 'Team', 'Customers'].map((name, i) => ({ id: i + 1, name }))const EVENTS: CalEvent[] = [ { id: 'e1', title: 'Standup', start: '2026-11-02T09:30', end: '2026-11-02T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e2', title: 'Standup', start: '2026-11-03T09:30', end: '2026-11-03T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e3', title: 'Standup', start: '2026-11-04T09:30', end: '2026-11-04T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e4', title: 'Standup', start: '2026-11-05T09:30', end: '2026-11-05T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e5', title: 'Standup', start: '2026-11-06T09:30', end: '2026-11-06T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e6', title: 'Ship checkout to production', start: '2026-11-02T11:00', end: '2026-11-02T12:00', cal: 1, location: 'Room Atlas', attendees: ['Tomás Oliveira', 'Mara Lindqvist'], resource: 'atlas' }, { id: 'e7', title: 'Search ranking review', start: '2026-11-03T14:00', end: '2026-11-03T15:30', cal: 3, attendees: ['Lena Fischer', 'Noor Haddad'], video: true, resource: 'birch' }, { id: 'e8', title: 'Acme onboarding', start: '2026-11-04T10:00', end: '2026-11-04T11:00', cal: 4, video: true, attendees: ['Priya Raman'] }, { id: 'e9', title: 'Incident review: mobile-bff', start: '2026-11-04T10:30', end: '2026-11-04T11:30', cal: 2, attendees: ['Sam Okafor', 'Jun Tanaka'], resource: 'cedar' }, { id: 'e10', title: 'Rotate edge certificates', start: '2026-11-05T13:00', end: '2026-11-05T14:00', cal: 2, locked: true, location: 'Do not move' }, { id: 'e11', title: 'Northwind renewal', start: '2026-11-05T15:00', end: '2026-11-05T16:00', cal: 4, tentative: true, location: 'Waiting on Inés' }, { id: 'e12', title: 'Release retro', start: '2026-11-06T11:00', end: '2026-11-06T12:00', cal: 1, video: true, resource: 'atlas' }, { id: 'e13', title: 'Design crit', start: '2026-11-04T09:00', end: '2026-11-04T10:00', cal: 3, resource: 'atlas' }, { id: 'e14', title: 'Hiring sync', start: '2026-11-04T13:00', end: '2026-11-04T14:30', cal: 3, resource: 'atlas' }, { id: 'e15', title: 'Billing walkthrough', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 4, resource: 'birch' }, { id: 'e16', title: 'Roadmap', start: '2026-11-04T15:00', end: '2026-11-04T16:30', cal: 3, resource: 'cedar' }, { id: 'a1', title: 'Jun on call', start: '2026-11-02', end: '2026-11-04', allDay: true, cal: 2 }, { id: 'a2', title: 'Release 2026.11', start: '2026-11-06', end: '2026-11-06', allDay: true, cal: 1 },]const COMPACT_VIEWS = ['month', 'agenda'] as constRooms timeline
resources adds the rows, and events point at one with resource. timeline sets the hours it spans.
tsx
import { state } from '@weft-js/core'import { Calendar } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function Rooms() { const s = useEvents() return <Calendar events={s.events.value} calendars={CALENDARS} resources={ROOMS} views={[...ROOM_VIEWS]} timeline={ROOM_HOURS} defaultView="timeline" defaultDate="2026-11-04" today={CAL_TODAY} now={CAL_NOW} locale="en-US" onMove={s.change} onResize={s.change} />}const CAL_TODAY = '2026-11-02'const CAL_NOW = '2026-11-04T10:40'const CALENDARS = ['Releases', 'On-call', 'Team', 'Customers'].map((name, i) => ({ id: i + 1, name }))const ROOMS = [{ id: 'atlas', name: 'Atlas', meta: '8 seats' }, { id: 'birch', name: 'Birch', meta: '6 seats' }, { id: 'cedar', name: 'Cedar', meta: '12 seats' }]const EVENTS: CalEvent[] = [ { id: 'e1', title: 'Standup', start: '2026-11-02T09:30', end: '2026-11-02T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e2', title: 'Standup', start: '2026-11-03T09:30', end: '2026-11-03T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e3', title: 'Standup', start: '2026-11-04T09:30', end: '2026-11-04T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e4', title: 'Standup', start: '2026-11-05T09:30', end: '2026-11-05T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e5', title: 'Standup', start: '2026-11-06T09:30', end: '2026-11-06T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e6', title: 'Ship checkout to production', start: '2026-11-02T11:00', end: '2026-11-02T12:00', cal: 1, location: 'Room Atlas', attendees: ['Tomás Oliveira', 'Mara Lindqvist'], resource: 'atlas' }, { id: 'e7', title: 'Search ranking review', start: '2026-11-03T14:00', end: '2026-11-03T15:30', cal: 3, attendees: ['Lena Fischer', 'Noor Haddad'], video: true, resource: 'birch' }, { id: 'e8', title: 'Acme onboarding', start: '2026-11-04T10:00', end: '2026-11-04T11:00', cal: 4, video: true, attendees: ['Priya Raman'] }, { id: 'e9', title: 'Incident review: mobile-bff', start: '2026-11-04T10:30', end: '2026-11-04T11:30', cal: 2, attendees: ['Sam Okafor', 'Jun Tanaka'], resource: 'cedar' }, { id: 'e10', title: 'Rotate edge certificates', start: '2026-11-05T13:00', end: '2026-11-05T14:00', cal: 2, locked: true, location: 'Do not move' }, { id: 'e11', title: 'Northwind renewal', start: '2026-11-05T15:00', end: '2026-11-05T16:00', cal: 4, tentative: true, location: 'Waiting on Inés' }, { id: 'e12', title: 'Release retro', start: '2026-11-06T11:00', end: '2026-11-06T12:00', cal: 1, video: true, resource: 'atlas' }, { id: 'e13', title: 'Design crit', start: '2026-11-04T09:00', end: '2026-11-04T10:00', cal: 3, resource: 'atlas' }, { id: 'e14', title: 'Hiring sync', start: '2026-11-04T13:00', end: '2026-11-04T14:30', cal: 3, resource: 'atlas' }, { id: 'e15', title: 'Billing walkthrough', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 4, resource: 'birch' }, { id: 'e16', title: 'Roadmap', start: '2026-11-04T15:00', end: '2026-11-04T16:30', cal: 3, resource: 'cedar' }, { id: 'a1', title: 'Jun on call', start: '2026-11-02', end: '2026-11-04', allDay: true, cal: 2 }, { id: 'a2', title: 'Release 2026.11', start: '2026-11-06', end: '2026-11-06', allDay: true, cal: 1 },]type Event = (typeof EVENTS)[number]function useEvents() { const events = state<Event[]>(EVENTS) const change = (e: Event, to: Partial<Event>) => { events.value = events.value.map(x => (x.id === e.id ? { ...x, ...to } : x)) } return { events, change, create: (e: Event) => (events.value = [...events.value, e]), edit: (e: Event) => change(e, e), remove: (e: Event) => (events.value = events.value.filter(x => x.id !== e.id)), }}const ROOM_VIEWS = ['timeline', 'day'] as constconst ROOM_HOURS: [number, number] = [540, 1020]Overlapping meetings
Events that overlap share the column in lanes, so none hides another. Switch to Week to see the same morning beside the rest.
tsx
import { state } from '@weft-js/core'import { Calendar } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function BusyDay() { const s = useEvents() return <Calendar events={s.events.value} calendars={CALENDARS} views={[...DAY_VIEWS]} defaultView="day" defaultDate="2026-11-04" today={CAL_TODAY} now={CAL_NOW} locale="en-US" firstDayOfWeek={1} workingHours={[540, 1080]} onMove={s.change} onResize={s.change} />}const CAL_TODAY = '2026-11-02'const CAL_NOW = '2026-11-04T10:40'const CALENDARS = ['Releases', 'On-call', 'Team', 'Customers'].map((name, i) => ({ id: i + 1, name }))const EVENTS: CalEvent[] = [ { id: 'e1', title: 'Standup', start: '2026-11-02T09:30', end: '2026-11-02T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e2', title: 'Standup', start: '2026-11-03T09:30', end: '2026-11-03T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e3', title: 'Standup', start: '2026-11-04T09:30', end: '2026-11-04T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e4', title: 'Standup', start: '2026-11-05T09:30', end: '2026-11-05T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e5', title: 'Standup', start: '2026-11-06T09:30', end: '2026-11-06T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e6', title: 'Ship checkout to production', start: '2026-11-02T11:00', end: '2026-11-02T12:00', cal: 1, location: 'Room Atlas', attendees: ['Tomás Oliveira', 'Mara Lindqvist'], resource: 'atlas' }, { id: 'e7', title: 'Search ranking review', start: '2026-11-03T14:00', end: '2026-11-03T15:30', cal: 3, attendees: ['Lena Fischer', 'Noor Haddad'], video: true, resource: 'birch' }, { id: 'e8', title: 'Acme onboarding', start: '2026-11-04T10:00', end: '2026-11-04T11:00', cal: 4, video: true, attendees: ['Priya Raman'] }, { id: 'e9', title: 'Incident review: mobile-bff', start: '2026-11-04T10:30', end: '2026-11-04T11:30', cal: 2, attendees: ['Sam Okafor', 'Jun Tanaka'], resource: 'cedar' }, { id: 'e10', title: 'Rotate edge certificates', start: '2026-11-05T13:00', end: '2026-11-05T14:00', cal: 2, locked: true, location: 'Do not move' }, { id: 'e11', title: 'Northwind renewal', start: '2026-11-05T15:00', end: '2026-11-05T16:00', cal: 4, tentative: true, location: 'Waiting on Inés' }, { id: 'e12', title: 'Release retro', start: '2026-11-06T11:00', end: '2026-11-06T12:00', cal: 1, video: true, resource: 'atlas' }, { id: 'e13', title: 'Design crit', start: '2026-11-04T09:00', end: '2026-11-04T10:00', cal: 3, resource: 'atlas' }, { id: 'e14', title: 'Hiring sync', start: '2026-11-04T13:00', end: '2026-11-04T14:30', cal: 3, resource: 'atlas' }, { id: 'e15', title: 'Billing walkthrough', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 4, resource: 'birch' }, { id: 'e16', title: 'Roadmap', start: '2026-11-04T15:00', end: '2026-11-04T16:30', cal: 3, resource: 'cedar' }, { id: 'a1', title: 'Jun on call', start: '2026-11-02', end: '2026-11-04', allDay: true, cal: 2 }, { id: 'a2', title: 'Release 2026.11', start: '2026-11-06', end: '2026-11-06', allDay: true, cal: 1 },]type Event = (typeof EVENTS)[number]function useEvents() { const events = state<Event[]>(EVENTS) const change = (e: Event, to: Partial<Event>) => { events.value = events.value.map(x => (x.id === e.id ? { ...x, ...to } : x)) } return { events, change, create: (e: Event) => (events.value = [...events.value, e]), edit: (e: Event) => change(e, e), remove: (e: Event) => (events.value = events.value.filter(x => x.id !== e.id)), }}const DAY_VIEWS = ['day', 'week'] as constAgenda of the week
The same events as a list, day by day: what a phone or a quick look wants.
tsx
import { Calendar } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function Agenda() { return ( <Calendar events={EVENTS} calendars={CALENDARS} views={[...AGENDA_VIEWS]} defaultView="agenda" defaultDate={CAL_TODAY} today={CAL_TODAY} now={CAL_NOW} locale="en-US" firstDayOfWeek={1} readOnly /> )}const CAL_TODAY = '2026-11-02'const CAL_NOW = '2026-11-04T10:40'const CALENDARS = ['Releases', 'On-call', 'Team', 'Customers'].map((name, i) => ({ id: i + 1, name }))const EVENTS: CalEvent[] = [ { id: 'e1', title: 'Standup', start: '2026-11-02T09:30', end: '2026-11-02T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e2', title: 'Standup', start: '2026-11-03T09:30', end: '2026-11-03T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e3', title: 'Standup', start: '2026-11-04T09:30', end: '2026-11-04T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e4', title: 'Standup', start: '2026-11-05T09:30', end: '2026-11-05T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e5', title: 'Standup', start: '2026-11-06T09:30', end: '2026-11-06T09:45', cal: 3, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR' }, { id: 'e6', title: 'Ship checkout to production', start: '2026-11-02T11:00', end: '2026-11-02T12:00', cal: 1, location: 'Room Atlas', attendees: ['Tomás Oliveira', 'Mara Lindqvist'], resource: 'atlas' }, { id: 'e7', title: 'Search ranking review', start: '2026-11-03T14:00', end: '2026-11-03T15:30', cal: 3, attendees: ['Lena Fischer', 'Noor Haddad'], video: true, resource: 'birch' }, { id: 'e8', title: 'Acme onboarding', start: '2026-11-04T10:00', end: '2026-11-04T11:00', cal: 4, video: true, attendees: ['Priya Raman'] }, { id: 'e9', title: 'Incident review: mobile-bff', start: '2026-11-04T10:30', end: '2026-11-04T11:30', cal: 2, attendees: ['Sam Okafor', 'Jun Tanaka'], resource: 'cedar' }, { id: 'e10', title: 'Rotate edge certificates', start: '2026-11-05T13:00', end: '2026-11-05T14:00', cal: 2, locked: true, location: 'Do not move' }, { id: 'e11', title: 'Northwind renewal', start: '2026-11-05T15:00', end: '2026-11-05T16:00', cal: 4, tentative: true, location: 'Waiting on Inés' }, { id: 'e12', title: 'Release retro', start: '2026-11-06T11:00', end: '2026-11-06T12:00', cal: 1, video: true, resource: 'atlas' }, { id: 'e13', title: 'Design crit', start: '2026-11-04T09:00', end: '2026-11-04T10:00', cal: 3, resource: 'atlas' }, { id: 'e14', title: 'Hiring sync', start: '2026-11-04T13:00', end: '2026-11-04T14:30', cal: 3, resource: 'atlas' }, { id: 'e15', title: 'Billing walkthrough', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 4, resource: 'birch' }, { id: 'e16', title: 'Roadmap', start: '2026-11-04T15:00', end: '2026-11-04T16:30', cal: 3, resource: 'cedar' }, { id: 'a1', title: 'Jun on call', start: '2026-11-02', end: '2026-11-04', allDay: true, cal: 2 }, { id: 'a2', title: 'Release 2026.11', start: '2026-11-06', end: '2026-11-06', allDay: true, cal: 1 },]const AGENDA_VIEWS = ['agenda', 'week'] as constWhen to use
Use it for
- People read and change a schedule of events
- Events move, resize or get created by dragging
Reach for something else
- InlineCalendar, when people only pick a day
- Agenda, when a read-only list of what is next is enough
Accessibility
- Tab
- Moves between the toolbar, the views and the events
- M
- On a focused event: starts moving it with the arrow keys
- Enter
- Opens the focused event
- Every drag has a keyboard route, and the event editor can change the same fields without dragging.
- Pass
todayandnowto keep the server and browser in step. Without them they arrive after the page loads.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
events | CalEvent[] | — | The events to show. You own this list. |
calendars | CalendarSource[] | — | The named sources in the side rail. |
view | CalView | State<CalView> | — | The view showing: a State to share it, or a value. |
defaultView | CalView | — | The view it opens on when view isn't given. Week without either. |
views | CalView[] | — | The views offered as tabs, in this order. All six without it. |
date | string | State<string> | — | The date the view is on (2026-11-04): a State to share it, or a value. |
defaultDate | string | — | The date it opens on when date isn't given. Today without either. |
timeZone | string | State<string | null> | — | The toolbar chip's zone. Without one, wall times show as they are. |
zones | { label: string; zone: string; }[] | — | Secondary zones in the rail. |
today | string | — | Today's date (2026-11-02), marked in every view. The browser's date after mount without it, so hydration writes nothing. |
now | string | — | The now line's wall time; the browser's clock after mount without it. |
locale | string | — | The locale for day and month names, times and the first day of the week. The browser's without it. |
hourCycle | string | — | h12 or h23 to force a clock; the locale's without it. |
firstDayOfWeek | number | — | The week's first day, 0 for Sunday to 6 for Saturday. The locale's without it. |
snap | number | — | Minutes a drag or resize snaps to. 15 without it. |
workingHours | [number, number] | — | The start and end of the working day, in minutes from midnight: [540, 1080] is 09:00 to 18:00. The rest is shaded. |
live | LiveState | — | The toolbar LiveStatus. |
resources | Resource[] | — | Timeline rows; events point at one with resource. |
timeline | [number, number] | — | The hours the timeline spans, in minutes from midnight. |
counts | Record<string, number> | — | Year view's counts; from events without it. |
readOnly | boolean | false | Turns off dragging, resizing, creating and the keyboard move mode. Events still open their popover. |
| Event | Type | Default | Description |
|---|---|---|---|
onViewChange | ((v: CalView) => void) | — | Hears every change of view, by tab, key or the mini month. |
onDateChange | ((d: string) => void) | — | Hears the new date when the arrows, Today, the mini month or a drill-in move it. |
onTimeZoneChange | ((z: string | null) => void) | — | Hears a zone picked from the toolbar chip, or null for wall times. |
onMove | ((e: CalEvent, to: EventChange, reason: Reason) => void | Promise<unknow… | — | Called with the event and its new times. Return a rejected promise to put it back. |
onResize | ((e: CalEvent, to: EventChange, reason: Reason) => void | Promise<unknow… | — | An event's edge dragged to a new time. A rejected promise puts it back and announces why. |
onCreate | ((e: CalEvent) => void) | — | A new event saved from the editor, after a drag over empty time, a press on a slot or New event. |
onEdit | ((e: CalEvent, scope?: RecurrenceScope | undefined) => void) | — | An event saved from the editor; scope says which of a repeating event's occurrences. |
onDelete | ((e: CalEvent, scope?: RecurrenceScope | undefined) => void) | — | An event deleted after its confirmation; scope says which of a repeating event's occurrences. |
onOpen | ((e: CalEvent) => void) | — | An event's popover opened, by press or Enter. |
onJoin | ((e: CalEvent) => void) | — | Join pressed in the popover of an event with a video link. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="calendar"] [data-part="root"]
rootapp-barapp-titlerange-labelspacerlisttriggerindicatorlayoutraileyebrowsourcesmainyear-wrap