Skip to content

Commit

Permalink
Finance, Token Manager: add “Max” button (#1130)
Browse files Browse the repository at this point in the history
A new component has been added locally: AmountInput. It uses TextInput internally, and
can optionally display a “Max” button.
  • Loading branch information
JuanCarlosFrutos authored May 25, 2020
1 parent 11415c4 commit 89404d6
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 28 deletions.
50 changes: 50 additions & 0 deletions apps/finance/app/src/components/AmountInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'
import PropTypes from 'prop-types'
import { ButtonBase, TextInput, noop, GU, RADIUS } from '@aragon/ui'

const MAX_BUTTON_WIDTH = 6 * GU

const AmountInput = React.forwardRef(function AmountInput(
{ showMax, onMaxClick, ...props },
ref
) {
return (
<TextInput
ref={ref}
min={0}
step="any"
adornment={
showMax && (
<ButtonBase
focusRingRadius={RADIUS}
onClick={onMaxClick}
css={`
width: ${MAX_BUTTON_WIDTH}px;
height: calc(100% - 2px);
text-transform: uppercase;
&:active {
transform: translate(0.5px, 0.5px);
}
`}
>
Max
</ButtonBase>
)
}
adornmentPosition="end"
adornmentSettings={{ width: MAX_BUTTON_WIDTH, padding: 1 }}
{...props}
/>
)
})

AmountInput.propTypes = {
showMax: PropTypes.bool,
onMaxClick: PropTypes.func,
}

AmountInput.defaultProps = {
onMaxClick: noop,
}

export default AmountInput
21 changes: 14 additions & 7 deletions apps/finance/app/src/components/NewTransfer/Deposit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
getTokenSymbol,
} from '../../lib/token-utils'
import { addressesEqual, isAddress } from '../../lib/web3-utils'
import AmountInput from '../AmountInput'
import ToggleContent from '../ToggleContent'
import TokenSelector from './TokenSelector'

Expand Down Expand Up @@ -248,11 +249,17 @@ class Deposit extends React.Component {
})
return true
}

