Command Palette

Search for a command to run...

Github

Calendar

A calendar component that allows users to select a date or a range of dates.

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

Installation

pnpm dlx shadcn@latest add @herocn/calendar

Usage

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

See the React DayPicker documentation for more information.

About

The Calendar component is built on top of React DayPicker.

Date Picker

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

Examples

Basic

A basic calendar component. We used className="rounded-lg border" to style the calendar.

October 2026
"use client";
import { Calendar } from "@/components/ui/calendar";
export function CalendarBasic() {	return <Calendar mode="single" className="rounded-lg border" />;}

Range Calendar

Use the mode="range" prop to enable range selection.

January 2026
February 2026
"use client";
import { addDays } from "date-fns";import * as React from "react";import type { DateRange } from "react-day-picker";
import { Calendar } from "@/components/ui/calendar";
export function CalendarRange() {	const [dateRange, setDateRange] = React.useState<DateRange | undefined>({		from: new Date(new Date().getFullYear(), 0, 12),		to: addDays(new Date(new Date().getFullYear(), 0, 12), 30),	});
	return (		<Calendar			mode="range"			defaultMonth={dateRange?.from}			selected={dateRange}			onSelect={setDateRange}			numberOfMonths={2}			className="rounded-lg border"		/>	);}

Month and Year Selector

Use captionLayout="dropdown" to show month and year dropdowns.

October 2026
"use client";
import { Calendar } from "@/components/ui/calendar";
export function CalendarCaption() {	return (		<Calendar			mode="single"			captionLayout="dropdown"			className="rounded-lg border"		/>	);}

Presets

October 2026
"use client";
import { addDays } from "date-fns";import * as React from "react";
import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import { Card, CardContent, CardFooter } from "@/components/ui/card";
export function CalendarWithPresets() {	const [date, setDate] = React.useState<Date | undefined>(		new Date(new Date().getFullYear(), 1, 12),	);	const [currentMonth, setCurrentMonth] = React.useState<Date>(		new Date(new Date().getFullYear(), new Date().getMonth(), 1),	);
	return (		<Card className="mx-auto w-fit max-w-76" size="sm">			<CardContent>				<Calendar					mode="single"					selected={date}					onSelect={setDate}					month={currentMonth}					onMonthChange={setCurrentMonth}					fixedWeeks					className="w-full p-0"				/>			</CardContent>			<CardFooter className="flex flex-wrap gap-2 border-t">				{[					{ label: "Today", value: 0 },					{ label: "Tomorrow", value: 1 },					{ label: "In 3 days", value: 3 },					{ label: "In a week", value: 7 },					{ label: "In 2 weeks", value: 14 },				].map((preset) => (					<Button						key={preset.value}						variant="outline"						size="sm"						className="flex-1"						onClick={() => {							const newDate = addDays(new Date(), preset.value);							setDate(newDate);							setCurrentMonth(								new Date(newDate.getFullYear(), newDate.getMonth(), 1),							);						}}					>						{preset.label}					</Button>				))}			</CardFooter>		</Card>	);}

Date and Time Picker

October 2026
"use client";
import { Clock2Icon } from "lucide-react";import * as React from "react";
import { Calendar } from "@/components/ui/calendar";import { Card, CardContent, CardFooter } from "@/components/ui/card";import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";import {	InputGroup,	InputGroupAddon,	InputGroupInput,} from "@/components/ui/input-group";
export function CalendarWithTime() {	const [date, setDate] = React.useState<Date | undefined>(		new Date(new Date().getFullYear(), new Date().getMonth(), 12),	);
	return (		<Card size="sm" className="mx-auto w-fit">			<CardContent>				<Calendar					mode="single"					selected={date}					onSelect={setDate}					className="p-0"				/>			</CardContent>			<CardFooter className="border-t bg-card">				<FieldGroup>					<Field>						<FieldLabel htmlFor="time-from">Start Time</FieldLabel>						<InputGroup>							<InputGroupInput								id="time-from"								type="time"								step="1"								defaultValue="10:30:00"								className="appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"							/>							<InputGroupAddon>								<Clock2Icon className="text-muted-foreground" />							</InputGroupAddon>						</InputGroup>					</Field>					<Field>						<FieldLabel htmlFor="time-to">End Time</FieldLabel>						<InputGroup>							<InputGroupInput								id="time-to"								type="time"								step="1"								defaultValue="12:30:00"								className="appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"							/>							<InputGroupAddon>								<Clock2Icon className="text-muted-foreground" />							</InputGroupAddon>						</InputGroup>					</Field>				</FieldGroup>			</CardFooter>		</Card>	);}

