Custom React Calendar Picker

When it comes to Javascript frameworks and open-sourced libraries, there is a ton of information out there. Consider this one more article tutorial for your digital trapper-keeper of tools!
Most applications include some sort of calendar date/time picker, whether it’s a form, filter, or other general application feature. One option is to go with the native operating system’s (OS), but where’s the fun in that? This can also be disruptive to the user’s experience because it will often introduce yet another popup for users to click through.
This article does a really good job at outlining 13 Date Pickers available to React JS. We’re going to specifically discuss react-date-picker
. This particular picker avoids using a modal and allows for customization to the extent that the calendar will look like it belongs to your website.
To begin, you will need to install both npm
(if you don’t have it already) and react-date-picker
.
npm install npm@latest -g
npm install --save react-date-picker
Like every other open-sourced library, you will need to import react-date-picker
at the top of whatever file/component you will be using it on.
import DatePicker from 'react-date-picker';
Next, you want to establish state values for your start and end dates so the pickers have something to update. If you’re using React State Hooks, it would look something like this:
const [startDate, setStartDate] = useState('');
const [endDate, setEndDate] = useState('');
If you’re new to react state hooks, what we defined above gives you a reference variable as well as a function used for updating the state. For example, startDate
can be referenced like any other variable later in the code. If we want to update startDate
to be today, we would do something like: setStartDate(new Date())
.
Now that the state is defined, we can put the actual date picker on the screen!
<DatePicker
calendarIcon={null}
className={'datepicker'}
value={startDate}
onChange={(date) => setStartDate(date)}
/><DatePicker
calendarIcon={null}
className={'datepicker'}
value={endDate}
onChange={(date) => setEndDate(date)}
/>
And just like that, you will have start and end date pickers, and you can reference their values with startDate
and endDate
. It’s that easy!
There are a couple of things we need to do in order to make sure these pickers are good enough for production. First, it’s important to look at the full scope of what a DatePicker
can do. There are quite a few fields not listed in their documentation that might be important to your user experience. For example, you may want to use month, day, or year placeholders.
<DatePicker
calendarIcon={null}
className={'datepicker'}
value={startDate}
monthPlaceholder={'MM'}
dayPlaceholder={'DD'}
yearPlaceholder={'YYYY'}
minDate={new Date{}}
onChange={(date) => handleChange(date)}
/>
More fields are listed here.
Another facet of the calendar picker that must be considered is this: What happens when a user manually enters a date?
This picker, unfortunately, does not validate any data added by a user, so someone could technically come to your website and enter 13/40/2000 and the picker would consider this valid. You will need to add validation onChange
that makes sure a user is entering a month between 1–12, an appropriate day, and a year that is four (4) characters long. If you have start and end date pickers, it would also be good to verify that the startDate
occurs before the endDate
. Another open-sourced library, date-fns is good for parsing, validating, and formatting dates. If you have any experience with Moment JS, this is a very similar tool — just lighter weight (you only import the functions you want to use).
Last but not least, we’re going to want to customize the date picker. You may have noticed that the DatePicker
component has a field called className
where I’ve passed it datepicker
, which is a class that I have named and defined in my .scss file. This field can be especially useful when you have more than one picker that you’d like to style consistently. You can also use the style accessors below to update different parts of the picker.
Remove the border from the picker inputs.
.react-date-picker__wrapper { border: 0px solid white !important;
}
Change the color of the “X” button.
.react-date-picker__button__icon { stroke: gray !important;
}
Change the style of today’s date in the calendar.
.react-calendar__tile--now { background: white !important; border: 1px solid yellow;
}
Change the style of the selected date (in the calendar view).
.react-calendar__tile--active { background: yellow !important; color: black !important;
}
Change the style of weekend dates (the calendar auto-highlights these, and I wanted to treat weekends like any other day).
.react-calendar__month-view__days__day--weekend { color: black !important background-color: white !important;
&:hover {
background-color: blue !important;
}}
Change the hover for date tiles.
.react-calendar__tile:hover { background-color: blue !important;
}
Add a box-shadow to the calendar. I like to use this box-shadow generator.
.react-date-picker__calendar { webkit-box-shadow: 0px 4px 14px 0px rgba(0, 0, 0, 0.34);
moz-box-shadow: 0px 4px 14px 0px rgba(0, 0, 0, 0.34);
box-shadow: 0px 4px 14px 0px rgba(0, 0, 0, 0.34);}
Change the color border of date inputs (manual entry).
.react-date-picker__inputGroup__input:invalid { background: rgba(235, 215, 0, 0.4);
}
Increase the size of date inputs.
input[name="day"], input[name="month"] { width: 20px !important;
text-align: center !important;
}input[name="year"] {
width: 50px !important;
text-align: center;}
Customize the actual input users see before clicking the calendar. Remember that datepicker
class I had applied to the pickers earlier?
.datepicker { border-radius: 30px;
outline: none;
font-size: 60px;
border: 0px;
padding: 0.5rem 1rem;
text-align: center;
font-style: italic;
color: gray;
margin-left: 1.5rem;
width: 250px;
background-color: white; ::placeholder {
color: #b8b8b8;
}}
You now have your own custom date picker! Get picking!