MonthPicker

Inline month, multiple months and months range picker
Import

Usage

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date | null>(null);
return (
<Group position="center">
<MonthPicker value={value} onChange={setValue} />
</Group>
);
}

Allow deselect

Set allowDeselect to allow user to deselect current selected date by clicking on it. allowDeselect is disregarded when type prop is range or multiple. When date is deselected onChange is called with null.

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date | null>(null);
return (
<Group position="center">
<MonthPicker allowDeselect value={value} onChange={setValue} />
</Group>
);
}

Multiple dates

Set type="multiple" to allow user to pick multiple dates:

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date[]>([]);
return (
<Group position="center">
<MonthPicker type="multiple" value={value} onChange={setValue} />
</Group>
);
}

Dates range

Set type="range" to allow user to pick dates range:

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
return (
<Group position="center">
<MonthPicker type="range" value={value} onChange={setValue} />
</Group>
);
}

Single date in range

By default, it is not allowed to select single date as range – when user clicks the same date second time it is deselected. To change this behavior set allowSingleDateInRange prop. allowSingleDateInRange is ignored when type prop is not range.

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
return (
<Group position="center">
<MonthPicker type="range" allowSingleDateInRange value={value} onChange={setValue} />
</Group>
);
}

Default date

Use defaultDate prop to set date value that will be used to determine which year should be displayed initially. For example to display 2015 year set defaultDate={new Date(2015, 1)}. If value is not specified, then defaultDate will use new Date(). Month, day, minutes and seconds are ignored in provided date object, only year is used – you can specify any date value.

Note that if you set date prop, then defaultDate value will be ignored.

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date | null>(null);
return (
<Group position="center">
<MonthPicker defaultDate={new Date(2015, 1)} value={value} onChange={setValue} />
</Group>
);
}

Controlled date

Set date, and onDateChange props to make currently displayed year and decade controlled. By doing so, you can customize date picking experience, for example, when user selects first date in range, you can add one year to current date value:

import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
const [date, setDate] = useState(new Date());
const handleChange = (val: [Date | null, Date | null]) => {
if (val[0] !== null && val[1] === null) {
setDate((current) => new Date(current.getFullYear() + 1, 1));
}
setValue(val);
};
return (
<Group position="center">
<MonthPicker
date={date}
onDateChange={setDate}
type="range"
value={value}
onChange={handleChange}
/>
</Group>
);
}

Min and max date

Set minDate and maxDate props to define min and max dates. If previous/next page is not available then corresponding control will be disabled.

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date | null>(null);
return (
<Group position="center">
<MonthPicker
value={value}
onChange={setValue}
defaultDate={new Date(2022, 1)}
minDate={new Date(2022, 1, 1)}
maxDate={new Date(2022, 8, 1)}
/>
</Group>
);
}

Add props to year and month control

You can add props to year and month controls with getYearControlProps and getMonthControlProps functions. Both functions accept date as single argument, props returned from the function will be added to year/month control. For example, it can be used to disable specific control or add styles:

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date | null>(null);
return (
<Group position="center">
<MonthPicker
value={value}
onChange={setValue}
getYearControlProps={(date) => {
if (date.getFullYear() === new Date().getFullYear()) {
return {
sx: (theme) => ({
color: theme.fn.primaryColor(),
fontWeight: 700,
}),
};
}
if (date.getFullYear() === new Date().getFullYear() + 1) {
return { disabled: true };
}
return {};
}}
getMonthControlProps={(date) => {
if (date.getMonth() === 1) {
return {
sx: (theme) => ({
color: theme.fn.primaryColor(),
fontWeight: 700,
}),
};
}
if (date.getMonth() === 5) {
return { disabled: true };
}
return {};
}}
/>
</Group>
);
}

Number of columns

Set numberOfColumns prop to define number of pickers that will be rendered side by side:

Demo is not available on small screens. Make your screen larger to see demo.
import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
return (
<Group position="center">
<MonthPicker type="range" numberOfColumns={2} value={value} onChange={setValue} />
</Group>
);
}

Max level

To disallow user going to the decade level set maxLevel="year":

2023
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
return (
<Group position="center">
<MonthPicker maxLevel="year" />
</Group>
);
}

Size

Size
xs
sm
md
lg
xl
import { MonthPicker } from '@mantine/dates';
function Demo() {
return <MonthPicker defaultValue={new Date()} />
}

Change year and months controls format

Use yearsListFormat and monthsListFormat props to change dayjs format of year/month controls:

import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
return (
<Group position="center">
<MonthPicker monthsListFormat="MM" yearsListFormat="YY" />
</Group>
);
}

Change label format

Use decadeLabelFormat and yearLabelFormat to change dayjs format of decade/year label:

import { useState } from 'react';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
const [value, setValue] = useState<Date | null>(null);
return (
<Group position="center">
<MonthPicker
decadeLabelFormat="YY"
yearLabelFormat="YYYY [year]"
value={value}
onChange={setValue}
/>
</Group>
);
}

Localization

Usually it is better to specify @mantine/dates package locale in DatesProvider, but you can also override locale per component:

import 'dayjs/locale/ru';
import { Group } from '@mantine/core';
import { MonthPicker } from '@mantine/dates';
function Demo() {
return (
<Group position="center">
<MonthPicker locale="ru" />
</Group>
);
}

