Skip to content
shadcn.io is not affiliated with official shadcn/ui

Shadcn Calendar for React and Tailwind

Select a date, dates, or a range from an inline calendar.

September 2026
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
1
2
3

Installation

bunx --bun shadcn@latest add https://kit.dev/r/calendar.json

Anatomy

Calendar is Ark Date Picker with inline. For a popup field, use Date Picker.

Calendar
├── CalendarViewControl
│   ├── CalendarPrevTrigger
│   ├── CalendarViewDate | CalendarViewTrigger
│   ├── CalendarMonthSelect
│   ├── CalendarYearSelect
│   └── CalendarNextTrigger
└── CalendarTable
    ├── CalendarWeekDays
    └── CalendarTableDays | CalendarTableMonths | CalendarTableYears | CalendarTableNextMonth

Wrap a view in CalendarView when you render day, month, and year grids together.

Usage

import {
  Calendar,
  CalendarNextTrigger,
  CalendarPrevTrigger,
  CalendarTable,
  CalendarTableDays,
  CalendarViewControl,
  CalendarViewDate,
  CalendarWeekDays,
} from "@/components/ui/calendar";
<Calendar>
  <CalendarViewControl>
    <CalendarPrevTrigger />
    <CalendarViewDate />
    <CalendarNextTrigger />
  </CalendarViewControl>
  <CalendarTable>
    <CalendarWeekDays />
    <CalendarTableDays />
  </CalendarTable>
</Calendar>

Values are DateValue[] from @internationalized/date. Use parseDate to build them.

Controlled

Use value and onValueChange.

Root Provider

Use useCalendar with CalendarRootProvider when you need the API outside the tree. Pass inline: true (and other machine options) to useCalendar(), not to the provider.

Examples

Default value

Date range

Set selectionMode="range".

Multiple dates

Set selectionMode="multiple".

Max selected dates

Limit multiple selection with maxSelectedDates.

Month and year selector

Default view

Open on the month grid. Click the header to move between day, month, and year.

Month picker

defaultView="month" and minView="month".

Year picker

defaultView="year" and minView="year".

Month range

Year range

Multiple months

Set numOfMonths and render CalendarTableNextMonth for the offset month.

Presets

CalendarPresetTrigger with values such as last7Days, last30Days, thisMonth.

Min and max

Unavailable dates

isDateUnavailable disables matching days (weekends here).

Select today

Fixed weeks

Always render 6 weeks so the height does not jump between months.

Week numbers

Set showWeekNumbers. CalendarWeekDays and CalendarTableDays add the week column.

Locale

locale and startOfWeek (0 = Sunday, 1 = Monday, …).

Custom cell size

Use [--cell-size:--spacing(n)]. Default is --spacing(9).

md:[--cell-size:--spacing(10)] lg:[--cell-size:--spacing(12)]

Guides

Date Picker

Calendar is always inline. Use Date Picker when you need an input, trigger, and popup.

parseDate

import { parseDate } from "@ark-ui/react/date-picker";

<Calendar defaultValue={[parseDate("2025-01-15")]} />

Multiple months

<Calendar numOfMonths={2} selectionMode="range">
  <CalendarTable>
    <CalendarWeekDays />
    <CalendarTableDays />
  </CalendarTable>
  <CalendarTable>
    <CalendarWeekDays />
    <CalendarTableNextMonth months={1} />
  </CalendarTable>
</Calendar>

API Reference

shadcn.io wraps Ark UI Date Picker with inline. Defaults below are shadcn.io values. lazyMount and unmountOnExit default to true (Ark: false). inline is true unless you override it.

asChild merges props onto a single child element.

Calendar

Root. Renders a div.

