Create a Custom Date Picker With React and TypeScript Using Day.js

Why not? — As it turns out, it’s pretty easy.

Pavel Pogosov
Better Programming
Published in
4 min readMay 26, 2022

In this article, we are going to create a simple react date picker from scratch. As our dates manipulation helper, we will use a library called “Day.js”. Please, don’t pay too much attention to styling. Our goal is to create a basic component, which you can modify however you want to.

So what is Day.js?

Day.js is a minimalist JavaScript library that parses, validates, manipulates, and displays dates. It’s really lightweight (only 2 kB!) and exposes quite simple API.

Why we can’t just use some library such as “react-datepicker”?

First of all, this article won’t be interesting at all, If I just show you how to install a library). In addition, I think there are some cases, which can be easily implemented without any 3rd party packages (which are usually hard to customize).

What is our final result?

What functionality do we have here?

  1. Calendar displaying dates of a current month, with names of the weekdays. Also, it can be flipped forward or backward.
  2. Functionality for selecting a specific date. By default, present-day will be selected.

Let’s get started!

Dependencies.

First of all, we need to install our dependencies. As I mentioned before, we will use Day.js and the library called “clsx”, which allows us to easily combine class names (It’s totally optional, I just prefer to use it)

App component.

Everything is quite simple. We will create a frame for our app and add a state for our calendar. Notice, that we invoke dayjs as our initial value here. It returns us the instance of the dayjs containing current date info. Also, we format the selected date and place it in the heading. Don’t worry about the import of DatePicker, we’ll implement it a little bit below.

Datepicker component

Next, we should create our datepicker root component. I’ll divide it into two separate parts.

The first part is DatePickerSelector, this is the place that contains our flip logic.

The second part DatePickerCalendar is responsible for displaying the calendar and selecting a specific date.

Our component receives two props:

  1. selectedDate is the dayjs instance, representing the chosen date.
  2. onChange is the handler that is called on clicking the date cell and gets the new date as its first argument.

Also, notice that we have another local state called shownDate. It will be responsible for displaying the proper months and years in our calendar.

DatePickerSelector component

As I mentioned before, this component will contain our flip logic. Nothing special here, we just handle our click events and increase/decrease our shownDate by month.

changeDateMonth is a function that decides whether we need to add or subtract a year as well.

DatePickerCalendar component

In order to implement this part, we need to create some helpers ahead. Firstly, let’s create an interface representing our single cell in the calendar, it will be called ICalendarCell. Additionally, we will write two more functions:

  1. getCalendarCells will get the current shown date and return an array of cells. Also, it will add days from the previous and next month to fill our calendar rows fully.
  2. getCalendarRows will return an array of rows for our calendar.

After this, we can move to our UI.

Everything is pretty straightforward here:

  1. handleSelectDate is a select date handler that takes advantage of closure and invokes onChange the needed date.
  2. rows is a memoized return value of our getCalendarRows. So it recalculates only when the shown date changes.
  3. In the 29–35 lines we render weekdays.
  4. In the 37–56 lines we render calendar days rows. Also, we attach proper class names depending on the selected date.

Thanks for reading!

I hope, you found this article useful. If you have any questions or suggestions, please leave comments. Your feedback helps me to become better.

Don’t forget to subscribe⭐️

Pavel Pogosov
Pavel Pogosov

Written by Pavel Pogosov

Senior Dev sharing web development knowledge. 100% original content. More on Twitter! 🚨 https://twitter.com/PogosovPavel

No responses yet

What are your thoughts?