Component
Calendar
A month grid for picking one date or a range of dates inline, for booking or availability surfaces where the date is the point of the screen. In a form, use DatePicker, which opens this grid in a popover.
Xem trước
import { Calendar } from "@/components/ui/calendar"
<Calendar />Cách dùng
Khi nào dùng
- A whole month on the page when the date is the point of the screen, such as availability or booking.
- Limiting the choice to real dates, with disabled days or a min and max date.
Khi nào không dùng
- Picking one date in a form, next to other fields. Use DatePicker.
- Showing events on their dates. This is a picker, not a schedule.
Biến thể
weekStartsOn
The first day of the week: 0 Sunday or 1 Monday. Follows the locale when not set.
import { Calendar } from "@/components/ui/calendar"
<Calendar />
<Calendar weekStartsOn={1} />Ví dụ
Inline
Calendar on the page, for when the date is the point of the screen.
import { Calendar } from "@/components/ui/calendar"
<Calendar weekStartsOn={1} />A range
Two months for a range that crosses a month. The first click sets the start, the second the end.
import { Calendar } from "@/components/ui/calendar"
<Calendar mode="range" numberOfMonths={2} />Nên và không nên
Nên
- Use Calendar inline when the date is the page's whole purpose, such as a booking or availability surface.
- Use DatePicker instead in forms, next to Input fields.
- Disable days that can never be picked, such as past days or closed days, over a minDate and maxDate.
- Use two months for ranges that often cross a month.
Không nên
- Don't use a range for one date; keep the single mode.
- Don't put a Calendar in your own popover for a form field; DatePicker already does that, with the focus handling.
Props
| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
|---|---|---|---|---|
| mode | enum | single | range | single | single picks one Date; range picks a start and an end ({ from, to }). After a complete range the next click starts a new one; a click on the day of a one-day range clears it. A range never spans a disabled day. |
| value | string | - | - | The picked Date, or in range mode the picked range ({ from, to }), when you control it. An explicit undefined clears the selection; omitting value uses internal state. Pair it with onValueChange. |
| defaultValue | string | - | - | The Date, or in range mode the range, picked on first render, when you don't control it. |
| onValueChange | function | - | - | Called with the picked Date, or undefined when the user unpicks it. In range mode it is called on every click: { from } after the first, { from, to } after the second, undefined when a one-day range is cleared. |
| disabled | boolean | - | false | true disables every day; a function receives a Date and disables single days, such as weekends or past dates. |
| minDate | string | - | - | No day before this Date can be picked or navigated to. |
| maxDate | string | - | - | No day after this Date can be picked or navigated to. |
| locale | string | - | - | A date-fns Locale object for month and weekday names. The default is enUS. |
| weekStartsOn | enum | 0 | 1 | - | The first day of the week: 0 Sunday or 1 Monday. Follows the locale when not set. |
| numberOfMonths | number | - | 1 | How many months show at once, side by side from sm and stacked below it. Use two for ranges that often cross a month. |
| rangeStartLabel | string | - | start of range | Range mode. Added to the start day's accessible name; translate it with the locale. |
| rangeEndLabel | string | - | end of range | Range mode. Added to the end day's accessible name; translate it with the locale. |
Cấu tạo
| Phần | Mô tả |
|---|---|
| root | The month view, padded md. With numberOfMonths above 1 the months sit side by side from sm and stack below it. |
| label | The caption row: the month and year, md medium text, centered between the navigation buttons. |
| icon | Tabler ChevronLeft and CaretRight, 16px, secondary, in the previous and next month buttons. |
| head | One weekday column header, xs medium secondary text. |
| item | One day: the cell and its button. The button is the md control height, square; the cell carries the selected fill. In range mode the two ends take the accent solid, rounded on the outer side and square toward the band. |
| range | A day between the two ends of a range; the cells form one band. |
Khả năng truy cập
Role: grid
| Phím | Hành động |
|---|---|
| Space, Enter | Picks the focused day. |
| ArrowDown, ArrowUp, ArrowLeft, ArrowRight | Moves focus to the day a week later or earlier, or the day before or after, skipping disabled days. |
| Home, End | Moves focus to the first or last day of the week. |
| PageUp, PageDown | Moves focus to the same day in the previous or next month. Shift goes by year. |
- One day button at a time is tabbable; the arrow keys move focus inside the grid, following the WAI-ARIA APG grid pattern. With several months they cross from one month into the next.
- The picked day's cell has aria-selected, the disabled days have native disabled buttons, and the caption is a polite live region, so a screen reader hears the month it lands on.
- In range mode every day in the range has aria-selected. The start and end buttons add rangeStartLabel and rangeEndLabel ("start of range", "end of range") to their accessible names; a one-day range gets both. The ends differ from the middle by fill and shape, and the DatePicker trigger or the caption names the dates, so the state never relies on color alone.
- The weekday header row is a real row of column headers.
Cài đặt
npx shadcn add https://werewolf-ui.vercel.app/r/calendar.jsonLệnh này thêm luôn styles/werewolf.css, bộ token mà mọi component dùng, và các component khác mà nó cần. Import file đó một lần trong CSS gốc, ngay sau @import "tailwindcss", với đường dẫn tính từ file CSS đó (từ app/globals.css là @import "../styles/werewolf.css").