MaskedDateInput

Masked date input with individual fields for day, month and year

Usage

MaskedDateInput is similar to TimePicker but for dates. It provides individual masked input fields for day, month, and year with an optional calendar dropdown for date selection.

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

function Demo() {
  return <MaskedDateInput label="Date of birth" />;
}

Controlled

The MaskedDateInput value is a string in YYYY-MM-DD format (for example 2000-06-15). When withTime is set, the value uses YYYY-MM-DD HH:mm:ss format (for example 2000-06-15 14:30:00). null is used to represent no value. The onChange function is called when all fields are filled or when all fields are cleared.

//
null
import { useState } from 'react';
import { Code } from '@mantine/core';
import { MaskedDateInput } from '@mantine/dates';

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

  return (
    <>
      <MaskedDateInput label="Date of birth" value={value} onChange={setValue} />
      <Code block mt="md">
        {value ?? 'null'}
      </Code>
    </>
  );
}

With time

Set the withTime prop to display hours and minutes fields in addition to date fields.

// :
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return <MaskedDateInput label="Date and time" withTime />;
}

With seconds

Set the withSeconds prop to display the seconds field. The withTime prop must also be set.

// ::
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return <MaskedDateInput label="Date and time" withTime withSeconds />;
}

12-hour format

Set format="12h" to use 12-hour time format. The am/pm selector is displayed automatically.

// :
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return <MaskedDateInput label="Date and time" withTime format="12h" />;
}

Change am/pm labels

Use the amPmLabels prop to customize am/pm labels:

// :
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return (
    <MaskedDateInput
      label="Date and time"
      withTime
      format="12h"
      amPmLabels={{ am: 'पू', pm: 'अ' }}
    />
  );
}

Date separator

Use the dateSeparator prop to change the separator displayed between date fields. The default is /.

..
--
/ /
import { Stack } from '@mantine/core';
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return (
    <Stack>
      <MaskedDateInput label="Dot separator" dateSeparator="." />
      <MaskedDateInput label="Dash separator" dateSeparator="-" />
      <MaskedDateInput label="Spaced slash separator" dateSeparator=" / " />
    </Stack>
  );
}

Time separator

Use the timeSeparator prop to change the separator displayed between time fields. The default is :.

// .
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return <MaskedDateInput label="Date and time" withTime timeSeparator="." />;
}

Fields order

Use the fieldsOrder prop to control the display order of day, month, and year fields. The default order is ['day', 'month', 'year'].

//
//
//
import { Stack } from '@mantine/core';
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return (
    <Stack>
      <MaskedDateInput label="Day / Month / Year (default)" fieldsOrder={['day', 'month', 'year']} />
      <MaskedDateInput label="Month / Day / Year" fieldsOrder={['month', 'day', 'year']} />
      <MaskedDateInput label="Year / Month / Day" fieldsOrder={['year', 'month', 'day']} />
    </Stack>
  );
}

Min and max dates

Set the minDate and maxDate props to restrict the selectable date range. If a value outside the allowed range is entered, it is clamped to the nearest valid date when the input loses focus.

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

function Demo() {
  return (
    <MaskedDateInput
      label="Date of birth"
      minDate="1924-01-01"
      maxDate="2024-12-31"
    />
  );
}

Allow deselect

Set the allowDeselect prop to allow clearing the value by clicking the selected date in the calendar dropdown:

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

function Demo() {
  return (
    <MaskedDateInput
      label="Date of birth"
      defaultValue="2000-06-15"
      allowDeselect
    />
  );
}

Without dropdown

Set withDropdown={false} to disable the calendar dropdown:

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

function Demo() {
  return <MaskedDateInput label="Date of birth" withDropdown={false} />;
}

Dropdown position

Use popoverProps to pass props down to the underlying Popover component. For example, to always display the dropdown above the input:

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

function Demo() {
  return (
    <MaskedDateInput
      label="Date of birth"
      popoverProps={{
        position: 'top-start',
        middlewares: { flip: false, shift: false },
      }}
    />
  );
}

Hours/minutes/seconds step

