Loëck Vézien
7 years ago
committed by
GitHub
15 changed files with 391 additions and 102 deletions
@ -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) |
|
@ -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), |
||||
|
}) |
||||
|
|
||||
|
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> |
||||
|
) |
||||
|
|
||||
|
type Props = { |
||||
|
accounts: Array<Account>, |
||||
|
onChange?: () => Account | void, |
||||
|
value?: Account | null, |
||||
|
t: T, |
||||
|
} |
||||
|
|
||||
|
export const SelectAccount = ({ accounts, onChange, value, 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) |
@ -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} /> |
||||
|
)} |
||||
|
/> |
||||
|
)) |
@ -0,0 +1,91 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React, { PureComponent } from 'react' |
||||
|
import Scrollbar from 'react-smooth-scrollbar' |
||||
|
import noop from 'lodash/noop' |
||||
|
|
||||
|
import Box from 'components/base/Box' |
||||
|
|
||||
|
type Props = { |
||||
|
maxHeight?: number | string, |
||||
|
children: any, |
||||
|
offsetLimit: Object, |
||||
|
onUpdate: Function, |
||||
|
} |
||||
|
|
||||
|
class GrowScroll extends PureComponent<Props> { |
||||
|
static defaultProps = { |
||||
|
onUpdate: noop, |
||||
|
offsetLimit: { |
||||
|
y: { |
||||
|
max: -3, |
||||
|
min: 3, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
componentDidMount() { |
||||
|
const { offsetLimit } = this.props |
||||
|
|
||||
|
if (this._scrollbar) { |
||||
|
this._scrollbar.addListener(function onScroll({ limit, offset }) { |
||||
|
if (limit.y > 0) { |
||||
|
const maxY = limit.y + offsetLimit.y.max |
||||
|
const minY = offsetLimit.y.min |
||||
|
|
||||
|
if (offset.y > maxY) { |
||||
|
this.scrollTo(offset.x, maxY) |
||||
|
} |
||||
|
|
||||
|
if (offset.y < minY) { |
||||
|
this.scrollTo(offset.x, minY) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
this.handleUpdate(this.props) |
||||
|
} |
||||
|
|
||||
|
componentWillReceiveProps(nextProps: Props) { |
||||
|
this.handleUpdate(nextProps) |
||||
|
} |
||||
|
|
||||
|
handleUpdate = (props: Props) => { |
||||
|
if (this._scrollbar) { |
||||
|
props.onUpdate(this._scrollbar) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
_scrollbar = undefined |
||||
|
|
||||
|
render() { |
||||
|
const { onUpdate, children, maxHeight, ...props } = this.props |
||||
|
|
||||
|
return ( |
||||
|
<Box grow relative> |
||||
|
<Scrollbar |
||||
|
damping={1} |
||||
|
style={{ |
||||
|
...(maxHeight |
||||
|
? { |
||||
|
maxHeight, |
||||
|
} |
||||
|
: { |
||||
|
bottom: 0, |
||||
|
left: 0, |
||||
|
position: 'absolute', |
||||
|
right: 0, |
||||
|
top: 0, |
||||
|
}), |
||||
|
}} |
||||
|
ref={r => r && (this._scrollbar = r.scrollbar)} |
||||
|
> |
||||
|
<Box {...props}>{children}</Box> |
||||
|
</Scrollbar> |
||||
|
</Box> |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default GrowScroll |
@ -0,0 +1,13 @@ |
|||||
|
import React from 'react' |
||||
|
import { storiesOf } from '@storybook/react' |
||||
|
|
||||
|
import Box from 'components/base/Box' |
||||
|
import GrowScroll from 'components/base/GrowScroll' |
||||
|
|
||||
|
const stories = storiesOf('GrowScroll', module) |
||||
|
|
||||
|
stories.add('basic', () => ( |
||||
|
<Box style={{ height: 400, border: '1px solid black' }}> |
||||
|
<GrowScroll>{[...Array(1000).keys()].map(v => <div key={v}>{v}</div>)}</GrowScroll> |
||||
|
</Box> |
||||
|
)) |
Loading…
Reference in new issue