1
ComponentsForm Controls

Calendar

Calendar wraps React DayPicker for single-date, multiple-date, and date-range selection.

Purpose

Calendar wraps React DayPicker for single-date, multiple-date, and date-range selection. Compose it with Popover and Button when a compact date field is needed.

Single date

import { useState } from "react";
import { Calendar } from "@/components/ui/calendar";

export function Example() {
  const [date, setDate] = useState<Date | undefined>(new Date(2026, 6, 9));
  return <Calendar mode="single" selected={date} onSelect={setDate} />;
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/calendar

Import

import type { DateRange, DropdownProps } from "react-day-picker";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverPopup, PopoverTrigger } from "@/components/ui/popover";

Need the machine-readable source metadata? View registry JSON.

Usage

Calendar is the inline date primitive. Use Date Picker when the calendar should live in a popover trigger. Month transitions animate by default; pass animate={false} to turn that off.

import { useState } from "react";
import { Calendar } from "@/components/ui/calendar";

export function Example() {
  const [date, setDate] = useState<Date | undefined>(new Date(2026, 6, 9));
  return <Calendar mode="single" selected={date} onSelect={setDate} />;
}

Examples

Selection modes, header navigation, locale and cell size are props of the same primitive.

Drilldown navigation

The header label opens month, year and decade pickers.

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

Reduced navigation

Arrow navigation only — for bookings within the next few weeks.

July 2026
<Calendar drilldown={false} mode="single" selected={date} onSelect={setDate} />

Multiple

const [dates, setDates] = useState<Date[] | undefined>([baseDate, secondDate]);

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

Range

Range mode previews the span while hovering.

const [range, setRange] = useState<DateRange | undefined>({ from, to });

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

Locale

Month names follow the locale on the server and the client.

import { de } from "react-day-picker/locale";

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

Cell size

<Calendar
  className="[--cell-size:--spacing(11)] sm:[--cell-size:--spacing(10)]"
  mode="single"
  selected={date}
  onSelect={setDate}
/>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • Use DayPicker mode="single", "multiple", or "range" with the corresponding selected-value type.
  • Outside days are visible by default; set showOutsideDays={false} to hide adjacent-month days.
  • Use DayPicker disabled matchers for unavailable dates.
  • captionLayout supports "label", "dropdown", "dropdown-months", and "dropdown-years". Bound dropdown years with startMonth and endMonth.
  • numberOfMonths renders responsive multi-month calendars.
  • month with onMonthChange controls the visible month; use defaultMonth for uncontrolled initial state.
  • Custom modifiers and modifiersClassNames are merged with the native range-preview modifiers.
  • classNames is merged slot by slot with Siteplane defaults rather than replacing the full DayPicker class map.

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Month navigation and drilldown titles use central Calendar motion tokens.
  • Range hover preview changes modifiers without changing the committed selection.
  • Popover date pickers use Popover motion; do not add local durations or transforms.
  • Reduced motion is handled by the global motion contract.

Accessibility

  • Preserve React DayPicker grid roles, keyboard navigation, focus management, and day labels.
  • Give the calendar a visible context or an accessible label.
  • Explain disabled date rules in nearby text when they are not self-evident.
  • A Popover date picker needs a clearly named trigger whose visible text reflects the current value or placeholder.

Implementation Guidance

  • Keep Calendar as the source of truth for date selection.
  • Use DayPicker props through the wrapper; do not rebuild its grid or navigation.
  • Preserve native classes, range-preview merging, focus behavior, and motion.
  • Use the canonical PopoverPopup name in new code.

On This Page