Skip to content

Commit 4d1fc6d

Browse files
authored
Merge pull request #16000 from ethereum/navigator-languages
fix: highlight all browser language preferences
2 parents 87ac0ae + 2e0e912 commit 4d1fc6d

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

src/components/LanguagePicker/useLanguagePicker.tsx

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,33 @@ export const useLanguagePicker = (handleClose?: () => void) => {
1717
const { t } = useTranslation("common")
1818
const locale = useLocale()
1919

20-
// Get the preferred language for the users browser
21-
const [navLang] = typeof navigator !== "undefined" ? navigator.languages : []
2220
const locales = useMemo(() => filterRealLocales(LOCALES_CODES), [])
23-
const intlLocalePreference = useMemo(
24-
() =>
25-
locales?.reduce((acc, cur) => {
26-
if (cur.toLowerCase() === navLang.toLowerCase()) return cur
27-
if (
28-
navLang.toLowerCase().startsWith(cur.toLowerCase()) &&
29-
acc !== navLang
30-
)
31-
return cur
32-
return acc
33-
}, "") as Lang,
34-
[navLang, locales]
35-
)
21+
22+
// Find all matching browser language preferences in order
23+
const intlLocalePreferences = useMemo(() => {
24+
// Get the preferred languages for the users browser
25+
const navLangs = typeof navigator !== "undefined" ? navigator.languages : []
26+
const preferences: Lang[] = []
27+
28+
for (const navLang of navLangs) {
29+
const match = locales?.find((locale) => {
30+
// Exact match first
31+
if (locale.toLowerCase() === navLang.toLowerCase()) return true
32+
// Then partial match (e.g., 'en-US' matches 'en')
33+
if (navLang.toLowerCase().startsWith(locale.toLowerCase())) return true
34+
return false
35+
}) as Lang | undefined
36+
37+
if (match && !preferences.includes(match)) {
38+
preferences.push(match)
39+
}
40+
}
41+
42+
return preferences
43+
}, [locales])
44+
45+
// Keep the first preference for backward compatibility
46+
const intlLocalePreference = intlLocalePreferences[0] || ""
3647

3748
const languages = useMemo<LocaleDisplayInfo[]>(
3849
() =>
@@ -43,17 +54,35 @@ export const useLanguagePicker = (handleClose?: () => void) => {
4354
locale as Lang,
4455
t
4556
)
46-
const isBrowserDefault = intlLocalePreference === localeOption
47-
return { ...displayInfo, isBrowserDefault }
57+
const isBrowserDefault = intlLocalePreferences.includes(
58+
localeOption as Lang
59+
)
60+
return {
61+
...displayInfo,
62+
isBrowserDefault,
63+
}
4864
})
4965
.sort((a, b) => {
50-
// Always put the browser's preferred language first
51-
if (a.localeOption === intlLocalePreference) return -1
52-
if (b.localeOption === intlLocalePreference) return 1
66+
const aPreferenceIndex = intlLocalePreferences.indexOf(
67+
a.localeOption as Lang
68+
)
69+
const bPreferenceIndex = intlLocalePreferences.indexOf(
70+
b.localeOption as Lang
71+
)
72+
73+
// First, sort by browser preferences (all browser preferences come first)
74+
if (a.isBrowserDefault && !b.isBrowserDefault) return -1
75+
if (!a.isBrowserDefault && b.isBrowserDefault) return 1
76+
77+
// If both are browser preferences, sort by preference order
78+
if (a.isBrowserDefault && b.isBrowserDefault) {
79+
return aPreferenceIndex - bPreferenceIndex
80+
}
81+
5382
// Otherwise, sort alphabetically by source name using localeCompare
5483
return a.sourceName.localeCompare(b.sourceName, locale)
5584
}) || [],
56-
[intlLocalePreference, locale, locales, t]
85+
[intlLocalePreferences, locale, locales, t]
5786
)
5887

5988
const intlLanguagePreference = languages.find(

0 commit comments

Comments
 (0)