Material-UI pickers
2.2.2

Date picker#

Date pickers use a dialog window or an inline popover to select a single date. The selected day is indicated by a filled circle. The current day is indicated by a different color and type weight.

Basic usage#

import React, { Fragment, useState } from "react";
import { DatePicker } from "material-ui-pickers";

function BasicDatePicker(props) {
  const [selectedDate, handleDateChange] = useState(new Date());

  return (
    <Fragment>
      <div className="picker">
        <DatePicker
          label="Basic example"
          value={selectedDate}
          onChange={handleDateChange}
          animateYearScrolling
        />
      </div>

      <div className="picker">
        <DatePicker
          autoOk
          label="Clearable"
          clearable
          disableFuture
          value={selectedDate}
          onChange={handleDateChange}
        />
      </div>

      <div className="picker">
        <DatePicker
          label="Date of birth"
          value={selectedDate}
          disableFuture
          openTo="year"
          format={props.getFormatString({
            moment: "DD/MM/YYYY",
            dateFns: "dd/MM/yyyy",
          })}
          views={["year", "month", "day"]}
          onChange={handleDateChange}
        />
      </div>
    </Fragment>
  );
}

export default BasicDatePicker;

Keyboard Input#

It is recommended to use keyboard input with mask for better desktop experience. More information about mask

import React, { Fragment, useState } from "react";
import { DatePicker } from "material-ui-pickers";

function KeyboardDatePicker(props) {
  const [selectedDate, handleDateChange] = useState(new Date());

  return (
    <Fragment>
      <div className="picker">
        <DatePicker
          keyboard
          clearable
          label="Uncontrolled input"
          value={selectedDate}
          onChange={handleDateChange}
          animateYearScrolling={false}
          minDate={new Date()}
          onInputChange={e => console.log("Keyboard Input:", e.target.value)}
        />
      </div>

      <div className="picker">
        <DatePicker
          keyboard
          label="Masked input"
          format={props.getFormatString({
            moment: "MM/DD/YYYY",
            dateFns: "MM/dd/yyyy",
          })}
          placeholder="10/10/2018"
          mask={value =>
            // handle clearing outside if value can be changed outside of the component
            value ? [/\d/, /\d/, "/", /\d/, /\d/, "/", /\d/, /\d/, /\d/, /\d/] : []
          }
          value={selectedDate}
          onChange={handleDateChange}
          disableOpenOnEnter
          animateYearScrolling={false}
        />
      </div>
    </Fragment>
  );
}

export default KeyboardDatePicker;

Different views#

It is also allowed to combine year, month and date selection views. Thus you can easily create

  • Year picker
  • Month picker
  • Month + year picker
import React, { Fragment, useState } from "react";
import { DatePicker, InlineDatePicker } from "material-ui-pickers";

function YearMonthPicker(props) {
  const [selectedDate, handleDateChange] = useState(new Date());

  return (
    <Fragment>
      <div className="picker">
        <DatePicker
          views={["year"]}
          label="Year only"
          value={selectedDate}
          onChange={handleDateChange}
          animateYearScrolling
        />
      </div>

      <div className="picker">
        <DatePicker
          views={["year", "month"]}
          label="Year and Month"
          helperText="With min and max"
          minDate={new Date("2018-03-01")}
          maxDate={new Date("2018-06-01")}
          value={selectedDate}
          onChange={handleDateChange}
        />
      </div>

      <div className="picker">
        <InlineDatePicker
          openTo="year"
          views={["year", "month"]}
          label="Year and Month"
          helperText="Start from year selection"
          value={selectedDate}
          onChange={handleDateChange}
        />
      </div>
    </Fragment>
  );
}

export default YearMonthPicker;

With min and max

Start from year selection

Inline mode#

import { InlineDatePicker } from "material-ui-pickers";
import React, { Fragment, useState } from "react";

function InlineDatePickerDemo(props) {
  const [selectedDate, handleDateChange] = useState(new Date());

  return (
    <Fragment>
      <div className="picker">
        <InlineDatePicker label="Basic example" value={selectedDate} onChange={handleDateChange} />
      </div>

      <div className="picker">
        <InlineDatePicker
          onlyCalendar
          label="Only calendar"
          helperText="No year selection"
          value={selectedDate}
          onChange={handleDateChange}
        />
      </div>

      <div className="picker">
        <InlineDatePicker
          keyboard
          clearable
          variant="outlined"
          label="With keyboard"
          value={selectedDate}
          onChange={handleDateChange}
          format={props.getFormatString({
            moment: "MM/DD/YYYY",
            dateFns: "MM/dd/yyyy",
          })}
          mask={[/\d/, /\d/, "/", /\d/, /\d/, "/", /\d/, /\d/, /\d/, /\d/]}
        />
      </div>
    </Fragment>
  );
}

export default InlineDatePickerDemo;

No year selection

Customization#

It is allowed to hardly customize displaying of dates. Thus you can add badges or fully change displaying of day.

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import clsx from "clsx";
import isValid from "date-fns/isValid";
import format from "date-fns/format";
import isSameDay from "date-fns/isSameDay";
import startOfWeek from "date-fns/startOfWeek";
import endOfWeek from "date-fns/endOfWeek";
import isWithinInterval from "date-fns/isWithinInterval";
import { DatePicker } from "material-ui-pickers";
import { IconButton, withStyles } from "@material-ui/core";

// this guy required only on the docs site to work with dynamic date library
import { cloneCrossUtils } from "utils/helpers";

class CustomElements extends PureComponent {
  state = {
    selectedDate: new Date(),
  };

  handleWeekChange = date => {
    this.setState({ selectedDate: startOfWeek(cloneCrossUtils(date)) });
  };

