@scaleway/use-i18n
Version:
A small hook to handle i18n
168 lines (167 loc) • 4.14 kB
JavaScript
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
};