parent
2e1d962b1a
commit
7f23e017b2
@ -1,113 +0,0 @@ |
||||
const Component = require('react').Component |
||||
const h = require('react-hyperscript') |
||||
const inherits = require('util').inherits |
||||
|
||||
module.exports = CurrencyInput |
||||
|
||||
inherits(CurrencyInput, Component) |
||||
function CurrencyInput (props) { |
||||
Component.call(this) |
||||
|
||||
const sanitizedValue = sanitizeValue(props.value) |
||||
|
||||
this.state = { |
||||
value: sanitizedValue, |
||||
emptyState: false, |
||||
focused: false, |
||||
} |
||||
} |
||||
|
||||
function removeNonDigits (str) { |
||||
return str.match(/\d|$/g).join('') |
||||
} |
||||
|
||||
// Removes characters that are not digits, then removes leading zeros
|
||||
function sanitizeInteger (val) { |
||||
return String(parseInt(removeNonDigits(val) || '0', 10)) |
||||
} |
||||
|
||||
function sanitizeDecimal (val) { |
||||
return removeNonDigits(val) |
||||
} |
||||
|
||||
// Take a single string param and returns a non-negative integer or float as a string.
|
||||
// Breaks the input into three parts: the integer, the decimal point, and the decimal/fractional part.
|
||||
// Removes leading zeros from the integer, and non-digits from the integer and decimal
|
||||
// The integer is returned as '0' in cases where it would be empty. A decimal point is
|
||||
// included in the returned string if one is included in the param
|
||||
// Examples:
|
||||
// sanitizeValue('0') -> '0'
|
||||
// sanitizeValue('a') -> '0'
|
||||
// sanitizeValue('010.') -> '10.'
|
||||
// sanitizeValue('0.005') -> '0.005'
|
||||
// sanitizeValue('22.200') -> '22.200'
|
||||
// sanitizeValue('.200') -> '0.200'
|
||||
// sanitizeValue('a.b.1.c,89.123') -> '0.189123'
|
||||
function sanitizeValue (value) { |
||||
let [ , integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value) |
||||
|
||||
integer = sanitizeInteger(integer) || '0' |
||||
decimal = sanitizeDecimal(decimal) |
||||
|
||||
return `${integer}${point}${decimal}` |
||||
} |
||||
|
||||
CurrencyInput.prototype.handleChange = function (newValue) { |
||||
const { onInputChange } = this.props |
||||
const { value } = this.state |
||||
|
||||
let parsedValue = newValue |
||||
const newValueLastIndex = newValue.length - 1 |
||||
|
||||
if (value === '0' && newValue[newValueLastIndex] === '0') { |
||||
parsedValue = parsedValue.slice(0, newValueLastIndex) |
||||
} |
||||
const sanitizedValue = sanitizeValue(parsedValue) |
||||
this.setState({ |
||||
value: sanitizedValue, |
||||
emptyState: newValue === '' && sanitizedValue === '0', |
||||
}) |
||||
onInputChange(sanitizedValue) |
||||
} |
||||
|
||||
// If state.value === props.value plus a decimal point, or at least one
|
||||
// zero or a decimal point and at least one zero, then this returns state.value
|
||||
// after it is sanitized with getValueParts
|
||||
CurrencyInput.prototype.getValueToRender = function () { |
||||
const { value } = this.props |
||||
const { value: stateValue } = this.state |
||||
|
||||
const trailingStateString = (new RegExp(`^${value}(.+)`)).exec(stateValue) |
||||
const trailingDecimalAndZeroes = trailingStateString && (/^[.0]0*/).test(trailingStateString[1]) |
||||
|
||||
return sanitizeValue(trailingDecimalAndZeroes |
||||
? stateValue |
||||
: value) |
||||
} |
||||
|
||||
CurrencyInput.prototype.render = function () { |
||||
const { |
||||
className, |
||||
placeholder, |
||||
readOnly, |
||||
inputRef, |
||||
type, |
||||
} = this.props |
||||
const { emptyState, focused } = this.state |
||||
|
||||
const inputSizeMultiplier = readOnly ? 1 : 1.2 |
||||
|
||||
const valueToRender = this.getValueToRender() |
||||
return h('input', { |
||||
className, |
||||
type, |
||||
value: emptyState ? '' : valueToRender, |
||||
placeholder: focused ? '' : placeholder, |
||||
size: valueToRender.length * inputSizeMultiplier, |
||||
readOnly, |
||||
onFocus: () => this.setState({ focused: true, emptyState: valueToRender === '0' }), |
||||
onBlur: () => this.setState({ focused: false, emptyState: false }), |
||||
onChange: e => this.handleChange(e.target.value), |
||||
ref: inputRef, |
||||
}) |
||||
} |
Loading…
Reference in new issue