Join our Discord Community

Calendar

React calendar component with date selection, range picking, and keyboard navigation. Perfect for date pickers, booking systems, and form inputs.

Need users to pick dates? Whether it's booking appointments, selecting birthdays, or choosing delivery dates, users expect intuitive calendar interfaces. The Calendar component handles everything from single dates to complex range selections.

Loading component...

Built on React DayPicker with full accessibility support, keyboard navigation, and customizable layouts that work on every device.

npx shadcn@latest add calendar

Why calendars work so well

Users understand calendar patterns from everywhere - phones, apps, booking sites:

  • Visual date selection - See months at a glance instead of typing dates
  • Keyboard navigation - Arrow keys and shortcuts work exactly as expected
  • Range selection - Perfect for booking systems and date periods
  • Accessibility first - Screen readers announce dates and navigation clearly
  • Mobile friendly - Touch gestures work naturally on any device
  • Form integration - Validates dates and handles edge cases automatically
  • Customizable layouts - Single month, multiple months, or dropdown navigation

Common calendar patterns you'll build

Simple date selection

Basic calendar for picking single dates:

Loading component...

Date range selection

Perfect for booking systems and period selection:

Loading component...

Multiple date selection

When users need to pick several individual dates:

Loading component...

Quick month and year jumping for better UX:

Loading component...

Popover date picker

Space-efficient date selection for forms:

Loading component...

Date and time combination

Complete scheduling with time selection:

Loading component...

Form validation integration

Proper error handling and validation:

Loading component...

API Reference

Calendar

The main calendar component built on React DayPicker with full customization and accessibility support.

PropTypeDefaultDescription
mode"single" | "multiple" | "range""single"Date selection mode - single date, multiple dates, or date range
selectedDate | Date[] | DateRange | undefined-Currently selected date(s) based on mode
onSelect(date?: Date | Date[] | DateRange) => void-Callback fired when date selection changes
defaultMonthDatenew Date()Initial month to display
monthDate-Controlled month display (use with onMonthChange)
onMonthChange(month: Date) => void-Callback when month navigation occurs
numberOfMonthsnumber1Number of months to display side by side
captionLayout"label" | "dropdown" | "dropdown-months" | "dropdown-years""label"Style of month/year navigation
showOutsideDaysbooleantrueShow grayed-out dates from adjacent months
fixedWeeksbooleanfalseAlways show 6 weeks (42 days) for consistent height
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 60First day of week (0 = Sunday, 1 = Monday, etc)
disabledMatcher | Matcher[]-Dates to disable (functions, arrays, or date objects)
hiddenMatcher | Matcher[]-Dates to completely hide from view
requiredbooleanfalseWhether date selection is required
localeLocale-date-fns locale for internationalization
classNamestring-Additional CSS classes for the calendar container
classNamesClassNames-Custom styling for individual calendar elements
componentsCustomComponents-Override default components (buttons, navigation, etc)
formattersFormatters-Custom date formatting functions

Selection Modes

Single Mode

Select one date at a time:

const [date, setDate] = useState<Date | undefined>()

<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
/>

Multiple Mode

Select multiple individual dates:

const [dates, setDates] = useState<Date[]>([])

<Calendar
  mode="multiple"
  selected={dates}
  onSelect={setDates}
/>

Range Mode

Select a date range with start and end:

import { DateRange } from "react-day-picker"

const [range, setRange] = useState<DateRange | undefined>()

<Calendar
  mode="range"
  selected={range}
  onSelect={setRange}
  numberOfMonths={2}
/>

Date Matchers

Powerful date matching for disabled/hidden dates:

Matcher TypeExampleDescription
Datenew Date(2024, 11, 25)Specific date
Date[][date1, date2, date3]Array of specific dates
DateRange{ from: date1, to: date2 }Date range
DayOfWeek{ dayOfWeek: [0, 6] }Weekends (Sunday=0, Saturday=6)
Function(date) => date < new Date()Custom logic function
DateBefore{ before: new Date() }All dates before specified date
DateAfter{ after: new Date() }All dates after specified date

Caption Layouts

LayoutDescription
"label"Simple text with arrow navigation (default)
"dropdown"Both month and year as dropdown selectors
"dropdown-months"Only month selector, year as text
"dropdown-years"Only year selector, month as text

Keyboard Navigation

KeyAction
Arrow KeysNavigate between dates
Enter / SpaceSelect focused date
HomeGo to start of week
EndGo to end of week
Page UpPrevious month
Page DownNext month
Shift + Page UpPrevious year
Shift + Page DownNext year
TabMove to navigation controls

Calendar best practices

What makes calendars feel intuitive and accessible:

  • Show current date clearly - Today should always be visually distinct
  • Logical navigation - Month/year dropdowns for quick jumping, arrows for step-by-step
  • Disable invalid dates - Gray out past dates, weekends, or blocked periods
  • Range feedback - Show start, middle, and end states clearly for range selection
  • Keyboard support - Arrow keys, Enter, and shortcuts should work perfectly
  • Mobile friendly - Touch targets are large enough for easy tapping
  • Form integration - Validate dates and show clear error messages
  • Loading states - Show skeleton or placeholder while data loads