@feugene/mu
Version:
Helpful TS utilities without dependencies
52 lines • 2.2 kB
JavaScript
// Hoisted constant regex to avoid re-allocating per call
const GROUPS_RE = /(\d{3})(?=\d)/g;
export default function number(value, a, b, c, d) {
// Normalize inputs into options
const defaults = {
decimals: 2,
decPoint: '.',
thousandsSeparator: ',',
clearDecimals: false,
};
let decimals;
let decPoint;
let thousandsSeparator;
let clearDecimals;
if (typeof a === 'object' && a != null) {
decimals = a.decimals ?? defaults.decimals;
decPoint = a.decPoint ?? defaults.decPoint;
thousandsSeparator = a.thousandsSeparator ?? defaults.thousandsSeparator;
clearDecimals = a.clearDecimals ?? defaults.clearDecimals;
}
else {
decimals = a ?? defaults.decimals;
decPoint = b ?? defaults.decPoint;
thousandsSeparator = c ?? defaults.thousandsSeparator;
clearDecimals = d ?? defaults.clearDecimals;
}
// Normalize decimals: integer, non-negative, default 2 on invalid
decimals = Number.isFinite(decimals) ? Math.abs(Math.trunc(decimals)) : 2;
const num = Number(value);
// Edge cases first
if (Number.isNaN(num))
return 'NaN';
if (!Number.isFinite(num))
return String(num);
const isNegZero = Object.is(num, -0);
const sign = num < 0 || isNegZero ? '-' : '';
const abs = Math.abs(num);
// Build fixed string once and split into integer/fractional parts
const fixed = abs.toFixed(decimals);
let [intStr, fracStr = ''] = fixed.split('.');
// Insert thousands separators into integer part
const j = intStr.length > 3 ? intStr.length % 3 : 0;
const intWithSep = (j ? intStr.slice(0, j) + thousandsSeparator : '') + intStr.slice(j).replace(GROUPS_RE, `$1${thousandsSeparator}`);
// Decide on fractional part rendering
const showFraction = decimals > 0 && !(clearDecimals && Number.isInteger(abs));
const fraction = showFraction ? decPoint + fracStr : '';
return sign + intWithSep + fraction;
}
export function numberRus(value, decimals = 2) {
return number(value, { decimals, decPoint: ',', thousandsSeparator: ' ', clearDecimals: true });
}
//# sourceMappingURL=number.mjs.map