aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components/currency-input/currency-input.component.js
blob: 0761a75c5efe66b41573a6b3db7e5b27ffd41d7d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import UnitInput from '../unit-input'
import CurrencyDisplay from '../currency-display'
import { getValueFromWeiHex, getWeiHexFromDecimalValue } from '../../helpers/conversions.util'
import { ETH } from '../../constants/common'

/**
 * Component that allows user to enter currency values as a number, and props receive a converted
 * hex value in WEI. props.value, used as a default or forced value, should be a hex value, which
 * gets converted into a decimal value depending on the currency (ETH or Fiat).
 */
export default class CurrencyInput extends PureComponent {
  static propTypes = {
    conversionRate: PropTypes.number,
    currentCurrency: PropTypes.string,
    nativeCurrency: PropTypes.string,
    onChange: PropTypes.func,
    onBlur: PropTypes.func,
    suffix: PropTypes.string,
    useFiat: PropTypes.bool,
    value: PropTypes.string,
  }

  constructor (props) {
    super(props)

    const { value: hexValue } = props
    const decimalValue = hexValue ? this.getDecimalValue(props) : 0

    this.state = {
      decimalValue,
      hexValue,
    }
  }

  componentDidUpdate (prevProps) {
    const { value: prevPropsHexValue } = prevProps
    const { value: propsHexValue } = this.props
    const { hexValue: stateHexValue } = this.state

    if (prevPropsHexValue !== propsHexValue && propsHexValue !== stateHexValue) {
      const decimalValue = this.getDecimalValue(this.props)
      this.setState({ hexValue: propsHexValue, decimalValue })
    }
  }

  getDecimalValue (props) {
    const { value: hexValue, useFiat, currentCurrency, conversionRate } = props
    const decimalValueString = useFiat
      ? getValueFromWeiHex({
        value: hexValue, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
      })
      : getValueFromWeiHex({
        value: hexValue, toCurrency: ETH, numberOfDecimals: 6,
      })

    return Number(decimalValueString) || 0
  }

  handleChange = decimalValue => {
    const { useFiat, currentCurrency: fromCurrency, conversionRate, onChange } = this.props

    const hexValue = useFiat
      ? getWeiHexFromDecimalValue({
        value: decimalValue, fromCurrency, conversionRate, invertConversionRate: true,
      })
      : getWeiHexFromDecimalValue({
        value: decimalValue, fromCurrency: ETH, fromDenomination: ETH, conversionRate,
      })

    this.setState({ hexValue, decimalValue })
    onChange(hexValue)
  }

  handleBlur = () => {
    this.props.onBlur(this.state.hexValue)
  }

  renderConversionComponent () {
    const { useFiat, currentCurrency, nativeCurrency } = this.props
    const { hexValue } = this.state
    let currency, numberOfDecimals

    if (useFiat) {
      // Display ETH
      currency = nativeCurrency || ETH
      numberOfDecimals = 6
    } else {
      // Display Fiat
      currency = currentCurrency
      numberOfDecimals = 2
    }

    return (
      <CurrencyDisplay
        className="currency-input__conversion-component"
        currency={currency}
        value={hexValue}
        numberOfDecimals={numberOfDecimals}
      />
    )
  }

  render () {
    const { suffix, ...restProps } = this.props
    const { decimalValue } = this.state

    return (
      <UnitInput
        {...restProps}
        suffix={suffix}
        onChange={this.handleChange}
        onBlur={this.handleBlur}
        value={decimalValue}
      >
        { this.renderConversionComponent() }
      </UnitInput>
    )
  }
}