import { parseAbbrValue } from './parseAbbrValue' import { removeSeparators } from './removeSeparators' import { removeInvalidChars } from './removeInvalidChars' import { escapeRegExp } from './escapeRegExp' import { type CurrencyInputProps } from '../CurrencyInputProps' export type CleanValueOptions = Pick< CurrencyInputProps, | 'decimalSeparator' | 'groupSeparator' | 'allowDecimals' | 'decimalsLimit' | 'allowNegativeValue' | 'disableAbbreviations' | 'prefix' | 'transformRawValue' > & { value: string } /** * Remove prefix, separators and extra decimals from value */ export const cleanValue = ({ value, groupSeparator = ',', decimalSeparator = '.', allowDecimals = true, decimalsLimit = 2, allowNegativeValue = true, disableAbbreviations = false, prefix = '', transformRawValue = (rawValue) => rawValue }: CleanValueOptions): string => { const transformedValue = transformRawValue(value) if (transformedValue === '-') { return transformedValue } const abbreviations = disableAbbreviations ? [] : ['k', 'm', 'b'] const reg = new RegExp(`((^|\\D)-\\d)|(-${escapeRegExp(prefix)})`) const isNegative = reg.test(transformedValue) // Is there a digit before the prefix? eg. 1$ const [prefixWithValue, preValue] = RegExp(`(\\d+)-?${escapeRegExp(prefix)}`).exec(value) || [] const withoutPrefix = prefix ? prefixWithValue ? transformedValue.replace(prefixWithValue, '').concat(preValue) : transformedValue.replace(prefix, '') : transformedValue const withoutSeparators = removeSeparators(withoutPrefix, groupSeparator) const withoutInvalidChars = removeInvalidChars(withoutSeparators, [ groupSeparator, decimalSeparator, ...abbreviations ]) let valueOnly = withoutInvalidChars if (!disableAbbreviations) { // disallow letter without number if ( abbreviations.some( (letter) => letter === withoutInvalidChars.toLowerCase().replace(decimalSeparator, '') ) ) { return '' } const parsed = parseAbbrValue(withoutInvalidChars, decimalSeparator) if (parsed) { valueOnly = String(parsed) } } const includeNegative = isNegative && allowNegativeValue ? '-' : '' if (decimalSeparator && valueOnly.includes(decimalSeparator)) { const [int, decimals] = withoutInvalidChars.split(decimalSeparator) const trimmedDecimals = decimalsLimit && decimals ? decimals.slice(0, decimalsLimit) : decimals const includeDecimals = allowDecimals ? `${decimalSeparator}${trimmedDecimals}` : '' return `${includeNegative}${int}${includeDecimals}` } return `${includeNegative}${valueOnly}` }