Calendar
Date, multi-date and date-range calendar built on React Aria, with month/year chip pickers, presets and a footer.
Description
Calendar wraps React Aria's Calendar and RangeCalendar behind one component. mode picks the selection shape (single, multiple, range) and swaps the underlying React Aria root to match. Rendered bare it's just a month grid; pass children and it becomes a full panel, a presets rail next to a body of month grids and a footer with actions.
Reach for it for date pickers, booking and availability screens, and report date filters. The presets rail (Calendar.Presets) is what makes shortcuts like "Last 7 days" or a fixed time list work without a separate component.
If the user types a date rather than pointing at one, use Input instead of forcing a picker. If the surface is a list of dated records, not a single date choice, that's a Table, not this.
Calendar is a Create UI Pro component. With a Pro seat, npx @create-ui/cli add calendar installs it, and the previews here are marked with a Pro badge. It pulls in Button, Scroll Area and Text Link automatically.
Installation
Anatomy
Calendar.Panel is a row of columns: a Calendar.Presets rail, the Calendar.Body (month grids plus footer), and optionally a second Calendar.Presets for a time list.
Bare <Calendar /> (no children) renders just Calendar.Months. Calendar.Months and Calendar.Month both auto-render their internals (header, grid) when given no children of their own, so most of this tree is optional.
Usage
Examples
Eight examples, in order: prop-level variations first, selection modes through states, then two full compositions, date range picker with presets and time picker, that show how Calendar.Panel, Calendar.Presets and Calendar.Footer fit together.
Selection modes
mode decides the shape of the controlled value: a single DateValue for "single", an array of them for "multiple", and { start, end } for "range". Switching modes switches the underlying React Aria root, so the controlled value has to switch with it.
Appearances
appearance tints the whole calendar together: selection fill, range rail, today ring, and the Calendar.TodayLink all follow it. primary is indigo, neutral is near-black.
Sizes
size scales the whole shell, not just the day cells: lg is a 40px day with a 24px panel radius and a 72px footer, md is a 32px day with a 16px radius and a 56px footer.
Shapes
shape applies to days, month/year chips and presets at once. rounded follows the responsive component radius, pill goes fully round, square removes it.
Header variants
headerVariant controls how month and year are navigated. single shows one combined chip, multiple splits month and year into separate chips, plain renders a static heading with no picker at all.
States
Pass minValue / maxValue to bound the selectable range, isDateUnavailable to block specific days (weekends, holidays), isDisabled to lock the whole calendar, or outsideMonth="hidden" to blank out days from neighboring months instead of dimming them.
Date range picker with presets
Calendar.Presets renders a scrollable rail next to Calendar.Body. Each Calendar.Preset with a value writes that range into the calendar and highlights itself while it matches, which is how shortcuts like "Last 7 days" work.
Time picker
A second Calendar.Presets column works as an ordinary button list instead of a date shortcut: drive isSelected and onPress directly on Calendar.Preset and skip the value prop.
Accessibility
ARIA notes:
- The day grid sets
role="grid"with each day as agridcell, via React Aria'sCalendarGrid. Only the focused day sits in the native tab order, a roving-tabindex pattern. aria-selectedandaria-disabledare managed per cell automatically as selection state changes; the grid'saria-labelannounces the visible month.Calendar.MonthYearTriggeris a real<button>witharia-expandedanddata-statereflecting whether its picker is open.Calendar.TodayLinkandCalendar.Presetrender as native interactive elements, so pointer and keyboard activation come for free.- Built on React Aria's
CalendarandRangeCalendarprimitives, so announcements for date changes, range start and end, and unavailable dates follow their tested accessibility behavior.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's classes (via cn()):
Data slots and attributes:
- Structure:
calendar,calendar-panel,calendar-body,calendar-months,calendar-month,calendar-header,calendar-nav-previous/calendar-nav-next,calendar-month-year,calendar-heading,calendar-month-year-trigger,calendar-month-grid/calendar-year-grid,calendar-month-year-item,calendar-grid,calendar-weekday,calendar-day,calendar-day-range,calendar-day-surface,calendar-day-label,calendar-day-indicator,calendar-presets,calendar-presets-inner,calendar-presets-label,calendar-presets-list,calendar-preset,calendar-footer,calendar-actions,calendar-today-link. - State and variant attributes:
data-size,data-appearance,data-modeon the root;data-offsetanddata-viewoncalendar-month;data-scopeanddata-stateoncalendar-month-year-trigger;data-selectedoncalendar-month-year-itemandcalendar-preset. - React Aria state, mirrored automatically on days and cells:
data-selected,data-disabled,data-unavailable,data-outside-month,data-today,data-hovered,data-focus-visible.
calendarDayVariants, calendarMonthYearItemVariants and calendarPresetVariants are exported if you want the class recipes directly.
Target a specific state in CSS:
Related Components
- Popover: pair with
Calendarto build a dropdown date picker that opens from a trigger button or input. - Input: use when the date should be typed rather than picked from a grid.
- Table: use for a list of dated records instead of a single date choice.
API Reference
Every part is exported twice: as a member of the Calendar namespace (Calendar.Panel) and as a flat component (CalendarPanel). The headings below use the dotted form.
The date grid, selection, and keyboard behavior come from React Aria Calendar and RangeCalendar. Props marked React Aria are inherited and behave exactly as they do there; everything else is added by Create UI.
Calendar
The selection root. Renders React Aria's Calendar (single, multiple) or RangeCalendar (range) depending on mode, and opens the context every other part reads size, appearance, shape and friends from.
Props
Variants
Calendar.Panel
The row shell around a presets rail and the body. Extends React.ComponentProps<"div">. Reads size from context for its border radius; no variants of its own.
Props
Calendar.Body
The column holding the month grids and footer, bordered on the left when it follows a presets rail. Extends React.ComponentProps<"div">.
Props
Calendar.Months
The row of month panels. Extends React.ComponentProps<"div">. With no children, renders one Calendar.Month per visibleMonths (read from the root), at consecutive offsets.
Props
Calendar.Month
One month's panel: header plus grid, or a month/year picker grid when its chip is open. Extends React.ComponentProps<"div">.
Props
Calendar.Header
The row above a month's grid: previous/next arrows around the month/year control. Extends React.ComponentProps<"div">.
Props
Calendar.Grid
The day grid for one month. Extends React Aria's CalendarGrid props.
Props
Calendar.Day
A single day cell. Extends React Aria's CalendarCell props.
Props
Calendar.Presets
A scrollable rail of shortcuts beside Calendar.Body. Extends React.ComponentProps<"div">.
Props
Calendar.Preset
One shortcut in a Calendar.Presets rail. Extends React Aria's Button props.
Props
Calendar.Footer
The bottom bar of a Calendar.Body, sized around its action button. Extends React.ComponentProps<"div">.
Props
Calendar.Actions
Right-aligned button group inside Calendar.Footer. Extends React.ComponentProps<"div">.
Props
Calendar.TodayLink
A text link that focuses today's date. Extends TextLink props.
Props
Types
DateValue and RangeValue come from react-aria-components. Every part also exports its props type (CalendarPanelProps, CalendarPresetProps, and so on).
Composition parts
Pieces the parts above render for you. None needs placing by hand unless you're rebuilding the header yourself.