Back to Heroui

Calendar

apps/docs/content/docs/en/react/components/(date-and-time)/calendar.mdx

3.2.411.9 KB
Original Source

Usage

tsx
import { Calendar } from '@heroui/react';
<ComponentPreview name="calendar-basic" />

Anatomy

tsx
import {Calendar} from '@heroui/react';

export default () => (
  <Calendar aria-label="Event date">
    <Calendar.Header>
      <Calendar.Heading />
      <Calendar.NavButton slot="previous" />
      <Calendar.NavButton slot="next" />
    </Calendar.Header>
    <Calendar.Grid>
      <Calendar.GridHeader>
        {(day) => <Calendar.HeaderCell>{day}</Calendar.HeaderCell>}
      </Calendar.GridHeader>
      <Calendar.GridBody>
        {(date) => <Calendar.Cell date={date} />}
      </Calendar.GridBody>
    </Calendar.Grid>
  </Calendar>
)

Examples

Disabled

<ComponentPreview name="calendar-disabled" />

Read Only

<ComponentPreview name="calendar-read-only" />

Default Value

<ComponentPreview name="calendar-default-value" />

Year Picker

Calendar.YearPickerTrigger, Calendar.YearPickerGrid, and their body/cell subcomponents provide an integrated year navigation pattern.

<ComponentPreview name="calendar-year-picker" />

Controlled

Use controlled value and focusedValue for external state coordination and custom shortcuts.

<ComponentPreview name="calendar-controlled" />

Min and Max Dates

<ComponentPreview name="calendar-min-max-dates" />

Unavailable Dates

Use isDateUnavailable to block dates such as weekends, holidays, or booked slots.

<ComponentPreview name="calendar-unavailable-dates" />

Weeks in Month

Set weeksInMonth to a fixed value (for example, 6) to keep the grid height stable when navigating between months. Use with care in non-Gregorian locales, similar to firstDayOfWeek.

<ComponentPreview name="calendar-weeks-in-month" />

Week View

Set visibleDuration={{ weeks: n }} to show one or more weeks at a time. Navigation advances by the visible week range. Use pageBehavior="single" to move one week at a time when showing multiple weeks.

<ComponentPreview name="calendar-week-view" />

Day View

Set visibleDuration={{ days: n }} to show a rolling window of consecutive days. Navigation advances by the visible day range. Use pageBehavior="single" to move one day at a time when showing multiple days.

<ComponentPreview name="calendar-day-view" />

Multiple Selection

Set selectionMode="multiple" to let users select several dates. value, defaultValue, and onChange use an array of dates.

<ComponentPreview name="calendar-multiple-selection" />

Focused Value

Programmatically control which date is focused using focusedValue and onFocusChange.

<ComponentPreview name="calendar-focused-value" />

Cell Indicators

You can customize Calendar.Cell children and use Calendar.CellIndicator to display metadata like events.

<ComponentPreview name="calendar-with-indicators" />

Custom Navigation Icons

Pass children to Calendar.NavButton to replace the default chevron icons.

<ComponentPreview name="calendar-custom-icons" />

Multiple Months

Render multiple grids with visibleDuration and offset for booking and planning experiences.

<ComponentPreview name="calendar-multiple-months" />

Real-World Example

<ComponentPreview name="calendar-booking-calendar" />

International Calendars

By default, Calendar displays dates using the calendar system for the user's locale. You can override this by wrapping your Calendar with I18nProvider and setting the Unicode calendar locale extension.

The example below shows the Indian calendar system:

<ComponentPreview name="calendar-international-calendar" />

Note: The onChange event always returns a date in the same calendar system as the value or defaultValue (Gregorian if no value is provided), regardless of the displayed locale. This ensures your application logic works consistently with a single calendar system while still displaying dates in the user's preferred format.

Customization

Tailwind CSS

<ComponentPreview name="calendar-custom-styles" />

Global CSS

css
@layer components {
  .calendar {
    @apply w-72 rounded-2xl border border-border bg-surface p-3 shadow-sm;
  }

  .calendar__heading {
    @apply text-sm font-semibold text-default-700;
  }

  .calendar__cell[data-selected="true"] {
    @apply bg-accent text-accent-foreground;
  }
}

Styling Reference

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

Calendar uses these classes in packages/styles/components/calendar.css and packages/styles/components/calendar-year-picker.css:

  • .calendar - Root container.
  • .calendar__header - Header row containing nav buttons and heading.
  • .calendar__heading - Current month label.
  • .calendar__nav-button - Previous/next navigation controls.
  • .calendar__grid - Main day grid.
  • .calendar__grid-header - Weekday header row wrapper.
  • .calendar__grid-body - Date rows wrapper.
  • .calendar__header-cell - Weekday header cell.
  • .calendar__cell - Interactive day cell.
  • .calendar__cell-indicator - Dot indicator inside a day cell.
  • .calendar-year-picker__trigger - Year picker toggle button.
  • .calendar-year-picker__trigger-heading - Heading text inside year picker trigger.
  • .calendar-year-picker__trigger-indicator - Indicator icon inside year picker trigger.
  • .calendar-year-picker__year-grid - Overlay grid of selectable years.
  • .calendar-year-picker__year-cell - Individual year option.

