Make your AI a shadcn expert

Shadcn Calendar

React calendar for bookings, filters, and date ranges. Built with TypeScript and Tailwind CSS for Next.js using Base UI — single days, ranges, and locales.

The shadcn calendar is a month grid. Click a day and it selects — one date, several dates, or a from/to range. Use it inline on a booking page. Wrap it in a Popover when the trigger should be a field.

Scroll to load preview...

Looking for a neobrutalism version for shadcn?

Same calendar, thicker borders. The NeoBrutalism calendar is the kit if you want that look.

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"
  />
)

mode="single" is one day. mode="range" is from/to. captionLayout="dropdown" jumps years.

Composition

CalendarDayButton

CalendarDayButton is the cell. Override it through components.DayButton.

Persian / Hijri / Jalali Calendar

Swap the DayPicker import in components/ui/calendar.tsx. Official still writes react-day-picker/persian; v10 ships that as @daypicker/persian. The rest of the file stays.

- import { DayPicker } from "react-day-picker"
+ import { DayPicker } from "react-day-picker/persian"
Scroll to load preview...

Basic

A single month. className="rounded-lg border" is the frame.

Scroll to load preview...

Range Calendar

mode="range" and numberOfMonths={2}. The fill is the span between from and to.

Scroll to load preview...

Month and Year Selector

captionLayout="dropdown" — month and year menus. Birthdays need this.

Scroll to load preview...

Presets

Buttons that set today, tomorrow, or in a week. Keep month in sync so the grid jumps with the preset.

Scroll to load preview...

Date and Time Picker

The grid picks the day. Native type="time" fields pick the clock.

Scroll to load preview...

Booked dates

Pass those days to disabled. Add a booked modifier if they should stay visible with a strike.

Scroll to load preview...

Custom Cell Size

--cell-size on the calendar. Override DayButton to drop a price under the number.

<Calendar
  mode="single"
  className="rounded-lg border [--cell-size:--spacing(11)] md:[--cell-size:--spacing(12)]"
/>
Scroll to load preview...

Week Numbers

showWeekNumber adds a column on the start.

Scroll to load preview...

RTL

Wrap with DirectionProvider and dir="rtl". Pass a DayPicker locale so weekday names match.

import { arSA } from "react-day-picker/locale"

<Calendar mode="single" locale={arSA} dir="rtl" />
Scroll to load preview...

API

These are react-day-picker props plus buttonVariant on the wrapper.

Prop

Type

CalendarDayButton

Prop

Type

className works on both. Pass a custom DayButton through components.

Keyboard

KeyAction
Arrow keysMove between days
Enter / SpaceSelect the focused day
Page Up / Page DownPrevious / next month
Shift + Page Up / Shift + Page DownPrevious / next year
Home / EndFirst / last day of the week

Notes

The 20th highlights the 19th

new Date("2025-06-01") is UTC midnight. West of UTC that is still May 31. Use new Date(2025, 5, 1), or set timeZone from Intl.DateTimeFormat().resolvedOptions().timeZone inside a useEffect so the server and the client agree.

Matcher functions run per day. An array of Dates is enough for a booked list.

With other components

Questions

Was this page helpful?

Sign in to leave feedback.