Calendar
A calendar is the month grid on its own. Most of the time you want it inside a DatePicker, which pairs it with a field that can be typed into; use it directly where the calendar is the page — a booking screen, a schedule.
import {
Calendar,
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeading,
CalendarNavButton,
} from "ropav";The parts split the grid from its chrome: CalendarHeader holds the heading and the two CalendarNavButtons (which take slot="previous" and slot="next"), and CalendarGrid holds the weekday row and the days. CalendarGridBody hands each date to its slot, so a cell can be rendered however the app needs.
October 2026
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
27 | 28 | 29 | 30 | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
calendar-basic.vue
<script setup lang="ts">
import {
Calendar,
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNavButton,
} from "ropav";
</script>
<template>
<Calendar aria-label="Event date">
<CalendarHeader>
<CalendarNavButton slot="previous" />
<CalendarHeading />
<CalendarNavButton slot="next" />
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
<template #default="{ day }">
<CalendarHeaderCell>{{ day }}</CalendarHeaderCell>
</template>
</CalendarGridHeader>
<CalendarGridBody>
<template #default="{ date }">
<CalendarCell :date />
</template>
</CalendarGridBody>
</CalendarGrid>
</Calendar>
</template>What can be chosen
min-value and max-value bound the range. is-date-unavailable rules out individual dates inside it — weekends, days already booked — which is a different thing from disabling the calendar: the grid still works, those days just cannot be taken.
selection-mode takes one date or several. For a start and an end that belong together, use a RangeCalendar rather than multiple selection.
How much is on screen
visible-duration decides how many months show at once and is also what paging moves by, so a two-month calendar steps two months. page-behavior chooses between moving a whole page and moving one unit. weeks-in-month fixes the number of rows, which stops the grid changing height as the reader pages through months of different shapes.
first-day-of-week overrides the locale, and create-calendar swaps the calendar system — injectable so a build can ship fewer of them than the full set.
Accessibility
- The grid is a real table with a
role="grid", so the arrow keys move by day and week the way a reader expects, and each cell announces its date and its state. - Give it an
aria-label. "Event date" tells a reader what the grid is for; without one they get a grid of numbers and have to work it out. - An unavailable date is announced as such rather than simply not responding, which is the difference between "you cannot pick that" and a control that seems broken.
- The heading is what tells a reader which month they have paged into. Keep it, even when the months are obvious on screen.
API
Calendar
| Prop | Type | Default | Description |
|---|---|---|---|
ariaDescribedby | string | — | |
ariaDetails | string | — | |
ariaLabel | string | — | |
ariaLabelledby | string | — | |
autoFocus | boolean | — | Whether the calendar takes focus as soon as it mounts. |
createCalendar | ((identifier: CalendarIdentifier) => Calendar) | — | Builds the calendar system for an identifier. Injectable so a build can ship fewer of them. |
defaultFocusedValue | DateValue | null | — | |
defaultValue | CalendarValue | — | |
defaultYearPickerOpen | boolean | false | |
firstDayOfWeek | "fri" | "mon" | "sat" | "sun" | "thu" | "tue" | "wed" | — | The day a week starts on, when it should not follow the locale. |
focusedValue | DateValue | null | — | |
id | string | — | |
isDateUnavailable | ((date: DateValue) => boolean) | — | Rules a date out even though it is inside the range. |
isDisabled | boolean | — | |
isInvalid | boolean | — | |
isReadOnly | boolean | — | |
isYearPickerOpen | boolean | — | Whether the year picker is open. |
maxValue | DateValue | null | — | |
minValue | DateValue | null | — | |
pageBehavior | "single" | "visible" | "visible" | |
selectionAlignment | "center" | "end" | "start" | "center" | |
selectionMode | "single" | "multiple" | "single" | Whether the calendar takes one date or several. |
value | CalendarValue | — | |
visibleDuration | DateDuration | {months: 1} | How much is on screen at once, which is also what paging moves by. |
weeksInMonth | number | — | A fixed number of week rows, so a month grid does not change height while paging. |
The default slot receives:
| Slot prop | Type |
|---|---|
isDisabled | boolean |
isInvalid | boolean |
state | AnyCalendarState |
| Event | Payload |
|---|---|
update:focusedValue | CalendarDate |
update:value | CalendarValue |
update:yearPickerOpen | boolean |
CalendarCell
| Prop | Type | Default | Description |
|---|---|---|---|
date* | CalendarDate | — | The date this cell stands for. |
The default slot receives:
| Slot prop | Type |
|---|---|
date | CalendarDate |
formattedDate | string |
isDisabled | boolean |
isFocused | boolean |
isFocusVisible | boolean |
isHovered | boolean |
isInvalid | boolean |
isOutsideMonth | boolean |
isOutsideVisibleRange | boolean |
isPressed | boolean |
isSelected | boolean |
isToday | boolean |
isUnavailable | boolean |
CalendarCellIndicator
Slots: default.
CalendarGrid
| Prop | Type | Default | Description |
|---|---|---|---|
offset | DateDuration | — | How far past the first visible date this grid starts, for a multi-month calendar. |
weekdayStyle | "long" | "narrow" | "short" | "short" | How wide the weekday names above the grid are written. |
Slots: default.
CalendarGridBody
The default slot receives:
| Slot prop | Type |
|---|---|
date | CalendarDate |
CalendarGridHeader
The default slot receives:
| Slot prop | Type |
|---|---|
day | string |
CalendarHeader
Slots: default.
CalendarHeaderCell
Slots: default.
CalendarHeading
| Prop | Type | Default | Description |
|---|---|---|---|
format | CalendarHeadingFormatOptions | — | Overrides the parts the heading is written from. |
offset | DateDuration | — | How far past the first visible date this heading describes. |
CalendarNavButton
| Prop | Type | Default | Description |
|---|---|---|---|
slot | "next" | "previous" | "next" | Which direction this button pages. |
Slots: default.