Browse Source

Improved SelectAccount component

master
Loëck Vézien 7 years ago
parent
commit
854f90f4a3
No known key found for this signature in database GPG Key ID: CBCDCE384E853AC4
  1. 5
      package.json
  2. 39
      src/components/SelectAccount.js
  3. 63
      src/components/SelectAccount/index.js
  4. 49
      src/components/SelectAccount/stories.js
  5. 1
      src/components/base/Icon/index.js
  6. 39
      src/components/base/Select/index.js
  7. 3
      static/i18n/en/translation.yml
  8. 3
      static/i18n/fr/translation.yml
  9. 14
      yarn.lock

5
package.json

@ -80,7 +80,7 @@
"redux-thunk": "^2.2.0",
"shortid": "^2.2.8",
"source-map-support": "^0.5.3",
"styled-components": "^3.1.2",
"styled-components": "^3.1.4",
"styled-system": "^1.1.1"
},
"devDependencies": {
@ -98,8 +98,9 @@
"babel-preset-flow": "^6.23.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chance": "^1.0.13",
"concurrently": "^3.5.1",
"dotenv": "^4.0.0",
"dotenv": "^5.0.0",
"electron": "1.7.11",
"electron-builder": "^19.55.2",
"electron-devtools-installer": "^2.2.3",

39
src/components/SelectAccount.js

@ -1,39 +0,0 @@
// @flow
import React from 'react'
import { connect } from 'react-redux'
import type { MapStateToProps } from 'react-redux'
import { getAccounts } from 'reducers/accounts'
import Select from 'components/base/Select'
import type { Account } from 'types/common'
const mapStateToProps: MapStateToProps<*, *, *> = state => ({
accounts: Object.entries(getAccounts(state)).map(([, account]: [string, any]) => account),
})
type Props = {
accounts: Array<Account>,
onChange: () => Account | void,
value: Account | null,
}
const SelectAccount = ({ accounts, value, onChange }: Props) => (
<Select
value={value}
renderSelected={item => item.name}
renderItem={item => (
<div key={item.id}>
{item.name} - {item.data.balance}
</div>
)}
keyProp="id"
items={accounts}
placeholder="Choose an account"
onChange={onChange}
/>
)
export default connect(mapStateToProps)(SelectAccount)

63
src/components/SelectAccount/index.js

@ -0,0 +1,63 @@
// @flow
import React from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import noop from 'lodash/noop'
import type { MapStateToProps } from 'react-redux'
import type { T, Account } from 'types/common'
import { formatBTC } from 'helpers/format'
import { getAccounts } from 'reducers/accounts'
import Select from 'components/base/Select'
import Box from 'components/base/Box'
import Text from 'components/base/Text'
const mapStateToProps: MapStateToProps<*, *, *> = state => ({
accounts: Object.entries(getAccounts(state)).map(([, account]: [string, any]) => account),
})
type Props = {
accounts: Array<Account>,
onChange?: () => Account | void,
value?: Account | null,
t: T,
}
const renderItem = item => (
<Box horizontal align="center">
<Box grow>
<Text color="night" fontSize={0} fontWeight="bold">
{item.name}
</Text>
</Box>
<Box>
<Text color="mouse" fontSize={0}>
{formatBTC(item.data.balance)}
</Text>
</Box>
</Box>
)
export const SelectAccount = ({ accounts, value, onChange, t }: Props) => (
<Select
value={value && accounts.find(a => value && a.id === value.id)}
renderSelected={renderItem}
renderItem={renderItem}
keyProp="id"
items={accounts}
placeholder={t('SelectAccount.placeholder')}
onChange={onChange}
/>
)
SelectAccount.defaultProps = {
onChange: noop,
value: undefined,
}
export default compose(connect(mapStateToProps), translate())(SelectAccount)

49
src/components/SelectAccount/stories.js

@ -0,0 +1,49 @@
// @flow
import React, { PureComponent } from 'react'
import { storiesOf } from '@storybook/react'
import Chance from 'chance'
import { SelectAccount } from 'components/SelectAccount'
const chance = new Chance()
const stories = storiesOf('SelectAccount', module)
const accounts = [...Array(20)].map(() => ({
id: chance.string(),
name: chance.name(),
type: 'BTC',
data: {
address: chance.string(),
balance: chance.floating({ min: 0, max: 20 }),
currentIndex: chance.integer({ min: 0, max: 20 }),
transactions: [],
},
}))
type State = {
value: any,
}
class Wrapper extends PureComponent<any, State> {
state = {
value: '',
}
handleChange = item => this.setState({ value: item })
render() {
const { render } = this.props
const { value } = this.state
return render({ onChange: this.handleChange, value })
}
}
stories.add('basic', () => (
<Wrapper
render={({ onChange, value }) => (
<SelectAccount onChange={onChange} value={value} accounts={accounts} t={k => k} />
)}
/>
))

1
src/components/base/Icon/index.js

@ -8,6 +8,7 @@ import FontAwesomeIcon from '@fortawesome/react-fontawesome'
const Container = styled.span`
${fontSize};
${color};
position: relative;
`
export default ({ name, ...props }: { name: string }) => (

39
src/components/base/Select/index.js

@ -8,9 +8,10 @@ import { space } from 'styled-system'
import type { Element } from 'react'
import Box from 'components/base/Box'
import Text from 'components/base/Text'
import Icon from 'components/base/Icon'
import Input from 'components/base/Input'
import Search from 'components/base/Search'
import Text from 'components/base/Text'
import Triangles from './Triangles'
@ -49,6 +50,7 @@ const TriggerBtn = styled(Box).attrs({
`
const Item = styled(Box).attrs({
align: 'center',
p: 2,
})`
background: ${p => (p.highlighted ? p.theme.colors.cream : p.theme.colors.white)};
@ -89,13 +91,31 @@ const FloatingTriangles = styled(Box).attrs({
padding-right: 1px;
`
const IconSelected = styled(Box).attrs({
bg: 'blue',
color: 'white',
align: 'center',
justify: 'center',
})`
border-radius: 50%;
height: 15px;
font-size: 5px;
width: 15px;
opacity: ${p => (p.selected ? 1 : 0)};
// add top for center icon
> * {
top: 1px;
}
`
class Select extends PureComponent<Props> {
static defaultProps = {
itemToString: (item: Object) => item && item.name,
keyProp: undefined,
}
renderItems = (items: Array<Object>, downshiftProps: Object) => {
renderItems = (items: Array<Object>, selectedItem: any, downshiftProps: Object) => {
const { renderItem, keyProp } = this.props
const { getItemProps, highlightedIndex } = downshiftProps
@ -104,8 +124,15 @@ class Select extends PureComponent<Props> {
{items.length ? (
items.map((item, i) => (
<ItemWrapper key={keyProp ? item[keyProp] : item.key} {...getItemProps({ item })}>
<Item highlighted={i === highlightedIndex}>
{renderItem ? renderItem(item) : <span>{item.name_highlight || item.name}</span>}
<Item highlighted={i === highlightedIndex} horizontal flow={10}>
<Box grow>
{renderItem ? renderItem(item) : <span>{item.name_highlight || item.name}</span>}
</Box>
<Box>
<IconSelected selected={selectedItem === item}>
<Icon name="check" />
</IconSelected>
</Box>
</Item>
</ItemWrapper>
))
@ -176,10 +203,10 @@ class Select extends PureComponent<Props> {
fuseOptions={fuseOptions}
highlight={highlight}
renderHighlight={renderHighlight}
render={items => this.renderItems(items, downshiftProps)}
render={items => this.renderItems(items, selectedItem, downshiftProps)}
/>
) : (
this.renderItems(items, downshiftProps)
this.renderItems(items, selectedItem, downshiftProps)
))}
</Container>
)}

3
static/i18n/en/translation.yml

@ -40,3 +40,6 @@ settings:
display:
language: Language
SelectAccount:
placeholder: Select a account

3
static/i18n/fr/translation.yml

@ -40,3 +40,6 @@ settings:
display:
language: Langage
SelectAccount:
placeholder: Sélectionner un compte

14
yarn.lock

@ -2219,6 +2219,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
chance@^1.0.13:
version "1.0.13"
resolved "https://registry.yarnpkg.com/chance/-/chance-1.0.13.tgz#666bec2db42b3084456a3e4f4c28a82db5ccb7e6"
chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
@ -3138,6 +3142,10 @@ dotenv@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
dotenv@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.0.tgz#0206eb5b336639bf377618a2a304ff00c6a1fddb"
downshift@^1.26.1:
version "1.26.1"
resolved "https://registry.yarnpkg.com/downshift/-/downshift-1.26.1.tgz#ae45a016f211d02f8000584d0b466142fde2dd6b"
@ -8535,9 +8543,9 @@ style-loader@^0.19.0, style-loader@^0.19.1:
loader-utils "^1.0.2"
schema-utils "^0.3.0"
styled-components@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.1.2.tgz#0769655335eb6800dc5f6691425f6f7fe1801e32"
styled-components@^3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.1.4.tgz#1bdc1409c9bacafee3510c573d23b73039b0d875"
dependencies:
buffer "^5.0.3"
css-to-react-native "^2.0.3"

Loading…
Cancel
Save