The Ultimate Material-UI v5 DatePicker and TimePicker Tutorial (Plus Styling!)

The MUI DatePicker and TimePicker components are highly functional and customizable components. They satisfy many use cases for selecting date and time, for example in forms or filters. In this tutorial we will explore how to use the pickers plus some of the best features available in the components.

After showing examples of several useful props, I will style the pickers with MUI v5 styling APIs. We will create the DateTimePicker seen below:

Styled MUI DateTimePicker
Styled MUI DateTimePicker

To clarify, there is a DatePicker, a TimePicker, and a DateTimePicker. Most of the time when I reference the DatePicker, it’s a reference to all three items.

The DatePicker relies on a third-party date-library. I’ll show the install and imports below to get everything running.

The Resources section contains full code and a link to a live Code Sandbox demo.

Imports and 3PL for DatePicker and TimePicker

There are four third-party date adapters supported by MUI. The one you use will impact the inputFormat prop value needed by the DatePicker.

The below code has the imports for the MUI pickers and for AdapterDateDayjs, the MUI adapter required for @date-io/dayjs (the 3pl I chose to use). Also notice how the LocalizationProvider is wrapping the DatePicker.

import AdapterDateDayjs from "@mui/lab/AdapterDayjs";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import DesktopTimePicker from "@mui/lab/DesktopTimePicker";
import DateTimePicker from "@mui/lab/DateTimePicker";
import DesktopDatePicker from "@mui/lab/DesktopDatePicker";

//JSX
<LocalizationProvider dateAdapter={AdapterDateDayjs}>
  <DesktopDatePicker inputFormat="MM/DD/YYYY" //depends on date lib />
</LocalizationProvider dateAdapter={AdapterDateDayjs}>

If you have difficulty with an invalid date format in inputFormat, try another commonly accepted date format. For example, the format I used above worked for Day.js, but the valid date format for date-fns is “MM/dd/yyyy”.

How to Use the Material-UI DatePicker

The MUI DatePicker has two primary components: a text input of some kind (usually a TextField) and the calendar popup. You can see the default styling below.

MUI DatePicker with default styling
MUI DatePicker with default styling

The TextField can have text directly entered into it. It will also update whenever a date is chosen from the popup.

The above image is technically a DesktopDatePicker component, designed specifically for desktop use. MobileDatePicker is available for smaller screens.

A common pattern for using Pickers is to create a state value and store the selected time in the state value. This same value will be used by the picker in its value prop:

const [value, setValue] = React.useState(new Date());

//JSX
<DesktopDatePicker
  label="Date"
  inputFormat="MM/DD/YYYY" //depends on date lib
  value={value}
  onChange={setValue}
/>

The onChange handler in the above example is directly calling the setValue function for setting state.

How to Use the Material-UI TimePicker

The MUI TimePicker also has two primary components: A TextField and a ‘clock’ popup.

Material-UI TimePicker with Default Styling
Material-UI TimePicker with Default Styling

Once again, a time can be directly keyed in and updating the clock will update the text. Also notice the small AM and PM buttons in the bottom corners. MobileTimePicker is available for smaller screens.

How to Use the Material-UI DateTimePicker

The DateTimePicker has three primary components: a TextField for keyed entry, a calendar popup and a clock popup.

The image below has been uniquely styled. We’ll dive into the classes and selectors for styling in a later section.

Using MUI's DateTimePicker
Using MUI’s DateTimePicker

Notice the two tabs at the bottom for switching between the calendar and clock popups. Whatever values are selected will update the text in the input field.

MUI DatePicker Variants

In Material-UI v4, the DatePicker had a variant prop for changing the component styling and behavior. For example, the pickers could be rendered as dialogs with a mask on the rest of the screen.

In MUI v5, the variant prop no longer exists (that I have found). However, the pickers have a prop called dialogProps. This can potentially be used to pass a Backdrop component for creating a mask.

MUI DatePicker Placeholder or Default Value

There is no placeholder prop on the pickers, but you can add a default value or starting value.

A few sections above I discussed how to use a state value with a Date Picker. The state value can be initialized with the current date or time, or a hardcoded date. Here is the code:

