add sendmax and button link for the amount field in sending funds form

This commit is contained in:
mmv 2019-05-21 16:16:12 +04:00
parent 7bac5ae822
commit 2010a6b7eb
9 changed files with 197 additions and 46 deletions

View File

@ -81,6 +81,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-final-form": "5.1.0",
"react-final-form-listeners": "^1.0.2",
"react-hot-loader": "4.8.7",
"react-infinite-scroll-component": "^4.5.2",
"react-redux": "7.0.3",

View File

@ -15,6 +15,7 @@ type Props = {
padding?: number,
validation?: (values: Object) => Object | Promise<Object>,
initialValues?: Object,
formMutators: Object,
}
const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
@ -24,15 +25,16 @@ const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
})
const GnoForm = ({
onSubmit, validation, initialValues, children, padding = 0,
onSubmit, validation, initialValues, children, padding = 0, formMutators,
}: Props) => (
<Form
validate={validation}
onSubmit={onSubmit}
initialValues={initialValues}
mutators={formMutators}
render={({ handleSubmit, ...rest }) => (
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)}>
{children(rest.submitting, rest.validating, rest)}
{children(rest.submitting, rest.validating, rest, rest.form.mutators)}
</form>
)}
/>

View File

@ -0,0 +1,29 @@
// @flow
/* eslint-disable react/button-has-type */
/* eslint-disable react/default-props-match-prop-types */
import * as React from 'react'
import cn from 'classnames/bind'
import styles from './index.scss'
const cx = cn.bind(styles)
type Props = {
type: 'button' | 'submit' | 'reset',
size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
weight?: 'light' | 'regular' | 'bolder' | 'bold',
color?: 'soft' | 'medium' | 'dark' | 'white' | 'fancy' | 'primary' | 'secondary' | 'warning' | 'disabled',
}
const GnoButtonLink = ({ type, size, weight, color, ...props }: Props) => (
<button type={type} className={cx(styles.btnLink, size, color, weight)} {...props} />
)
GnoButtonLink.defaultProps = {
type: 'button',
size: 'md',
weight: 'regular',
color: 'secondary',
}
export default GnoButtonLink

View File

@ -0,0 +1,79 @@
.btnLink {
background: transparent;
border: none;
text-decoration: underline;
font-family: 'Roboto Mono', monospace;
cursor: pointer;
}
.sm {
font-size: $smallFontSize;
}
.md {
font-size: $mediumFontSize;
}
.lg {
font-size: $largeFontSize;
}
.xl {
font-size: $extraLargeFontSize;
}
.xxl {
font-size: $xxlFontSize;
}
.light {
font-weight: $lightFont;
}
.regular {
font-weight: $regularFont;
}
.bolder {
font-weight: $bolderFont;
}
.bold {
font-weight: $boldFont;
}
.soft {
color: #888888;
}
.medium {
color: #686868;
}
.dark {
color: black;
}
.fancy {
color: $fancy;
}
.warning {
color: $warning;
}
.primary {
color: $fontColor;
}
.secondary {
color: $secondary;
}
.disabled {
color: $disabled;
}
.white {
color: white;
}

View File

@ -9,7 +9,7 @@ const cx = classNames.bind(styles)
type Props = {
className?: string,
children: React$Node,
margin?: 'sm' | 'md' | 'lg' | 'xl',
margin?: 'xs' | 'sm' | 'md' | 'lg' | 'xl',
align?: 'center' | 'end' | 'start',
grow?: boolean,
}

View File

@ -7,6 +7,11 @@
.grow {
flex: 1 1 auto;
}
.marginXs {
margin-bottom: $xs;
}
.marginSm {
margin-bottom: $sm;
}

View File

