Vize

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.