QuarterPickerInput

Quarter, multiple quarters and quarters range picker input

QuarterPicker props

QuarterPickerInput supports most of the QuarterPicker props. Read through the QuarterPicker documentation to learn about all component features that are not listed on this page.

Usage

The value is a date string in YYYY-MM-DD format pointing to the first day of the selected quarter:

import { useState } from 'react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <QuarterPickerInput
      label="Pick date"
      placeholder="Pick date"
      value={value}
      onChange={setValue}
    />
  );
}

Multiple quarters

Set type="multiple" to allow users to pick multiple quarters:

import { useState } from 'react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string[]>([]);
  return (
    <QuarterPickerInput
      type="multiple"
      label="Pick dates"
      placeholder="Pick dates"
      value={value}
      onChange={setValue}
    />
  );
}

Quarters range

Set type="range" to allow users to pick a quarters range:

import { useState } from 'react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[string | null, string | null]>([null, null]);
  return (
    <QuarterPickerInput
      type="range"
      label="Pick dates range"
      placeholder="Pick dates range"
      value={value}
      onChange={setValue}
    />
  );
}

Presets

Use the presets prop to add custom quarter presets. Presets are displayed next to the calendar. Any date inside the quarter can be used as a preset value:

import dayjs from 'dayjs';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
import { QuarterPickerInput } from '@mantine/dates';

dayjs.extend(quarterOfYear);

function Demo() {
  return (
    <QuarterPickerInput
      label="Pick quarter"
      placeholder="Pick quarter"
      presets={[
        { value: dayjs().startOf('quarter').format('YYYY-MM-DD'), label: 'This quarter' },
        { value: dayjs().add(1, 'quarter').startOf('quarter').format('YYYY-MM-DD'), label: 'Next quarter' },
        { value: dayjs().subtract(1, 'quarter').startOf('quarter').format('YYYY-MM-DD'), label: 'Last quarter' },
        { value: dayjs().add(1, 'year').startOf('year').format('YYYY-MM-DD'), label: 'Q1 next year' },
      ]}
    />
  );
}

To use presets with type="range", define the value as a tuple of two dates:

import dayjs from 'dayjs';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
import { QuarterPickerInput } from '@mantine/dates';

dayjs.extend(quarterOfYear);

function Demo() {
  return (
    <QuarterPickerInput
      type="range"
      label="Pick quarters range"
      placeholder="Pick quarters range"
      presets={[
        {
          value: [dayjs().startOf('year').format('YYYY-MM-DD'), dayjs().startOf('quarter').format('YYYY-MM-DD')],
          label: 'Year to date',
        },
        {
          value: [dayjs().startOf('year').format('YYYY-MM-DD'), dayjs().startOf('year').add(9, 'month').format('YYYY-MM-DD')],
          label: 'This year',
        },
        {
          value: [dayjs().subtract(1, 'year').startOf('year').format('YYYY-MM-DD'), dayjs().subtract(1, 'year').startOf('year').add(9, 'month').format('YYYY-MM-DD')],
          label: 'Last year',
        },
        {
          value: [dayjs().startOf('quarter').format('YYYY-MM-DD'), dayjs().add(1, 'quarter').startOf('quarter').format('YYYY-MM-DD')],
          label: 'Next two quarters',
        },
      ]}
    />
  );
}

Open picker in modal

By default, QuarterPicker is rendered inside Popover. You can change that to Modal by setting dropdownType="modal":

import { useState } from 'react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <QuarterPickerInput
      dropdownType="modal"
      label="Pick date"
      placeholder="Pick date"
      value={value}
      onChange={setValue}
    />
  );
}

Value format

Use the valueFormat prop to change the dayjs format of the value label. The default format is [Q]Q YYYY, for example Q2 2026:

import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <QuarterPickerInput
      valueFormat="YYYY [Q]Q"
      type="multiple"
      label="Pick quarter"
      placeholder="Pick quarter"
    />
  );
}

Value formatter

valueFormatter is a more powerful alternative to the valueFormat prop. It allows formatting the value label with a custom function. The function is the same for all component types (default, multiple and range) – you need to perform additional checks inside the function to handle different types.

Example of using a custom formatter function with type="multiple":

import dayjs from 'dayjs';
import { useState } from 'react';
import { QuarterPickerInput, DateFormatter } from '@mantine/dates';

