shadcn.io is not affiliated with official shadcn/ui
Components
Free
Calendar for Vue
Choose one day, several days, or a range without opening a popover first. For Vue with Ark UI, when the month should stay on the page while someone picks.
Framework
UI library
Month view for one day, several days, or a range. It stays on the page.
Use it when choosing the date is the task. When the date is one field among many, a Date Picker opens this grid in a popover. In Vue, Ark UI moves between days with the arrow keys, and Enter selects.
Installation
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Moves focus to the previous day within the current week.
Arrow Right
Moves focus to the next day within the current week.
Arrow Up
Moves focus to the same day of the week in the previous week.
Arrow Down
Moves focus to the same day of the week in the next week.
Home
Moves focus to the first day of the current month.
End
Moves focus to the last day of the current month.
Page Up
Moves focus to the same day of the month in the previous month.
Page Down
Moves focus to the same day of the month in the next month.
Enter
Selects the focused date.
Space
Activate the focused control.
Demos
Hijri
This month follows a Persian calendar, not a Gregorian grid with translated labels. The selected day starts at 12 June 2025 so there is a stable date to look at. Reach for it when the product's dates are Jalali or Hijri. A locale on an ordinary calendar only renames months and weekdays, so the calendar system has to change as well.
Basic
Previous and next sit around the month title, with no year menu. fixedWeeks keeps every month six rows tall so the block does not jump. Use the plain title when dates are near today and paging by month is fine. A birthday decades back needs year menus, not that walk.
Range
Two months sit side by side, and the selection runs eighteen days from the 20th. Use a range for a stay, a report window, or a filter with a from and a to. A single day is the wrong mode, because a second click should extend the first, not replace it.
Caption
The control row replaces the plain month title with month and year menus. That is the layout for a birthday, a document date, or any value far from the current month. People should not hammer next through twenty years. Keep the plain title when the range is the next few weeks and the menus would only add chrome.
Presets
Today, Tomorrow, and Next week sit under the grid and write the selection themselves. Add shortcuts when most people want a relative date and the grid is the fallback. The button should also move the visible month, or Next week looks like it did nothing while last month stays on screen. Skip shortcuts when the dates have nothing in common.
Time
From and To sit under the days, defaulting to 10:30 and 12:30. The grid still only picks a date, and the clocks are separate inputs, so a meeting can have hours without the calendar storing them. Keep the month visible this way when a popover would hide it. Label both fields, because an unlabeled time is easy to misread as part of the date.
Booked Dates
A run of days is unavailable and drawn with a line through the number. Those days stay visible so the month looks full, but they cannot be selected. Use that for reservations, blackout dates, or a cutoff in the past. Hiding the days makes the grid look broken, so if the strike is unclear, say nearby why those dates are blocked.
Custom Days
Each in-month day shows its number and a price, 100 on weekdays and 120 on weekends. The selection is a range that starts on the 8th. Render the cell when a day carries a fare, a capacity, or a marker, and keep the extra to a few characters. The price sits under the number and should not replace it.
Week Numbers
A column of week numbers sits beside the days. Turn that on for scheduling or payroll, where people already name weeks, and leave it off a birthday picker, where it is noise. Those numbers follow the locale's week rules, so do not label a Monday start and let the column count from Sunday. fixedWeeks still keeps the month a constant height.
Multiple
Several days can be selected at once, starting here with the 4th, the 12th, and the 18th. Use that for shifts or exceptions, dates that are not one continuous stay. A range fits better when the value is a start and an end. Selecting a day toggles it, so the set can change without a separate clear control.
Rtl
dir is rtl and the locale is Arabic, so the week runs from the inline start and the month controls follow the text. Set direction on the calendar when the page is Arabic or Hebrew, not only on a wrapper the grid never sees. The previous and next controls already follow the inline direction. Mirroring the icons yourself can aim them backward.
FAQ
When should I use a Calendar instead of a Date Picker?
Use the Calendar when the month should stay visible on the page, such as a booking screen or a dashboard filter. When the date belongs in a form field, use the Date Picker: an input that opens this calendar in a popover.
How do I select a date range with the Calendar in Vue?
Set selectionMode to range, and numOfMonths to 2 to show two months side by side. The value then holds the start and end dates, as in the Range demo.
How do I let users pick several dates in the Calendar?
Set selectionMode to multiple: the value becomes a list of dates, as in the Multiple demo.
maxSelectedDates caps how many can be picked.
How do I disable booked or past dates in the Calendar?
Pass isDateUnavailable, a function that returns true for days that can't be picked, and min or max to limit the range.
The Booked Dates demo keeps booked days visible with a line through them.
How do I let users jump to a year, such as a birth year, in the Ark UI Calendar?
Add CalendarMonthSelect and CalendarYearSelect to the control row, as the Caption demo does, so nobody clicks back month by month.
Why does the Calendar select the day before the date I set?
Its values are calendar dates without a time, so they don't shift with time zones. Create them with parseDate from a string such as 2025-06-01, rather than converting a Date that carries a time.
Can the Calendar show a Persian or Hijri calendar?
Yes. The Hijri demo shows a Persian calendar. A locale on its own only translates the month and weekday names; the calendar system has to change too, as that demo does.
How do I install the Calendar in Vue?
Run the command in the Installation section above: it adds calendar to your components/ui folder with the packages it needs. React and Solid use the shadcn CLI, Vue uses shadcn-vue and Svelte uses shadcn-svelte, each after its one-time setup.
API Reference
Calendar
<div>data-slot="calendar"
PropType
open?boolean
The controlled open state of the date picker. Two-way with v-model:open.
defaultOpen?boolean
The initial open state of the date picker when rendered.
Use when you don't need to control the open state of the date picker.
value?DateValue[]
The controlled selected date(s). Two-way with v-model.
defaultValue?DateValue[]
The initial selected date(s) when rendered.
Use when you don't need to control the selected date(s) of the date picker.
view?"day" | "month" | "year"
The view of the calendar. Two-way with v-model:view.
Type
"day" | "month" | "year"
defaultView?"day" | "month" | "year"
The default view of the calendar.
Type
"day" | "month" | "year"
Default
"day"
closeOnSelect?boolean
Whether the calendar should close after the date selection is complete.
This is ignored when the selection mode is multiple.
A function that creates a Calendar object for a given calendar identifier.
Enables non-Gregorian calendar support (Persian, Buddhist, Islamic, etc.)
without bundling all calendars by default.
import { createCalendar } from "@internationalized/date"
{ locale: "fa-IR", createCalendar }
How to hide content when mounted but not present.
- display-none: HTML hidden attribute. Effects stay alive.
- activity: React 19 <Activity mode="hidden">. Effects pause. Requires React 19+.
Type
"display-none" | "activity"
Default
"display-none"
id?string
The unique identifier of the machine.
ids?object
The ids of the elements in the date picker. Useful for composition.
The selection mode of the calendar.
- single - only one date can be selected
- multiple - multiple dates can be selected
- range - a range of dates can be selected
Type
"single" | "multiple" | "range"
Default
"single"
showWeekNumbers?boolean
Whether to show the week number column in the day view.
skipAnimationOnMount?boolean
Whether to allow the initial presence animation.
Default
false
startOfWeek?number
The first day of the week.
0 - Sunday
1 - Monday
2 - Tuesday
3 - Wednesday
4 - Thursday
5 - Friday
6 - Saturday
Use the provided child element as the default rendered element, combining their props and behavior.
AttributeType
data-disabled?string
Present when disabled is true.
data-empty?string
Present when empty is true.
data-readonly?string
Present when readOnly is true.
data-state"open" | "closed"
"open" or "closed".
Type
"open" | "closed"
CalendarWeekDays
<thead>data-slot="calendar-table-head"
PropType
format?"narrow" | "short" | "long"
Weekday label width. short is two letters (Su), matching the other
calendar bases.
Type
"narrow" | "short" | "long"
Default
"short"
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
AttributeType
data-disabled?string
Present when disabled.
data-view?string
The view of the tablehead.
CalendarTableDays
PropType
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
AttributeType
data-disabled?string
Present when disabled is true.
data-empty?string
Present when empty is true.
data-readonly?string
Present when readOnly is true.
data-state"open" | "closed"
"open" or "closed".
Type
"open" | "closed"
CalendarTableNextMonth
PropType
months?number
The number of months to offset.
Default
1
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
AttributeType
data-disabled?string
Present when disabled is true.
data-empty?string
Present when empty is true.
data-readonly?string
Present when readOnly is true.
data-state"open" | "closed"
"open" or "closed".
Type
"open" | "closed"
CalendarWeekNumberHeaderCell
<th>data-slot="calendar-week-number-header-cell"
PropType
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
class?string
Merged with the part's classes.
AttributeType
data-disabled?string
Present when disabled.
data-type?string
The type of the item.
data-view?string
The view of the weeknumberheadercell.
CSS variableType
--cell-sizestring
CalendarWeekNumberCell
<td>data-slot="calendar-week-number-cell"
PropType
weekDateValue[]
The week's days, the row it numbers.
weekIndexnumber
The week's row in the month, from 0.
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
class?string
Merged with the part's classes.
AttributeType
data-disabled?string
Present when disabled.
data-type"week-number"
The type of the item.
Default
"week-number"
data-view"day"
The view of the weeknumbercell.
Default
"day"
data-week-indexstring
Mirrors weekIndex.
CSS variableType
--cell-sizestring
CalendarTableMonths
PropType
columns?number
How many months each row holds.
Default
4
format?"short" | "long"
How month names are written: short (Jan) or long (January).
Type
"short" | "long"
Default
"short"
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
AttributeType
data-disabled?string
Present when disabled is true.
data-empty?string
Present when empty is true.
data-readonly?string
Present when readOnly is true.
data-state"open" | "closed"
"open" or "closed".
Type
"open" | "closed"
CalendarTableYears
PropType
columns?number
How many years each row holds.
Default
4
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
AttributeType
data-disabled?string
Present when disabled is true.
data-empty?string
Present when empty is true.
data-readonly?string
Present when readOnly is true.
data-state"open" | "closed"
"open" or "closed".
Type
"open" | "closed"
CalendarRootProvider
<div>data-slot="calendar"
PropType
valueUseDatePickerReturn
What useCalendar() returns: the state and API, made outside the component to control it.
hideMode?"display-none" | "activity"
How to hide content when mounted but not present.
- display-none: HTML hidden attribute. Effects stay alive.
- activity: React 19 <Activity mode="hidden">. Effects pause. Requires React 19+.
Type
"display-none" | "activity"
Default
"display-none"
lazyMount?boolean
Whether to enable lazy mounting. Ark default: false.
Default
true
skipAnimationOnMount?boolean
Whether to allow the initial presence animation.
Default
false
unmountOnExit?boolean
Whether to unmount on exit. Ark default: false.
Default
true
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.