pkg-components
Version:
86 lines (74 loc) • 2.64 kB
text/typescript
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}`
}