WeekPicker

Inline week, multiple weeks and weeks range picker

Usage

WeekPicker renders the same calendar as DatePicker, but selects whole weeks: hovering any day highlights its week and clicking selects it. Week numbers are always displayed.

#MoTuWeThFrSaSu
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return <WeekPicker value={value} onChange={setValue} />;
}

Week value

The value is a date string in YYYY-MM-DD format that points to the first day of the selected week. The first day of the week is determined by the firstDayOfWeek prop or by the DatesProvider settings (Monday by default). Use getStartOfWeek and getEndOfWeek exported from @mantine/dates to get the week boundaries from the value.

#MoTuWeThFrSaSu

Value: –

Week: –

import { useState } from 'react';
import { Text } from '@mantine/core';
import { getEndOfWeek, getStartOfWeek, WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <>
      <WeekPicker value={value} onChange={setValue} />
      <Text mt="md" size="sm">
        Value: {value || '–'}
      </Text>
      <Text size="sm">
        Week: {value ? `${getStartOfWeek(value)} – ${getEndOfWeek(value)}` : '–'}
      </Text>
    </>
  );
}

Allow deselect

Set allowDeselect to allow users to deselect the currently selected week by clicking on it. allowDeselect is disregarded when the type prop is range or multiple. When a week is deselected, onChange is called with null.

#MoTuWeThFrSaSu
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return <WeekPicker allowDeselect value={value} onChange={setValue} />;
}

Multiple weeks

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

#MoTuWeThFrSaSu
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

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

Weeks range

Set type="range" to allow users to pick a weeks range. The value is a tuple of the first day of the first week and the first day of the last week:

#MoTuWeThFrSaSu
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

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

Single week in range

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

#MoTuWeThFrSaSu
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[string | null, string | null]>([null, null]);
  return (
    <WeekPicker type="range" allowSingleDateInRange value={value} onChange={setValue} />
  );
}

First day of week

Set the firstDayOfWeek prop to change which day starts the week (0 – Sunday, 6 – Saturday). It changes both the calendar layout and the value that is emitted:

#SuMoTuWeThFrSa
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker firstDayOfWeek={0} />;
}

Week controls

Every week number is a button that selects its week. Days are not focusable, they can only be clicked with the mouse. Use getWeekControlProps to pass props to week controls based on the first date of the week, for example to disable specific weeks:

#MoTuWeThFrSaSu
import dayjs from 'dayjs';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return (
    <WeekPicker
      getWeekControlProps={(weekStart) => ({
        'aria-label': `Select week starting on ${dayjs(weekStart).format('D MMMM')}`,
        disabled: dayjs(weekStart).day(5).isBefore(dayjs(), 'day'),
      })}
    />
  );
}

Presets

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

#MoTuWeThFrSaSu
import dayjs from 'dayjs';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return (
    <WeekPicker
      presets={[
        { value: dayjs().format('YYYY-MM-DD'), label: 'This week' },
        { value: dayjs().add(1, 'week').format('YYYY-MM-DD'), label: 'Next week' },
        { value: dayjs().subtract(1, 'week').format('YYYY-MM-DD'), label: 'Last week' },
        { value: dayjs().add(4, 'week').format('YYYY-MM-DD'), label: 'In a month' },
      ]}
    />
  );
}

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

#MoTuWeThFrSaSu
import dayjs from 'dayjs';
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[string | null, string | null]>([null, null]);
  return (
    <WeekPicker
      type="range"
      value={value}
      onChange={setValue}
      presets={[
        {
          value: [dayjs().format('YYYY-MM-DD'), dayjs().add(1, 'week').format('YYYY-MM-DD')],
          label: 'Next two weeks',
        },
        {
          value: [dayjs().subtract(3, 'week').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')],
          label: 'Last four weeks',
        },
        {
          value: [dayjs().startOf('month').format('YYYY-MM-DD'), dayjs().endOf('month').format('YYYY-MM-DD')],
          label: 'This month',
        },
      ]}
    />
  );
}

Default date

Use the defaultDate prop to set the date value that will be used to determine which month should be displayed initially. Note that if you set the date prop, then the defaultDate value will be ignored.

#MoTuWeThFrSaSu
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker defaultDate="2015-02-01" />;
}

Hide outside dates

