@scaleway/use-i18n
Version:
A small hook to handle i18n
178 lines (177 loc) • 4.09 kB
JavaScript
import formatters from "./formatters.js";
import { filesize } from "filesize";
//#region src/formatUnit.ts
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.toString());
} else {
const value = filesize(amount, {
base,
output: "object",
round: maximumFractionDigits
});
computedExponent = exponents[value.exponent];
computedValue = Number.parseFloat(value.value.toString());
}
}
const exp = computedExponent;
return `${new Intl.NumberFormat(locale, {
maximumFractionDigits,
minimumFractionDigits
}).format(computedValue)} ${short ? formatShortUnit(locale, exp, unit, compoundUnit) : formatLongUnit(locale, exp, unit, computedValue)}`;
};
const supportedUnits = {
"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-humanized": format({
humanize: true,
unit: "byte"
}),
"bytes-per-second-humanized": format({
compoundUnit: "second",
humanize: true,
unit: "byte"
}),
...exponents.reduce((acc, exponent) => ({
...acc,
[`${exponent.name}byte`]: format({
exponent,
unit: "byte"
}),
[`${exponent.name}byte-per-second`]: format({
compoundUnit: "second",
exponent,
unit: "byte"
}),
[`${exponent.name}byte-humanized`]: format({
exponent,
humanize: true,
unit: "byte"
})
}), {})
};
const formatUnit = (locale, number, { unit, ...options }) => supportedUnits[unit]?.(locale, number, options) ?? "";
//#endregion
export { formatUnit as default, supportedUnits };