Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: useDatePicker sometimes limits day of month to 30 #3256

Open
jordanoverbye opened this issue Jun 22, 2022 · 11 comments
Open

bug: useDatePicker sometimes limits day of month to 30 #3256

jordanoverbye opened this issue Jun 22, 2022 · 11 comments
Labels
enhancement New feature or request rsp:DatePicker

Comments

@jordanoverbye
Copy link

jordanoverbye commented Jun 22, 2022

🐛 Bug Report

This bug can be reproduced using the interactive demos on the useDatePicker documentation page.

When I first interact with the component I'm unable to enter any dates which have 31 as the day of the month. When I type in 31, my text is cleared and the value is set to 01.

🤔 Expected Behavior

A user should be able to enter dates that have 31 as the day of the month, for example 31st Jan 2022.

😯 Current Behavior

  1. Focus into the day segment
  2. Type in 31
  3. Day segment shows 01
  4. Enter in a month and day to get a valid date
  5. Change day of month from 01 to 31

💁 Possible Solution

  • Looks like something in useDateFieldState is the issue, but haven't had time to investigate.
  • Looks like aria-valuemax="30" is set when the component is first rendered, but after some user interaction it gets set to aria-valuemax="31"

🔦 Context

💻 Code Sample

You can also see this issue in the "styled" code sandbox examples of useDatePicker.

🌍 Your Environment

Software Version(s)
react-spectrum "@react-aria/datepicker": "3.0.0"
Browser Chrome
Operating System Mac

Full list of dependencies can be found in the package.json https://codesandbox.io/s/reverent-faraday-5nwk87?file=/package.json

🧢 Your Company/Team

N/A

🕷 Tracking Issue (optional)

N/A

@devongovett
Copy link
Member

This is because there's always a date under the hood, even when the placeholder is visible. It defaults to today's date, but can be set via the placeholderValue prop as well. You can see it if you focus a segment and press the up or down arrow keys. So, you might not be able to type 31 if the month of the placeholder only has 30 days, for example. Perhaps a little confusing.

The alternative would be to allow 31 (or the maximum across all months in a given calendar system), but then if you enter a month with fewer days later, adjust it. But the number of days in a month might still depend on the year in case of leap years, so even that might be wrong. The actual minimums and maximums can't be determined until a full date is entered, so right now we default it to today's date (or the placeholder value if provided). Not totally sure what the best behavior would be... 🤔

@RaspberryEuphoria
Copy link

I'm sorry to intrude but this issue is really exacerbated when the date format is dd-mm-yyyy, since you have to type the day before the month.

I got around it by using the placeholder value as @devongovett suggested 🙏, which I initialised as placeholderValue: toCalendarDate(new CalendarDateTime(2024, 1, 31)) (a leap year), but I was wondering if there was a more proper way to do this.

@devongovett
Copy link
Member

We discussed this as a team and we agree that the behavior should change: allow the maximum value across all months to be entered, and only constrain to the actual maximum once all fields have been entered.

This is slightly challenging because the value is always currently represented as a date even when all fields haven't yet been entered. Therefore the manipulation logic such as incrementing, decrementing, etc. is done using a date object, which only supports valid dates. So we'd need to replicate some of this logic outside the date library so it happens on each field independently instead. This will take some refactoring.

@Gekkio
Copy link

Gekkio commented Sep 1, 2022

I'd like to point out that there are two slightly different scenarios that are affected: entering a date, and replacing a date. Both have bad UX at the moment with ddmmyyyy.

Let's say we want to enter the date 31.10.2022 (October 31th, 2022).

This is how it should work in my opinion:

[  ] [  ] [    ] <- initial state
[31] [  ] [    ] <- partial date
[31] [10] [    ] <- partial date
[31] [10] [2022] <- finished!

As far as I understand, this is what the UX would be after the suggested behaviour change.
But then we have the other scenario: let's imagine we already have 01.02.2020 (February 1st, 2020) and intend to replace the whole date.

I think this is how it should work optimally from an UX point of view, at least for users using a keyboard:

[01] [02] [2020] <- initial state
[31] [02] [2020] <- full, but invalid date
[31] [10] [2020] <- full, but wrong date
[31] [10] [2022] <- finished!

The problem is that from the user's point of view entering the date is still in progress after they've typed "31", but technically we have an invalid (not partial!) date at that point and the situation is only resolved after the month has been changed. As far as I understand, the suggested behaviour change would not necessarily fix this, because it's ambiguous what "all fields have been entered" means when we have a mix of new user input and some parts of the previous value.

@gopeter
Copy link

gopeter commented Feb 3, 2023

Since we are in February now, the example here https://react-spectrum.adobe.com/react-spectrum/DateField.html also jumps directly to the month once I enter "3" in the day field

@fknop
Copy link

fknop commented Apr 13, 2023

Same issue here with dd/mm/yyyy, the behavior is very weird when setting the initial date or replacing a date.
Is there any plans on fixing this?

@snowystinger
Copy link
Member

Yes, we'd like to address this. We haven't had the time to get to it yet, but we do accept contributions. Otherwise, if you could 'thumbs up' the issue description, we do check for those when deciding what bugs to prioritize.

@snowystinger snowystinger moved this from 📋 Waiting for Sprint to 🏗 In Progress in RSP Component Milestones Jun 14, 2023
@LFDanLu LFDanLu moved this from 🏗 In Progress to 📋 Waiting for Sprint in RSP Component Milestones Sep 20, 2023
@marano
Copy link

marano commented Nov 24, 2023

@RaspberryEuphoria 's workaround works well. Only issue is that the placeholder will dictate which date is selected when you open the calendar. To avoid always opening on 1/1/2024 I have implemented onOpenChange to switch back to the current date when the calendar is opened.

const defaultPlaceholderValue = new CalendarDate(2024, 1, 1);

const [placeholderValue, setPlaceholderValue] = useState(defaultPlaceholderValue);
  
<DatePicker
  placeholderValue={placeholderValue}
  ...
  onOpenChange={(isOpen: boolean) => {
    if (isOpen) {
      const today = new Date();
      const day = getDate(today);
      const month = getMonth(today) + 1; // +1 because months are 0-indexed
      const year = getYear(today);
      setPlaceholderValue(new CalendarDate(year, month, day));
    } else {
      setPlaceholderValue(defaultPlaceholderValue);
    }
  }}
>

@Eldraed
Copy link

Eldraed commented Dec 17, 2024

Hello,
We have the same issue when using the useDatePicker hooks.

In our case, we have some consumers that wants to use the DatePicker for Birthdates or for some dates that might be easier to write than to search in the picker itself.
And since we are based in Europe, our format is dd/mm/yyyy which creates this issue (US side, you do not have any issue because when you set the month first you do not have any issue with the day segment 😛).

For now, I have implemented a similar workaround as suggested by @marano that replace the placeholderValue only if placeholderValue (or today() if none) is a date with a month that has less than 31 days in it.

It's clearly a temporary fix and we would love to have something that works perfectly for any date.

Do you guys have an idea on any projected date to fix that issue ?

Thanks 🙂

@Qnemes
Copy link

Qnemes commented Feb 17, 2025

Same weird behaviour - when I'm trying to enter days 30 or 31, it jumps to month disallowing me to finish days amount. It allows only when you provide full date and return to retype days.

@rawnly
Copy link

rawnly commented Feb 27, 2025

Same here, we're having same issue as @Qnemes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request rsp:DatePicker
Projects
Status: 📋 Waiting for Sprint
Development

No branches or pull requests