UNPKG

@scaleway/use-i18n

Version:
168 lines (167 loc) 4.14 kB
import { filesize } from "filesize"; import formatters from "./formatters.js"; const exponents = [ { name: "", symbol: "" }, { name: "kilo", symbol: "K" }, { name: "mega", symbol: "M" }, { name: "giga", symbol: "G" }, { name: "tera", symbol: "T" }, { name: "peta", symbol: "P" }, { name: "exa", symbol: "E" }, { name: "zetta", symbol: "Z" }, { name: "yotta", symbol: "Y" } ]; const frOctet = { plural: "octets", singular: "octet" }; const localesWhoFavorOctetOverByte = { fr: frOctet, "fr-ca": frOctet, "fr-fr": frOctet, ro: { plural: "octeți", singular: "octet" } }; const symbols = { long: { bit: { plural: "bits", singular: "bit" }, byte: { plural: "bytes", singular: "byte" } }, short: { bit: "b", byte: "B", octet: "o" } }; const compoundUnitsSymbols = { second: "ps" }; const formatShortUnit = (locale, exponent, unit, compoundUnit) => { let shortenedUnit = symbols.short[unit]; if (unit === "byte" && Object.keys(localesWhoFavorOctetOverByte).includes(locale)) { shortenedUnit = symbols.short.octet; } return `${exponent.symbol}${shortenedUnit}${compoundUnit ? compoundUnitsSymbols[compoundUnit] : ""}`; }; const formatLongUnit = (locale, exponent, unit, amount) => { let translation = symbols.long[unit]; if (unit === "byte" && Object.keys(localesWhoFavorOctetOverByte).includes(locale)) { translation = localesWhoFavorOctetOverByte[locale]; } return `${exponent.name}${formatters.getTranslationFormat( `{amount, plural, =0 {${translation.singular}} =1 {${translation.singular}} other {${translation.plural}} }`, locale ).format({ amount })}`; }; const format = ({ compoundUnit, exponent, unit, humanize = false }) => (locale, amount, { maximumFractionDigits, minimumFractionDigits, short = true, base = 10 }) => { let computedExponent = exponent; let computedValue = amount; if (humanize) { if (computedExponent) { const value = filesize(amount, { base, exponent: exponents.findIndex( (exp) => exp.name === computedExponent.name ), output: "object", round: maximumFractionDigits }); computedValue = Number.parseFloat(value.value); } else { const value = filesize(amount, { base, output: "object", round: maximumFractionDigits }); computedExponent = exponents[value.exponent]; computedValue = Number.parseFloat(value.value); } } return `${new Intl.NumberFormat(locale, { maximumFractionDigits, minimumFractionDigits }).format(computedValue)} ${short ? formatShortUnit( locale, computedExponent, unit, compoundUnit ) : formatLongUnit( locale, computedExponent, unit, computedValue )}`; }; const supportedUnits = { // bits "bits-humanized": format({ humanize: true, unit: "bit" }), "bits-per-second-humanized": format({ compoundUnit: "second", humanize: true, unit: "bit" }), ...exponents.reduce( (acc, exponent) => ({ ...acc, [`${exponent.name}bit`]: format({ exponent, unit: "bit" }), [`${exponent.name}bit-per-second`]: format({ compoundUnit: "second", exponent, unit: "bit" }), [`${exponent.name}bit-humanized`]: format({ exponent, humanize: true, unit: "bit" }), [`${exponent.name}bit-per-second-humanized`]: format({ compoundUnit: "second", exponent, humanize: true, unit: "bit" }) }), {} ), // bytes "bytes-humanized": format({ humanize: true, unit: "byte" }), ...exponents.reduce( (acc, exponent) => ({ ...acc, [`${exponent.name}byte`]: format({ exponent, unit: "byte" }), [`${exponent.name}byte-humanized`]: format({ exponent, humanize: true, unit: "byte" }) }), {} ) }; const formatUnit = (locale, number, { unit, ...options }) => supportedUnits[unit]?.(locale, number, options) ?? ""; export { formatUnit as default, supportedUnits };