diff --git a/src/components/RequestAmount/index.js b/src/components/RequestAmount/index.js index d37b081b..de2677a6 100644 --- a/src/components/RequestAmount/index.js +++ b/src/components/RequestAmount/index.js @@ -102,6 +102,7 @@ export class RequestAmount extends PureComponent { value={right} onChange={this.handleChangeAmount('right')} renderRight={{rightUnit.code}} + showAllDigits /> diff --git a/src/components/base/InputCurrency/index.js b/src/components/base/InputCurrency/index.js index 51c8da89..b5686eb1 100644 --- a/src/components/base/InputCurrency/index.js +++ b/src/components/base/InputCurrency/index.js @@ -17,11 +17,11 @@ function parseValue(value) { return value.toString().replace(/,/g, '.') } -function format(unit: Unit, value: number, useGrouping = false) { +function format(unit: Unit, value: number, { isFocused, showAllDigits }) { return formatCurrencyUnit(unit, value, { - useGrouping, + useGrouping: !isFocused, disableRounding: true, - showAllDigits: false, + showAllDigits: !!showAllDigits && !isFocused, }) } @@ -44,11 +44,12 @@ type Props = { unit: Unit, units: Array, value: number, + showAllDigits?: boolean, } type State = { unit: Unit, - isFocus: boolean, + isFocused: boolean, displayValue: string, } @@ -58,37 +59,52 @@ class InputCurrency extends PureComponent { renderRight: null, units: [], value: 0, + showAllDigits: false, } state = { - isFocus: false, - displayValue: '0', + isFocused: false, + displayValue: '', unit: this.props.unit, } componentWillMount() { - const { value } = this.props - const { unit } = this.state - const displayValue = format(unit, value, true) - this.setState({ displayValue }) + this.syncInput({ isFocused: false }) } componentWillReceiveProps(nextProps: Props) { + const { value, showAllDigits } = this.props const { unit } = this.state - if (this.props.value !== nextProps.value) { - const { isFocus } = this.state - const displayValue = isFocus - ? (nextProps.value / 10 ** unit.magnitude).toString() - : format(unit, nextProps.value, true) - this.setState({ displayValue }) + const needsToBeReformatted = + value !== nextProps.value || showAllDigits !== nextProps.showAllDigits + if (needsToBeReformatted) { + const { isFocused } = this.state + this.setState({ + displayValue: + nextProps.value === 0 + ? '' + : format(unit, nextProps.value, { + isFocused, + showAllDigits: nextProps.showAllDigits, + }), + }) } } handleChange = (v: string) => { v = parseValue(v) + // allow to type directly `.` in input to have `0.` + if (v.startsWith('.')) { + v = `0${v}` + } + // forbid multiple 0 at start - if (v.startsWith('00')) { + if (v === '' || v.startsWith('00')) { + const { onChange } = this.props + const { unit } = this.state + onChange(0, unit) + this.setState({ displayValue: '' }) return } @@ -98,19 +114,19 @@ class InputCurrency extends PureComponent { } this.emitOnChange(v) - this.setState({ displayValue: v || '0' }) + this.setState({ displayValue: v || '' }) } - handleBlur = () => { - const { value } = this.props - const { unit } = this.state - this.setState({ isFocus: false, displayValue: format(unit, value, true) }) - } + handleBlur = () => this.syncInput({ isFocused: false }) + handleFocus = () => this.syncInput({ isFocused: true }) - handleFocus = () => { - const { value } = this.props + syncInput = ({ isFocused }) => { + const { value, showAllDigits } = this.props const { unit } = this.state - this.setState({ isFocus: true, displayValue: format(unit, value) }) + this.setState({ + isFocused, + displayValue: value === 0 ? '' : format(unit, value, { isFocused, showAllDigits }), + }) } emitOnChange = (v: string) => { @@ -124,7 +140,7 @@ class InputCurrency extends PureComponent { } renderListUnits = () => { - const { units, value } = this.props + const { units, value, showAllDigits } = this.props const { unit } = this.state if (units.length <= 1) { @@ -138,7 +154,10 @@ class InputCurrency extends PureComponent { keyProp="code" flatLeft onChange={item => { - this.setState({ unit: item, displayValue: format(item, value, true) }) + this.setState({ + unit: item, + displayValue: format(item, value, { isFocused: false, showAllDigits }), + }) }} items={units} value={unit} @@ -150,8 +169,8 @@ class InputCurrency extends PureComponent { } render() { - const { renderRight } = this.props - const { displayValue } = this.state + const { renderRight, showAllDigits } = this.props + const { displayValue, unit } = this.state return ( { onFocus={this.handleFocus} onBlur={this.handleBlur} renderRight={renderRight || this.renderListUnits()} + placeholder={format(unit, 0, { isFocused: false, showAllDigits })} /> ) } diff --git a/src/components/base/InputCurrency/stories.js b/src/components/base/InputCurrency/stories.js index 3fcc1fcd..a58aca81 100644 --- a/src/components/base/InputCurrency/stories.js +++ b/src/components/base/InputCurrency/stories.js @@ -3,6 +3,7 @@ import React, { Component } from 'react' import { storiesOf } from '@storybook/react' import { action } from '@storybook/addon-actions' +import { boolean } from '@storybook/addon-knobs' import { getCurrencyByCoinType } from '@ledgerhq/currencies' @@ -14,7 +15,7 @@ const { units } = getCurrencyByCoinType(1) class Wrapper extends Component { state = { - value: 1000e8, + value: 0, unit: units[0], } @@ -38,7 +39,13 @@ class Wrapper extends Component { stories.add('InputCurrency', () => ( ( - + )} /> ))