---
title: Calendar
description: A date field component that allows users to enter and edit date.
icon: calendar
author:
  name: shadcn
  url: https://github.com/shadcn
mode: wide
---

<PoweredBy
  packages={[
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/calendar' },
    { name: 'Lucide', url: 'https://lucide.dev/' },
    { name: 'React Day Picker', url: 'https://daypicker.dev/' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/calendar
```

<ComponentPreview name="calendar-demo" title="Calendar" description="A calendar showing the current date." />

## Usage

The Calendar component is built on react-day-picker and supports various modes and configurations for different date selection needs:

```tsx expandable
import { Calendar } from '@/components/redpanda-ui/calendar';
import { useState } from 'react';

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

return <Calendar mode="single" selected={date} onSelect={setDate} variant="outlined" />;

// Date range selection
const [dateRange, setDateRange] = useState<DateRange | undefined>();

return <Calendar mode="range" selected={dateRange} onSelect={setDateRange} numberOfMonths={2} variant="outlined" />;

// Multiple date selection
const [dates, setDates] = useState<Date[]>([]);

return <Calendar mode="multiple" selected={dates} onSelect={setDates} variant="outlined" />;

// With disabled dates
const isDateDisabled = (date: Date) => {
  return date < new Date() || date.getDay() === 0 || date.getDay() === 6;
};

return <Calendar mode="single" selected={date} onSelect={setDate} disabled={isDateDisabled} variant="outlined" />;
```

### Surface variants

Use `variant` for the calendar surface rather than overriding its border, padding, or background.

| Variant    | Surface                                                         |
| ---------- | --------------------------------------------------------------- |
| `default`  | Padded background without a frame                               |
| `outlined` | Rounded border and default padding                              |
| `elevated` | Outlined surface with a small shadow                            |
| `embedded` | Transparent surface without padding, for a padded card or popup |

Date selection, keyboard navigation, and day components work the same in every variant.

### Date-action appearance and composition

Calendar owns the selected, range, today, focus, and disabled date-action treatments. Date actions are native
buttons using DayPicker's `type`, `tabIndex`, ARIA attributes, and event handlers, not the general Button appearance
API. `buttonVariant` styles only the month navigation controls.

Use `booked` for the supported struck-through booking treatment. It accepts the same date matchers as DayPicker's
`disabled` prop. Booking appearance does not change availability: also pass `disabled` when those dates cannot be selected.

```tsx
const bookedDates = [new Date(2026, 9, 26), new Date(2026, 9, 27)];

<Calendar booked={bookedDates} disabled={bookedDates} mode="single" onSelect={setDate} selected={date} />;
```

The public `classNames`, `styles`, `modifiersClassNames`, and `modifiersStyles` paint maps have been removed.
Legacy map props also fail with an explicit migration error at runtime, including when forwarded through a spread.
Use the finite surface variants and `booked` treatment instead. Root `className` and root `style` remain the
existing layout/cell-sizing contract; they are not replacements for retired day paint maps.

Custom day content remains supported through `components.DayButton`. Forward every received native prop and the
original `day` and `modifiers` to `CalendarDayButton`; this preserves DayPicker's focus, keyboard, ARIA, and
availability protocol. Incoming day `className`/`style` belong to that framework protocol, not an additional public
Button styling API. Refs are forwarded without replacing DayPicker's internal focus ref, including React callback cleanup.

```tsx
import { CalendarDayButton } from '@/components/redpanda-ui/calendar';
import type { ComponentProps } from 'react';

function PricedDay({ children, day, modifiers, ...props }: ComponentProps<typeof CalendarDayButton>) {
  return (
    <CalendarDayButton day={day} modifiers={modifiers} {...props}>
      {children}
      {modifiers['outside'] !== true && <span>$100</span>}
    </CalendarDayButton>
  );
}
```

Do not set `disabled` from `modifiers.disabled` inside a custom day renderer. DayPicker intentionally keeps a
focused disabled day natively focusable with `aria-disabled` while preventing selection. Forward its supplied
attributes instead. Day actions default to `type="button"`, so ordinary selection does not submit an enclosing form.

## When to use

Use this decision tree to determine when to use the Calendar component and which configuration is most appropriate:

```mermaid
graph TD;
    A[❓ Need date input?] -->|Yes| B[Yes];
    A -->|No| C[⚠️ No - use other components];
    B --> D{Inline date display?};
    D -->|Yes| E[✅ Yes - use Calendar];
    D -->|No| F[⚠️ No - use DatePicker];
    E --> G{Single date?};
    G -->|Yes| H[✅ Yes - mode='single'];
    G -->|No| I[No - check selection type];
    I --> J{Date range?};
    J -->|Yes| K[✅ Yes - mode='range'];
    J -->|No| L[✅ No - mode='multiple'];
    K --> M{Long range?};
    M -->|Yes| N[✅ Yes - numberOfMonths=2];
    M -->|No| O[✅ No - numberOfMonths=1];
    H --> P{Need restrictions?};
    P -->|Yes| Q[✅ Yes - add disabled prop];
    P -->|No| R[✅ No - basic setup];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class E,H,K,L,N,O,Q,R recommended;
    class C,F discouraged;
    class A,D,G,I,J,M,P decision;
    class B neutral;
```

### Mode Guidelines

- **Single mode**: Birthdate selection, appointment dates, event dates
- **Range mode**: Hotel bookings, vacation planning, reporting periods
- **Multiple mode**: Available dates, blackout dates, recurring events

### Calendar vs DatePicker

- **Use Calendar when**: You have space for inline display, users need to see surrounding dates context, visual date exploration is important
- **Use DatePicker when**: Space is limited, part of a form, simple date input without exploration needs

## Anatomy

The Calendar component is built on react-day-picker with custom styling and components:

```
Calendar Component Structure:
┌─────────────────────────────────────────┐
│ Calendar Root Container                 │
│ ┌─────────────────────────────────────┐ │
│ │ Navigation Bar                      │ │
│ │ [◀ Prev] [Month Year] [Next ▶]      │ │
│ │                                     │ │
│ │ - Dropdown: month/year selection    │ │
│ │ - Buttons: navigation controls      │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ Weekday Headers                     │ │
│ │ [Mon] [Tue] [Wed] [Thu] [Fri] [Sat] │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ Date Grid                           │ │
│ │ [30] [31] [ 1] [ 2] [ 3] [ 4] [ 5]  │ │
│ │ [ 6] [ 7] [ 8] [ 9] [10] [11] [12]  │ │
│ │ [13] [14] [15] [16] [17] [18] [19]  │ │
│ │ [20] [21] [22] [23] [24] [25] [26]  │ │
│ │ [27] [28] [29] [30] [31] [ 1] [ 2]  │ │
│ │                                     │ │
│ │ - Day buttons: individual dates     │ │
│ │ - States: selected, today, disabled │ │
│ │ - Range: start, middle, end         │ │
│ └─────────────────────────────────────┘ │
│                                         │
│ Multi-month layout (when enabled):     │
│ [Month 1] [Month 2] [Month 3]           │
└─────────────────────────────────────────┘
```

### Component Composition

- **DayPicker Root**: Base component from react-day-picker with custom theming
- **Navigation**: Custom chevron icons and dropdown selectors
- **Day Buttons**: Native date actions with owned selection states and DayPicker's keyboard/focus protocol
- **Weekday Headers**: Localized day name labels
- **Date Grid**: Responsive grid layout with proper spacing
- **Range Selection**: Visual indicators for start, middle, and end dates
- **Accessibility**: Full keyboard navigation and screen reader support

## Examples

### Default

<ComponentPreview name="calendar-demo" description="A simple calendar" />

### Popover DatePicker

<ComponentPreview name="popover-datepicker-demo" description="A calendar used as date picker in a popover" />

### Booked

<ComponentPreview name="calendar-booked-demo" description="A calendar with booked/reserved slots" />

### Custom Days

<ComponentPreview name="calendar-custom-days-demo" description="A calendar with custom component to display days" />

### Disabled Days

<ComponentPreview name="calendar-disabled-days-demo" description="A calendar with disabled days" />

### Disabled Weekends

<ComponentPreview name="calendar-disabled-weekends-demo" description="A calendar with disabled weekends" />

### Event Slots

<ComponentPreview name="calendar-event-slots-demo" description="A calendar with event slots displayed underneath" />

### Form

<ComponentPreview name="calendar-form-demo" description="A calendar with a form" />

### Date-fns

<ComponentPreview
  name="calendar-date-fns-demo"
  description="A calendar with a compact date range formatted with date-fns"
/>

### Localized

<ComponentPreview name="calendar-localized-demo" description="A calendar with different locales" />

### Month Day Dropdown

<ComponentPreview name="calendar-month-day-dropdown-demo" description="A calendar with month day dropdown" />

### Multi Month Multi Select

<ComponentPreview
  name="calendar-multi-month-multi-select-demo"
  description="A calendar with multi select over multiple months"
/>

### Multi Month Range

<ComponentPreview name="calendar-multi-month-range-demo" description="A calendar with range over multiple months" />

### Presets

<ComponentPreview name="calendar-presets-demo" description="A calendar with preselectable presets" />

### Range Minimum and Maximum Days

<ComponentPreview
  name="calendar-range-minimum-and-maximum-demo"
  description="A calendar with a range spanning across a minimum and maximum number of days"
/>

### Range Minimum Days

<ComponentPreview
  name="calendar-range-minimum-demo"
  description="A calendar with a range spanning across a minimum number of days"
/>

### Single Month Range

<ComponentPreview name="calendar-single-month-range-demo" description="A calendar with range over a single month" />

### Size

<ComponentPreview name="calendar-size-demo" description="A calendar with size that adjusts based on a viewport" />

### Start End Month

<ComponentPreview name="calendar-start-end-month-demo" description="A calendar with start and end of the month" />

### Time Picker

<ComponentPreview name="calendar-time-picker-demo" description="A calendar with time picker" />

### Time Picker Inline

<ComponentPreview name="calendar-time-picker-inline-demo" description="A calendar with time picker displayed inline" />

### Time Presets

<ComponentPreview name="calendar-time-presets-demo" description="A calendar with preselectable time presets" />

This example only selects a local date and time. Its footer describes that selection; it does not book a meeting
or provide an inert review action. Time actions use the standard Button shadow and selected treatment.

### Today

<ComponentPreview name="calendar-today-demo" description="A calendar with today button" />

### Week Numbers

<ComponentPreview name="calendar-week-numbers-demo" description="A calendar with week numbers" />

### Appointment Slots

<ComponentPreview
  name="calendar-appointment-slots-demo"
  description="Calendar with hourly time slots rendered inline per day for appointment picking."
/>

### Per-Day Pricing

<ComponentPreview
  name="calendar-pricing-demo"
  description="Calendar with per-day pricing numbers rendered via the dayButton composition."
/>

## Props

<div className="flex flex-row gap-x-3">
  <ExternalLink href="https://daypicker.dev/" text="Docs" />
  <ExternalLink href="https://daypicker.dev/docs/anatomy" text="API Reference" />
</div>

## Date Picker

You can use the `<Calendar>` component to build a date picker. See the [Date Picker](/docs/date-picker) page for more information.

## Credits

- We use [react-day-picker](https://daypicker.dev/) for the calendar component.
- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/calendar) for the calendar style.
- We took many components from [Shadcn UI Blocks](https://ui.shadcn.com/blocks/calendar) for the calendar component.
