Skip to content

Month Picker ​

Allows users to select a month and year, either by typing it directly or by choosing from a popup of a year header and a twelve-month grid.

Usage ​

Use the Month Picker when a field represents a whole month (a reporting period, a billing month, a statement month) rather than a specific day. For a specific day use the Date Picker instead.

Keyboard Handling ​

The user can use the following keyboard shortcuts in order to navigate through the month picker:

  • Enter / Space - Opens the popup, or selects the focused month when open. Pressing it on the already selected month deselects it and clears the value.
  • Left / Right - Moves focus to the previous/next month, crossing into the previous/next year from January/December.
  • Up / Down - Moves focus one row (three months) up/down.
  • Home / End - Moves focus to January/December of the shown year.
  • PageUp / PageDown - Moves focus to the same month of the previous/next year.
  • Tab / Shift+Tab - Moves between the year buttons and the months. Focus stays inside the open popup.
  • Esc - Closes the popup and returns focus to the control that opened it.

API Reference ​

Component attribute(s) ​

x-h-month-picker
x-h-month-picker-trigger
x-h-month-picker-popup

Attributes ​

x-h-month-picker ​

AttributeValuesRequiredDescription
data-sizesm
default
falseChanges the size of the month picker.

x-h-month-picker-popup ​

AttributeValuesRequiredDescription
data-alignbottom-start
bottom
bottom-end
right-start
right
right-end
left-start
left
left-end
top-start
top
top-end
falseAligns the popup relative to the picker trigger.
data-aria-prev-yearstringfalseSets the aria-label attribute value for the previous year button.
data-aria-next-yearstringfalseSets the aria-label attribute value for the next year button.

Modifiers ​

ModifierDescription
tableUse when the input is inside a table

Configuration ​

You can pass a configuration object to the popup as an expression or as a value.

KeyDescription
localeThe locale of the month names as a BCP 47 language tag. If not provided, it is taken from the page's <html lang> attribute, then the browser locale.

Some locales, such as bg-BG, conventionally abbreviate months numerically, so the popup grid shows numbers there. The text input is unaffected because it uses the full month name.

Model ​

The month picker reads and writes months as YYYY-MM strings (e.g. "2025-06"). The text input displays the month using the user's locale (e.g. "June 2025"). The model value is unaffected by the display format.

To clear the value, delete the text in the input, click the already selected month in the popup, or set the bound model to an empty string.

Events ​

EventDescription
changeFired on the inner input when the user picks a month from the popup or types a valid month. The event bubbles, so a listener can be placed on the x-h-month-picker element. Read the new value from the bound model, as the input's own value holds the formatted display text instead.

There is no need to use $watch to react to user selection - listen for change instead. See Listening for changes.

Validation timing ​

By default this control shows native-constraint errors (for example required) only after the user interacts with it or attempts to submit, not on page load. To validate on load instead, set data-validate="immediate" on a wrapping x-h-fieldset, x-h-field, or any ancestor element. Setting aria-invalid="true" yourself always shows the error immediately. See Fieldset for details.

Data Slots ​

SlotElement
month-pickerx-h-month-picker
cell-input-monthx-h-month-picker.table
month-picker-triggerx-h-month-picker-trigger
month-picker-calendarx-h-month-picker-popup

Examples ​

html
<div
  x-h-month-picker
  x-data="{
  month: '',
  init() {
    const d = new Date();
    this.month = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}`;
  }
}"
>
  <input type="text" id="month-input-1" />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup x-model="month"></div>
</div>

Listening for changes ​

html
<div x-h-month-picker x-data="{ month: '' }" @change="console.log('Selected month:', month)">
  <input type="text" id="month-input-change" />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup x-model="month"></div>
</div>

With locale ​

html
<div x-h-month-picker x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-locale" />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup="{ locale: 'bg-BG' }" x-model="month"></div>
</div>

With a year-first locale ​

In a locale that writes the year before the month, such as Japanese, Chinese or Hungarian, the input shows the year first.

html
<div x-h-month-picker x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-year-first" />
  <button x-h-month-picker-trigger aria-label="月を選択"></button>
  <div x-h-month-picker-popup="{ locale: 'ja-JP' }" x-model="month"></div>
</div>

With translated labels ​

Translate the trigger's aria-label and the popup's data-aria-* labels along with the locale, so screen readers announce every button in the page's language.

html
<div x-h-month-picker x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-labels" />
  <button x-h-month-picker-trigger aria-label="Изберете месец"></button>
  <div x-h-month-picker-popup="{ locale: 'bg-BG' }" x-model="month" data-aria-prev-year="предишна година" data-aria-next-year="следваща година"></div>
</div>

Small size ​

html
<div x-h-month-picker data-size="sm" x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-sm" />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup x-model="month"></div>
</div>

Invalid ​

Reacts to the native invalid state or to the aria-invalid attribute.

html
<div x-h-month-picker x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-invalid" aria-invalid="true" />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup x-model="month"></div>
</div>

Disabled ​

Set the native disabled attribute on the inner input to disable the whole picker.

html
<div x-h-month-picker x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-disabled" disabled />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup x-model="month"></div>
</div>

Read-only ​

Set the native readonly attribute on the inner input. The value is shown with a muted background, and neither typing nor the popup can change it.

html
<div x-h-month-picker x-data="{ month: '2026-07' }">
  <input type="text" id="month-input-readonly" readonly />
  <button x-h-month-picker-trigger aria-label="Choose month"></button>
  <div x-h-month-picker-popup x-model="month"></div>
</div>