Interactive States

Calendar supports both pseudo-classes and React Aria data attributes:

  • Selected: [data-selected="true"]
  • Today: [data-today="true"]
  • Unavailable: [data-unavailable="true"]
  • Outside month: [data-outside-month="true"]
  • Hovered: :hover or [data-hovered="true"]
  • Pressed: :active or [data-pressed="true"]
  • Focus visible: :focus-visible or [data-focus-visible="true"]
  • Disabled: :disabled or [data-disabled="true"]

API Reference

Calendar

Calendar inherits all props from React Aria Calendar.

PropTypeDefaultDescription
selectionMode'single' | 'multiple''single'Whether one or many dates can be selected.
valueDateValue | null or DateValue[] | null-Controlled selected date(s). Use an array when selectionMode is multiple.
defaultValueDateValue | null or DateValue[] | null-Initial selected date(s) (uncontrolled).
onChange(value: DateValue | null) or (value: DateValue[] | null) => void-Called when selection changes.
focusedValueDateValue-Controlled focused date.
onFocusChange(value: DateValue) => void-Called when focus moves to another date.
minValueDateValueCalendar-aware 1900-01-01Earliest selectable date.
maxValueDateValueCalendar-aware 2099-12-31Latest selectable date.
weeksInMonthnumber-The number of weeks in a month. This overrides the default set by the locale.
isDateUnavailable(date: DateValue) => boolean-Marks dates as unavailable.
firstDayOfWeek'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'-Overrides the locale default for the first day of the week.
pageBehavior'visible' | 'single''visible'Whether paging advances by the visible duration or one unit at a time.
selectionAlignment'start' | 'center' | 'end''center'Aligns the visible range to the selection on initial render.
isDisabledbooleanfalseDisables interaction and selection.
isReadOnlybooleanfalseKeeps content readable but prevents selection changes.
isInvalidbooleanfalseMarks the calendar as invalid for validation UI.
visibleDuration{months?: number; weeks?: number; days?: number}{months: 1}Visible time range. Use { months: n } for month view, { weeks: n } for week view, or { days: n } for day view.
defaultYearPickerOpenbooleanfalseInitial open state of internal year picker.
isYearPickerOpenboolean-Controlled year picker open state.
onYearPickerOpenChange(isOpen: boolean) => void-Called when year picker open state changes.

Composition Parts

ComponentDescription
Calendar.HeaderHeader container for navigation and heading.
Calendar.HeadingFormatted heading for the visible range. Supports offset (for multi-month layouts) and format (month/year/day options).
Calendar.NavButtonPrevious/next navigation control (slot=\"previous\" or slot=\"next\").
Calendar.GridDay grid for one month (offset supported for multi-month layouts).
Calendar.GridHeaderWeekday header container.
Calendar.GridBodyDate cell body container.
Calendar.HeaderCellWeekday label cell.
Calendar.CellIndividual date cell.
Calendar.CellIndicatorOptional indicator element for custom metadata.
Calendar.YearPickerTriggerTrigger to toggle year-picker mode.
Calendar.YearPickerTriggerHeadingLocalized heading content inside the year-picker trigger.
Calendar.YearPickerTriggerIndicatorToggle icon inside the year-picker trigger.
Calendar.YearPickerGridOverlay year selection grid container.
Calendar.YearPickerGridBodyBody renderer for year grid cells.
Calendar.YearPickerCellIndividual year option cell.

Year Picker Parts

Year picker subcomponents inherit formatting props from React Aria useCalendarHeading and useCalendarYearPicker.

ComponentPropTypeDefaultDescription
Calendar.YearPickerTriggerHeadingformatDateFormatterOptions-Customize month/year label (e.g. {month: 'short'}).
Calendar.YearPickerTriggerHeadingoffset{months?: number}-Shift the heading relative to the focused date (multi-month layouts).
Calendar.YearPickerGridformatDateFormatterOptions{year: 'numeric'}Customize year cell labels (era, calendar system, etc.).
Calendar.YearPickerGridvisibleYearsnumbermin–max span or 20Number of years shown in the sliding window. Defaults to the full range between minValue and maxValue when both are set.

Calendar.Cell Render Props

When Calendar.Cell children is a function, React Aria render props are available:

PropTypeDescription
formattedDatestringLocalized day label for the cell.
isSelectedbooleanWhether the date is selected.
isUnavailablebooleanWhether the date is unavailable.
isDisabledbooleanWhether the cell is disabled.
isOutsideMonthbooleanWhether the date belongs to adjacent month.

For a complete list of supported calendar systems and their identifiers, see:

  • @internationalized/date — date types (CalendarDate, CalendarDateTime, ZonedDateTime) and utilities used by all date components
  • I18nProvider — override locale for a subtree
  • useLocale — read the current locale and layout direction
<RelatedComponents component="calendar" />