Hacker0x01 / react-datepicker

A simple and reusable datepicker component for React
https://reactdatepicker.com/
MIT License
8.1k stars 2.24k forks source link

Not retaining invalid input creates an accessibility failure and usability issues #3789

Open mellis481 opened 2 years ago

mellis481 commented 2 years ago

Describe the bug When a date is manually entered into a DatePicker component instance, if the string entered is invalid (eg. not a valid date string, not within a specified range, etc.), the input is either cleared or reverted to the last valid date value. This is an accessibility failure of WCAG success criterion 3.3.1 Error Identification which requires invalid input to be effectively identified/communicated to users including clear instruction for remediation. Additionally, reverting the invalid value to a different value without informing the user, creates a usability issue as demonstrated in this video where an invalid value is set, the user hits ENTER, focus is changed to a new field, but the value the user entered (which he/she thought was going to be used) was not retained.

To Reproduce Steps to reproduce the behavior:

  1. Go to any react-datepicker example (use this CodeSandbox if desired).
  2. Manually enter an invalid date (either an invalid date string or a date outside a specified range).
  3. Blur the field.
  4. The invalid input is not retained.

Expected behavior The invalid input is retained for the user to see and the component exposes that it is invalid.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop:

dgreene1 commented 1 year ago

@martijnrusschen or @aij can you provide input on whether or not you would support a PR that allows users to “catch” or “hook into” an error caused by a user typing in a date that is not valid?

JanderSilv commented 1 year ago

This is a desired feature by my team as well.

dgreene1 commented 1 year ago

@martijnrusschen or @aij would you accept a PR?

martijnrusschen commented 1 year ago

@dgreene1 Yes!

dgreene1 commented 1 year ago

@martijnrusschen to be clear, we will be providing a PR that allows a user to opt-in to the ability to listen to this classification of error. We will not change default behavior. Hopefully that’s not an issue?

martijnrusschen commented 1 year ago

Sounds good! Thanks for the support.

Lumenate commented 1 year ago

@martijnrusschen @dgreene1 Hello, are there any updates on this? My team really need this behaviour controlled.

jpierson-at-riis commented 1 year ago

Possibly related: https://github.com/Hacker0x01/react-datepicker/issues/768

dgreene1 commented 1 year ago

@martijnrusschen, @aij, @Lumenate, @jpierson-at-riis we will be submitting a PR some time this quarter-- hopefully sooner. The signature for this new mechanism will be the same as onChange except it will be called onBeforeChange and it will have the unmutated text that the user entered. Basically it's onChangeRaw but you don't have to check if the user has completed their thought by checking if its after a blur event or an enter keypress.

martijnrusschen commented 1 year ago

@dgreene1 sounds good!

dgreene1 commented 1 year ago

@martijnrusschen, @aij would it be okay if we also add a doNotTryToFormatInput flag so that we keep for the user's input exactly as is for better error handling.

JanderSilv commented 11 months ago

Hey @dgreene1, could you share how this correction is going?

dgreene1 commented 11 months ago

@JanderSilv we ended up avoiding this by using our own input and avoiding theirs altogether. We still use the calendar pop up.

JanderSilv commented 11 months ago

@dgreene1 If you could provide any piece of code showing how to do it, or at least the steps to achieve this, I hadn't much luck trying to implement. I appreciate any help.

sandrina-p commented 10 months ago

Hi all. I'm facing the same need in my company. This behavior is really an Accessibility (A11Y) concern as explained above. A new prop doNotTryToFormatInput would work just fine to solve it. (or renaming it to ignoreInvalidFormat). Or even better, do a breaking-change and remove this behavior all together.

I'll be exploring a workaround for this today.

JanderSilv commented 9 months ago

Hi @sandrina-p , did you find a workaround?

sandrina-p commented 9 months ago

@JanderSilv yes I did but just for dates, not for any type of string.

For example, if the minimum date is today, and the user writes "2020-01-01", I was able to keep it. But if they type "hello", then I didn't find a way to keep it.

To keep the "2020-01-01" I used useRef in the DatePicker. I used it to add an eventListener "change" (which targes the native input), and then stored its value in my component state. Finally passed the value back to the <DatePicker through the selected prop.

JanderSilv commented 9 months ago

@sandrina-p To solve the "hello" case, I guess you can use a custom masked input. It will block the user from typing non-digits and the user wont need to type "-", just the numbers.

We use the react-number-format, but I guess any masked input library can do the job.

sandrina-p commented 9 months ago

@JanderSilv give me a codesandbox and I can try to debug it.