Calendar

A date picker calendar component built on react-day-picker. Supports single date selection, date range selection, multiple months, and custom day rendering. Responsive layout switches from vertical to horizontal on wider screens.

Anatomy

<Calendar> renders a full calendar grid with navigation arrows, weekday headers, and day buttons. Uses data-slot="calendar" and provides data attributes for selected, range, today, and outside days.

May 2026

Selection Modes

The calendar supports single date selection and range selection modes via the mode prop.

Single selection

May 2026

Range selection

May 2026

Enhanced Navigation

Use showTodayButtonto add a “Today” button above the grid that snaps the viewed month back to the current date. Use captionLayout="dropdown" with startMonth / endMonth to replace the static caption with month and year dropdowns for faster navigation.

Today button + dropdown navigation

May 2026

Month & year dropdown only

May 2026

Design Guidelines

Do

  • Use for date selection. Calendar is ideal when users need to pick a specific date or range visually.
  • Show outside days. The showOutsideDays prop (on by default) helps users understand the date context.
  • Pair with a Popover for inline use. Wrap the calendar in a Popover for space-efficient date pickers.

Don't

  • Don't use for known dates. If users are entering a known date (birthday), a text input with date format is faster.
  • Don't show too many months. More than 2 side-by-side months creates layout issues on smaller screens.
  • Don't forget disabled dates. Use the disabled prop to prevent selection of unavailable dates.

Developer Reference

Accessibility

  • Built on react-day-picker — implements WAI-ARIA date picker pattern.
  • Arrow keys navigate between days, Page Up/Down for months.
  • Day buttons announce their date and selection state to screen readers.
  • Today's date is highlighted via data-today.
  • Range selection uses data-range-start, data-range-end, data-range-middle.
  • Responsive layout: flex-col on mobile, md:flex-row for multi-month.

Usage

import { Calendar } from "@/components/ui/calendar"

// Single date selection
const [date, setDate] = React.useState<Date | undefined>(new Date())

<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
  className="rounded-lg border border-border"
/>

// Range selection
const [range, setRange] = React.useState<DateRange | undefined>()

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

// With Today button — snaps the viewed month back to today
<Calendar
  mode="single"
  showTodayButton
  className="rounded-lg border border-border"
/>

// Month & year dropdown navigation
<Calendar
  mode="single"
  captionLayout="dropdown"
  startMonth={new Date(new Date().getFullYear() - 10, 0)}
  endMonth={new Date(new Date().getFullYear() + 10, 11)}
  className="rounded-lg border border-border"
/>

// Combined: Today button + dropdown navigation
<Calendar
  mode="single"
  showTodayButton
  captionLayout="dropdown"
  startMonth={new Date(new Date().getFullYear() - 10, 0)}
  endMonth={new Date(new Date().getFullYear() + 10, 11)}
  className="rounded-lg border border-border"
/>

// With disabled dates
<Calendar
  mode="single"
  disabled={{ before: new Date() }}
/>

// Multiple months
<Calendar
  mode="single"
  numberOfMonths={2}
/>