UNPKG

@activecollab/components

Version:

ActiveCollab Components

182 lines (180 loc) • 7.37 kB
export const currencyMultiplier = { k: 1000, m: 1000000, b: 1000000000, t: 1000000000000 }; export const fixedDecimalSpaces = (num, fixed) => { fixed = fixed || 0; fixed = Math.pow(10, fixed); const parts = num.toString().split("."); if (parts.length > 1 && parseInt(parts[1]) > fixed) { return Math.floor(num * fixed) / fixed; } return Math.round(num * fixed) / fixed; }; export const getNumberFromString = function (number, thousandSeparator, decimalSeparator) { if (thousandSeparator === void 0) { thousandSeparator = ","; } if (decimalSeparator === void 0) { decimalSeparator = "."; } if (typeof number === "string" && number === "") { return NaN; } if (!isNaN(Number(number)) || typeof number === "number") { return Number(number); } if (decimalSeparator === ",") { const parts = number.split(decimalSeparator); let result = 0; if (parts.length === 2) { result = parts[0] ? parseFloat(String(parts[0]).replaceAll(thousandSeparator, "")) : 0; if (result < 0) { result -= parts[1] ? parseFloat(String(parts[1])) / Math.pow(10, parts[1].length) : 0; } else { result += parts[1] ? parseFloat(String(parts[1])) / Math.pow(10, parts[1].length) : 0; } return result; } if (parts.length === 1) { result = parseFloat(String(parts[0]).replaceAll(thousandSeparator, "")); return result; } return 0; } else { return parseFloat(String(number).replaceAll(thousandSeparator, "")); } }; /** * @function formatNumber * @description * Formats a number or string into a human-readable format with options for thousand separators, * decimal precision, and shortening the number using suffixes (K, M, B, T). * It can handle negative numbers and optionally trim decimals and set number of decimal places based on the configuration. * * @param {string | number} n - The number or string to be formatted. * @param {"," | "." | " " | ""} [thousandSeparator=","] - The character to use as a thousand separator. * @param {"," | "."} [decimalSeperator="."] - The character to use as a decimal separator. * @param {boolean} [trimDecimals=true] - Whether to trim decimals to the specified number of decimal spaces. * @param {number} [decimalSpaces=2] - The number of decimal spaces to keep in the formatted output. * @param {"long" | "short"} [format="long"] - The format type, either "long" for full numbers or "short" for shortened numbers with suffixes. * @param {number} [shortenThreshold=1000] - The minimum numeric value at which the number should be shortened * using suffixes. Numbers below this threshold will always be shown in long format. * * @returns {string} - The formatted number as a string with separators and potentially with decimals. * * @example * formatNumber(1500) // "1,500.00" * formatNumber(1500000, ",", ".", true, 2, "short") // "1.5M" */ export const formatNumber = function (n, thousandSeparator, decimalSeperator, trimDecimals, decimalSpaces, format, shortenThreshold) { if (thousandSeparator === void 0) { thousandSeparator = ","; } if (decimalSeperator === void 0) { decimalSeperator = "."; } if (trimDecimals === void 0) { trimDecimals = true; } if (decimalSpaces === void 0) { decimalSpaces = 2; } if (format === void 0) { format = "long"; } if (shortenThreshold === void 0) { shortenThreshold = 1000; } if (n === undefined || n === null) return ""; const number = getNumberFromString(n, thousandSeparator, decimalSeperator); if (isNaN(number)) { return ""; } const isNegative = number < 0; let absoluteNumber = Math.abs(number); const suffixes = ["", "K", "M", "B", "T"]; let scale = 0; const shouldShorten = absoluteNumber >= shortenThreshold && format === "short"; while (shouldShorten && scale < suffixes.length - 1 && absoluteNumber >= 1000) { absoluteNumber /= 1000; scale++; } let formattedNum = scale === 0 ? fixedDecimalSpaces(absoluteNumber, decimalSpaces) : parseFloat(absoluteNumber.toFixed(1)); if (formattedNum === 1000 && scale > 0 && scale < 4) { formattedNum = 1; scale++; } const result = numberWithSeparator(trimDecimals ? formattedNum : formattedNum.toFixed(decimalSpaces), thousandSeparator, decimalSeperator); return isNegative ? "-" + result + suffixes[scale] : "" + result + suffixes[scale]; }; export const numberWithSeparator = function (x, thousandSeparator, decimalSeparator, format) { if (thousandSeparator === void 0) { thousandSeparator = ","; } if (decimalSeparator === void 0) { decimalSeparator = "."; } if (format === void 0) { format = true; } if (!format) { return x; } const parts = x.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator); return parts.join(decimalSeparator); }; /** * @function formatCurrency * @description * Formats a number or string as a currency string with options for thousand separators, * decimal precision, currency code, currency code position, and the use of suffixes (K, M, B, T) if needed. * It can handle negative values and supports customization of the currency code and its position. * * @param {string | number} n - The number or string to be formatted as currency. * @param {"," | "." | " " | ""} [thousandSeparator=","] - The character to use as a thousand separator. * @param {"," | "."} [decimalSeperator="."] - The character to use as a decimal separator. * @param {boolean} [trimDecimals=false] - Whether to trim decimals to the specified number of decimal spaces. * @param {number} [decimalSpaces=2] - The number of decimal spaces to keep in the formatted output. * @param {"long" | "short"} [format="long"] - The format type, either "long" for full numbers or "short" for shortened numbers with suffixes. * @param {string} [currencyCode=""] - The currency code to append or prepend to the formatted number. * @param {"right" | "left"} [currencyCodePosition="right"] - The position of the currency code relative to the formatted number. * * @returns {string} - The formatted currency string, including the currency code if provided. * * @example * formatCurrency(1500, ",", ".", false, 2, "long", "USD", "right") // "1,500.00 USD" * formatCurrency(1500000, ",", ".", true, 2, "short", "JPY", "left") // "JPY 1.5M" */ export const formatCurrency = function (n, thousandSeparator, decimalSeperator, trimDecimals, decimalSpaces, format, currencyCode, currencyCodePosition) { if (thousandSeparator === void 0) { thousandSeparator = ","; } if (decimalSeperator === void 0) { decimalSeperator = "."; } if (trimDecimals === void 0) { trimDecimals = false; } if (decimalSpaces === void 0) { decimalSpaces = 2; } if (format === void 0) { format = "long"; } if (currencyCode === void 0) { currencyCode = ""; } if (currencyCodePosition === void 0) { currencyCodePosition = "right"; } const formattedNum = formatNumber(n, thousandSeparator, decimalSeperator, trimDecimals, decimalSpaces, format, 10000); if (!currencyCode) { return formattedNum; } return currencyCodePosition === "right" ? formattedNum + " " + currencyCode : currencyCode + " " + formattedNum; }; //# sourceMappingURL=currencyUtils.js.map