const formatter: DateFormatter = ({ type, date, locale, format }) => {
  if (type === 'multiple' && Array.isArray(date)) {
    if (date.length === 1) {
      return dayjs(date[0]).locale(locale).format(format);
    }

    if (date.length > 1) {
      return `${date.length} dates selected`;
    }

    return '';
  }

  return '';
};

function Demo() {
  const [value, setValue] = useState<string[]>([]);

  return (
    <QuarterPickerInput
      label="Pick 2 dates or more"
      placeholder="Pick 2 dates or more"
      value={value}
      onChange={setValue}
      type="multiple"
      valueFormatter={formatter}
    />
  );
}

Clearable

Set the clearable prop to display a clear button in the right section. Note that if you set the rightSection prop, the clear button will not be displayed.

import dayjs from 'dayjs';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <QuarterPickerInput
      clearable
      defaultValue={dayjs().format('YYYY-MM-DD')}
      label="Pick date"
      placeholder="Pick date"
    />
  );
}

Clear section mode

The clearSectionMode prop determines how the clear button and rightSection are rendered:

  • 'both' (default) – render both the clear button and rightSection
  • 'rightSection' – render only the user-supplied rightSection, ignore clear button
  • 'clear' – render only the clear button, ignore rightSection
import { CaretDownIcon } from '@phosphor-icons/react';
import { Stack } from '@mantine/core';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <Stack>
      <QuarterPickerInput
        label="clearSectionMode='both' (default)"
        placeholder="Pick quarter"
        defaultValue="2026-04-01"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="both"
      />

      <QuarterPickerInput
        label="clearSectionMode='rightSection'"
        placeholder="Pick quarter"
        defaultValue="2026-04-01"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="rightSection"
      />

      <QuarterPickerInput
        label="clearSectionMode='clear'"
        placeholder="Pick quarter"
        defaultValue="2026-04-01"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="clear"
      />
    </Stack>
  );
}

Disabled state

import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <QuarterPickerInput
      disabled
      label="Disabled"
      placeholder="Pick quarter"
      defaultValue="2026-04-01"
    />
  );
}

Min and max dates

minDate and maxDate props define the minimum and maximum dates that can be picked. Quarters that end before minDate or start after maxDate are disabled:

import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <QuarterPickerInput
      label="Pick quarter"
      placeholder="Pick quarter"
      defaultDate="2026-01-01"
      minDate="2026-04-01"
      maxDate="2027-07-01"
    />
  );
}

Max level

maxLevel prop allows to set the maximum level that can be reached by clicking on the label in the header.

import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return <QuarterPickerInput maxLevel="year" label="Pick quarter" placeholder="Pick quarter" />;
}

Input props

QuarterPickerInput component supports Input and Input.Wrapper component features and all button element props. The QuarterPickerInput documentation does not include all features supported by the component – see the Input documentation to learn about all available features.

Radius
Size
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <QuarterPickerInput
      placeholder="Pick date"
      label="Pick date"
      withAsterisk
    />
  );
}

With icon

import { useState } from 'react';
import { CalendarBlankIcon } from '@phosphor-icons/react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  const icon = <CalendarBlankIcon size={18} />;
  return (
    <QuarterPickerInput
      leftSection={<CalendarBlankIcon size={18} />}
      leftSectionPointerEvents="none"
      label="Pick date"
      placeholder="Pick date"
      value={value}
      onChange={setValue}
    />
  );
}

Native level select

import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  return (
    <QuarterPickerInput
      withNativeLevelSelect
      label="Pick quarter"
      placeholder="Pick quarter"
    />
  );
}

Get element ref

import { useRef } from 'react';
import { QuarterPickerInput } from '@mantine/dates';

function Demo() {
  const ref = useRef<HTMLButtonElement>(null);
  return <QuarterPickerInput ref={ref} />;
}

Accessibility

If QuarterPickerInput is used without the label prop, it will not be announced properly by screen readers:

import { QuarterPickerInput } from '@mantine/core';

// Inaccessible input – screen reader will not announce it properly
function Demo() {
  return <QuarterPickerInput />;
}

Set aria-label to make the input accessible. In this case the label will not be visible, but screen readers will announce it:

import { QuarterPickerInput } from '@mantine/core';

// Accessible input – it has aria-label
function Demo() {
  return <QuarterPickerInput aria-label="My input" />;
}

If the label prop is set, the input will be accessible and it is not required to set aria-label:

import { QuarterPickerInput } from '@mantine/core';

// Accessible input – it has associated label element
function Demo() {
  return <QuarterPickerInput label="My input" />;
}