DEV Community

Cover image for A React library for Y-M-D dropdown date picker
Yuichiro Tachibana (Tsuchiya)
Yuichiro Tachibana (Tsuchiya)

Posted on • Originally published at whitphx.info on

A React library for Y-M-D dropdown date picker

I created react-ymd-date-select, a React library for Year, Month, and Day dropdown UI.

react-ymd-date-select sample screenshot

whitphx/react-ymd-date-select - GitHub

We sometimes need Y-M-D dropdown UI like the screenshot above rather than calendar UI. For example, when asking users to select their birth dates, Y-M-D dropdown is preferable because calendar widgets are usually difficult to seek to far old years, and conversely, its benefits such as intuitively showing days-of-week are not needed.

I actually encountered such a situation, however, I could not find any existing packages that meet my needs. In turn, building it by myself looks simple, but actually, there are some nuts as below.

  • Generating the arrays of year, month, and day numbers and labels.
  • Validating the combination of Y-M-D. For example, 2022-02-29 (Feb 29, 2022) is an invalid combination - that date does not exist.
  • Combining the 3 values from Y, M, D <select >s into one date string, and integrating it with the form component state or form library, e.g. React Hook Form through value and onChange props.

And sometimes there come more requirements like

  • To set the default year.
  • To show only year and month selects (hide the day dropdown).

So, to handle these, I made a library react-ymd-date-select.

With the useDateSelect() hook provided by this library, you can create original Y-M-D components like the sample below, focusing on the view behavior as cumbersome logic has been encapsulated into the hook.

The value prop and the argument of onChange() are string formatted in yyyy-MM-DD, which is ISO8601 format, and the same as the value of the native <input type="date" />. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date#value

See the demo page for more information.

import { useState } from "react";
import { useDateSelect } from "react-ymd-date-select";

interface CustomDateSelectProps {
  onChange: (value: string) => void;
  value: string;
}
function CustomDateSelect(props: CustomDateSelectProps) {
  const dateSelect = useDateSelect(props.value, props.onChange);

  return (
    <>
      <input
        type="date"
        value={dateSelect.dateValue || ""}
        onChange={dateSelect.onDateChange}
      />
      <label>
        Year
        <select value={dateSelect.yearValue} onChange={dateSelect.onYearChange}>
          {dateSelect.yearOptions.map((yearOption) => (
            <option key={yearOption.value} value={yearOption.value}>
              {yearOption.label}
            </option>
          ))}
        </select>
      </label>
      <label>
        Month
        <select
          value={dateSelect.monthValue}
          onChange={dateSelect.onMonthChange}
        >
          {dateSelect.monthOptions.map((monthOption) => (
            <option key={monthOption.value} value={monthOption.value}>
              {monthOption.label}
            </option>
          ))}
        </select>
      </label>
      <label>
        Day
        <select value={dateSelect.dayValue} onChange={dateSelect.onDayChange}>
          {dateSelect.dayOptions.map((dayOption) => (
            <option key={dayOption.value} value={dayOption.value}>
              {dayOption.label}
            </option>
          ))}
        </select>
      </label>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
altovoy profile image
Luis Alejandro Torres Ibarra

This library is great!

Helped me so much in my DropdownCalendar implementation, i has only a recommendation, in month & year change would be interesting change the day options array & the current selected day.
I made a small adaptation of the hook in React, you can see that in this github gist

Thanks for your incredible work!

Collapse
 
whitphx profile image
Yuichiro Tachibana (Tsuchiya)

Hi, thank you for the comment!
I understand your point, and that's what I also had been thinking too.
At that time, I didn't implement it because I thought there would be some UX flaw like the following:

  1. The user wants to input 2022/01/31, for example.
  2. But the user selected 2022/02/31 as a mistake.
  3. Then the day is cleared, so the user will have to select the day again after selecting the correct month.

So I implemented only checking the invalid combinations of Y-M-D and in that case returning null from the hook so that indicating an error can be implemented on the component layer.

Clearing the day selection can also be a good option, but I could not put it in the core code yet.

Implementation of a correct error message is still at a ticket though: github.com/whitphx/react-ymd-date-...

Collapse
 
ayselmammadova profile image
Aysel Mammadova

Hi, thank you for the library! I need some help. Can i change first year on "useDateSelect" ?

Collapse
 
whitphx profile image
Yuichiro Tachibana (Tsuchiya) • Edited

Yes, it accepts some options as an object via its third argument and it includes the firstYear option (and lastYear too) as below (Ref github.com/whitphx/react-ymd-date-...)

useDateSelect(value, onChange, { firstYear: 2000 });
Enter fullscreen mode Exit fullscreen mode