Calendar
12 partsA fully accessible, headless date calendar for picking a single day. The
root owns the selected value and the displayed month ("placeholder"), builds
the localized month grid(s), and wires up roving keyboard navigation,
min/max bounds, and disabled/unavailable predicates. Use it to build an
inline date picker or as the body of a popover/DatePicker.
Compose it with CalendarHeader (CalendarPrev / CalendarHeading /
CalendarNext) and one CalendarGrid per month. Supports v-model for the
selected date and v-model:placeholder for the visible month.
Demo
Anatomy
Import the parts and compose them. Each part forwards attributes to its underlying element.
import {
CalendarRoot,
CalendarHeader,
CalendarHeading,
CalendarPrev,
CalendarNext,
CalendarGrid,
CalendarGridHead,
CalendarGridBody,
CalendarGridRow,
CalendarHeadCell,
CalendarCell,
CalendarCellTrigger,
} from '@robonen/primitives/display/calendar';
<CalendarRoot>
<CalendarHeader />
<CalendarHeading />
<CalendarPrev />
<CalendarNext />
<CalendarGrid />
<CalendarGridHead />
<CalendarGridBody />
<CalendarGridRow />
<CalendarHeadCell />
<CalendarCell />
<CalendarCellTrigger />
</CalendarRoot>API Reference
CalendarRoot
RootA fully accessible, headless date calendar for picking a single day. The root owns the selected value and the displayed month ("placeholder"), builds the localized month grid(s), and wires up roving keyboard navigation, min/max bounds, and disabled/unavailable predicates. Use it to build an inline date picker or as the body of a popover/`DatePicker`. Compose it with `CalendarHeader` (`CalendarPrev` / `CalendarHeading` / `CalendarNext`) and one `CalendarGrid` per month. Supports `v-model` for the selected date and `v-model:placeholder` for the visible month.
| Prop | Type | Description |
|---|---|---|
defaultValue? | Date | Date[] | Uncontrolled default selected date (or dates when multiple). |
defaultPlaceholder? | Date | Uncontrolled default placeholder (displayed month). |
minValue? | Date | Minimum selectable date. |
maxValue? | Date | Maximum selectable date. |
isDateUnavailable? | (date: Date) => boolean | Predicate marking a date as unavailable (not selectable). |
isDateDisabled? | (date: Date) => boolean | Predicate marking a date as disabled. |
pagedNavigation? | boolean | Prev/Next navigate by numberOfMonths instead of one month. |
weekStartsOn? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | First day of week (0=Sun ... 6=Sat). |
weekdayFormat? | WeekDayFormat | Width of localized weekday names. |
fixedWeeks? | boolean | Always render 6 weeks per month. |
numberOfMonths? | number | Number of months displayed simultaneously. |
disabled? | boolean | Disable the whole calendar. |
readonly? | boolean | Make the calendar read-only. |
initialFocus? | boolean | Auto-focus the calendar on mount. |
locale? | string | Locale for Intl formatting. |
dir? | 'ltr' | 'rtl' | Reading direction. |
nextPage? | (placeholder: Date) => Date | Override "next page" navigation logic. |
prevPage? | (placeholder: Date) => Date | Override "prev page" navigation logic. |
calendarLabel? | string | Calendar accessible label prefix. |
multiple? | boolean | Allow selecting multiple dates; model becomes a Date[]. |
preventDeselect? | boolean | Prevent deselecting the last selected date by re-clicking it. |
disableDaysOutsideCurrentView? | boolean | Disable days that belong to adjacent months (outside the current view). |
dateAdapter? | DateAdapter<Date> | Pluggable date backend driving all date math/formatting. Falls back to the
app ConfigProvider dateAdapter (native Date) when omitted. |
modelValue? | Date | Date[] | undefined | Two-way bound value (v-model). |
placeholder? | Date | Two-way bound value (v-model:placeholder). |
| Event | Payload |
|---|---|
update:modelValue | [value: Date | Date[] | undefined] |
update:placeholder | [value: Date] |
CalendarHeader
HeaderLayout container for the calendar's top bar. Holds the `CalendarPrev`, `CalendarHeading`, and `CalendarNext` controls above the month grid(s).
No props or events — renders its element and forwards attributes.
CalendarHeading
HeadingDisplays the currently visible month and year (e.g. "June 2026"), or a range when multiple months are shown. Marked `aria-hidden` since the grid already carries the full accessible label; expose the value via its default slot to customize the rendering.
No props or events — renders its element and forwards attributes.
CalendarPrev
PrevButton that pages the calendar backward (by one month, or by `numberOfMonths` when paged navigation is enabled). Auto-disables when the previous page would fall before `minValue` or the calendar is disabled.
| Prop | Type | Description |
|---|---|---|
prevPage? | (placeholder: Date) => Date | Override the root's prevPage for just this button. |
CalendarNext
NextButton that pages the calendar forward (by one month, or by `numberOfMonths` when paged navigation is enabled). Auto-disables when the next page would fall after `maxValue` or the calendar is disabled.
| Prop | Type | Description |
|---|---|---|
nextPage? | (placeholder: Date) => Date | Override the root's nextPage for just this button. |
CalendarGrid
GridThe `role="grid"` table for a single month. Provides grid context (the month it renders) to its head/body cells; render one per visible month when `numberOfMonths > 1`.
| Prop | Type | Description |
|---|---|---|
month? | Date | The month this grid represents. Defaults to the root placeholder's month. |
CalendarGridHead
GridHeadThe grid's `<thead>` wrapper holding the row of weekday `CalendarHeadCell` labels. Marked `aria-hidden` since each day cell already carries its full accessible label, avoiding a double weekday-column announcement.
No props or events — renders its element and forwards attributes.
CalendarGridBody
GridBodyThe grid's `<tbody>` wrapper containing the week rows (`CalendarGridRow`) of day cells.
No props or events — renders its element and forwards attributes.
CalendarGridRow
GridRowA single table row (`<tr>`) representing one week of the month, or the weekday-label row inside the grid head.
No props or events — renders its element and forwards attributes.
CalendarHeadCell
HeadCellA `scope="col"` weekday header cell (`<th>`). Renders the localized short label in its slot while exposing the full weekday name as the `aria-label` when a `day` is provided.
| Prop | Type | Description |
|---|---|---|
day? | Date | The day this header cell represents — used for aria-label. |
CalendarCell
CellA single `role="gridcell"` day container (`<td>`). Reflects the date's state (selected, disabled, unavailable, outside-view, today) as `data-*` attributes and `aria-*` for styling, and wraps the focusable `CalendarCellTrigger`.
| Prop | Type | Description |
|---|---|---|
date | Date | The date this cell represents. |
CalendarCellTrigger
CellTriggerThe focusable, clickable day button inside a `CalendarCell`. Selects its `day` on click/Enter/Space, drives roving focus and full arrow-key / Home-End / PageUp-Down keyboard navigation (paging the month when focus crosses the visible range), and exposes day state through its slot.
| Prop | Type | Description |
|---|---|---|
day | Date | The day this trigger represents. |
month? | Date | The month this trigger's cell belongs to. Defaults to grid context. |