Create a Material-UI Custom Date Picker with React js.

In this article, I'll cover How to create a custom date picker in material-ui.

I have already explained How to Integrate the Material-UI with the React JS link here.

If you're a beginner, I highly recommend referring to the How to Integrate Material-UI with React.js article. It provides a step-by-step guide to setting up a React.js application with Material-UI. The article covers everything from configuring the Node.js environment and creating a new React app using create-react-app to installing Material-UI, Google Web Fonts, and Font Icons. Each step is explained in detail with clear instructions and illustrations.

Now I will explain how to create a custom date picker in material-ui.

Material-UI

Picture 1. Material-UI X V7.22.5

Click on the Date and Time Pickers.

Click on the Date Component.

Date Component

Picture 2. Material-UI X -DatePicker

Material-UI (MUI) DatePicker

If you're using Material-UI, its DatePicker component is a common choice.

The @mui/x-date-pickers library requires a specific version of date-fn's. Ensure you install it as a dependency.

npm install @mui/x-date-pickers
npm install date-fns
npm install date-fns@latest

In your project directory, navigate to the src folder and create a new folder named Mui_Component.

Inside the Mui_Component folder, create the CustomDatePicker.jsx, and define your component using either function.

import * as React from "react";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import TextField from "@mui/material/TextField";

export default function BasicDatePicker({ selectedDate, setSelectedDate, Picker_name }) {
  return (
    <LocalizationProvider dateAdapter={AdapterDateFns}>
      <DatePicker
        label={Picker_name}
        value={selectedDate}
        onChange={(newValue) => setSelectedDate(newValue)}
        renderInput={(params) => <TextField {...params} />}
      />
    </LocalizationProvider>
  );
}

Mui_Component folder, and the CustomBasicDatePicker.jsx page created.

App. js page

import { useState } from "react";
import "./App.css";
import BasicDatePicker from "./Mui_Component/CustomBasicDatePicker";
import { format } from "date-fns";

function App() {
  const [selectedDate, setSelectedDate] = useState(null);

  return (
    <div className="App">
      <div className="App-header">
        <div>
          <h5>{"MUI - Basic Date Picker"}</h5>
        </div>
        <BasicDatePicker
          selectedDate={selectedDate}
          setSelectedDate={setSelectedDate}
          Picker_name="Select a date"
        />
        <h6>
          {selectedDate
            ? format(new Date(selectedDate), "dd-MM-yyyy")
            : "No date selected"}
        </h6>
      </div>
    </div>
  );
}

export default App;

Date picker

Picture 3. Mui BasicDatePicker

Now I'm going to customize this DatePicker.

Customise MUI DatePicker with AdapterDayjs

Material-UI (MUI) provides powerful components, including a DatePicker, to enhance React applications. This guide covers how to install and use MUI's DatePicker with AdapterDayjs, along with customization options for a better user experience.

1. Installing Dependencies

To use MUI DatePicker, you need to install the required dependencies. Run the following command in your React project.

npm install @mui/x-date-pickers dayjs

2. Importing Required Components

Before using the DatePicker, import the necessary components in your React file.

import React from "react";
import { IconButton, Stack } from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import ClearIcon from "@mui/icons-material/Clear";

3. Modify my previous Basic DatePicker Component

Below is a simple modified DatePicker implementation with props.

import React from "react";
import { IconButton, Stack } from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import ClearIcon from "@mui/icons-material/Clear";

const CustomDatePicker = ({ selectedDate, onChange, label, onClick }) => {
  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <Stack direction="row" spacing={1} alignItems="center">
        <DatePicker
          label={label}
          value={selectedDate}
          onChange={(newValue) => onChange(newValue)}
          slotProps={{
            textField: { fullWidth: true },
          }}
        />
        {selectedDate && (
          <IconButton onClick={onClick}>
            <ClearIcon />
          </IconButton>
        )}
      </Stack>
    </LocalizationProvider>
  );
};

export default CustomDatePicker;

Now we have added a clear icon and a clear state.

{selectedDate && (
  <IconButton onClick={onClick}>
    <ClearIcon />
  </IconButton>
)}

Basic Date Picker

Add a close icon with a function

Below is a simple modified DatePicker implementation with props, along with the updated App.js page.

Now we have added a clear icon and a clear state.

import { useState } from "react";
import "./App.css";
import CustomDatePicker from "./Mui_Component/BasicDatePicker";
import { format } from "date-fns";

function App() {
  const [selectedDate, setSelectedDate] = useState(null);

  const handleValueChange = (newDate) => {
    setSelectedDate(newDate);
  };

  const handleClear = () => {
    setSelectedDate(null);
  };

  return (
    <div className="App">
      <div className="App-header">
        <div>
          <h5>{"MUI - Basic Date Picker"}</h5>
        </div>
        <div>
          <CustomDatePicker
            label="Select Date"
            selectedDate={selectedDate}
            onChange={handleValueChange}
            onClick={handleClear}
          />
          <h6>
            {selectedDate
              ? format(new Date(selectedDate), "dd/MM/yyyy")
              : "No date selected"}
          </h6>
        </div>
      </div>
    </div>
  );
}

export default App;

Clear Function

const handleClear = () => {
    setSelectedDate(null);
  };

