Calendar

12 parts

A 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

Loading demo…

Anatomy

Import the parts and compose them. Each part forwards attributes to its underlying element.

vue
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

Root

A 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.

PropTypeDescription
defaultValue?Date | Date[]Uncontrolled default selected date (or dates when multiple).
defaultPlaceholder?DateUncontrolled default placeholder (displayed month).
minValue?DateMinimum selectable date.
maxValue?DateMaximum selectable date.
isDateUnavailable?(date: Date) => booleanPredicate marking a date as unavailable (not selectable).
isDateDisabled?(date: Date) => booleanPredicate marking a date as disabled.
pagedNavigation?booleanPrev/Next navigate by numberOfMonths instead of one month.
weekStartsOn?0 | 1 | 2 | 3 | 4 | 5 | 6First day of week (0=Sun ... 6=Sat).
weekdayFormat?WeekDayFormatWidth of localized weekday names.
fixedWeeks?booleanAlways render 6 weeks per month.
numberOfMonths?numberNumber of months displayed simultaneously.
disabled?booleanDisable the whole calendar.
readonly?booleanMake the calendar read-only.
initialFocus?booleanAuto-focus the calendar on mount.
locale?stringLocale for Intl formatting.
dir?'ltr' | 'rtl'Reading direction.
nextPage?(placeholder: Date) => DateOverride "next page" navigation logic.
prevPage?(placeholder: Date) => DateOverride "prev page" navigation logic.
calendarLabel?stringCalendar accessible label prefix.
multiple?booleanAllow selecting multiple dates; model becomes a Date[].
preventDeselect?booleanPrevent deselecting the last selected date by re-clicking it.
disableDaysOutsideCurrentView?booleanDisable 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[] | undefinedTwo-way bound value (v-model).
placeholder?DateTwo-way bound value (v-model:placeholder).
Emits
EventPayload
update:modelValue[value: Date | Date[] | undefined]
update:placeholder[value: Date]

CalendarHeader

Header

Layout 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

Heading

Displays 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

Prev

Button 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.

PropTypeDescription
prevPage?(placeholder: Date) => DateOverride the root's prevPage for just this button.

CalendarNext

Next

Button 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.

PropTypeDescription
nextPage?(placeholder: Date) => DateOverride the root's nextPage for just this button.

CalendarGrid

Grid

The `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`.

PropTypeDescription
month?DateThe month this grid represents. Defaults to the root placeholder's month.

CalendarGridHead

GridHead

The 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

GridBody

The grid's `<tbody>` wrapper containing the week rows (`CalendarGridRow`) of day cells.

No props or events — renders its element and forwards attributes.

CalendarGridRow

GridRow

A 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

HeadCell

A `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.

PropTypeDescription
day?DateThe day this header cell represents — used for aria-label.

CalendarCell

Cell

A 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`.

PropTypeDescription
dateDateThe date this cell represents.

CalendarCellTrigger

CellTrigger

The 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.

PropTypeDescription
dayDateThe day this trigger represents.
month?DateThe month this trigger's cell belongs to. Defaults to grid context.