@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
174 lines (173 loc) • 5.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.alignCurrencySymbol = alignCurrencySymbol;
exports.formatNumberCoreParts = exports.formatNumberCore = exports.enhanceSR = void 0;
exports.formatToParts = formatToParts;
exports.prepareMinus = void 0;
exports.prepareMinusParts = prepareMinusParts;
var _defaults = require("../../../shared/defaults.js");
var _componentHelper = require("../../../shared/component-helper.js");
var _helpers = require("../../../shared/helpers.js");
var _constants = require("./constants.js");
var _currencyDisplay = require("./currencyDisplay.js");
function toIntlOptions({
decimals: _decimals,
...rest
}) {
return rest;
}
function getFormatParts({
number,
locale = null,
options = null
}) {
if (typeof Intl !== 'undefined' && typeof Intl.NumberFormat === 'function') {
const inst = new Intl.NumberFormat(locale || _defaults.LOCALE, toIntlOptions(options || {}));
if (typeof inst.formatToParts === 'function') {
return inst.formatToParts(Number(number));
}
return [{
value: inst.format(Number(number)),
type: 'unknown'
}];
}
return [{
value: String(number),
type: 'unknown'
}];
}
function formatToParts(args) {
try {
return getFormatParts(args);
} catch (e) {
(0, _componentHelper.warn)('NumberFormat: Failed to format number with Intl.NumberFormat:', e);
}
return [{
value: String(args.number),
type: 'unknown'
}];
}
function joinParts(parts) {
return parts.reduce((acc, {
value
}) => acc + value, '');
}
function alignParts(parts, currencyDisplay) {
return parts.map(item => {
if (item.type === 'currency') {
return {
...item,
value: alignCurrencySymbol(item.value, currencyDisplay)
};
}
return item;
});
}
function alignCurrencySymbol(output, currencyDisplay) {
if (typeof output === 'string' && currencyDisplay === 'name') {
output = output.replace(/(nor[^\s]+?)\s(\w+)/i, '$2');
}
return String(output);
}
const prepareMinus = (display, locale) => {
if (!(locale && /(no|nb|nn)$/i.test(locale))) {
return display;
}
const first = display.charAt(0);
const second = display.charAt(1);
if (first === '-' && second === '-') {
return display;
}
const reg = `^(${_constants.NUMBER_MINUS})`;
if (new RegExp(reg).test(first)) {
if (parseFloat(second) > 0) {
display = display.replace(new RegExp(reg + '(.*)'), '-$2');
} else {
display = display.replace(new RegExp(reg + '([^0-9]+)(.*)'), '$2-$3');
}
}
return display;
};
exports.prepareMinus = prepareMinus;
function prepareMinusParts(display, parts, locale) {
const number = prepareMinus(display, locale);
if (!parts || number === display) {
return {
number,
parts: parts !== null && parts !== void 0 ? parts : []
};
}
const nextParts = parts.map(part => {
if (part.type === 'minusSign' && display.startsWith(part.value) && number.startsWith('-')) {
return {
...part,
value: '-'
};
}
return part;
});
if (joinParts(nextParts) === number) {
return {
number,
parts: nextParts
};
}
return {
number,
parts: []
};
}
const enhanceSR = (value, aria, locale) => {
if (_helpers.IS_MAC && Math.abs(parseFloat(String(value))) <= 99999) {
aria = String(aria).replace(/\s([0-9])/g, '$1');
}
aria = prepareMinus(aria, locale);
return aria;
};
exports.enhanceSR = enhanceSR;
function replaceNaNWithDash(number) {
const string = String(number);
const replaced = string.replace(/NaN/, _constants.ABSENT_VALUE_FORMAT);
if (!/NaN/.test(string)) {
return replaced;
}
const escapedDash = (0, _componentHelper.escapeRegexChars)(_constants.ABSENT_VALUE_FORMAT);
return replaced.replace(new RegExp(`([^\\s])${escapedDash}`, 'g'), `$1 ${_constants.ABSENT_VALUE_FORMAT}`);
}
const formatNumberCore = (number, locale, options = {}, formatter = null) => {
return formatNumberCoreParts(number, locale, options, formatter).number;
};
exports.formatNumberCore = formatNumberCore;
const formatNumberCoreParts = (number, locale, options = {}, formatter = null) => {
let parts = [];
try {
if (options.currencyDisplay) {
options.currencyDisplay = (0, _currencyDisplay.getFallbackCurrencyDisplay)(locale, options.currencyDisplay);
}
delete options.decimals;
parts = getFormatParts({
number: formatter ? Number(number) : parseFloat(String(number)),
locale,
options
}).map(item => formatter ? formatter(item) : item);
parts = alignParts(parts, options.currencyDisplay);
number = joinParts(parts);
if (new RegExp(`^(${_constants.NUMBER_MINUS})(0|0[^\\d]|0\\s.*)$`).test(String(number))) {
number = String(number).replace(new RegExp(`(${_constants.NUMBER_MINUS})0`), '0');
}
} catch (e) {
(0, _componentHelper.warn)(`Number could not be formatted: ${JSON.stringify([number, locale, options])}`, e);
}
number = replaceNaNWithDash(alignCurrencySymbol(number, options.currencyDisplay));
if (joinParts(parts) !== String(number)) {
parts = [];
}
return {
number: String(number),
parts
};
};
exports.formatNumberCoreParts = formatNumberCoreParts;
//# sourceMappingURL=formatNumberCore.js.map