Use hoursStep, minutesStep and secondsStep props to control the increment/decrement step for each time field when using arrow keys:

// ::
import { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return (
    <MaskedDateInput
      label="Date and time"
      withTime
      withSeconds
      hoursStep={1}
      minutesStep={5}
      secondsStep={10}
    />
  );
}

Paste events

By default, MaskedDateInput handles pasted values in YYYY-MM-DD and YYYY-MM-DD HH:mm:ss formats. With the pasteSplit prop you can provide a custom paste parser that extracts day, month, and year values from a pasted string:

//

Try pasting a date in DD.MM.YYYY format. For example, try pasting 15.06.2000

import { Code, Text } from '@mantine/core';
import { MaskedDateInput } from '@mantine/dates';

const re = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/;

const customPasteSplit = (value: string) => {
  const match = value.match(re);
  if (!match) {
    return { day: null, month: null, year: null };
  }

  return {
    day: Number(match[1]),
    month: Number(match[2]),
    year: Number(match[3]),
  };
};

function Demo() {
  return (
    <div>
      <MaskedDateInput label="Paste date here" pasteSplit={customPasteSplit} />
      <Text mt="md">
        Try pasting a date in DD.MM.YYYY format. For example, try pasting{' '}
        <Code>15.06.2000</Code>
      </Text>
    </div>
  );
}

Clearable

Set the clearable prop to display a clear button in the right section of the input.

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

function Demo() {
  return <MaskedDateInput label="Date of birth" clearable defaultValue="2000-06-15" />;
}

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 { MaskedDateInput } from '@mantine/dates';

function Demo() {
  return (
    <Stack>
      <MaskedDateInput
        label="clearSectionMode='both' (default)"
        defaultValue="2000-06-15"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="both"
      />

      <MaskedDateInput
        label="clearSectionMode='rightSection'"
        defaultValue="2000-06-15"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="rightSection"
      />

      <MaskedDateInput
        label="clearSectionMode='clear'"
        defaultValue="2000-06-15"
        clearable
        rightSection={<CaretDownIcon size={16} />}
        clearSectionMode="clear"
      />
    </Stack>
  );
}

Disabled

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

function Demo() {
  return <MaskedDateInput label="Date of birth" disabled />;
}

Read only

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

function Demo() {
  return <MaskedDateInput label="Date of birth" defaultValue="2000-06-15" readOnly />;
}

Input props

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

Input description

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

function Demo() {
  return (
    <MaskedDateInput
      label="Input label"
      description="Input description"
    />
  );
}

Get refs

Use dayRef, monthRef, yearRef, hoursRef, minutesRef, secondsRef and amPmRef props to get refs of the inner inputs:

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

function Demo() {
  const dayRef = useRef<HTMLInputElement>(null);
  const monthRef = useRef<HTMLInputElement>(null);
  const yearRef = useRef<HTMLInputElement>(null);

  return (
    <MaskedDateInput
      dayRef={dayRef}
      monthRef={monthRef}
      yearRef={yearRef}
    />
  );
}

onFocus and onBlur

onFocus is called when one of the inputs receives focus and onBlur is called when focus leaves all inputs:

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

function Demo() {
  return (
    <MaskedDateInput
      onFocus={() => console.log('Focused')}
      onBlur={() => console.log('Blurred')}
    />
  );
}

Accessibility

Each field has an English aria-label by default (Day, Month, Year, Hours, Minutes, Seconds, AM/PM), and the fields are grouped under the label. Use the corresponding props to translate the labels. Also set an aria-label for the clear button if clearable is used:

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

function Demo() {
  return (
    <MaskedDateInput
      label="Fecha de nacimiento"
      dayInputLabel="Día"
      monthInputLabel="Mes"
      yearInputLabel="Año"
      clearButtonProps={{ 'aria-label': 'Borrar fecha' }}
    />
  );
}

Keyboard interactions:

KeyDescription
ArrowDownDecrements current value by step
ArrowUpIncrements current value by step
HomeSets current value to min possible value
EndSets current value to max possible value
BackspaceClears current value
ArrowRightMoves focus to the next input
ArrowLeftMoves focus to the previous input