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.

  1. How to Integrate the Material-UI with React JS
  2. Create a Material-UI Custom Select Component with React js.
  3. How to Integrate the Material-UI with React JS

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.

Create a custom date picker

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

MUI X

Material-UI X V7.22.5

Click on the Date and Time Pickers.

Click on the Date Component

Date Component

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-fns. 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;

Basic date picker

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 customisation 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, along with the updated App.js page.

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 added a Clear Icon and clear state

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

update APP.js also.

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;

This code snippet is for managing a selected date using React's useState hook. Here's a short explanation:

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

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

  const handleClear = () => {
    setSelectedDate(null);
  };
  1. useState(null) initializes selectedDate with null, meaning no date is selected initially.
  2. handleValueChange(newDate) updates selectedDate with the new date when the user selects one.
  3. handleClear() resets selectedDate to null, effectively clearing the selected date.

Clear Function

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

Add a close icon with a function

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"
                     }
                 }
             }
         }
     }
 }
 />

Explanation

  • slotProps={{ textField: { ... } }}: This modifies the properties of the TextField inside the component.
  • fullWidth: true: Makes the input field stretch to the full width of its container.
  • sx={...}: Uses Material-UI's sx prop for styling.
    • "& .MuiOutlinedInput-root": Targets the root of the outlined input field.
    • border: "none": Removes the border from the input.
    • "& fieldset": { border: "none" }: Specifically removes the border from the fieldset, which wraps the input in an outlined TextField.

This ensures that the input field appears borderless, making it look cleaner or blend seamlessly with the UI.

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: Data Format and Year Format

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"
            // minDate={new Date(Date.now())}
            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"
            // 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>
      </div>
    </div>
  );
}

export default App;

MUI

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>

if yearView={true} is true

 views={yearView ? ["year"] : undefined}

Year view

Select year

Restricting Past Dates in DatePicker Using minDate

In the DatePicker component, the prop:

minDate={new Date(Date.now())}

Explanation

  • Date.now() gets the current timestamp in milliseconds.
  • new Date(Date.now()) converts it into a Date object.
  • minDate ensures that the user cannot select a date before today.

Usage

This is useful when you want to restrict past dates, such as for booking systems or scheduling events.

Customize date picker

Conclusion

With MUI DatePicker and AdapterDayjs, you can easily integrate and customize date selection in your React projects. Use styles, props, and reusable components to create a seamless user experience.

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