Advanced Customizing the DatePicker

You can customize the DatePicker using the sx prop and Material-UI styling.

import React from "react";
import { IconButton, Stack } from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import ClearIcon from "@mui/icons-material/Clear";
import dayjs from "dayjs";

const CustomDatePicker = ({
  selectedDate,
  name,
  variant,
  format,
  margin,
  minDate,
  disabled,
  onChange,
  onClick,
  yearView,
  label,
}) => {
  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <div
        style={{
          padding: "10px",
          backgroundColor: "#f9f9f9",
          borderRadius: "8px",
          display: "inline-block",
          boxShadow: "0px 4px 6px rgba(0, 0, 0, 0.1)",
        }}
      >
        <Stack direction="row" spacing={1} alignItems="center">
          <DatePicker
            label={label}
            name={name}
            value={selectedDate ? dayjs(selectedDate) : null}
            disabled={disabled}
            variant={variant}
            format={format}
            margin={margin}
            minDate={minDate ? dayjs(minDate) : null}
            onChange={(newDate) => onChange(newDate)}
            views={yearView ? ["year"] : undefined}
            slotProps={{
              textField: {
                fullWidth: true,
                sx: {
                  "& .MuiOutlinedInput-root": {
                    border: "none",
                    "& fieldset": { border: "none" },
                  },
                },
              },
            }}
          />
          {selectedDate && (
            <IconButton onClick={onClick}>
              <ClearIcon />
            </IconButton>
          )}
        </Stack>
      </div>
    </LocalizationProvider>
  );
};

export default CustomDatePicker;

1. Removing the Border and Adding Custom Styles

<DatePicker
            label={label}
            name={name}
            value={selectedDate ? dayjs(selectedDate) : null}
            onChange={(newDate) => onChange(newDate)}
            views={yearView ? ["year"] : undefined}
            slotProps={{
              textField: {
                fullWidth: true,
                sx: {
                  "& .MuiOutlinedInput-root": {
                    border: "none",
                    "& fieldset": { border: "none" }
                  }
                }
              }
            }}
          />

2. Styling the Container

To wrap the DatePicker inside a styled container.

<div
  style={{
    padding: "10px",
    backgroundColor: "#f9f9f9",
    borderRadius: "8px",
    display: "inline-block",
    boxShadow: "0px 4px 6px rgba(0, 0, 0, 0.1)",
  }}
>
  <DatePicker />
</div>

Using a Custom DatePicker Component

import { useState } from "react";
import "./App.css";
import CustomDatePicker from "./Mui_Component/CustomDatePicker";
import { format } from "date-fns";

function App() {
  const [selectedDate, setSelectedDate] = useState(null);
  const [selectedYear, setSelectedYear] = useState(null);

  const handleValueChange = (newDate) => {
    setSelectedDate(newDate);
  };

  const handleClear = () => {
    setSelectedDate(null);
  };

  const handleYearValueChange = (value) => {
    setSelectedYear(value);
  };

  const handleYearClear = () => {
    setSelectedYear(null);
  };

  return (
    <div className="App">
      <div className="App-header">
        <div>
          <h5>{"MUI - Basic Date Picker"}</h5>
        </div>
        <div>
          <CustomDatePicker
            label="Select Date"
            id="BasicDateDate"
            title="Basic Date Picker"
            arialabel="Basic Date Picker"
            variant="inline"
            format="DD/MM/YYYY" // Format corrected for dayjs compatibility
            yearView={false}
            margin="normal"
            autoOk={true}
            selectedDate={selectedDate}
            onChange={handleValueChange}
            onClick={handleClear}
          />
          <h6>
            {selectedDate
              ? format(new Date(selectedDate), "dd/MM/yyyy")
              : "No date selected"}
          </h6>
        </div>
        <div>
          <CustomDatePicker
            label="Select Year"
            id="BasicDateYear"
            title="Basic Date Picker"
            arialabel="Basic Date Picker"
            variant="inline"
            format="YYYY" // Format corrected for dayjs compatibility
            yearView={true}
            margin="normal"
            autoOk={true}
            selectedDate={selectedYear}
            onChange={handleYearValueChange}
            onClick={handleYearClear}
          />
          <h6>
            {selectedYear
              ? format(new Date(selectedYear), "dd/MM/yyyy")
              : "No date selected"}
          </h6>
        </div>
      </div>
    </div>
  );
}

export default App;

Displaying Only Year Selection

To allow users to select only a year, modify the views prop.

<div>
  <CustomDatePicker
    label="Select Year"
    id="BasicDateYear"
    title="Basic Date Picker"
    arialabel="Basic Date Picker"
    variant="inline"
    format="YYYY" // Format corrected for dayjs compatibility
    yearView={true}
    margin="normal"
    // minDate={new Date(Date.now())}
    autoOk={true}
    selectedDate={selectedYear}
    onChange={handleYearValueChange}
    onClick={handleYearClear}
  />
  <h6>
    {selectedYear
      ? format(new Date(selectedYear), "dd/MM/yyyy")
      : "No date selected"}
  </h6>
</div>

MUI

Up Next
    Ebook Download
    View all
    Learn
    View all
    Globally based Software Developing & Data Processing Company