Skip to content
v2.5.0
English
Русский
Documentation

MonthPicker

MonthPicker is the grid-based month-selection subsystem used directly or as part of the calendar family.

Patterns

Standard Month Grid

When to use:

  • users pick a month, such as a billing period, a report month, or a card expiry month

Composition notes:

  • let MonthPickerLayout generate the grid; it renders 12 or 13 months, depending on the calendar system
  • pass locale to the root once; the layout reads it for the month names
  • remember that cells are keyed by the first day of each month

Trade-offs:

  • simple and reliable
  • one year at a time; the app adds year navigation (see Controlled/Stateful)
months-of-one-year.tsx · 11 lines
import { MonthPicker, MonthPickerCell, MonthPickerLayout } from '@vega-ui/react';

export default function MonthsOfOneYear() {
  return (
    <MonthPicker aria-label='Start month, 2026' locale='en-US' year='2026-01-01' defaultSelected='2026-03-01' style={{ width: '100%' }}>
      <MonthPickerLayout>
        <MonthPickerCell />
      </MonthPickerLayout>
    </MonthPicker>
  );
}

Dense Embedded Month Selector

When to use:

  • the month selector is part of a toolbar, a filter popover, or a side panel

Composition notes:

  • use four columns and format='short' so the year fits in three rows
  • keep the root size small, and put the year control next to the grid
  • the example keeps the full month and year in the trigger and in its accessible name

Trade-offs:

  • compact
  • short names are ambiguous in some locales; keep the full name in the trigger or summary
month-filter-in-a-popover.tsx · 49 lines
import {
  Button,
  Icon,
  MonthPicker,
  MonthPickerCell,
  MonthPickerLayout,
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@vega-ui/react';
import { ChevronDown } from '@vega-ui/icons';
import { useState } from 'react';

Custom Grid Rendering

When to use:

  • the row structure itself must change, which a cell template cannot do

Composition notes:

  • build rows with createMonthPickerGrid instead of ordering months by hand; pass the same calendar as the picker
  • format labels with formatCalendarDate in that calendar (or Intl.DateTimeFormat for Gregorian keys), never from the ISO key
  • when the label is shortened, as with narrow names here, give the full name in aria-label

Trade-offs:

  • full control over markup
  • labels and locale are the app's job; prefer a cell template when only the content changes
custom-grid-rendering.tsx · 30 lines
import {
  MonthPicker,
  MonthPickerItem,
  MonthPickerRow,
  MonthPickerRowGroup,
  createMonthPickerGrid,
} from '@vega-ui/react';

const YEAR = '2026-01-01';
const narrowFormat = new Intl.DateTimeFormat('en-US', { month: 'narrow', timeZone: 'UTC' });
const longFormat = new Intl.DateTimeFormat('en-US', { month: 'long', timeZone: 'UTC' });
const rows = createMonthPickerGrid({ year: YEAR, cols: 6 });

Cell Template

When to use:

  • month cells need extra content such as a total, a status, or a hint

Composition notes:

  • children of MonthPickerLayout are rendered once per month inside a cell context
  • read the month with useMonthPickerCellContext(): { col, date, fields, label }; date is the first day of the month
  • render the content inside MonthPickerCell so the cell keeps selection, focus, and disabled states
  • take month numbers from label or fields, never from the ISO date string; they differ in non-Gregorian calendars
  • look data up by date, which is the same in every calendar system

Trade-offs:

  • keeps the grid, keys, and keyboard behavior of the layout
  • richer cells can crowd small sizes
en-US
ru-RU
ar-EG
he-IL
cell-template.tsx · 48 lines
import {
  MonthPicker,
  MonthPickerCell,
  MonthPickerLayout,
  useMonthPickerCellContext,
} from '@vega-ui/react';

const spending: Record<string, number> = {
  '2026-01-01': 1240,
  '2026-02-01': 980,
  '2026-03-01': 1415,
  '2026-04-01': 1102,

Comparison

Quick Decision Rule

Use MonthPicker when users should choose a month from a grid. Use DayPicker for specific dates and YearPicker for year selection.

MonthPicker vs DayPicker

  • Use MonthPicker for month-level choices.
  • Use DayPicker for day-level selection.

MonthPicker vs YearPicker

  • Use MonthPicker for the month within a year context.
  • Use YearPicker when the year itself is the target.

Choose This Component When

  • the value is a month
  • a dense month grid is the right interaction

Do Not Choose This Component When

  • users need a specific date or year instead of a month

Troubleshooting

The Month Labels Feel Inconsistent With The Rest Of The Date UI

Symptom

Month names in the picker do not match other date surfaces.

Likely Cause

Labels were hardcoded or formatted with a different locale strategy.

How To Verify

  • compare the picker labels with the rest of the app’s date formatting

Fix

Use locale-driven formatting consistently and prefer the supplied layout/helper functions.

Custom Grid Rendering Breaks Selection Clarity

Symptom

Months can still be selected, but users cannot tell which month is active or selected.

Likely Cause

Custom rendering discarded key selection-state affordances.

How To Verify

  • test selected, active, and disabled month states in the custom layout

Fix

Preserve the state cues from the standard month item pattern.

The Picker Feels Like A Generic Grid Instead Of A Calendar Primitive

Symptom

The UI technically works, but it no longer reads as a coherent month selector.

Likely Cause

The layout was customized beyond the point where month semantics stay obvious.

How To Verify

  • review the component without developer context

Fix

Keep month labels and ordering explicit, and lean on the provided layout/helper APIs where possible.