Accessibility

Aria labels

Set ariaLabels prop to specify aria-label attributes for next/previous controls:

import { MonthPicker } from '@mantine/dates';
function Demo() {
return (
<MonthPicker
ariaLabels={{
nextDecade: 'Next decade',
previousDecade: 'Previous decade',
nextYear: 'Next year',
previousYear: 'Previous year',
yearLevelControl: 'Change to decade view',
}}
/>
);
}

Year/month control aria-label

Use getYearControlProps/getMonthControlProps to customize aria-label attribute:

import { MonthPicker } from '@mantine/dates';
function Demo() {
return (
<MonthPicker
getYearControlProps={(date) => ({
'aria-label': `Select year ${date.getFullYear()}`,
})}
getMonthControlProps={(date) => ({
'aria-label': `Select month ${date.getFullYear()}/${date.getMonth()}`,
})}
/>
);
}

Keyboard interactions

Note that the following events will only trigger if focus is on month control.

KeyDescription
ArrowRightFocuses next non-disabled month
ArrowLeftFocuses previous non-disabled month
ArrowDownFocuses next non-disabled month in the same column
ArrowUpFocuses previous non-disabled month in the same column

MonthPicker component props

NameTypeDescription
allowDeselect
boolean
Determines whether user can deselect the date by clicking on selected item, applicable only when type="default"
allowSingleDateInRange
boolean
Determines whether single year can be selected as range, applicable only when type="range"
ariaLabels
CalendarAriaLabels
aria-label attributes for controls on different levels
columnsToScroll
number
Number of columns to scroll when user clicks next/prev buttons, defaults to numberOfColumns
date
Date
Date that is displayed, used for controlled component
decadeLabelFormat
string | ((startOfDecade: Date, endOfDecade: Date) => ReactNode)
dayjs label format to display decade label or a function that returns decade label based on date value, defaults to "YYYY"
defaultDate
Date
Initial date that is displayed, used for uncontrolled component
defaultLevel
"year" | "decade"
Initial level displayed to the user (decade, year, month), used for uncontrolled component
defaultValue
Date | DatesRangeValue | Date[]
Default value for uncontrolled component
getMonthControlProps
(date: Date) => Partial<PickerControlProps>
Adds props to month picker control based on date
getYearControlProps
(date: Date) => Partial<PickerControlProps>
Adds props to year picker control based on date
level
"year" | "decade"
Current level displayed to the user (decade, year, month), used for controlled component
locale
string
dayjs locale, defaults to value defined in DatesProvider
maxDate
Date
Maximum possible date
maxLevel
"year" | "decade"
Max level that user can go up to (decade, year), defaults to decade
minDate
Date
Minimum possible date
monthsListFormat
string
dayjs format for months list
numberOfColumns
number
Number of columns to render next to each other
onChange
(value: DatePickerValue<Type>) => void
Called when value changes
onDateChange
(date: Date) => void
Called when date changes
onLevelChange
(level: MonthPickerLevel) => void
Called when level changes
onNextDecade
(date: Date) => void
Called when next decade button is clicked
onNextYear
(date: Date) => void
Called when next year button is clicked
onPreviousDecade
(date: Date) => void
Called when previous decade button is clicked
onPreviousYear
(date: Date) => void
Called when previous year button is clicked
size
"xs" | "sm" | "md" | "lg" | "xl"
Component size
type
"default" | "multiple" | "range"
Picker type: range, multiple or default
value
Date | DatesRangeValue | Date[]
Value for controlled component
withCellSpacing
boolean
Determines whether controls should be separated by spacing, true by default
yearLabelFormat
string | ((year: Date) => ReactNode)
dayjs label format to display year label or a function that returns year label based on year value, defaults to "YYYY"
yearsListFormat
string
dayjs format for years list

MonthPicker component Styles API

NameStatic selectorDescription
calendar.mantine-MonthPicker-calendarCalendar root element
calendarHeader.mantine-MonthPicker-calendarHeaderCalendar header root element
calendarHeaderControl.mantine-MonthPicker-calendarHeaderControlPrevious/next calendar header controls
calendarHeaderControlIcon.mantine-MonthPicker-calendarHeaderControlIconIcon of previous/next calendar header controls
calendarHeaderLevel.mantine-MonthPicker-calendarHeaderLevelLevel control (changes levels when clicked, month -> year -> decade)
decadeLevelGroup.mantine-MonthPicker-decadeLevelGroupGroup of decades levels
decadeLevel.mantine-MonthPicker-decadeLevelDecade level root element
pickerControl.mantine-MonthPicker-pickerControlButton used to pick months and years
yearsList.mantine-MonthPicker-yearsListYears list table element
yearsListRow.mantine-MonthPicker-yearsListRowYears list row element
yearsListCell.mantine-MonthPicker-yearsListCellYears list cell element
yearLevelGroup.mantine-MonthPicker-yearLevelGroupGroup of year levels
yearLevel.mantine-MonthPicker-yearLevelYear level root element
monthsList.mantine-MonthPicker-monthsListMonths list table element
monthsListRow.mantine-MonthPicker-monthsListRowMonths list table row element
monthsListCell.mantine-MonthPicker-monthsListCellMonths list table cell element