A composable calendar component with day, week, and month views for displaying and managing events with drag interactions.
Import the Agenda component and the useAgenda hook. Access all subcomponents using dot notation.
import {Agenda, useAgenda} from "@heroui-pro/react";
const agenda = useAgenda({
events: [...],
defaultView: "week",
});
<Agenda {...agenda}>
<Agenda.Header>
<Agenda.Heading />
<Agenda.ViewSelector />
<Agenda.Navigation>
<Agenda.NavButton slot="previous" />
<Agenda.TodayButton />
<Agenda.NavButton slot="next" />
</Agenda.Navigation>
</Agenda.Header>
<Agenda.Body>
{/* Day / Week view */}
<Agenda.WeekHeader />
<Agenda.AllDaySection>
<Agenda.AllDayLabel>all-day</Agenda.AllDayLabel>
{agenda.allDayLayout.map((item) => (
<Agenda.AllDayEvent key={item.event.id} event={item.event} colStart={item.colStart} colSpan={item.colSpan} row={item.row} />
))}
</Agenda.AllDaySection>
<Agenda.TimeGrid>
<Agenda.CurrentTimeIndicator />
{agenda.visibleDays.map((day) => (
<Agenda.DayColumn key={day.toString()} date={day}>
{agenda.getEventsForDay(day).map((event) => (
<Agenda.Event key={event.id} event={event} />
))}
</Agenda.DayColumn>
))}
</Agenda.TimeGrid>
{/* Month view */}
<Agenda.MonthGrid>
{agenda.visibleWeeks.map((week, i) => {
const rowLayout = agenda.getMonthRowLayout(week);
return (
<Agenda.MonthRow key={i} spanningRowCount={rowLayout.rowCount}>
{rowLayout.items.map((item) => (
<Agenda.MonthSpanningEvent key={item.event.id} event={item.event} colStart={item.colStart} colSpan={item.colSpan} row={item.row} />
))}
{week.map((day, colIdx) => (
<Agenda.MonthCell key={day.toString()} date={day} spanningRowCount={rowLayout.rowCountPerCol[colIdx] ?? 0}>
{agenda.getPerCellEvents(day, week).map((event) => (
<Agenda.MonthEvent key={event.id} event={event} />
))}
</Agenda.MonthCell>
))}
</Agenda.MonthRow>
);
})}
</Agenda.MonthGrid>
</Agenda.Body>
</Agenda>The Agenda supports three views controlled via the ViewSelector or programmatically through setView:
Events are defined as an array of AgendaEvent objects:
interface AgendaEvent {
id: string;
title: string;
start: CalendarDateTime;
end: CalendarDateTime;
color?: string;
isAllDay?: boolean;
isReadOnly?: boolean;
status?: "confirmed" | "unconfirmed";
}Set status: "unconfirmed" to render an event with a dashed border and transparent background, indicating a tentative or pending event.
Set isReadOnly: true to prevent an event from being moved or resized. The event can still be selected but drag interactions are disabled and the resize handle is hidden.
All drag interactions work out of the box when callbacks are provided:
On mobile, drag interactions (create, move, resize) are disabled by default. The consumer controls this by passing undefined for the drag callbacks when on a small screen.
const agenda = useAgenda({
events,
onEventCreate: (event) => { /* { start, end } */ },
onEventMove: (id, start, end) => { /* moved */ },
onEventResize: (id, start, end) => { /* resized */ },
onEventDelete: (id) => { /* deleted via Delete/Backspace key */ },
onEventSelect: (id) => { /* selected */ },
});All-day events appear in a collapsible section above the time grid. Multi-day all-day events span across day columns.
The section includes an expand/collapse toggle. When collapsed, event counts are shown per day (e.g. "2 events"). Customize the collapsed label with the collapsedLabel prop on Agenda.AllDaySection.
Multi-day all-day events render as bars spanning across the month grid row. Use getMonthRowLayout(week) to compute layout positions and getPerCellEvents(day, week) for per-cell events.
Agenda.MonthCell limits visible events via the maxEvents prop (default: 2). Overflow shows a "N more" link that navigates to the day view. Customize the label with the moreLabel prop.
Clicking a date number in the month grid navigates to that date in day view. The first day of each month shows the month name (e.g. "May 1").
Saturday and Sunday columns automatically receive a subtle gray background (data-weekend attribute) in all views.
A live indicator shows the current time in the time grid:
.agenda — Root container. Sets CSS custom properties for sizing.--agenda-slot-height — Height of each hour slot (default: 60px).--agenda-time-column-width — Width of the time labels column (default: 58px).--agenda-current-time-color — Color of the current time indicator (default: var(--color-danger)).--agenda-event-radius — Border radius of event cards (default: var(--radius-md))..agenda__header — Flex container for heading, view selector, and navigation..agenda__heading — Month/year title text..agenda__navigation — Wrapper for nav buttons and today button..agenda__nav-button — Override hook for navigation arrow buttons (uses HeroUI Button)..agenda__today-button — Override hook for the Today button (uses HeroUI Button)..agenda__view-selector — Override hook for the view selector (uses HeroUI Segment)..agenda__week-header — Row of day headers above the time grid..agenda__day-header — Individual day header with name and date..agenda__time-grid — Scrollable time grid container..agenda__time-labels — Sticky column of hour labels..agenda__time-label — Individual hour label..agenda__day-column — Column for a single day's events..agenda__time-slot — Individual hour slot row..agenda__event — Positioned event card in the time grid..agenda__event-title — Event title text..agenda__event-time — Event time range text..agenda__resize-handle — Bottom resize handle with hover indicator..agenda__all-day-section — Grid container for all-day events..agenda__all-day-toggle — Expand/collapse chevron button..agenda__all-day-label — "all-day" label text..agenda__all-day-event — All-day event bar..agenda__all-day-summary — Collapsed event count per day..agenda__month-grid — Month grid container..agenda__month-weekday-header — Sticky weekday names row..agenda__month-row — Week row in the month grid..agenda__month-cell — Individual day cell..agenda__month-cell-date — Date number button (navigates to day view)..agenda__month-cell-more — "N more" overflow link..agenda__month-event — Per-cell event in month view..agenda__month-spanning-event — Multi-day event bar spanning across cells.[data-dragging] — Applied during drag interactions.[data-resizing] — Applied during resize.[data-selected="true"] — Applied to selected events.[data-status="unconfirmed"] — Dashed border style for tentative events.[data-readonly] — Applied to read-only events.[data-weekend] — Applied to weekend columns and cells.[data-today] — Applied to today's date elements.[data-drop-target] — Applied to the target cell during drag..agenda__create-preview — Dashed preview rectangle during drag-to-create..agenda__drop-preview — Outlined preview at the target position during drag-to-move.The main hook for managing agenda state. Returns all data and methods needed by the component.
| Option | Type | Default | Description |
|---|---|---|---|
events | AgendaEvent[] | — | Array of events to display. Required. |
defaultView | "day" | "week" | "month" | "week" | Initial view. |
view | "day" | "week" | "month" | — | Controlled view state. |
onViewChange | (view: AgendaView) => void | — | Called when the view changes. |
defaultDate | CalendarDate | today | Initial focused date. |
date | CalendarDate | — | Controlled date state. |
onDateChange | (date: CalendarDate) => void | — | Called when the date changes. |
startHour | number | 0 | First visible hour in the time grid. |
endHour | number | 24 | Last visible hour in the time grid. |
slotDuration | number | 60 | Duration of each time slot in minutes. |
onEventCreate | (event: {start, end}) => void | — | Called when dragging to create a new event. |
onEventDelete | (id: string) => void | — | Called when Delete/Backspace is pressed on a selected event. |
onEventMove | (id, start, end) => void | — | Called when an event is dragged to a new position. |
onEventResize | (id, start, end) => void | — | Called when an event is resized. |
onEventSelect | (id: string | null) => void | — | Called when an event is selected or deselected. |
selectedEventId | string | null | — | Controlled selected event state. |
Root component. Wraps children in context and Motion providers.
Also supports all HTML div props.
Container for heading, view selector, and navigation controls.
Also supports all HTML div props.
Displays the current month and year (e.g. "May 2026").
Also supports all HTML h1 props.
Segmented control for switching between day, week, and month views. Built on the HeroUI Segment component.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "md" | "lg" | "sm" | Size of the segment control. |
Navigation button for previous/next. Built on the HeroUI Button component.
| Prop | Type | Default | Description |
|---|---|---|---|
slot | "previous" | "next" | — | Direction of navigation. |
Button to navigate to today's date. Built on the HeroUI Button component.
Collapsible section for all-day events with a CSS grid layout for spanning events.
| Prop | Type | Default | Description |
|---|---|---|---|
collapsedLabel | (count: number) => string | "N events" | Custom label for collapsed event counts. |
An all-day event bar positioned in the grid.
| Prop | Type | Default | Description |
|---|---|---|---|
event | AgendaEvent | — | The event data. Required. |
colStart | number | — | Grid column start index (0-based). |
colSpan | number | — | Number of columns to span. |
row | number | — | Row index for stacking. |
A timed event card positioned absolutely in a day column. Supports drag-to-move and drag-to-resize.
| Prop | Type | Default | Description |
|---|---|---|---|
event | AgendaEvent | — | The event data. Required. |
A day cell in the month grid. Limits visible events and shows overflow.
| Prop | Type | Default | Description |
|---|---|---|---|
date | CalendarDate | — | The date for this cell. Required. |
maxEvents | number | 2 | Maximum number of events to show before overflow. |
moreLabel | (count: number) => string | "N more" | Custom label for the overflow link. |
spanningRowCount | number | 0 | Number of spanning event rows above this cell. |
A multi-day event bar in the month grid, positioned absolutely across cells.
| Prop | Type | Default | Description |
|---|---|---|---|
event | AgendaEvent | — | The event data. Required. |
colStart | number | — | Column start index (0-based). |
colSpan | number | — | Number of columns to span. |
row | number | — | Row index for vertical stacking. |
A per-cell event in the month grid. Supports drag-to-move across cells.
| Prop | Type | Default | Description |
|---|---|---|---|
event | AgendaEvent | — | The event data. Required. |