setMaxUserBalance = () => {
const { selectedToken, amount } = this.state
const { userBalance, decimals } = selectedToken.data
const adjustedAmount = fromDecimals(userBalance, decimals)
this.setState({
amount: { ...amount, value: adjustedAmount },
})
}
render() {
const { appAddress, network, title, tokens } = this.props
const { amount, reference, selectedToken } = this.state

let errorMessage
if (selectedToken.error === TOKEN_NOT_FOUND_ERROR) {
errorMessage = 'Token not found'
Expand All @@ -268,6 +275,7 @@ class Deposit extends React.Component {
addressesEqual(selectedToken.value, ETHER_TOKEN_FAKE_ADDRESS)
const tokenSelected = selectedToken.value && !ethSelected
const isMainnet = network.type === 'main'
const isMaxButtonVisible = selectedToken && selectedToken.data.symbol

return (
<form onSubmit={this.handleSubmit}>
Expand All @@ -279,12 +287,11 @@ class Deposit extends React.Component {
/>
<SelectedTokenBalance network={network} selectedToken={selectedToken} />
<Field label="Amount">
<TextInput
type="number"
value={amount.value}
<AmountInput
onChange={this.handleAmountUpdate}
min={0}
step="any"
onMaxClick={this.setMaxUserBalance}
showMax={isMaxButtonVisible}
value={amount.value}
required
wide
/>
Expand Down
33 changes: 18 additions & 15 deletions apps/finance/app/src/components/NewTransfer/Withdrawal.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import {
useTheme,
} from '@aragon/ui'
import LocalIdentitiesAutoComplete from '../LocalIdentitiesAutoComplete/LocalIdentitiesAutoComplete'
import { toDecimals } from '../../lib/math-utils'
import { toDecimals, fromDecimals } from '../../lib/math-utils'
import { addressPattern, isAddress } from '../../lib/web3-utils'
import AmountInput from '../AmountInput'

const NO_ERROR = Symbol('NO_ERROR')
const RECEIPIENT_NOT_ADDRESS_ERROR = Symbol('RECEIPIENT_NOT_ADDRESS_ERROR')
Expand Down Expand Up @@ -112,6 +113,15 @@ class Withdrawal extends React.Component {
onWithdraw(token.address, recipientAddress, adjustedAmount, reference)
}

setMaxUserBalance = () => {
const { selectedToken, amount } = this.state
const token = this.nonZeroTokens()[selectedToken]
const adjustedAmount = fromDecimals(token.amount.toString(), token.decimals)
this.setState({
amount: { ...amount, value: adjustedAmount },
})
}

render() {
const { title } = this.props
const { amount, recipient, reference, selectedToken } = this.state
Expand All @@ -135,6 +145,8 @@ class Withdrawal extends React.Component {
selectedToken === NULL_SELECTED_TOKEN
)

const isVisibleMaxButton = Boolean(selectedToken !== NULL_SELECTED_TOKEN)

return tokens.length ? (
<form onSubmit={this.handleSubmit}>
<h1>{title}</h1>
Expand All @@ -156,15 +168,15 @@ class Withdrawal extends React.Component {
</Field>
<Field label="Amount" required>
<CombinedInput>
<TextInput
type="number"
value={amount.value}
<AmountInput
onChange={this.handleAmountUpdate}
min={0}
step="any"
onMaxClick={this.setMaxUserBalance}
showMax={isVisibleMaxButton}
value={amount.value}
required
wide
/>

<DropDown
header="Token"
placeholder="Token"
Expand Down Expand Up @@ -199,15 +211,6 @@ class Withdrawal extends React.Component {

const CombinedInput = styled.div`
display: flex;
input[type='text'] {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0;
}
input[type='text'] + div > div:first-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
`

const ValidationError = ({ message }) => {
Expand Down
50 changes: 50 additions & 0 deletions apps/token-manager/app/src/components/AmountInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'
import PropTypes from 'prop-types'
import { ButtonBase, TextInput, noop, GU, RADIUS } from '@aragon/ui'

const MAX_BUTTON_WIDTH = 6 * GU

const AmountInput = React.forwardRef(function AmountInput(
{ showMax, onMaxClick, ...props },
ref
) {
return (
<TextInput
ref={ref}
min={0}
step="any"
adornment={
showMax && (
<ButtonBase
focusRingRadius={RADIUS}
onClick={onMaxClick}
css={`
width: ${MAX_BUTTON_WIDTH}px;
height: calc(100% - 2px);
text-transform: uppercase;
&:active {
transform: translate(0.5px, 0.5px);
}
`}
>
Max
</ButtonBase>
)
}
adornmentPosition="end"
adornmentSettings={{ width: MAX_BUTTON_WIDTH, padding: 1 }}
{...props}
/>
)
})

AmountInput.propTypes = {
showMax: PropTypes.bool,
onMaxClick: PropTypes.func,
}

AmountInput.defaultProps = {
onMaxClick: noop,
}

export default AmountInput
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
GU,
Info,
SidePanel,
TextInput,
useSidePanelFocusOnReady,
} from '@aragon/ui'
import { isAddress } from '../../web3-utils'
Expand All @@ -18,6 +17,7 @@ import {
splitDecimalNumber,
} from '../../utils'
import LocalIdentitiesAutoComplete from '../LocalIdentitiesAutoComplete/LocalIdentitiesAutoComplete'
import AmountInput from '../AmountInput'

// Any more and the number input field starts to put numbers in scientific notation
const MAX_INPUT_DECIMAL_BASE = 6
Expand Down Expand Up @@ -334,15 +334,16 @@ function TokenPanelContent({
: 'Number of tokens to remove'
}
>
<TextInput
type="number"
<AmountInput
ref={holderAddress ? amountInputRef : undefined}
value={amountField.value}
onChange={handleAmountChange}
min={tokenStep}
max={amountField.max}
min={tokenStep}
onChange={handleAmountChange}
onMaxClick={() => updateAmount(amountField.max)}
step={tokenStep}
value={amountField.value}
required
showMax
wide
/>
</Field>
Expand Down

0 comments on commit 89404d6

Please sign in to comment.