Set hideOutsideDates to hide days of the selected week that are outside of the displayed month. When numberOfColumns is larger than 1, outside dates are hidden by default, set hideOutsideDates={false} to display whole weeks:

#MoTuWeThFrSaSu
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker hideOutsideDates />;
}

Min and max date

Set the minDate and maxDate props to define minimum and maximum dates. A week can be selected if it contains at least one enabled day. Note that the value is the first day of the week, it can be before minDate.

#MoTuWeThFrSaSu
import dayjs from 'dayjs';
import { useState } from 'react';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <WeekPicker
      value={value}
      onChange={setValue}
      minDate={dayjs().subtract(2, 'week').format('YYYY-MM-DD')}
      maxDate={dayjs().add(2, 'week').format('YYYY-MM-DD')}
    />
  );
}

Exclude dates

excludeDate disables individual days. A week that contains enabled days can still be selected through those days:

#MoTuWeThFrSaSu
import dayjs from 'dayjs';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker excludeDate={(date) => dayjs(date).day() === 0 || dayjs(date).day() === 6} />;
}

Add props to day, year and month control

Use getDayProps, getMonthControlProps and getYearControlProps to add props to the corresponding controls:

#MoTuWeThFrSaSu
import dayjs from 'dayjs';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return (
    <WeekPicker
      getDayProps={(date) => {
        if (dayjs(date).day() === 5) {
          return { style: { color: 'var(--mantine-color-blue-filled)', fontWeight: 700 } };
        }
        return {};
      }}
      getMonthControlProps={(date) => (dayjs(date).month() === 1 ? { disabled: true } : {})}
      getYearControlProps={(date) => (dayjs(date).year() === 2028 ? { disabled: true } : {})}
    />
  );
}

Number of columns

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

#MoTuWeThFrSaSu
#MoTuWeThFrSaSu

Demo is not available on small screens. Make your screen larger to see the demo.

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

function Demo() {
  const [value, setValue] = useState<[string | null, string | null]>([null, null]);
  return (
    <WeekPicker type="range" numberOfColumns={2} value={value} onChange={setValue} />
  );
}

Max level

To disallow users from going to the decade level, set maxLevel="year":

#MoTuWeThFrSaSu
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker maxLevel="year" />;
}

Full width

Set the fullWidth prop to make the week picker stretch to fill 100% of its parent container width:

#MoTuWeThFrSaSu
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker fullWidth />;
}

Size

#MoTuWeThFrSaSu
Size
import dayjs from 'dayjs';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker defaultValue={dayjs().format('YYYY-MM-DD')} />;
}

Localization

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

#пнвтсрчтптсбвс
import 'dayjs/locale/ru';
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker locale="ru" />;
}

Native level select

Set the withNativeLevelSelect prop to replace the calendar header level button with native <select> elements:

#MoTuWeThFrSaSu
import { WeekPicker } from '@mantine/dates';

function Demo() {
  return <WeekPicker withNativeLevelSelect />;
}

Accessibility

Aria labels

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

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

function Demo() {
  return (
    <WeekPicker
      ariaLabels={{
        nextDecade: 'Next decade',
        previousDecade: 'Previous decade',
        nextYear: 'Next year',
        previousYear: 'Previous year',
        nextMonth: 'Next month',
        previousMonth: 'Previous month',
        yearLevelControl: 'Change to decade view',
        monthLevelControl: 'Change to year view',
      }}
    />
  );
}

Week control aria-label

By default, week controls have an aria-label with the first and the last day of the week. Use getWeekControlProps to customize it:

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

function Demo() {
  return (
    <WeekPicker
      getWeekControlProps={(weekStart) => ({
        'aria-label': `Select week starting on ${weekStart}`,
      })}
    />
  );
}

Keyboard interactions

Only week controls (week numbers) can be focused with the keyboard.

KeyDescription
ArrowDownFocuses next non-disabled week control, switches to the next month if needed
ArrowUpFocuses previous non-disabled week control, switches to the previous month if needed
Enter/SpaceSelects the focused week

When presets are used, only one preset button is in the tab order. With focus on a preset, ArrowDown and ArrowUp move focus between presets without selecting them, Enter or Space selects the focused preset, and Tab moves focus to the calendar.

When the level is changed with the keyboard (for example, Enter on the month label), focus moves to the label of the new level or to the grid control in the tab order if the new level does not have a clickable label.