Skip to content

Commit c57d3b8

Browse files
authored
fix(i18n): fallback on missing plural translation (#860)
1 parent 146963a commit c57d3b8

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

config/i18n.ts

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,26 @@ export const countryLocaleVariants: Record<string, (LocaleObjectData & { country
7878
],*/
7979
}
8080

81+
function createPluralRule(locale: string, mapping: Record<string, number>) {
82+
return (choice: number, choicesLength: number) => {
83+
const name = new Intl.PluralRules(locale).select(choice)
84+
const plural = mapping[name] || 0
85+
86+
// In case translation doesn't have all plural forms, use the last available form
87+
if (plural > choicesLength - 1) {
88+
if (import.meta.dev) {
89+
// oxlint-disable-next-line no-console -- warn logging
90+
console.warn(
91+
`Plural form index ${plural} for choice ${choice} exceeds available forms ${choicesLength} for locale ${locale}.`,
92+
)
93+
}
94+
return choicesLength - 1
95+
}
96+
97+
return plural
98+
}
99+
}
100+
81101
const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: string }))[] = [
82102
{
83103
code: 'en',
@@ -89,10 +109,7 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
89109
file: 'ar.json',
90110
name: 'العربية',
91111
dir: 'rtl',
92-
pluralRule: (choice: number) => {
93-
const name = new Intl.PluralRules('ar-EG').select(choice)
94-
return { zero: 0, one: 1, two: 2, few: 3, many: 4, other: 5 }[name]
95-
},
112+
pluralRule: createPluralRule('ar-EG', { zero: 0, one: 1, two: 2, few: 3, many: 4, other: 5 }),
96113
},
97114
{
98115
code: 'az-AZ',
@@ -148,10 +165,7 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
148165
code: 'hu-HU',
149166
file: 'hu-HU.json',
150167
name: 'Magyar',
151-
pluralRule: (choice: number) => {
152-
const name = new Intl.PluralRules('hu-HU').select(choice)
153-
return { zero: 0, one: 0, two: 1, few: 1, many: 1, other: 1 }[name]
154-
},
168+
pluralRule: createPluralRule('hu-HU', { zero: 0, one: 0, two: 1, few: 1, many: 1, other: 1 }),
155169
},
156170
{
157171
code: 'zh-CN',
@@ -197,21 +211,13 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
197211
code: 'ru-RU',
198212
file: 'ru-RU.json',
199213
name: 'Русский',
200-
pluralRule: (choice: number) => {
201-
const name = new Intl.PluralRules('ru-RU').select(choice)
202-
return { zero: 2, one: 0, two: 1, few: 1, many: 2, other: 3 }[name]
203-
},
214+
pluralRule: createPluralRule('ru-RU', { zero: 2, one: 0, two: 1, few: 1, many: 2, other: 3 }),
204215
},
205216
{
206217
code: 'uk-UA',
207218
file: 'uk-UA.json',
208219
name: 'Українська',
209-
pluralRule: (choice: number) => {
210-
if (choice === 0) return 0
211-
212-
const name = new Intl.PluralRules('uk-UA').select(choice)
213-
return { zero: 0, one: 1, two: 0, few: 2, many: 3, other: 4 }[name]
214-
},
220+
pluralRule: createPluralRule('uk-UA', { zero: 0, one: 1, two: 0, few: 2, many: 3, other: 4 }),
215221
},
216222
/*{
217223
code: 'ru-RU',
@@ -226,10 +232,7 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
226232
code: 'cs-CZ',
227233
file: 'cs-CZ.json',
228234
name: 'Čeština',
229-
pluralRule: (choice: number) => {
230-
const name = new Intl.PluralRules('cs-CZ').select(choice)
231-
return { zero: 2, one: 0, two: 1, few: 1, many: 2, other: 2 }[name]
232-
},
235+
pluralRule: createPluralRule('cs-CZ', { zero: 2, one: 0, two: 1, few: 1, many: 2, other: 2 }),
233236
} /*
234237
{
235238
code: 'pl-PL',
@@ -287,12 +290,7 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
287290
code: 'pl-PL',
288291
file: 'pl-PL.json',
289292
name: 'Polski',
290-
pluralRule: (choice: number) => {
291-
if (choice === 0) return 0
292-
293-
const name = new Intl.PluralRules('pl-PL').select(choice)
294-
return { zero: 0, one: 1, two: 0, few: 2, many: 3, other: 4 }[name]
295-
},
293+
pluralRule: createPluralRule('pl-PL', { zero: 0, one: 1, two: 0, few: 2, many: 3, other: 4 }),
296294
},
297295
{
298296
code: 'pt-BR',

0 commit comments

Comments
 (0)