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

Add Pluralization rules based on Intl.PluralRules #2020

Open
3 tasks done
ssendev opened this issue Nov 16, 2024 · 0 comments
Open
3 tasks done

Add Pluralization rules based on Intl.PluralRules #2020

ssendev opened this issue Nov 16, 2024 · 0 comments
Labels
Status: Proposal Request for comments

Comments

@ssendev
Copy link

ssendev commented Nov 16, 2024

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

@ssendev ssendev added the Status: Proposal Request for comments label Nov 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Proposal Request for comments
Projects
None yet
Development

No branches or pull requests

1 participant