On this page
Import
import { MonthPicker } from '@envsemble/envui';
Usage
A MonthPicker takes its label, a description and an error, and its value is a month as YYYY-MM.
- Uncontrolled:
defaultValue, which a form reset restores. - Controlled:
valueandonValueChange, which receives the month, ornullonce the field is cleared. clearableadds a clear button to the field and the popup.
import { useState } from 'react';
import { MonthPicker } from '@envsemble/envui';
export default function ReportMonth() {
const [month, setMonth] = useState<string | null>('2026-10');
return (
<div style={{ inlineSize: 'min(100%, 16rem)' }}>
<MonthPicker
label="Report month"
description="The month the report covers."
value={month}
onValueChange={setMonth}
clearable
/>
</div>
);
}Range and format
min and max, as YYYY-MM, make earlier and later months unavailable, as the FiscalYear example shows. formatOptions takes Intl.DateTimeFormat options for the shown value, by default the long month and the year, as the ShortFormat example shows; locale is EnvUIProvider's, else the browser's, and months are Gregorian, also in a locale with a calendar of its own.
<MonthPicker label="Budget month" min="2026-04" max="2027-03" />
<MonthPicker label="Expires" formatOptions={{ month: '2-digit', year: '2-digit' }} />
In a form
name submits the month as YYYY-MM, and required keeps an empty field's form from submitting. Use readOnly, not disabled, for a month people can't change.
<form onSubmit={submit}>
<MonthPicker label="Period" name="period" placeholder="Choose a month" required />
<Button type="submit">Submit expenses</Button>
</form>
Sizes and the popup
size is sm, md or lg; without it the field takes its container's control height. visibleLabel={false} hides the label for a field whose purpose is clear, and placeholder shows while it is empty. open, defaultOpen and onOpenChange control the popup; onOpenChange also receives why it opens or closes, PickerOpenChangeDetails. clearLabel, thisMonthLabel, previousYearLabel and nextYearLabel name its buttons.
Composition
The field, env-month-picker, shares DatePicker's parts: the control, env-date-picker-control, with the label, env-date-picker-label, the value, env-date-picker-value, the clear button, env-date-picker-clear, and the calendar icon, env-date-picker-icon; then the description, env-field-description, and the error, env-field-error. The popup is DatePicker's picker card, env-picker-popup with env-date-picker-popup and env-month-picker-popup. Its body, env-picker-popup-body, has a header, env-month-picker-header, with the previous year, env-month-picker-previous, the year, env-month-picker-title, and the next year, env-month-picker-next; the year's grid, env-month-picker-year and env-month-picker-grid, of months, env-month-picker-month, each with data-month and a mark, env-month-picker-month-mark; and its footer, env-picker-popup-footer with env-date-picker-actions, the actions. ref reaches the field's button, and className and style its root.
Customize
Its popup is frosted, as every popup is: --env-popup-opacity, --env-popup-blur and --env-popup-shadow, set on a theme, change it, as Popover describes.
Accessibility
You provide
- A
label, oraria-labelon a field without one. - Validation and its
error. - The labels in the application's language.
envUI provides
- The field as a
comboboxbutton named by its label, with its description and error. - The year as a grid of months, each named by month and year, with one tab stop.
Props
MonthPicker
A field for a month of a year that shows the value in the reader's locale and opens a year of months to choose it from, with keyboard access like Calendar's.
| Prop | Type | Description |
|---|---|---|
value | stringnull | The value: a month as YYYY-MM. null, or an empty string, for none. |
defaultValueDefault null | stringnull | The value an uncontrolled field starts with, and that a form reset restores; none by default. |
onValueChange | ( | Receives the new value as YYYY-MM, or null once the field is cleared. |
min | string | The earliest month, as YYYY-MM; earlier months are unavailable. |
max | string | The latest month, as YYYY-MM; later months are unavailable. |
locale | string | The locale of the shown value and the month names: EnvUIProvider's, else the browser's. Months are Gregorian, also in a locale with a calendar of its own. |
formatOptions | Intl. | How the field shows the value: Intl.DateTimeFormat options, by default the long month and the year, in the Gregorian calendar unless they name another. |
clearLabelDefault 'Clear', or EnvUIProvider's messages.monthPicker.clear | string | Accessible name of the field's clear button and text of the popup's. |
thisMonthLabelDefault 'This month', or EnvUIProvider's messages.monthPicker.thisMonth | string | The popup's shortcut to the current month. |
previousYearLabelDefault 'Previous year', or EnvUIProvider's messages.monthPicker.previousYear | string | Accessible name of the popup's previous year button. |
nextYearLabelDefault 'Next year', or EnvUIProvider's messages.monthPicker.nextYear | string | Accessible name of the popup's next year button. |
ref | Ref< | The field's button, which shows the value and opens the popup. |
className | string | The field's class, on its root element. |
style | CSSProperties | Styles of the field's root element. |
name | string | The name the value is submitted under with a form. |
requiredDefault false | boolean | A value is needed: an empty field keeps its form from submitting and takes focus. |
readOnlyDefault false | boolean | The value can be read and focused but not changed. |
placeholder | string | Shown while the field is empty and its label floats or is hidden. |
clearableDefault false | boolean | A clear button in the field and in the popup removes the value. |
open | boolean | Whether the popup is open; with `onOpenChange` it controls it. |
defaultOpenDefault false | boolean | Whether an uncontrolled popup starts open; closed by default. |
onOpenChange | ( | Called with the new state, and why, when the popup opens or closes. |
label | ReactNode | The field's visible name, such as Project name; it also names the control for assistive technology. |
description | ReactNode | Lasting guidance under the field, such as a format or a limit, linked to the control as its description. |
error | ReactNode | A message under the field that says how to correct the value. While it is set, the control is invalid (aria-invalid) and the message joins its description, after the description. |
size | 'sm''md''lg' | The control height, sm, md or lg; without it, the container's, and else md. sm is for a field with its label hidden. |
visibleLabelDefault true | boolean | The label shows in the field, where it rests while the field is empty and floats into the outline while the field is in use or has a value. false hides it, for a field whose purpose is clear without it, such as a search in a toolbar: the label still names the field for assistive technology, and a placeholder gives the visible guidance. |
Also accepts the native props of <button>, such as ref, className and aria-* attributes.
Part names
Each part's class and state attributes are public and versioned, for an application's CSS to style.
env-month-picker- The month field.
env-month-picker-grid- The grid of months.
env-month-picker-header- The row with the year and the previous and next buttons.
env-month-picker-month- One month.
env-month-picker-month-mark- The mark under a month, such as the current one.
env-month-picker-next- The button for the next year.
env-month-picker-popup- The popup with the months.
env-month-picker-previous- The button for the previous year.
env-month-picker-title- The year.
env-month-picker-year- The year's grid of months.
data-month- Any value, or present on env-month-picker-month
Strings
EnvUIProvider's messages overrides each, and a component's own label prop wins over it.
messages.monthPicker.clear"Clear"The clear button's name.messages.monthPicker.thisMonth"This month"Picks the current month.messages.monthPicker.previousYear"Previous year"The previous-year button's name.messages.monthPicker.nextYear"Next year"The next-year button's name.
Changelog
- 1.0.0
showLabelisvisibleLabel, named after the label thatvisibleLabel={false}hides.MonthPicker, for a month of a year, with
minandmax.- 1.0.0-prerelease.6
Colors under the pointer and while pressed change with
--env-motion-ease-enter, rather than easing in slowly, so hover and press show from the first frame.The popup opens over
--env-motion-duration-medium, fading in and growing from 98 % with--env-motion-ease-enter, rather than growing from 96 % over the slow duration, so it shows from its first frames rather than late.The year buttons show larger arrows, 1.25 rem, on slightly smaller buttons, and the header keeps a little room under it, as the calendar's.
The grid's month names keep one length where the locale makes nearly all of them that long, such as Sep rather than Sept among en-GB's three-letter months; names with punctuation, and locales whose names vary, keep the locale's own.
Months outside
minandmaxtake the disabled text color, faded, as a calendar's unavailable days do; this month keeps its accent color.The
floatingvariant and thevariantprop are gone: the field is outlined, and takessize="lg"in a long form on a page. The field takes a text area's rounded corners rather than round ends. A small one with a visible label takes the medium height, so its floated label and its value each have room, and says so in the console while developing:smis for a field with its label hidden.- 1.0.0-prerelease.5
The popup is frosted: the popup's color lets a little of what is behind through, blurred, with a soft shadow and no outline edge but a faint hairline in dark, and is solid with its edge at high contrast and with reduced transparency. Its inset is a panel's, as wide as a popup row's corner: 14 px, 11.2 px at the compact scale. The year leads its header, its buttons side by side at the end; this month is in the accent color rather than ringed, and a month under the pointer takes the neutral fill.