26 lines
1.0 KiB
JavaScript
26 lines
1.0 KiB
JavaScript
// Locale-aware number formatting with compact notation for big values.
|
|
|
|
export function createFormatter(locale) {
|
|
const make = (options) => new Intl.NumberFormat(locale, options);
|
|
const decimals = make({ maximumFractionDigits: 2 });
|
|
const integer = make({ maximumFractionDigits: 0 });
|
|
const fixed2 = make({ minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
const compact = make({ notation: 'compact', maximumFractionDigits: 2 });
|
|
const scientific = make({ notation: 'scientific', maximumFractionDigits: 2 });
|
|
|
|
function number(n) {
|
|
if (!Number.isFinite(n)) return '∞';
|
|
const abs = Math.abs(n);
|
|
if (abs < 1000) return Number.isInteger(n) ? integer.format(n) : decimals.format(n);
|
|
if (abs < 1e6) return integer.format(n);
|
|
return abs < 1e15 ? compact.format(n) : scientific.format(n);
|
|
}
|
|
|
|
/** Amounts of money: always two decimals while small. */
|
|
function money(n) {
|
|
return Math.abs(n) < 1000 ? fixed2.format(n) : number(n);
|
|
}
|
|
|
|
return { number, money, price: (n) => fixed2.format(n) };
|
|
}
|