hypeserver / react-date-range

A React component for choosing dates and date ranges.
MIT License
2.57k stars 658 forks source link

feature/touchscreen-friendly #608

Open jsweet-dev opened 1 year ago

jsweet-dev commented 1 year ago

Types of changes

I've added touch event handlers to the DayCell component to make date range selection more user friendly on touchscreen devices.

Put an x in the boxes that apply

Description

Previously, when using a touchscreen device it was difficult to select a range of dates. It was necessary to open the DateRangePicker tap the start date of the desired range (which would then close the picker), then reopen the DateRangePicker, tap the end date input box at the top, then tap the desired end date to select the range.

With this enhancement, you open the DateRangePicker, begin by touching and holding your finger on the desired start date (or simply tap for a single day, rather than a range). Next, to select a range, swipe/drag to the desired end date. When you lift your finger to end the touch interaction, the selected date range is set.

You can easily see the selected dates change as you interact with the calendar as the selection is highlighted just as it is when using a mouse.

Methodology

To accomplish this enhancement, I am using document.elementsFromPoint with coordinates from the touchmove events to emulate the mouseenter behavior. Unlike mouse events, touch events do not retarget as the touch point is moved over different elements, it stays anchored to the element at the first touch point (the start day of the range being selected). Because of this, as the touch is moved and when the touch ends, it is the start day that is the target of the fired events and that will call the onDragSelection... functions (using the mouse... aliases from the props). So, I needed a way for the first selected day to be aware of the date that the touch was currently over and where it ended. I thought about making changes in a parent component that had access to all the child DayCells, but instead decided to add a data-day attribute to each DayCell button which the starting day (sibling element) could access. This seemed to be more consistent with the existing mouse handling and involve fewer code changes.

Review

I have done local testing using Chrome developer tools using device emulation. I've also run yarn run lint and yarn run test and did not get any issues or errors related to this code (there were some warnings about babylon being deprecated, no license field in package.json, and updating caniuse-lite, but these were not part of the work in this branch and all tests passed).

Still, any review and feedback on this work is welcome and appreciated!

Thanks!

Related Issue: #578