const [value, setValue] = React.useState(new Date("04/01/2022 12:00:00"));
const [value, setValue] = React.useState(new Date());

The first value can be used with a Date Picker, a Time Picker, or a DateTimePicker component. The components are smart enough to parse out the portion of the date they need.

The second value initializes to the current date. Both of these options are using JavaScripts Date object.

MUI DatePicker Icon

Here’s example code for changing some Date Picker icons. It was not immediately intuitive to me and I had to go searching deep in the docs. However, it makes sense for MUI to treat the composing picker icons as components.

import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
import ArrowLeftIcon from "@mui/icons-material/ArrowLeft";
import ArrowRightIcon from "@mui/icons-material/ArrowRight";

//JSX
<DatePicker
  components={{
    OpenPickerIcon: CalendarMonthIcon,
    LeftArrowIcon: ArrowLeftIcon,
    RightArrowIcon: ArrowRightIcon
  }}
/>

Here’s a screenshot of the updated icons. MUI has several calendar icons to choose from. The arrows are only slightly different than the original icons.

Custom DatePicker Icons
Custom DatePicker Icons

MUI Picker renderInput Prop

The renderInput is an interesting prop (note: it is also a required prop). It provides an opportunity to customize the text input component. However, I played with this a little and found it difficult to customize the input in a useful way, so I recommend sticking with TextField.

renderInput={(params) => {
  return <TextField {...params} />;
}}

Here’s a screenshot of some of the params being passed to the input component (the TextField).

MUI Picker RenderInput Props
MUI Picker RenderInput Props

The InputProps value seen above is controlled by the InputProps prop on the Date Picker. Here’s the value I passed to the InputProp in order to color the calendar icon blue:

InputProps={{ sx: { "& .MuiSvgIcon-root": { color: "blue" } } }}

The BEST MUI Picker Props

In addition to the excellent props mentioned above, here are three important props to be aware of:

  • views – This controls whether a user can only see a ‘day’, ‘month’, or ‘year’ view (or a combo of the three). It accepts an array of strings, i.e. views={["month"]}.
  • showDaysOutsideCurrentMonth – This Boolean controls whether days outside the month are visible in the starting and ending weeks of the month. For example, if the month starts on a Wednesday, show the preceding Sunday through Tuesday in the first row.
  • clearable – This adds a small “clear” button for resetting the picker value. Pressing the clear button will leave the picker input with an empty value. Interesting, the TypeScript typing seemed to be missing for this so I had to add //@ts-ignore above the prop.
Month view in MUI Picker
Month view in MUI Picker

Styling the MUI DatePicker

The picker components can be styling using either the styled API or the sx prop (kind of…). If you intend to use the sx prop, you actually need to use the sx prop inside of PopperProps like the below code shows:

PopperProps={{
  sx: popperSx
}}

This is because the Popper renders in a different place in the DOM tree than the TextField input of the picker component. The styling values need to be passed directly to the popper.

DatePicker Border

If you want to add border around the popper (i.e. the calendar or clock components), target the div with class MuiPaper-root using a nested selector. Here’s the code for adding border to DatePicker.

//Passed to PopperProps sx
"& .MuiPaper-root": {
  border: "1px solid black",
}

DatePicker Full Width

Setting the Date or Time pickers to use the full screen width is actually quite difficult. You can see the result below after I set width: "100%" on several of the divs within the popper. I was able to get the top area and bottom tabs to expand, but not the calendar days.

MUI DatePicker Full Width
MUI DatePicker Full Width

DatePicker Height

Date Picker height is also difficult to adjust in a useful way. You can set height at the root of the PopperProps sx value, but getting the compositional elements of the Popper to expand vertically is challenging.

DatePicker Margin and Padding

Margin and padding should be set at the root of the sx value.

//Passed to PopperProps sx
"& .MuiPaper-root": {
  padding: 2,
  marginTop: 1
}

Adding marginTop will create spacing between the Clock/Calendar portion of the component and the TextField input component.

Padding at the root of PopperProps sx creates space between any border and the interior days or clock elements.

MUI DatePicker Text Color and BackgroundColor

All the subcomponents of the pickers can be styled. With the below code I set custom background color for the padded area, the date dropdown and days area, the bottom tabs, and the day buttons. I also gave the day buttons a light gray text color.