Booked dates

January 2026
"use client";
import * as React from "react";
import { Calendar } from "@/components/ui/calendar";import { Card, CardContent } from "@/components/ui/card";
export function CalendarBookedDates() {	const [date, setDate] = React.useState<Date | undefined>(		new Date(new Date().getFullYear(), 0, 6),	);	const bookedDates = Array.from(		{ length: 15 },		(_, i) => new Date(new Date().getFullYear(), 0, 12 + i),	);
	return (		<Card className="mx-auto w-fit p-0">			<CardContent className="p-0">				<Calendar					mode="single"					defaultMonth={date}					selected={date}					onSelect={setDate}					disabled={bookedDates}					modifiers={{						booked: bookedDates,					}}					modifiersClassNames={{						booked: "[&>button]:line-through opacity-100",					}}				/>			</CardContent>		</Card>	);}

Custom Cell Size

You can customize the size of calendar cells using the --cell-size CSS variable.

December 2026
"use client";
import { addDays } from "date-fns";import * as React from "react";import type { DateRange } from "react-day-picker";
import {	Calendar,	CalendarDayButton,} from "@/components/ui/calendar";import { Card, CardContent } from "@/components/ui/card";
export function CalendarCustomDays() {	const [range, setRange] = React.useState<DateRange | undefined>({		from: new Date(new Date().getFullYear(), 11, 8),		to: addDays(new Date(new Date().getFullYear(), 11, 8), 10),	});
	return (		<Card className="mx-auto w-fit p-0">			<CardContent className="p-0">				<Calendar					mode="range"					defaultMonth={range?.from}					selected={range}					onSelect={setRange}					numberOfMonths={1}					captionLayout="dropdown"					className="[--cell-size:--spacing(10)] md:[--cell-size:--spacing(12)]"					formatters={{						formatMonthDropdown: (date) => {							return date.toLocaleString("default", { month: "long" });						},					}}					components={{						DayButton: ({ children, modifiers, day, ...props }) => {							const isWeekend =								day.date.getDay() === 0 || day.date.getDay() === 6;
							return (								<CalendarDayButton day={day} modifiers={modifiers} {...props}>									{children}									{!modifiers.outside && (										<span>{isWeekend ? "$120" : "$100"}</span>									)}								</CalendarDayButton>							);						},					}}				/>			</CardContent>		</Card>	);}

Week Numbers

Use showWeekNumber to show week numbers.

January 2026
01
02
03
04
05
"use client";
import * as React from "react";
import { Calendar } from "@/components/ui/calendar";import { Card, CardContent } from "@/components/ui/card";
export function CalendarWeekNumbers() {	const [date, setDate] = React.useState<Date | undefined>(		new Date(new Date().getFullYear(), 0, 12),	);
	return (		<Card className="mx-auto w-fit p-0">			<CardContent className="p-0">				<Calendar					mode="single"					defaultMonth={date}					selected={date}					onSelect={setDate}					showWeekNumber				/>			</CardContent>		</Card>	);}

RTL

أكتوبر 2026
"use client";
import * as React from "react";import { arSA, he } from "react-day-picker/locale";
import {	type Translations,	useTranslation,} from "@/components/language-selector";import { Calendar } from "@/components/ui/calendar";
const translations: Translations = {	en: {		dir: "ltr",		values: {},	},	ar: {		dir: "rtl",		values: {},	},	he: {		dir: "rtl",		values: {},	},};
const locales = {	ar: arSA,	he: he,} as const;
export function CalendarRtl() {	const { dir, language } = useTranslation(translations, "ar");	const [date, setDate] = React.useState<Date | undefined>(new Date());
	return (		<Calendar			mode="single"			selected={date}			onSelect={setDate}			className="rounded-lg border [--cell-size:--spacing(9)]"			captionLayout="dropdown"			dir={dir}			locale={				dir === "rtl" ? locales[language as keyof typeof locales] : undefined			}		/>	);}

To enable RTL support, import the locale from react-day-picker/locale and pass both the locale and dir props to the Calendar component:

import { arSA } from "react-day-picker/locale"
<Calendar  mode="single"  selected={date}  onSelect={setDate}  locale={arSA}  dir="rtl"/>

Reference

Props

The Calendar component accepts all props from react-day-picker DayPicker plus the following:

PropTypeDefault