@ -1,6 +1,7 @@
// @flow
import React from 'react'
import { List } from 'immutable'
import { OnChange } from 'react-final-form-listeners'
import { withStyles } from '@material-ui/core/styles'
import MenuItem from '@material-ui/core/MenuItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
@ -17,6 +18,7 @@ import { selectedTokenStyles, selectStyles } from './style'
type SelectFieldProps = {
tokens: List<Token>,
classes: Object,
onTokenChange: Function,
}
type SelectedTokenProps = {
@ -47,7 +49,7 @@ const SelectedToken = ({ token, classes }: SelectedTokenProps) => (
const SelectedTokenStyled = withStyles(selectedTokenStyles)(SelectedToken)
const TokenSelectField = ({ tokens, classes }: SelectFieldProps) => (
const TokenSelectField = ({ tokens, onTokenChange, classes }: SelectFieldProps) => (
<Field
name="token"
component={SelectField}
@ -65,6 +67,11 @@ const TokenSelectField = ({ tokens, classes }: SelectFieldProps) => (
<ListItemText primary={token.name} secondary={`${token.balance} ${token.symbol}`} />
</MenuItem>
))}
<OnChange name="token">
{() => {
onTokenChange()
}}
</OnChange>
</Field>
)

View File

@ -11,11 +11,12 @@ import Row from '~/components/layout/Row'
import GnoForm from '~/components/forms/GnoForm'
import Link from '~/components/layout/Link'
import Col from '~/components/layout/Col'
import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Hairline from '~/components/layout/Hairline'
import ButtonLink from '~/components/layout/ButtonLink'
import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField'
import {
lg, md, sm, secondary, xs,
} from '~/theme/variables'
@ -73,6 +74,16 @@ const SendFunds = ({
classes, onClose, safeAddress, etherScanLink, safeName, ethBalance, tokens,
}: Props) => {
const handleSubmit = () => {}
const formMutators = {
setMax: (args, state, utils) => {
const { token } = state.formState.values
utils.changeValue(state, 'amount', () => token && token.balance)
},
onTokenChange: (args, state, utils) => {
utils.changeValue(state, 'amount', () => '')
},
}
return (
<React.Fragment>
@ -121,45 +132,55 @@ ETH
<Hairline />
</Col>
</Row>
<GnoForm onSubmit={handleSubmit}>
{() => (
<React.Fragment>
<Row margin="md">
<Col xs={12}>
<Field
name="recipientAddress"
component={TextField}
type="text"
validate={composeValidators(required, mustBeEthereumAddress)}
placeholder="Recipient*"
text="Recipient*"
className={classes.addressInput}
/>
</Col>
</Row>
<Row>
<Col>
<TokenSelectField tokens={tokens} />
</Col>
</Row>
<Row>
<Col layout="column">
<Paragraph size="md" color="disabled" style={{ letterSpacing: '-0.5px' }}>
Amount
</Paragraph>
<Field
name="amount"
component={TextField}
type="text"
validate={composeValidators(required)}
placeholder="Amount*"
text="Amount*"
className={classes.addressInput}
/>
</Col>
</Row>
</React.Fragment>
)}
<GnoForm onSubmit={handleSubmit} formMutators={formMutators}>
{(...args) => {
const mutators = args[3]
return (
<React.Fragment>
<Row margin="md">
<Col xs={12}>
<Field
name="recipientAddress"
component={TextField}
type="text"
validate={composeValidators(required, mustBeEthereumAddress)}
placeholder="Recipient*"
text="Recipient*"
className={classes.addressInput}
/>
</Col>
</Row>
<Row margin="sm">
<Col>
<TokenSelectField tokens={tokens} onTokenChange={mutators.onTokenChange} />
</Col>
</Row>
<Row margin="xs">
<Col between="lg">
<Paragraph size="md" color="disabled" style={{ letterSpacing: '-0.5px' }} noMargin>
Amount
</Paragraph>
<ButtonLink weight="bold" onClick={mutators.setMax}>
Send max
</ButtonLink>
</Col>
</Row>
<Row>
<Col>
<Field
name="amount"
component={TextField}
type="text"
validate={composeValidators(required)}
placeholder="Amount*"
text="Amount*"
className={classes.addressInput}
/>
</Col>
</Row>
</React.Fragment>
)
}}
</GnoForm>
</Block>
</React.Fragment>

View File

@ -1416,7 +1416,7 @@
dependencies:
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.4.4":
"@babel/runtime@^7.1.5", "@babel/runtime@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d"
integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==
@ -13669,6 +13669,13 @@ react-fast-compare@^2.0.2:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
react-final-form-listeners@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-final-form-listeners/-/react-final-form-listeners-1.0.2.tgz#b52da984300281cf1f69a6412e86df6249e2bf1c"
integrity sha512-AaUUHcXRhD3esC80yUfYPI8FJ3TUiMu0f4hk18QL8NMCWjokg6NWS32WkRJsH3bLWDoiy7+uNVOAAyO/XoupyA==
dependencies:
"@babel/runtime" "^7.1.5"
react-final-form@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-5.1.0.tgz#f9402dfdf9325e5605cd8c9c7f4ef3e9ecf0702c"