Using MUI's DateTimePicker
DatePicker Background Color
//Passed to PopperProps sx
const popperSx: SxProps = {
  "& .MuiPaper-root": {
    backgroundColor: "rgba(120, 120, 120, 0.2)"
  },
  "& .MuiCalendarPicker-root": {
    backgroundColor: "rgba(45, 85, 255, 0.4)"
  },
  "& .MuiPickersDay-dayWithMargin": {
    color: "rgb(229,228,226)",
    backgroundColor: "rgba(50, 136, 153)"
  },
  "& .MuiTabs-root": { backgroundColor: "rgba(120, 120, 120, 0.4)" }
};

Notice the variety of nested selectors I had to create to accomplish this detailed styling. You can find these class names by examining the DOM.

Here’s how to add styling to the TextField input component.

Resources and Related Posts

The MUI Tooltip also uses PopperProps for styling.

Material-UI Picker docs

Code Sandbox Link

import * as React from "react";
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import AdapterDateDayjs from "@mui/lab/AdapterDayjs";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import DesktopTimePicker from "@mui/lab/DesktopTimePicker";
import DateTimePicker from "@mui/lab/DateTimePicker";
import DesktopDatePicker from "@mui/lab/DesktopDatePicker";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
import ArrowLeftIcon from "@mui/icons-material/ArrowLeft";
import ArrowRightIcon from "@mui/icons-material/ArrowRight";
import { SxProps } from "@mui/system";

export default function MaterialUIPickers() {
  //const [value, setValue] = React.useState(new Date("04/01/2022 12:00:00"));
  const [value, setValue] = React.useState(new Date());

  const handleChange = (newValue) => {
    setValue(newValue);
  };

  const popperSx: SxProps = {
    "& .MuiPaper-root": {
      border: "1px solid black",
      padding: 2,
      marginTop: 1,
      backgroundColor: "rgba(120, 120, 120, 0.2)"
    },
    "& .MuiCalendarPicker-root": {
      backgroundColor: "rgba(45, 85, 255, 0.4)"
    },
    "& .PrivatePickersSlideTransition-root": {},
    "& .MuiPickersDay-dayWithMargin": {
      color: "rgb(229,228,226)",
      backgroundColor: "rgba(50, 136, 153)"
    },
    "& .MuiTabs-root": { backgroundColor: "rgba(120, 120, 120, 0.4)" }
  };

  return (
    <>
      <LocalizationProvider dateAdapter={AdapterDateDayjs}>
        <Stack spacing={3}>
          <DesktopDatePicker
            label="Date"
            inputFormat="MM/DD/YYYY" //depends on date lib
            value={value}
            onChange={setValue}
            renderInput={(params) => {
              return <TextField {...params} />;
            }}
            views={["day", "month"]}
            showDaysOutsideCurrentMonth //very useful
            //@ts-ignore
            clearable //Typing seems to be missing for this
          />
          <DesktopTimePicker
            label="Time"
            value={value}
            onChange={handleChange}
            renderInput={(params) => <TextField {...params} />}
          />
          <DateTimePicker
            label="Date And Time Picker"
            value={value}
            onChange={handleChange}
            components={{
              OpenPickerIcon: CalendarMonthIcon,
              LeftArrowIcon: ArrowLeftIcon,
              RightArrowIcon: ArrowRightIcon
            }}
            InputProps={{ sx: { "& .MuiSvgIcon-root": { color: "blue" } } }}
            PopperProps={{
              sx: popperSx
            }}
            renderInput={(params) => <TextField {...params} />}
          />
        </Stack>
      </LocalizationProvider>
      <div style={{ marginTop: 50 }}>
        <a
          target="_blank"
          href="https://smartdevpreneur.com/the-ultimate-material-ui-v5-datepicker-and-timepicker-tutorial/"
        >
          Here's everything to know about styling the Date Picker!
        </a>
      </div>
    </>
  );
}
Share this post:

8 thoughts on “The Ultimate Material-UI v5 DatePicker and TimePicker Tutorial (Plus Styling!)”

  1. Man it’s amazing article, it’s help me to do my task , i read too much articles and nothing good! thank u a lot!<3

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.