mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.12k stars 1.27k forks source link

[pickers] different onChange behaviour with date-fns adapter #8221

Open lpillonel opened 1 year ago

lpillonel commented 1 year ago

Duplicates

Latest version

Steps to reproduce 🕹

Link to live example: https://codesandbox.io/s/cocky-dubinsky-ceysq1?file=/demo.tsx

Steps:

  1. use a DatePickercomponent with AdapterDateFns
  2. Set an onChange callback

https://user-images.githubusercontent.com/29228/224657692-651eb41d-3453-4c1c-87d3-facb22e1ee06.mov

Current behavior 😯

The onChange event is triggered everytime the year changes : if I want to set 1984 for the year, onChange will be triggered for year 0001, 0019, 0198, 1984.

Expected behavior 🤔

onChange event with a new year should be triggered only when the 4 digits of the year have been capured, like with the others adapters.

Context 🔦

No response

Your environment 🌎

npx @mui/envinfo ``` System: OS: macOS 13.2.1 Binaries: Node: 18.13.0 - ~/.nvm/versions/node/v18.13.0/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 8.19.3 - ~/.nvm/versions/node/v18.13.0/bin/npm Browsers: Chrome: Not Found Edge: Not Found Firefox: Not Found Safari: 16.3 npmPackages: @emotion/react: ^11.10.0 => 11.10.6 @emotion/styled: ^11.10.0 => 11.10.6 @mui/base: 5.0.0-alpha.119 @mui/core-downloads-tracker: 5.11.12 @mui/icons-material: 5.11.11 @mui/lab: ^5.0.0-alpha.96 => 5.0.0-alpha.122 @mui/material: ^5.10.2 => 5.11.12 @mui/private-theming: 5.11.12 @mui/styled-engine: 5.11.11 @mui/styles: ^5.10.2 => 5.11.12 @mui/system: 5.11.12 @mui/types: 7.2.3 @mui/utils: 5.11.12 @mui/x-date-pickers: ^6.0.1 => 6.0.1 @types/react: ^18.0.15 => 18.0.28 react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 typescript: ^4.7.4 => 4.9.5 ```

Order ID or Support key 💳 (optional)

No response

flaviendelangle commented 1 year ago

date-fns consider that the year 0002 is a valid year, which is why we are firing onChange on this adapter and not on others.

You can check the 2nd argument passed to onChange to ignore date not passing the validation (like on the Only update when the value is valid here).

Otherwise, you can manually check the date to ignore some calls.

The expectations around the onChange behavior are very subjective and we won't be able to have something suiting everybody's needs. Are current approach is to fire onChange often but to give the tools for people to easily ignore some of these events if they want.

lpillonel commented 1 year ago

The behaviour I'm expecting is actually to have to onChange triggered only when I have entered 4 digits for the year segment. My issue is I have an autosave on my value, which is triggered on all date changes even so the user wanted to capture 2014 (and not triggering a save for 0002, 0020, 0201, while that could also be valid dates).

I also updated the codesanbox to show another inconsistency : With fr-CH locale, behaviour is not the same : display behaves like with day.js adapter (displaying "correct" year segment), but changes are still always triggered 🤔

lpillonel commented 1 year ago

@flaviendelangle : Are you sure this is expected behaviour ? If so, then ho can I get a "onChange" event only when the 4 digits of the year are entered with the dateFns adapter ?

flaviendelangle commented 1 year ago

Sorry about the delay,

It's the expected behavior if we say that the fields should reflect the library's decision. For date-fns the year 0020 is valid, so we consider it valid.

If we consider that the field can neglect the library's decision and say that the year 0020 is not valid, then we need to discuss how to let people who want to enter 0020 do it.

One smaller solution could be to pass a new argument to onChange that somehow let's you know that the user typed 20 in this section and let you reject the onChange. It's not effortless on your side, but it could be implemented quicker.