Event Calendar
Events on a month grid, a week or a day of hours, or an agenda list, with Today, previous and next.Month
Preview
Code
October 2026
Installation
Package
CLI (copy source)
pnpm
pnpm add @advui/datanpm
npm install @advui/dataUsage
import { EventCalendar } from '@advui/data'
<EventCalendar
events={[
{ id: 'standup', title: 'Team standup', start: new Date(2026, 9, 28, 9), end: new Date(2026, 9, 28, 9, 30) },
]}
onEventPress={(event) => open(event.id)}
/>Examples
Week
Starts on Monday; events that overlap share the day’s width. Drag an event, or its bottom edge, to change it; a line marks the current time.Preview
Code
Oct 26 – Nov 1, 2026
Agenda
A list of the month’s days with events, which suits phones.Preview
Code
October 2026
Thu, Oct 1
5W round kickoff, Thursday, October 1, 2026, 10:00 AM to 11:00 AM
Wed, Oct 7
Data review, Wednesday, October 7, 2026, 2:00 PM to 3:00 PM
Mon, Oct 12
Field visit: Bago, All day, Monday, October 12, 2026 to Wednesday, October 14, 2026
Tue, Oct 13
Field visit: Bago, All day, Monday, October 12, 2026 to Wednesday, October 14, 2026
Wed, Oct 14
Field visit: Bago, All day, Monday, October 12, 2026 to Wednesday, October 14, 2026
Fri, Oct 16
Kobo training, Friday, October 16, 2026, 9:00 AM to 12:00 PM
Fri, Oct 23
Submissions close, All day, Friday, October 23, 2026
Wed, Oct 28
Team standup, Wednesday, October 28, 2026, 9:00 AM to 9:30 AM
Map review, Wednesday, October 28, 2026, 11:00 AM to 12:00 PM
API reference
EventCalendar
| Prop | Type | Default | Description |
|---|---|---|---|
events required | readonly CalendarEvent[] | — | `{ id, title, start, end?, allDay?, tone? }` events. |
view | 'month' | 'week' | 'day' | 'agenda' | — | The view shown. |
defaultView | 'month' | 'week' | 'day' | 'agenda' | 'month' | Starting `view` when uncontrolled. |
onViewChange | (view: EventCalendarView) => void | — | Called with the new `view`. |
views | EventCalendarView[] | ['month', 'week', 'day', 'agenda'] | The views to switch between, in order. With one, there is no switcher. |
date | Date | — | A day in the shown month, week or day. |
defaultDate | Date | — | Starting `date` when uncontrolled. Default: today. |
onDateChange | (date: Date) => void | — | Called with the new `date`: previous, next, Today, or a day opened. |
onEventPress | (event: CalendarEvent) => void | — | Makes events buttons. Without it they are text. |
onEventChange | (change: CalendarEventChange) => void | — | Makes timed events in the week and day views movable: drag one to another time or day (a long press first on touch screens), its bottom edge to change when it ends, or use the arrow keys or screen reader actions. Called with `{ event, start, end }`: update `events` with them. |
snapMinutes | number | 15 | Minutes that moved times snap to, from midnight. |
now | Date | — | The time on the line across today in the week and day views. Default: the clock, each minute, from after the first render. |
onDatePress | (date: Date) => void | — | A month day’s number or a week day’s heading was pressed. With the day view in `views`, that day opens there too. |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | First day of the week: 0 is Sunday, 1 Monday. |
locale | string | — | BCP 47 locale for dates and times. Defaults to the device locale. |
today | Date | — | Overrides today, for tests and screenshots. |
maxEventsPerDay | number | 3 | Lines a month day shows: its events, or fewer and “+2 more”. |
timeGridHeight | SizeTokens | number | '128' | Height of the scrolling hours in the week and day views. |
scrollToHour | number | 8 | The hour at the top when the week or day view opens. |
labels | Partial<EventCalendarLabels> | — | Button names and words, such as `today`, `nextMonth`, `allDay` and `more(count)`, for other languages. |
CalendarEvent
One event.| Prop | Type | Default | Description |
|---|---|---|---|
id required | string | — | Unique key. |
title required | string | — | Shown and read. |
start required | Date | — | When it starts. |
end | Date | — | When it ends: default an hour after `start`. For an all-day event, its last day. |
allDay | boolean | — | Fills whole days; shown above the hours in the week and day views. |
tone | 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral' | 'primary' | Color, as a soft fill with its text color. |
readOnly | boolean | — | Not moved or resized, even with `onEventChange`. |
Accessibility
- The month is a
tablenamed by its month, with a column header per weekday; each day is acell(web). - A day’s number is a button named with its date and event count (“Wednesday, October 28, 2026, 4 events”), with
aria-current="date"for today; iOS and Android add “today” to the name. - Events are buttons when
onEventPressis set, named with their title, day and times (“Team standup, Wednesday, October 28, 2026, 9:00 AM to 9:30 AM”); otherwise that name is hidden text. - In the week and day views each day is a
groupnamed by its date (web), holding its events in time order. The time gutter is hidden. - With
onEventChange, timed events in the week and day views are buttons even withoutonEventPress, described by how to move them with the keyboard (web). Each change is announced with the event’s new name. On iOS and Android they have actions instead: “Move 15 minutes earlier”, “Move to Thursday”, “End 15 minutes later”… - The current-time line is hidden from screen readers.
- The title is a polite live region, so moving by month, week or day is announced. The view switcher is a Toggle Group (
radiogroup). - On phones a month day shows dots for its events, hidden from screen readers: its name counts them, and its number opens the day.
| Key | Action |
|---|---|
| Tab | Moves through the toolbar, then the days and events in order. |
| Enter / Space | Opens a day or presses an event. |
| Arrow keys | Move between views in the switcher. |
| Up / Down | With `onEventChange`, move a focused event `snapMinutes` earlier or later. |
| Left / Right | Move a focused event to the day before or after, if shown. |
| Shift + Up / Down | End a focused event earlier or later. |
| Escape | Puts an event that is being dragged back. |
Responsive behavior
Below sm a month day shows dots instead of event titles; the agenda view lists them in full.
Platform notes
Web
The days and the all-day row stay pinned above the hours with
position: sticky. A mouse drags an event once it moves, a finger after holding still for a moment; near the top or bottom of the hours a drag scrolls them.iOS
The week and day views are a ScrollView whose header is pinned (
stickyHeaderIndices), scrolled to scrollToHour once laid out. iOS has no table roles: days and events are buttons. A long press picks an event up (near its bottom edge, its end), and the hours and the ScrollArea around them stop scrolling until the finger lifts, so a drag reaches the hours in view. Not yet checked on a device.Android
Same as iOS, with the ripple on events when the config has
androidRipple.