PropTypeDefaultDescription
asChildbooleanfalseRender the child element instead of a div.
classNamestring-Class names on the root. Set [--cell-size:] here.
closeOnSelectbooleantrueClose after selection. Ignored for multiple. Little effect when inline.
createCalendar(identifier: CalendarIdentifier) => Calendar-Non-Gregorian calendars.
defaultFocusedValueDateValue-Uncontrolled focused date.
defaultOpenboolean-Uncontrolled open state.
defaultValueDateValue[]-Uncontrolled selected dates.
defaultView"day" | "month" | "year""day"Initial view.
disabledboolean-Disable the calendar.
fixedWeeksboolean-Always show 6 weeks in the day view.
focusedValueDateValue-Controlled focused date.
format(date: DateValue, details: LocaleDetails) => string-Format for inputs (Date Picker).
hideMode"display-none" | "activity""display-none"How to hide inactive views. activity needs React 19+.
idstring-Unique id for the machine.
idsobject-Element ids for composition.
inlinebooleantrueRender on the page, not in a popup.
invalidboolean-Mark as invalid.
isDateUnavailable(date: DateValue, locale: string) => boolean-Disable matching dates.
lazyMountbooleantrueMount views on first use.
localestring"en-US"BCP 47 locale.
maxDateValue-Latest selectable date.
maxSelectedDatesnumber-Cap for selectionMode="multiple".
maxView"day" | "month" | "year""year"Highest view.
minDateValue-Earliest selectable date.
minView"day" | "month" | "year""day"Lowest view.
namestring-Native input name (Date Picker).
numOfMonthsnumber-Months to display. Use with CalendarTableNextMonth.
onFocusChange(details: FocusChangeDetails) => void-Focused date changed.
onOpenChange(details: OpenChangeDetails) => void-Open state changed.
onValueChange(details: ValueChangeDetails) => void-Selection changed. { value: DateValue[] }.
onViewChange(details: ViewChangeDetails) => void-View changed.
onVisibleRangeChange(details: VisibleRangeChangeDetails) => void-Visible month range changed.
openboolean-Controlled open state.
openOnClickbooleanfalseOpen on input click (Date Picker).
outsideDaySelectablebooleanfalseAllow days outside the visible month.
parse(value: string, details: LocaleDetails) => DateValue | undefined-Parse input text (Date Picker).
placeholderstring-Input placeholder (Date Picker).
positioningPositioningOptions-Popup position (Date Picker).
readOnlyboolean-Non-editable.
requiredboolean-Required for forms.
selectionMode"single" | "multiple" | "range""single"How many dates can be selected.
showWeekNumbersboolean-ISO week column in the day view.
startOfWeeknumber-0 Sunday … 6 Saturday.
timeZonestring"UTC"Time zone.
translationsPartial<IntlTranslations>-Localized strings.
unmountOnExitbooleantrueUnmount inactive views.
valueDateValue[]-Controlled selected dates.
view"day" | "month" | "year"-Controlled view.
AttributeDescription
data-slotcalendar
data-scopedate-picker
data-partroot
data-state"open" or "closed"
data-disabledPresent when disabled
data-readonlyPresent when read-only
CSS variableDefaultDescription
--cell-size--spacing(9)Width/height of day cells

CalendarRootProvider

Takes the API from useCalendar. Pass inline: true to useCalendar().

PropTypeDefaultDescription
valueUseDatePickerReturnrequiredReturn value of useCalendar().
asChildbooleanfalseRender the child element instead of a div.
classNamestring-Class names on the root.
lazyMountbooleantrueMount views on first use.
unmountOnExitbooleantrueUnmount inactive views.

CalendarViewControl

Header row for prev/next and the month label or selects.

PropTypeDefaultDescription
asChildbooleanfalseMerge onto a single child.
classNamestring-Class names on the control.
AttributeDescription
data-slotcalendar-view-control
data-partview-control
data-view"day", "month", or "year"

CalendarPrevTrigger / CalendarNextTrigger

Navigate the visible range. Render as Button size="icon-md" variant="ghost" with aria-label "Previous" / "Next". Chevrons flip in RTL.

PropTypeDefaultDescription
asChildbooleantrueMerged onto the inner Button.
classNamestring-Class names on the trigger.

CalendarViewDate

Visible month/year label (RangeText).

PropTypeDefaultDescription
asChildbooleanfalseMerge onto a single child.
classNamestring-Class names on the label.

CalendarViewTrigger

Button that changes view (day → month → year). Defaults to rendering CalendarViewDate.

CalendarView

One calendar view.

