For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Calendar

A date picker calendar built on react-day-picker with support for single, multiple, and range selection.

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

export const CalendarDemo = () => {
  const [date, setDate] = useState<Date | undefined>(new Date());
  return (
    <Calendar mode="single" selected={date} onSelect={setDate} className="rounded-lg border" />
  );
};

Single

Select one date at a time. This is the default and most common mode.

"use client";
 
import { useState } from "react";
import { Calendar } from "@/components/ui/calendar";
 
export function CalendarSingle() {
  const [date, setDate] = useState<Date | undefined>(new Date());
 
  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      className="rounded-lg border"
    />
  );
}

Range

Select a start and end date. The days between are highlighted.

"use client";
 
import { useState } from "react";
import type { DateRange } from "react-day-picker";
import { Calendar } from "@/components/ui/calendar";
 
export function CalendarRange() {
  const [range, setRange] = useState<DateRange | undefined>();
 
  return (
    <Calendar
      mode="range"
      selected={range}
      onSelect={setRange}
      numberOfMonths={2}
      className="rounded-lg border"
    />
  );
}

Multiple

Select several individual dates.

"use client";
 
import { useState } from "react";
import { Calendar } from "@/components/ui/calendar";
 
export function CalendarMultiple() {
  const [dates, setDates] = useState<Date[] | undefined>();
 
  return (
    <Calendar
      mode="multiple"
      selected={dates}
      onSelect={setDates}
      className="rounded-lg border"
    />
  );
}

Disabled Dates

Pass a disabled matcher to block specific dates from selection.

<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
  disabled={(day) => day < new Date()}
/>

Multiple Months

Show more than one month at once with numberOfMonths.

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

Props

Calendar forwards all props to DayPicker. The most common:

PropTypeDefaultDescription
mode"single" | "multiple" | "range"—Selection mode
selectedDate | Date[] | DateRange—Controlled selected value
onSelect(value) => void—Callback when selection changes
showOutsideDaysbooleantrueShow days from adjacent months
numberOfMonthsnumber1Number of months to display
disabledMatcher | Matcher[]—Dates to disable
defaultMonthDate—Initial month to display
classNamestring—Additional CSS classes
classNamesClassNames—Override internal class names

See the full react-day-picker docs for all available props.

Usage

import { Calendar } from "@/components/ui/calendar";
 
// Single selection
<Calendar mode="single" selected={date} onSelect={setDate} />
 
// Range selection
<Calendar mode="range" selected={range} onSelect={setRange} numberOfMonths={2} />
 
// Disabled past dates
<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
  disabled={(day) => day < new Date()}
/>

Specs

# Mint — Calendar Specs
 
## Component
- name: calendar
- file: registry/mint/calendar.tsx
- installs to: components/ui/calendar.tsx
- dependencies: react-day-picker, lucide-react
- registryDependencies: button
 
## External dependency
react-day-picker@^10.0.0 — must be installed separately:
  pnpm add react-day-picker
 
## What is it
A fully styled date-picker calendar wrapping react-day-picker. Supports
single date, multiple date, and date range selection. Navigation buttons
use the existing Button component (outline variant, size-7). All styling
is applied via DayPicker's classNames prop — no CSS overrides needed.
 
## Visual identity
Clean grid layout. Days are ghost buttons (size-8). Selected days get
primary background. Today gets accent background. Range selections fill
accent between start/end, with primary on the endpoints. Navigation
chevrons are opacity-50, rising to full opacity on hover.
 
## Design tokens
--primary: bg + text for selected days
--accent: bg + text for today and range-middle
--muted-foreground: weekday headers, outside days, disabled days
--border: calendar border (applied via className on root)
 
## Modes
- single: one date selected at a time
- multiple: several independent dates
- range: start + end + highlighted middle
 
## Class name keys (react-day-picker v9+)
months, month, month_caption, caption_label, nav, button_previous,
button_next, month_grid, weekdays, weekday, weeks, week, day,
day_button, range_start, range_end, selected, today, outside,
disabled, range_middle, hidden
 
## Conventions
- Always wrap in a controlled component with useState for selected/onSelect
- Add className="rounded-lg border" on the Calendar for a contained look
- Use numberOfMonths={2} with mode="range" for UX clarity
- Pass disabled={(day) => day < new Date()} to block past dates
- Do not use Calendar alone as a form input — pair with a Popover + Input
  (that pattern is the DatePicker component)

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/calendar