Month Picker
Accessible, unstyled grid of the twelve months of a year with year paging.
| Package | @vizejs/ui/month-picker |
| Maturity | stable |
| Own the source | vize lib pull month-picker |
| Requires | calendar, controllable-state, id, locale |
| Aliases | month grid, month input, billing month, year view |
| Covers | HTML input type=month, WAI-ARIA grid, MUI MonthCalendar |
Usage
import { MonthPicker } from "@vizejs/ui/month-picker";
Or copy the source into your project with vize lib pull month-picker (see Source Distribution).
API
MonthPicker
Source: src/families/date-time/month-picker/month-picker.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string | null | undefined |
undefined |
Consumer-owned base id; nullish values use a deterministic fallback. |
modelValue |
PlainYearMonth | null | undefined |
undefined |
Controlled month; undefined selects uncontrolled mode and null clears. |
defaultValue |
PlainYearMonth | null | undefined |
null |
Initial uncontrolled month. |
min |
PlainYearMonth | null | undefined |
undefined |
Earliest selectable month. |
max |
PlainYearMonth | null | undefined |
undefined |
Latest selectable month. |
isMonthUnavailable |
((value: PlainYearMonth) => boolean) | undefined |
undefined |
Predicate for months that stay focusable but cannot be selected. |
locale |
string | undefined |
undefined |
BCP 47 locale; defaults to the nearest LocaleProvider. |
dir |
"ltr" | "rtl" | undefined |
undefined |
Text direction; defaults to the nearest LocaleProvider. |
calendar |
string | undefined |
undefined |
Intl calendar used for display labels only. |
numberingSystem |
string | undefined |
undefined |
Intl numbering system for labels. |
monthFormat |
MonthPickerFormat | undefined |
"short" |
Month label width. |
columns |
number | undefined |
3 |
Months per grid row. |
today |
PlainDate | null | undefined |
undefined |
Explicit current date; the SSR-safe way to mark the current month. |
now |
DateTimeNow | undefined |
undefined |
Injectable clock evaluated during setup on server and client. |
timeZone |
string | undefined |
undefined |
IANA time zone used with now and the post-mount host clock. |
disabled |
boolean | undefined |
false |
Disable navigation, focus, and selection. |
readOnly |
boolean | undefined |
false |
Allow navigation while blocking selection. |
name |
string | undefined |
undefined |
Hidden input name that submits YYYY-MM. |
previousLabel |
string | undefined |
"Previous year" |
Accessible name of the previous-year control. |
nextLabel |
string | undefined |
"Next year" |
Accessible name of the next-year control. |
ariaLabel |
string | undefined |
undefined |
Accessible name for the picker group. |
ariaLabelledby |
string | undefined |
undefined |
Ids that label the picker group; defaults to the year heading. |
ariaDescribedby |
string | undefined |
undefined |
Ids that describe the picker group. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue |
[value: PlainYearMonth | null] |
Fired when the picker requests a new controlled month. |
change |
[ value: PlainYearMonth | null, previous: PlainYearMonth | null, nativeEvent: Event | null, ] |
Fired after a distinct selection with the previous month and triggering event. |
update:focusedMonth |
[value: PlainYearMonth] |
Fired when keyboard or navigation moves the focused month. |
Slots
| Slot | Slot props | Description |
|---|---|---|
heading |
MonthPickerSlotState |
Year heading content. Receives picker state. |
previous |
MonthPickerSlotState |
Previous-year control content. |
next |
MonthPickerSlotState |
Next-year control content. |
cell |
MonthPickerCellState |
Month cell content. Receives the cell state; defaults to the localized month. |
Behavior
Normative state x input -> outcome table for month-picker.vue
(@vizejs/ui/month-picker), a grid of the twelve months of one year built on
the shared linear period grid (period-grid-runtime.ts). Every row is proven
by the named test.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| MP1 | known year | render | a role="group" labelled by the live year heading holds a <table role="grid"> of columns-wide rows; one roving tabindex=0 month; the current month has aria-current="date"; name submits YYYY-MM |
renders a labelled month grid with roving focus and the current month |
| MP2 | focused | Arrow / Home / End / PageUp / PageDown | ±1 month, ±1 row, row edges, ±1 year, Shift ±10 years; Enter/Space selects and emits update:modelValue and change |
keyboard moves by month, row, row edge, year, and decade; activation selects |
| MP3 | RTL / bounds | arrows / activation / previous–next | RTL flips horizontal arrows; focus clamps to min/max; out-of-range months are disabled; unavailable months stay focusable and unselectable; year controls disable at bounds |
RTL, min/max bounds, unavailability, and year paging controls |
| MP4 | no value, no clock | mount / expose | pending until mount, then the host clock picks the year; setValue, navigate, and focus are exposed |
pending until mount without a clock, exposed API, and unit helpers |
| MP5 | SSR/hydration | isolated requests | byte-identical markup and silent hydration with an explicit today |
renders byte-identical month picker markup across isolated SSR requests, hydrates month picker markup without mismatches |
SSR determinism follows calendar.behavior.md: pass today or now +
timeZone, or a value, to render a complete grid on the server.
Parts: root, header, previous, heading, next, grid, row, cell, month.