Trang này chưa có bản tiếng Việt. Nội dung dưới đây là bản tiếng Anh.
Components
Calendar
A bare calendar built on react-day-picker for selecting a single day, multiple days, or a date range, with keyboard navigation and dropdown month and year controls.
This is the primitive. If you want a typed date input — MM/dd/yyyy in English, dd/MM/yyyy in Vietnamese — a popover, and presets like “Today” or “Last 7 days” already wired up, use the Tier 2 composites DatePicker and DateRangePicker instead.
Basic usage
Use mode="single" for a one-day picker. The calendar manages its own selection state when left uncontrolled; leave mode off entirely and it renders read-only.
Range selection
Set mode="range" and render two months with numberOfMonths for booking and reporting date pickers.
Multiple days
With mode="multiple" users can toggle any number of individual, non-contiguous days.
Dropdown caption
Pass captionLayout="dropdown" to swap the static month label for month and year dropdowns — handy for jumping across distant dates like a birthdate. Bound the year list with startMonth / endMonth. The month names in the dropdown follow the same locale as the grid — see below.
Localisation
Since 3.0.0 the calendar follows ComitorLocaleProvider, twice over. Weekday and month names come from the provider's date-fns locale — vi under locale="vi", enUS for every other code (give the provider dateFnsLocale={enGB} for British dates). The screen-reader labels react-day-picker attaches — the navigation buttons, the dropdowns, the name of every day — come from the provider's calendar strings. A date-fns locale carries no interface text, so a Vietnamese app used to hear react-day-picker's hard-coded English, “Go to the Previous Month”, in the middle of a Vietnamese screen. A locale prop still wins for the names, a labels prop for the labels.
The month dropdown is abbreviated with the code of whichever locale is in force, so a calendar with no locale no longer mixes an English grid with a vi-VN dropdown, as it did before 3.0.0. It still never asks for toLocaleString('default'), as the vendored copy did: that resolves against whatever locale the process is running under, so the server and the browser could produce different strings and React would report a hydration mismatch.
Disabled dates
The disabled prop accepts a matcher — here every day before June 17 is non-selectable and dimmed.
Content inside a day
CalendarDayButton is exported so you can add a second line to a day — an event count, a price, a status dot — without rebuilding the cell. Swap components.DayButton for a wrapper that renders the day number plus your own <span>; the component styles that span at text-xs and opacity-90.
Props
| Prop | Kiểu | Mặc định | Mô tả |
|---|---|---|---|
mode | 'single' | 'multiple' | 'range' | — | Selection behavior — a single day, an array of days, or a contiguous date range. Leave it off for a read-only calendar. |
selected | Date | Date[] | DateRange | — | Controlled selected value. Pair with onSelect; omit for an uncontrolled calendar. The shape follows mode. |
onSelect | (value) => void | — | Called when the selection changes. Shape matches the active mode. |
defaultMonth | Date | current month | The month displayed on first render when uncontrolled. |
month / onMonthChange | Date / (month: Date) => void | — | Controls which month is displayed. Use both to drive navigation from outside the calendar. |
startMonth / endMonth | Date | — | Bounds for navigation, and the range the year dropdown offers under captionLayout="dropdown". |
numberOfMonths | number | 1 | How many months to render side by side. Useful for range pickers. |
captionLayout | 'label' | 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label' | Renders the month/year as a static label or as navigable dropdowns. |
buttonVariant | 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link' | 'ghost' | Button variant applied to the previous/next navigation buttons. |
showOutsideDays | boolean | true | Show days from adjacent months that fill the leading and trailing weeks. |
disabled | Matcher | Matcher[] | — | Days that cannot be selected — a date, range, predicate, or matcher object. |
locale | Locale (date-fns) | provider’s | Weekday and month names, and the abbreviations in the month dropdown. Without it the calendar takes the date-fns locale of ComitorLocaleProvider: vi under locale="vi", enUS for every other code unless the provider is given a dateFnsLocale. |
labels | Partial<Labels> | provider’s | The screen-reader labels react-day-picker attaches — navigation buttons, dropdowns, the name of each day. Defaults to the calendar strings of ComitorLocaleProvider (“Go to previous month”, “Today, …, selected”). A locale from react-day-picker/locale carries labels of its own, which then win over the provider’s; this prop wins over both. |
formatters | Partial<Formatters> | — | Per-slot label formatters. Merged over the component’s own formatMonthDropdown, so overriding one leaves the rest intact. |
components | Partial<CustomComponents> | — | Swap individual internals. Merged over the component’s defaults — pass DayButton to build on CalendarDayButton rather than replacing it. |
className | string | — | Additional Tailwind classes merged onto the calendar root. |
classNames | Partial<ClassNames> | — | Override individual element class names (day, weekday, nav, etc.). |
All other react-day-picker props are forwarded to the underlying DayPicker.
Accessibility
- The grid follows the WAI-ARIA date picker pattern — days are reachable with arrow keys, and Enter or Space selects the focused day.
- Previous and next navigation render as real
<button>elements with accessible labels — “Go to previous month” and “Go to next month”, in the provider's language — and takearia-disabledat the ends of the navigable range. A disabled day instead gets the nativedisabledattribute, so it drops out of the tab order; style it fromdata-disabledon the cell. - The day cell carries
aria-selected, and the state is spelled out in the day button'saria-label— today reads “Today, …” and a chosen day ends in “, selected” (“Hôm nay, …” and “, đã chọn” in Vietnamese) — so neither state rests on colour alone. react-day-picker emits noaria-current; today reaches CSS asdata-today. - Focused days receive a visible
focus-visiblering using the brand ring token, and focus is automatically moved to the focused day when navigating months. - A selected day is a control in its on state, so it uses the control pair —
bg-control-onwithtext-control-check— the same pair as a checkedCheckbox. Splitting the pair works by accident in the default palette, where the two tokens happen to be equal, and breaks in the high-contrast one. - Extra content you render inside a day is capped at
opacity-90. The day stays clickable and focusable, so it is not exempt from the 4.5:1 text threshold. The worst case is a selected day in the light high-contrast palette:opacity-80lands at 4.43:1 and fails, 85% clears at 4.79:1, and the shipped 90% leaves headroom at 5.15:1. - Known limitation: the today and range middle tints both use
--accent, which sits near 1.1:1 against the calendar background. They read as a soft cue, not as information — pair them with a real signal if the state has to be perceivable on its own.