browsertrix/frontend/src/utils/number.ts
Emma Segal-Grossman c5b808ba40
Ensure dates are formatted with the current app locale (and not browser default) (#1697)
### Motivation

While using the browser default locale is often good enough, we probably
want more full control over locales, especially when we allow users to
choose their own locale — it's a poor experience to not have dates and
numbers formatted consistently with your chosen locale.

### Changes

Ensures (almost) all instances of `<sl-format-date>` as well as `Intl.*`
have the correct locale passed into them from our Lit localization
system.

The one exception here is in `frontend/src/utils/number.ts` where
ordinal suffixes aren't localized, so the locale is hardcoded to `en` —
I'll revisit this in the future.
2024-04-20 16:30:33 -04:00

37 lines
888 B
TypeScript

/**
* Internationalized number formatter
* Usage:
* ```ts
* const formatter = numberFormatter()
* formatter.format(10000); // 10,000
* formatter.format(10, { ordinal: true }); // 10th
* ```
**/
export function numberFormatter(
locales?: string | string[],
opts?: Intl.NumberFormatOptions,
) {
const numFormat = new Intl.NumberFormat(locales, opts);
// TODO localize
const pluralRules = new Intl.PluralRules("en", { type: "ordinal" });
const suffixes = new Map<Intl.LDMLPluralRule, string>([
["one", "st"],
["two", "nd"],
["few", "rd"],
["other", "th"],
]);
const format = (n: number, opts: { ordinal?: boolean } = {}) => {
if (opts.ordinal) {
const rule = pluralRules.select(n);
const suffix = suffixes.get(rule);
return `${numFormat.format(n)}${suffix}`;
}
return numFormat.format(n);
};
return { format };
}