Agenda
A day at a time for a phone: a week strip, swipeable days and a button to add.
SourcePackage @weft-js/warp
Preview
tsx
import { state } from '@weft-js/core'import { Agenda } from '@weft-js/warp'import type { CalEvent } from '@weft-js/warp-core'export function TeamWeek() { const events = state(TEAM_EVENTS) const move = (e: CalEvent, to: { start: string; end: string }) => (events.value = events.value.map(x => (x.id === e.id ? { ...x, ...to } : x))) return ( <div style="block-size:620px;position:relative"> <Agenda events={events.value} calendars={TEAM_CALENDARS} defaultDate={TODAY} today={TODAY} now={SCHEDULE_NOW} timeZone={TEAM_ZONE} locale="en-GB" firstDayOfWeek={1} onMove={move} onCreate={e => (events.value = [...events.value, e])} /> </div> )}const TODAY = '2026-11-03'const SCHEDULE_NOW = '2026-11-03T10:40'const TEAM_ZONE = 'Europe/Stockholm'const TEAM_CALENDARS = ['Platform', 'Web', 'Data', 'Mobile', 'Releases', 'Time off'].map((name, i) => ({ id: i + 1, name }))const TEAM_EVENTS: CalEvent[] = [ { id: 'e1', title: 'Platform standup', start: '2026-11-02T09:00', end: '2026-11-02T09:15', cal: 1, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', location: 'Room Atlas', attendees: ['Mara Lindqvist', 'Jun Tanaka'] }, { id: 'e2', title: 'Platform standup', start: '2026-11-03T09:00', end: '2026-11-03T09:15', cal: 1, recurrence: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', location: 'Room Atlas', attendees: ['Mara Lindqvist', 'Jun Tanaka'] }, { id: 'e3', title: 'Checkout review', start: '2026-11-03T10:00', end: '2026-11-03T11:00', cal: 2, video: true, attendees: ['Priya Raman', 'Tomás Oliveira', 'Mara Lindqvist'] }, { id: 'e4', title: 'Incident review: mobile-bff', start: '2026-11-03T13:00', end: '2026-11-03T13:45', cal: 4, video: true, location: 'Room Birch', attendees: ['Sam Okafor', 'Inés Vidal', 'Jun Tanaka'] }, { id: 'e5', title: 'Ranking v2 handover', start: '2026-11-03T15:00', end: '2026-11-03T16:00', cal: 3, location: 'Room Cedar', attendees: ['Lena Fischer', 'Noor Haddad'] }, { id: 'e6', title: 'Priya out of office', start: '2026-11-03', end: '2026-11-03', allDay: true, cal: 6 }, { id: 'e7', title: 'Release 2026.11', start: '2026-11-04T11:00', end: '2026-11-04T12:00', cal: 5, attendees: ['Mara Lindqvist', 'Jun Tanaka', 'Tomás Oliveira'] }, { id: 'e8', title: 'Design crit', start: '2026-11-04T14:00', end: '2026-11-04T15:00', cal: 2, tentative: true, video: true }, { id: 'e9', title: 'Cost review', start: '2026-11-05T10:00', end: '2026-11-05T11:00', cal: 1, recurrence: 'FREQ=MONTHLY', attendees: ['Mara Lindqvist', 'Lena Fischer'] }, { id: 'e10', title: 'On-call handover', start: '2026-11-06T16:00', end: '2026-11-06T16:30', cal: 1, recurrence: 'FREQ=WEEKLY', video: true },]Installation
npm install @weft-js/warpUsage
tsx
import { Agenda } from '@weft-js/warp'When to use
Use it for
- A calendar on a phone or in a narrow column
Reach for something else
- Calendar, when there is room for a whole week
Accessibility
- LeftandRight
- Move between days in the strip
- Shift+F10
- Moves the focused event
- The week strip is a set of tabs. A long press always has a keyboard path.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
events | CalEvent[] | — | The events. |
date | string | State<string> | — | The day it opens on: a state it writes as you page, or a plain value. |
defaultDate | string | — | The day it opens on. |
title | unknown | — | The heading. |
calendars | CalendarSource[] | — | The calendars the events belong to, for their colours and names. |
timeZone | string | — | The IANA zone times are shown in, such as Europe/Berlin. The browser's otherwise. |
today | string | — | Pins today's date, for server rendering and tests. The browser's clock otherwise. |
now | string | — | Pins the current time, for server rendering and tests. The browser's clock otherwise. |
locale | string | — | The language and region used to format values. |
hourCycle | string | — | h12 for AM and PM, h23 for a 24-hour clock. The locale's otherwise. |
firstDayOfWeek | number | — | 0 is Sunday, 1 is Monday. |
| Event | Type | Default | Description |
|---|---|---|---|
onDateChange | ((d: string) => void) | — | Called with the new day when you page or jump to today. |
onLongPress | ((e: CalEvent) => void) | — | Long press: open your own sheet. Without it the built-in MoveSheet opens and calls onMove. |
onMove | ((e: CalEvent, to: { start: string; end: string; resource?: string | und… | — | An event was moved. Without onLongPress, the built-in MoveSheet does this. |
onOpen | ((e: CalEvent) => void) | — | An event was pressed. |
onCreate | ((e: CalEvent) => void) | — | Adds the + button, which opens the editor. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="agenda"] [data-part="row"]
rowrootapp-barapp-titlespacerstripviewporttrackpageday-title