Getting started

Get started with @mantine/dates package

License

Installation

yarn add @mantine/dates dayjs

After installation import package styles at the root of your application:

import '@mantine/core/styles.css';
// ‼️ import dates styles after core package styles
import '@mantine/dates/styles.css';

Do not forget to import styles

Followed the installation instructions above but something is not working (calendars and date pickers have no styles and look broken)? You've fallen into the trap of not importing dates styles! To fix this issue, import dates styles at the root of your application:

import '@mantine/dates/styles.css';

Usage

After installing the @mantine/dates package and importing styles, you can use all components from it:

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

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

Date values as strings

@mantine/dates components work with date strings: YYYY-MM-DD or YYYY-MM-DD HH:mm:ss depending on the component. Those strings do not include any timezone-specific information.

dayjs

@mantine/dates components use dayjs under the hood for date manipulations and formatting. dayjs is a required dependency – you cannot change it to another date library. If you want to use a different date library in your application, you will need to install it separately.

DatesProvider

The DatesProvider component lets you set various settings that are shared across all components exported from the @mantine/dates package. DatesProvider supports the following settings:

  • locale – dayjs locale. Note that you also need to import the corresponding locale module from dayjs. The default value is en.
  • firstDayOfWeek – a number from 0 to 6, where 0 is Sunday and 6 is Saturday. The default value is 1 – Monday.
  • weekendDays – an array of numbers from 0 to 6, where 0 is Sunday and 6 is Saturday. The default value is [0, 6] – Saturday and Sunday.
  • consistentWeeks – boolean. If true, every month will have 6 weeks. The default value is false.
import 'dayjs/locale/ru';
import { DatesProvider, MonthPickerInput, DatePickerInput } from '@mantine/dates';

function Demo() {
  return (
    <DatesProvider settings={{ locale: 'ru', firstDayOfWeek: 0, weekendDays: [0] }}>
      <MonthPickerInput label="Pick month" placeholder="Pick month" />
      <DatePickerInput mt="md" label="Pick date" placeholder="Pick date" />
    </DatesProvider>
  );
}

Consistent weeks

If you want to avoid layout shifts, set consistentWeeks: true in the DatesProvider settings. This will ensure that every month has 6 weeks, even if outside days are not in the same month.

MoTuWeThFrSaSu
import { DatePicker, DatesProvider } from '@mantine/dates';

function Demo() {
  return (
    <DatesProvider settings={{ consistentWeeks: true }}>
      <DatePicker />
    </DatesProvider>
  );
}

Formatting without dayjs

All formatting props accept a function in addition to a dayjs format string. The function receives the date as a YYYY-MM-DD string (or YYYY-MM-DD HH:mm:ss for components that include time) and returns the label to display. Use it to format dates with Intl.DateTimeFormat instead of dayjs – this way you do not need to import dayjs/locale/* modules for every language that your application supports:

import { DatePickerInput, DatesProvider } from '@mantine/dates';

const locale = 'de';

// 'YYYY-MM-DD' is parsed as UTC by the Date constructor,
// add time part to parse it in the local timezone instead
const toDate = (value: string) => new Date(`${value}T00:00:00`);

function Demo() {
  return (
    <DatesProvider settings={{ locale }}>
      <DatePickerInput
        label="Pick date"
        placeholder="Pick date"
        valueFormatter={({ date }) =>
          typeof date === 'string'
            ? new Intl.DateTimeFormat(locale, { dateStyle: 'long' }).format(toDate(date))
            : ''
        }
        monthLabelFormat={(date) =>
          new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }).format(toDate(date))
        }
        weekdayFormat={(date) =>
          new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(toDate(date))
        }
        monthsListFormat={(date) =>
          new Intl.DateTimeFormat(locale, { month: 'short' }).format(toDate(date))
        }
        yearsListFormat={(date) =>
          new Intl.DateTimeFormat(locale, { year: 'numeric' }).format(toDate(date))
        }
      />
    </DatesProvider>
  );
}

The following props accept a function:

| Prop | Components | | --- | --- | | valueFormatter | DatePickerInput, MonthPickerInput, YearPickerInput | | valueFormat | DateInput, DateTimePicker, InlineDateTimePicker | | monthLabelFormat | Calendar, DatePicker, DateInput, MiniCalendar, MonthLevel and all components that use them | | yearLabelFormat | Calendar, DatePicker, YearLevel and all components that use them | | decadeLabelFormat | Calendar, DatePicker, DecadeLevel and all components that use them | | weekdayFormat | Calendar, DatePicker, Month, WeekdaysRow and all components that use them | | monthsListFormat | Calendar, MonthPicker, MonthsList and all components that use them | | yearsListFormat | Calendar, YearPicker, YearsList and all components that use them |

Note that DateInput.valueFormat is also used to parse user input. When it is set to a function, the component can no longer parse arbitrary formats – set the dateParser prop to handle typed values.

To apply formatters to all instances of a component, define them in theme.components instead of setting them on every usage:

import { createTheme, MantineProvider } from '@mantine/core';
import { DateFormatter } from '@mantine/dates';

const valueFormatter: DateFormatter = ({ date, locale }) =>
  typeof date === 'string'
    ? new Intl.DateTimeFormat(locale, { dateStyle: 'long' }).format(new Date(`${date}T00:00:00`))
    : '';

const theme = createTheme({
  components: {
    DatePickerInput: {
      defaultProps: { valueFormatter },
    },
  },
});

function App() {
  return <MantineProvider theme={theme}>{/* Your app */}</MantineProvider>;
}

Formatters do not remove the dayjs dependency – it is still used internally for date parsing and arithmetic. What they do remove is the need to import a dayjs locale module per supported language.

Custom parse format

Some components like DateInput require the custom parse format dayjs plugin. You need to extend dayjs with this plugin before using components that require it. Note that this is usually done once in your application root file, so you don't need to do it every time you use the component.

import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';

dayjs.extend(customParseFormat);

Localization and server components

To add localization, you must import import 'dayjs/locale/x'; in your application (x is the locale name) and set locale either on DatesProvider or on each component individually.

Example of setting the locale on DatesProvider:

import 'dayjs/locale/ru';

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

function Demo() {
  return (
    <DatesProvider settings={{ locale: 'ru' }}>
      {/* Your app  */}
    </DatesProvider>
  );
}

The code above works in all environments, except Next.js app router. If you are using Next.js app router, you must add 'use client'; to the top of the file where you are importing dayjs/locale/x – locale data is required both on client and server.

'use client';

import 'dayjs/locale/ru';

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

function Demo() {
  return (
    <DatesProvider settings={{ locale: 'ru' }}>
      {/* Your app  */}
    </DatesProvider>
  );
}