adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.63k stars 1.09k forks source link

[useDateRangePickerState] Date ranges that cross unavailable dates do not trigger the invalid state #5302

Open mstanaland opened 11 months ago

mstanaland commented 11 months ago

Provide a general summary of the issue here

Using a date range picker built using the useDateRangePickerState and useDateRangePicker hooks, a keyboard user can use the DateFields to enter a date range that crosses a day marked as unavailable using the isDateUnavailable prop without triggering the invalid state.

The range is correctly considered invalid if the start or end date is unavailable, but not if the unavailable date is in the middle of the range. This is true regardless of the value of allowsNonContiguousRanges.

The behavior of selecting date using the popup calendar is correct: It does not allow the user to select a range that crosses an unavailable day.

example

๐Ÿค” Expected Behavior?

I would expect state.isInvalid to be true if the state.value range included an unavailable date.

๐Ÿ˜ฏ Current Behavior

state.isInvalid is false when an unavailable day falls in the middle of the state.value range.

๐Ÿ’ Possible Solution

No response

๐Ÿ”ฆ Context

We need to accurately show the validation state of the input.

๐Ÿ–ฅ๏ธ Steps to Reproduce

Here is a fork of the Tailwind CSS styled example modified to show the incorrect validation state: https://codesandbox.io/s/allowsnoncontiguousranges-bug-tyckst?file=/src/App.js

Version

react-aria@3.29.1, react-stately@3.27.1

What browsers are you seeing the problem on?

Firefox, Chrome, Safari, Microsoft Edge

If other, please specify.

No response

What operating system are you using?

MacOS 13.6

๐Ÿงข Your Company/Team

No response

๐Ÿ•ท Tracking Issue

No response

LFDanLu commented 11 months ago

Perhaps we could expand the invalid value check here to automatically catch if a range contains a unavailable date and allowsNonContiguousRanges is false. Not sure if this proved problematic in the past since https://react-spectrum.adobe.com/react-aria/useDateRangePicker.html#unavailable-dates implies that was intentionally left to the user to implement for the field itself via the isInvalid prop, perhaps to give full control to the user? @devongovett do you remember any reasons behind the above choice?

devongovett commented 11 months ago

I think the problem was that we'd have to loop through every possible date to determine if there is any intersection. It would be more efficient to do this outside the component where you might have the unavailable dates stored as ranges. There is an example of this in the docs: https://react-spectrum.adobe.com/react-spectrum/DateRangePicker.html#unavailable-dates