A month or a year picked in a field, for monthly and yearly reports, billing periods and card expiry.
$ pnpm dlx shadcn@latest add @dashral/month-pickerInstallation
$ pnpm dlx shadcn@latest add @dashral/month-pickerAdds the component, the components it builds on, its npm packages and the theme tokens it uses. Or by its full URL: https://dashral.com/r/month-picker.json
When to use
- A month or a year rather than a day: a monthly or yearly report, a billing period, a card's expiry, a fiscal year (view="year").
When not to use
- A day: Date Picker.
- A start and an end: Date Range Picker.
- Fixed periods such as 7D, 30D or 12M: Segmented Control.
Usage
The month in state, as its 1st; min and max limit what can be picked.
"use client"
import { useState } from "react"
import { MonthPicker } from "@/components/dashral/month-picker"
export default function ReportMonth() {
const [month, setMonth] = useState<Date | undefined>()
return <MonthPicker label="Report month" value={month} onValueChange={setMonth} max={new Date()} />
}Using the npm package? Import from @dashral/ui/components/month-picker instead, here and in the examples; the rest is the same.
Examples
API reference
MonthPicker
| Prop | Type | Default |
|---|---|---|
view | "month" | "year"What it picks: a month of a year, or a year. | "month" |
value / defaultValue | DateThe 1st of the month picked (January 1st for a year), controlled or initial. | — |
onValueChange | (value: Date | undefined) => voidCalled with the new value. | — |
placeholder | stringShown before anything is picked. | "Pick a month" / "Pick a year" |
min / max | DateThe earliest and latest month (or year) that can be picked; the rest are greyed out. | — |
locale / formatOptions | string / Intl.DateTimeFormatOptionsThe month names and how the button writes the value. | LocaleProvider's / the month and year |
disabled | booleanThe whole picker can't be used. | false |
label | ReactNodeShown above, linked to the control. | — |
description | ReactNodeA hint under the control. | — |
error | boolean | ReactNodetrue shows the error style; a message also shows under the control. | — |
labelAction | ReactNodeAt the end of the label's row, e.g. a “Forgot password?” link or the current value. | — |
withAsterisk | booleanMarks the label with an asterisk, e.g. alongside required. | false |
classNames | { root, label, description, error, trigger, content }Classes for each part. | — |
Keyboard
| Keys | Action |
|---|---|
| EnterorSpace | Open the panel |
| Arrow keys | Move through the months or years (left and right swap in right-to-left) |
| HomeorEnd | The first or last month (or year) |
| Enter | Pick and close |
| Escape | Close |
Accessibility
- The picked month (or this month when nothing is picked) takes the focus when the panel opens, and the focus goes back to the button when it closes.
- Each month is read in full ("March 2026"); the picked one is pressed and this month is marked as the current date.
Motion
- Opens with a fade, a scale from 95%, a 2px blur clearing and a 4px slide from its trigger's side, on the spring (--duration-standard); closes faster (--duration-fast, --ease-exit). No blur with reduced motion.