react-spectrum
react-spectrum copied to clipboard
Locale should probably be set from the system's Locale, not browser langauge
Provide your feedback here.
By default, react-aria's useDefaultLocale falls back to using the language from the browser. This leads to a discrepancy between a native <input type="date" /> and what we get from e.g useDateField.
For example, my browser is set to use english as the preferred language, but my system uses norwegian for locale. This causes this to happen:
Native <input type="date" />:
useDateField input:
🔦 Context
It's causing a discrepancy between the native date formats and react-aria's date formats.
💻 Code Sample
A potential change could look something like this:
// useDefaultLocale.ts#32-35
let locale = typeof window !== 'undefined' && window[localeSymbol]
|| (typeof Intl !== 'undefined' && Intl.DateTimeFormat().resolvedOptions().locale)
// @ts-ignore
|| (typeof navigator !== 'undefined' && (navigator.language || navigator.userLanguage))
|| 'en-US';
Version
latest
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?
Windows 11, OSX
to be honest, im not sure what is the expected behavior. should we default to the user’s browser settings or their system settings? maybe there was a reason for us defaulting to the browsers setting that i’m unaware of so maybe one of my team members can chime in
otherwise, if you want them to match the system settings, you could maybe call Intl.DateTimeFormat().resolvedOptions().locale and then pass it through the i18nProvider as a workaround for now
to be honest, im not sure what is the expected behavior. should we default to the user’s browser settings or their system settings? maybe there was a reason for us defaulting to the browsers setting that i’m unaware of so maybe one of my team members can chime in
There may be a good reason that I'm not seeing, but my expectation would be that the fields should match the native date-input as close as possible.
otherwise, if you want them to match the system settings, you could maybe call
Intl.DateTimeFormat().resolvedOptions().localeand then pass it through the i18nProvider as a workaround for now
Yeah, I'm doing this now, but it feels.. off setting this. We're also building this in a ui-library, so to avoid providing the locale several times we would need to override this in every consuming app, so it's a bit.. tedious. :)
We use priority of user settings: OS is the most general, then the browser, then the specific application in the browser, and so forth. Every instance that is more specific wins, if it was the other way around, then there'd be no way to change the settings from what the OS provides, and we don't want that.
I'm not sure why the native input type="date" would use the OS setting and not the browser setting first. However, there are discussions around this behavior and it appears that you can actually change the order the locale is resolved in some browsers (such as chrome) https://stackoverflow.com/questions/57666095/browser-default-locale-intl-datetimeformat-vs-navigator-language
And there's this in the spec https://html.spec.whatwg.org/multipage/input.html#input-impl-notes which isn't actually prescriptive beyond all date inputs should display the same.
I can't imagine there aren't bugs logged against the browsers for this. It would be good to track them down or log our own to see what conclusions they reached.
At this point, I'm not sure if we can change it to use Intl.DateTimeFormat().resolvedOptions().locale as it would probably be regarded as a breaking change. We might be able to make a case for matching native inputs if we think it's common to use a mix of our date picker and the native date pickers.
Is that how this issue came up? because you have both in the same application? Or are you only using one of them at a time?
We should consult the globalization team on this. I believe they might have raised something similar in the past as well. Even if the language of the website content is in a particular language, users might expect dates and numbers to be formatted according to a different setting. navigator.language also only specifies language, not region, so these are slightly different things. I could see it both ways tbh.
We use priority of user settings: OS is the most general, then the browser, then the specific application in the browser, and so forth. Every instance that is more specific wins, if it was the other way around, then there'd be no way to change the settings from what the OS provides, and we don't want that.
Yes, but the "problem" is that language doesnt necessarily equal locale. It's quite common where I work to have English language but localized formats, and it's how the laptops are given out to the users when set up initially.
At this point, I'm not sure if we can change it to use
Intl.DateTimeFormat().resolvedOptions().localeas it would probably be regarded as a breaking change. We might be able to make a case for matching native inputs if we think it's common to use a mix of our date picker and the native date pickers. Is that how this issue came up? because you have both in the same application? Or are you only using one of them at a time?
No, the opposite; it came up when we were moving away from / replacing the native inputs, and someone said that there was a discrepancy. I think the argument would be equally strong if only using your variant, since it makes it more seamless to move from the native picker to yours.
Hey all, sorry for the delay. After consulting with our globalization team, we decided not to make a change here. They pointed out that there is actually already a discrepancy between browsers:
So some browsers use the browser language preference for <input type="date"> and Intl.DateTimeFormat and others use the OS setting, and some have no distinction between them. Based on this, we think it makes sense continuing to prioritize the browser's language setting over the OS language setting. There's not a clear benefit to changing this, especially since it wouldn't work across all browsers. At least right now the behavior is consistently always the browser language.
You can also use IntlProvider to override the locale to match whatever you want, if you prefer:
<IntlProvider locale={new Intl.DateTimeFormat().resolvedOptions().locale}>
{/* your app here */}
</IntlProvider>
Fair enough. 🫤