PropTypeDefaultDescription
view"day" | "month" | "year"-Which grid this block is.
asChildbooleanfalseMerge onto a single child.
classNamestring-Class names on the view.

CalendarMonthSelect / CalendarYearSelect

Native <select> dropdowns. Year/month select wrap a chevron. CalendarMonthSelect accepts Ark’s month format options.

CalendarTable

Day/month/year grid. Renders a table.

PropTypeDefaultDescription
columnsnumber-Column count for month/year grids.
asChildbooleanfalseMerge onto a single child.
classNamestring-Class names on the table.

CalendarWeekDays

Header row. format: "narrow" (default), "short", "long". Adds a week-number header when showWeekNumbers is set.

CalendarTableDays

Day cells for the focused month. Adds week-number cells when showWeekNumbers is set.

CalendarTableNextMonth

Day cells offset by months (default 1) via getOffset.

CalendarTableMonths / CalendarTableYears

Month and year grids (getMonthsGrid / getYearsGrid). columns default 4.

CalendarTableCell

One selectable cell. value is a DateValue (day) or number (month/year).

PropTypeDefaultDescription
valueDateValue | numberrequiredCell value.
visibleRangeVisibleRange-Visible range for offset months.
disabledboolean-Disable the cell.
classNamestring-Class names on the cell trigger.
AttributeDescription
data-selectedPresent when selected
data-todayPresent for today
data-disabledPresent when disabled
data-unavailablePresent when unavailable
data-in-rangePresent inside a range
data-range-start / data-range-endRange endpoints
data-focusPresent when focused

CalendarPresetTrigger

Quick range. value is a preset such as "last7Days", "last30Days", "thisMonth", "lastMonth", "thisWeek", "lastWeek". Use asChild with Button.

CalendarTodayTrigger

Button that calls selectToday() from context.

CalendarWeekNumberHeaderCell / CalendarWeekNumberCell

Week-number column. Prefer showWeekNumbers on the root with CalendarWeekDays / CalendarTableDays.

Other Date Picker parts

CalendarLabel, CalendarControl, CalendarTrigger, CalendarClearTrigger are still exported for popup/input composition. Prefer Date Picker for those layouts.

useCalendar

Creates the date-picker API for CalendarRootProvider.

const calendar = useCalendar({ inline: true });
calendar.selectToday();

CalendarContext / useCalendarContext

Render-prop or hook access. Use inside Calendar or CalendarRootProvider.

PropertyTypeDescription
valueDateValue[]Selected dates.
valueAsStringstring[]Selected dates as strings.
focusedValueDateValueFocused date.
view"day" | "month" | "year"Current view.
weeksDateValue[][]Weeks in the visible month.
weekDaysWeekDay[]Weekday labels.
visibleRangeVisibleRangeVisible start/end.
selectionModeSelectionModesingle, multiple, or range.
selectToday() => voidSelect today.
setValue(values: DateValue[]) => voidSet selection.
clearValue(options?: { focus?: boolean }) => voidClear selection.
setView(view: DateView) => voidChange view.
goToNext / goToPrev() => voidMove the visible range.
getOffset(duration: DateDuration) => DateValueOffsetData for an adjacent month.
getMonthsGrid(props?: MonthGridProps) => MonthGridValueMonth cells.
getYearsGrid(props?: YearGridProps) => YearGridValueYear cells.
getWeekNumber(week: DateValue[]) => numberISO week number.
isUnavailable(date: DateValue) => booleanWhether a date is blocked.

CalendarContext children: (context) => ReactNode.

Accessibility

Complies with the Date Picker WAI-ARIA pattern for the grid. Prev/next controls have aria-label. Decorative chevrons are aria-hidden.

Keyboard support

KeyDescription
ArrowLeftPrevious day in the week (flips in RTL).
ArrowRightNext day in the week.
ArrowUpSame weekday in the previous week.
ArrowDownSame weekday in the next week.
HomeFirst day of the month.
EndLast day of the month.
PageUpSame day in the previous month.
PageDownSame day in the next month.
EnterSelect the focused date.
EscClose a popup Date Picker. No-op when inline.