Marble UI
← Components

Month / Year Picker

Preview: Month

Month picker: year header with prev/next and a 4×3 month grid (arrow-key navigable ListBox grid).

Import

import { MonthPicker, YearPicker } from '@marbleui/ui'

Props

<MonthPicker>

PropTypeDefaultDescription
onChange *required(v: { year: number; month: number; }) => void—
classNamestring—
maxYearnumber—
minYearnumber—
value{ year: number; month: number; }—

<YearPicker>

Year picker: pages of 12 years (a 4×3 grid aligned to multiples of 12), with prev/next to change page.

PropTypeDefaultDescription
onChange *required(y: number) => void—
classNamestring—
valuenumber—

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria ListBox · React Aria ListBoxItem. Follow the primitive's docs for the full keyboard map.

Usage notes

MonthPicker chooses a month from a grid under a year header; YearPicker chooses a year from a page of 12. Use them for billing periods, expiry dates or report months where the day doesn’t matter; for a full date use DatePicker.

const [period, setPeriod] = useState({ year: 2026, month: 10 })
<MonthPicker value={period} onChange={setPeriod} minYear={2020} maxYear={2026} />
<YearPicker value={fiscalYear} onChange={setFiscalYear} />
  • Both are controlled: the selection shows only what you pass in value, so update it in onChange (required). month is 1–12, not 0–11 as in JS Date.
  • minYear and maxYear only disable the year arrows; single months can’t be disabled, and YearPicker has no limits.
  • The grid is a React Aria ListBox: arrow keys move in both directions and Enter or Space selects. Month names follow the locale, and the year heading is a live region, so paging is announced. The arrows mirror in right-to-left layouts.
  • The shown year follows value: changing it to another year from outside moves the header (and YearPicker’s page).
Example source · show
import { useState } from 'react'
import { MonthPicker, YearPicker } from './month-year-picker'

function Month() { const [v, setV] = useState({ year: 2026, month: 10 }); return <div className="flex flex-col gap-2"><MonthPicker value={v} onChange={setV} /><span className="text-xs text-fg-muted">Billing period: {v.year}-{String(v.month).padStart(2, '0')}</span></div> }
function Year() { const [v, setV] = useState(2026); return <YearPicker value={v} onChange={setV} /> }
export const styles = { Month, Year }

Source: packages/ui/src/month-year-picker/month-year-picker.tsx

Catalog

Category
date-time
Priority
Extra
Primitive
composed
React Aria
Calendar