Skip to content

Commit

Permalink
feat(inputs): ability to add icons to input fields
Browse files Browse the repository at this point in the history
  • Loading branch information
schnogz committed Jan 30, 2020
1 parent 6cbc4a4 commit dd21ad5
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 170 deletions.
41 changes: 28 additions & 13 deletions packages/blockchain-info-components/src/Form/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import PropTypes from 'prop-types'
import React from 'react'
import styled from 'styled-components'

import { Icon } from '../Icons'

const BaseTextInput = styled.input.attrs({
type: 'text',
'data-lpignore': props => props.noLastPass,
Expand All @@ -13,11 +15,11 @@ const BaseTextInput = styled.input.attrs({
width: 100%;
height: ${props => props.height};
min-height: ${props => props.height};
padding: 6px 12px;
padding: ${props => (props.icon ? '6px 12px 6px 38px' : '6px 12px')};
box-sizing: border-box;
font-size: 16px;
font-weight: 500;
color: ${props => props.theme['gray-6']};
color: ${props => props.theme['gray400']};
background-color: ${props => props.theme.white};
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
Expand All @@ -37,7 +39,17 @@ const BaseTextInput = styled.input.attrs({
background-color: ${props => props.theme['gray-1']};
}
`

const Container = styled.div`
display: flex;
width: 100%;
align-items: center;
position: relative;
`
const InputIcon = styled(Icon)`
position: absolute;
top: 12px;
left: 12px;
`
const selectBorderColor = state => {
switch (state) {
case 'initial':
Expand Down Expand Up @@ -83,18 +95,21 @@ class TextInput extends React.Component {
}

render () {
const { errorState, disabled, ...rest } = this.props
const borderColor = selectBorderColor(errorState)
const { disabled, errorState, icon, iconSize, ...rest } = this.props

return (
<BaseTextInput
ref={this.refInput}
borderColor={borderColor}
disabled={disabled}
data-e2e={this.props['data-e2e']}
onKeyDown={this.onKeyPressed}
{...rest}
/>
<Container>
{icon && <InputIcon name={icon} size={iconSize} />}
<BaseTextInput
borderColor={selectBorderColor(errorState)}
disabled={disabled}
data-e2e={this.props['data-e2e']}
icon={icon}
onKeyDown={this.onKeyPressed}
ref={this.refInput}
{...rest}
/>
</Container>
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const TextBox = field => {
disableSpellcheck,
errorBottom,
height,
icon,
input,
maxLength,
meta,
Expand All @@ -57,6 +58,7 @@ const TextBox = field => {
disableSpellcheck={disableSpellcheck}
errorState={errorState}
height={height}
icon={icon}
initial={initial}
maxLength={maxLength}
noLastPass={noLastPass}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { ComponentDropdown, Icon, Link, Text } from 'blockchain-info-components'
import { equals, flatten, includes } from 'ramda'
import { Field, reduxForm } from 'redux-form'
import { FormattedMessage } from 'react-intl'
import { includes } from 'ramda'
import React from 'react'
import styled from 'styled-components'

import { model } from 'data'
import {
SelectBoxBchAddresses,
SelectBoxBtcAddresses,
TabMenuTransactionStatus,
TextBox
} from 'components/Form'
import media from 'services/ResponsiveService'
import { TabMenuTransactionStatus, TextBox } from 'components/Form'

const { WALLET_TX_SEARCH } = model.form

Expand All @@ -23,36 +17,6 @@ const Container = styled.div`
align-items: center;
width: 100%;
`
const Controls = styled.div`
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: auto;
& input {
border: 1px solid ${props => props.theme['gray-2']}!important;
margin-right: 100px;
}
& button {
border: 1px solid ${props => props.theme['gray-2']}!important;
}
`
const Addresses = styled.div`
width: 100%;
margin-left: 0;
margin-right: 15px;
@media (min-width: 1200px) {
width: 300px;
}
`
const Status = styled.div`
width: 100%;
@media (min-width: 1200px) {
width: 360px;
}
`
const Search = styled.div`
position: relative;
display: flex;
Expand All @@ -79,32 +43,7 @@ const ReportingIcon = styled(Icon)`
width: 40px;
margin-right: 10px;
`
const SearchIcon = styled(Icon)`
position: absolute;
top: 10px;
right: 10px;
${media.laptop`
display: none;
`}
`

const SearchField = styled(Field)`
min-width: 100px;
max-width: 250px;
& > input {
padding-right: 34px;
overflow: hidden;
text-overflow: ellipsis;
}
${media.laptop`
display: none;
`}
`

const PRIVATE_KEY_EXPORT_COINS = ['ETH', 'XLM']
const ACCOUNT_FILTER_COINS = ['BTC', 'BCH']
const TX_EXPORT_COINS = ['BTC', 'BCH']

const EthPrivateKeys = () => (
Expand All @@ -116,113 +55,84 @@ const EthPrivateKeys = () => (
</Link>
)
const TransactionFilters = ({
accounts,
coin,
handleClickReporting,
onShowPrivateKey,
onShowEthPrivateKeyLegacy,
isLegacyEthAddr
}) => {
const options =
includes(coin, ACCOUNT_FILTER_COINS) && accounts
? flatten(
accounts
.filter(({ label }) => !equals(label, 'All'))
.map(({ options }) => options)
)
: []

return (
<Container>
<Controls>
{options.length > 1 && (
<Addresses>
<Field
name='source'
component={
coin === 'BTC' ? SelectBoxBtcAddresses : SelectBoxBchAddresses
}
excludeLockbox
height='40px'
/>
</Addresses>
)}
<Status>
<Field
name='status'
statuses={['', 'sent', 'received', 'transferred']}
component={TabMenuTransactionStatus}
/>
</Status>
</Controls>
<Controls>
<Search>
{includes(coin, PRIVATE_KEY_EXPORT_COINS) && (
<EthPrivateKeysWrapper>
{isLegacyEthAddr ? (
<ComponentDropdown
down
forceSelected
color={'gray-5'}
selectedComponent={<EthPrivateKeys />}
components={[
<ExportEthPrivateKeyText
size='small'
onClick={onShowPrivateKey}
>
<FormattedMessage
id='scenes.transactions.export.ethkey'
defaultMessage='Export Private Key'
/>
</ExportEthPrivateKeyText>,
<ExportEthPrivateKeyText
size='small'
onClick={onShowEthPrivateKeyLegacy}
>
<FormattedMessage
id='scenes.transactions.export.ethkeyarchived'
defaultMessage='Export Archived Private Key'
/>
</ExportEthPrivateKeyText>
]}
/>
) : (
<Link
size={'12px'}
weight={400}
}) => (
<Container>
<Field
name='status'
statuses={['', 'sent', 'received', 'transferred']}
component={TabMenuTransactionStatus}
/>
<Search>
{includes(coin, PRIVATE_KEY_EXPORT_COINS) && (
<EthPrivateKeysWrapper>
{isLegacyEthAddr ? (
<ComponentDropdown
down
forceSelected
color={'gray-5'}
selectedComponent={<EthPrivateKeys />}
components={[
<ExportEthPrivateKeyText
size='small'
onClick={onShowPrivateKey}
data-e2e='exportPrivateKeyLink'
>
<FormattedMessage
id='scenes.transactions.export.ethkey'
defaultMessage='Export Private Key'
/>
</Link>
)}
</EthPrivateKeysWrapper>
)}
{includes(coin, TX_EXPORT_COINS) && (
<ReportingIcon
name='request'
size='24px'
cursor
color='gray-2'
onClick={handleClickReporting}
data-e2e='generateTxReport'
</ExportEthPrivateKeyText>,
<ExportEthPrivateKeyText
size='small'
onClick={onShowEthPrivateKeyLegacy}
>
<FormattedMessage
id='scenes.transactions.export.ethkeyarchived'
defaultMessage='Export Archived Private Key'
/>
</ExportEthPrivateKeyText>
]}
/>
) : (
<Link
size={'12px'}
weight={400}
onClick={onShowPrivateKey}
data-e2e='exportPrivateKeyLink'
>
<FormattedMessage
id='scenes.transactions.export.ethkey'
defaultMessage='Export Private Key'
/>
</Link>
)}
<SearchField
name='search'
height='40px'
component={TextBox}
data-e2e='transactionsMenuSearchBox'
/>
<SearchIcon name='search' size='20px' />
</Search>
</Controls>
</Container>
)
}
</EthPrivateKeysWrapper>
)}
{includes(coin, TX_EXPORT_COINS) && (
<ReportingIcon
name='request'
size='24px'
cursor
color='gray-2'
onClick={handleClickReporting}
data-e2e='generateTxReport'
/>
)}
<Field
component={TextBox}
data-e2e='transactionsMenuSearchBox'
height='40px'
icon='search'
name='search'
placeholder='Search'
/>
</Search>
</Container>
)

export default reduxForm({
form: WALLET_TX_SEARCH,
Expand Down

0 comments on commit dd21ad5

Please sign in to comment.