  formatWeekSelectLabel = (date, invalidLabel) => {
    let dateClone = cloneCrossUtils(date);

    return dateClone && isValid(dateClone)
      ? `Week of ${format(startOfWeek(dateClone), "MMM do")}`
      : invalidLabel;
  };

  renderWrappedWeekDay = (date, selectedDate, dayInCurrentMonth) => {
    const { classes } = this.props;
    let dateClone = cloneCrossUtils(date);
    let selectedDateClone = cloneCrossUtils(selectedDate);

    const start = startOfWeek(selectedDateClone);
    const end = endOfWeek(selectedDateClone);

    const dayIsBetween = isWithinInterval(dateClone, { start, end });
    const isFirstDay = isSameDay(dateClone, start);
    const isLastDay = isSameDay(dateClone, end);

    const wrapperClassName = clsx({
      [classes.highlight]: dayIsBetween,
      [classes.firstHighlight]: isFirstDay,
      [classes.endHighlight]: isLastDay,
    });

    const dayClassName = clsx(classes.day, {
      [classes.nonCurrentMonthDay]: !dayInCurrentMonth,
      [classes.highlightNonCurrentMonthDay]: !dayInCurrentMonth && dayIsBetween,
    });

    return (
      <div className={wrapperClassName}>
        <IconButton className={dayClassName}>
          <span> {format(dateClone, "d")} </span>
        </IconButton>
      </div>
    );
  };

  render() {
    const { selectedDate } = this.state;

    return (
      <div className="picker">
        <DatePicker
          label="Week picker"
          value={selectedDate}
          onChange={this.handleWeekChange}
          renderDay={this.renderWrappedWeekDay}
          labelFunc={this.formatWeekSelectLabel}
        />
      </div>
    );
  }
}

const styles = theme => ({
  dayWrapper: {
    position: "relative",
  },
  day: {
    width: 36,
    height: 36,
    fontSize: theme.typography.caption.fontSize,
    margin: "0 2px",
    color: "inherit",
  },
  customDayHighlight: {
    position: "absolute",
    top: 0,
    bottom: 0,
    left: "2px",
    right: "2px",
    border: `1px solid ${theme.palette.secondary.main}`,
    borderRadius: "50%",
  },
  nonCurrentMonthDay: {
    color: theme.palette.text.disabled,
  },
  highlightNonCurrentMonthDay: {
    color: "#676767",
  },
  highlight: {
    background: theme.palette.primary.main,
    color: theme.palette.common.white,
  },
  firstHighlight: {
    extend: "highlight",
    borderTopLeftRadius: "50%",
    borderBottomLeftRadius: "50%",
  },
  endHighlight: {
    extend: "highlight",
    borderTopRightRadius: "50%",
    borderBottomRightRadius: "50%",
  },
});

export default withStyles(styles)(CustomElements);

Component Api#

Note Any prop not recognized by the pickers and their sub-components are passed down to material-ui TextField component.

Name Type Description
adornmentPosition"start" | "end"Specifies position of keyboard button adornment
allowKeyboardControlbooleanEnables keyboard listener for moving between days in calendar
ampmbooleanControl 12h or 24h view mode for clock
animateYearScrollingbooleanTo animate scrolling to current year (with scrollIntoView)
autoOkbooleanAuto accept date on selection
cancelLabelReactNode"Cancel" label message
clearablebooleanClearable mode (for inline pickers works only for clearing input)
clearLabelReactNode"Clear" label message
disableFuturebooleanDisable future dates
disableOpenOnEnterbooleanDo not open picker on enter keypress
disablePastbooleanDisable past dates
emptyLabelstringMessage displaying in text field, if null passed (doesn't work in keyboard mode)
formatstringFormat string
initialFocusedDateDateTypeDate that will be initially highlighted
InputAdornmentPropsPartial<InputAdornmentProps>Props to pass to keyboard input adornment
invalidDateMessageReactNodeMessage, appearing when date cannot be parsed
invalidLabelstringMessage displaying in text field, if date is invalid (doesn't work in keyboard mode)
keepCharPositionsbooleanDo not move chars on removing in masked input
keyboardbooleanOn/off manual keyboard input mode
KeyboardButtonPropsPartial<IconButtonProps>Props to pass to keyboard adornment button
keyboardIconReactNodeIcon displayed for open picker button in keyboard mode
labelFunc(date: any, invalidLabel: string) => stringDynamic formatter of text field label
leftArrowIconReactNodeLeft arrow icon
mask(string | RegExp)[] | ((value: string) => (string | RegExp)[])Input mask, used in keyboard mode read more here
maxDateDateTypeMax selectable date
maxDateMessageReactNodeError message, shown if date is more then maximal date
minDateDateTypeMin selectable date
minDateMessageReactNodeError message, shown if date is less then minimal date
okLabelReactNode"OK" label message
onChange *(date: any) => voidonChange callback
onClose() => voidOn close callback
onMonthChange(date: any) => voidCallback firing on month change
onOpen() => voidOn open callback
onYearChange(date: any) => voidCallback firing on year change
openTo"year" | "month" | "day"Initial view to show when date picker is open
openToYearSelectionboolean@deprecated use openTo instead
renderDayRenderDayCustom renderer for day
rightArrowIconReactNodeRight arrow icon
shouldDisableDate(day: any) => booleanDisable specific date
showTodayButtonbooleanIf true today button will be displayed Note* that clear button has higher priority
TextFieldComponent"symbol" | "object" | "style" | "title" | "time" | "link" | "menu" | "dialog" | "text" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | ... 156 more ... | FunctionComponent<...>Component that should replace the default Material-UI TextField
todayLabelReactNode"Today" label message
value *DateTypePicker value
views("year" | "month" | "day")[]Array of views to show. Order year -> month -> day