Open
Description
Clear and concise description of the problem
The default pluralization rules are pretty simple and Intl.PluralRules has 97% browsersupport so it would be nice to have an implementation based on it with fallback to the current simple one. Which maybe needs revising since it can currently return a number greater than choicesLength - 1 that then crashes vue
Suggested solution
Here is an implementation that works with the current api but the implementation could be cleaner without the Proxy
const pluralOrder: Intl.LDMLPluralRule[] = [
'zero',
'one',
'two',
'few',
'many',
'other',
]
function pluralSort(a: Intl.LDMLPluralRule, b: Intl.LDMLPluralRule) {
return pluralOrder.indexOf(a) - pluralOrder.indexOf(b)
}
const pluralRules = new Proxy(
{} as {
[lang: string]:
| ((choice: number, choicesLength: number) => number)
| undefined
},
{
get: (target, prop: string) => {
if (prop in target) return target[prop]
try {
const rules = new Intl.PluralRules(prop)
const categories = rules
.resolvedOptions()
.pluralCategories.sort(pluralSort)
return (target[prop] = (choice: number, choicesLength: number) => {
const rule = rules.select(choice)
const n = categories.indexOf(rule)
return Math.min(n, choicesLength - 1)
})
} catch (e) {
target[prop] = undefined
}
},
},
)
Alternative
If shipping it by default is considered too large it could live in an extra import so that it's easy to use
import pluralRules from '@intlify/plural'
The implementation could also be cleaner if instead of an object pluralRules could be a function that receives the locale maybe it would be a factory so that it only gets called once per locale
Additional context
No response
Validations
- Read the Contributing Guidelines
- Read the Documentation
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.