Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by shadcn
Edit on GitHub

Calendar

A date field component that allows users to enter and edit date.

Installation

bash
npx shadcn@latest add @redpanda/calendar
bash
pnpm dlx shadcn@latest add @redpanda/calendar
bash
yarn dlx shadcn@latest add @redpanda/calendar
bash
bunx shadcn@latest add @redpanda/calendar
bash
nubx shadcn@latest add @redpanda/calendar
bash
aube dlx shadcn@latest add @redpanda/calendar

Usage

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

tsx
import { Calendar } from '@/components/redpanda-ui/calendar';import { useState } from 'react';
// Single date selectionconst [date, setDate] = useState<Date | undefined>(new Date());
return <Calendar mode="single" selected={date} onSelect={setDate} variant="outlined" />;
// Date range selectionconst [dateRange, setDateRange] = useState<DateRange | undefined>();
return <Calendar mode="range" selected={dateRange} onSelect={setDateRange} numberOfMonths={2} variant="outlined" />;
// Multiple date selectionconst [dates, setDates] = useState<Date[]>([]);
return <Calendar mode="multiple" selected={dates} onSelect={setDates} variant="outlined" />;
// With disabled datesconst 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:

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:

plaintext
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

Popover DatePicker

Booked

Custom Days

Disabled Days

Disabled Weekends

Event Slots

Form

Date-fns

Localized

Month Day Dropdown

Multi Month Multi Select

Multi Month Range

Presets

Range Minimum and Maximum Days

Range Minimum Days

Single Month Range

Size

Start End Month

Time Picker

Time Picker Inline

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

Week Numbers

Appointment Slots

Per-Day Pricing

Props

Date Picker

You can use the <Calendar> component to build a date picker. See the Date Picker page for more information.

Credits

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?