MyCrypto/common/components/ui/Dropdown.jsx

82 lines
1.7 KiB
React
Raw Normal View History

2017-05-23 23:06:01 +00:00
// @flow
import React, { Component } from 'react';
2017-07-04 01:25:01 +00:00
type Props<T> = {
2017-07-04 03:21:19 +00:00
value: T,
options: T[],
ariaLabel: string,
formatTitle: (option: T) => any,
extra?: any,
onChange: (value: T) => void
};
2017-05-23 23:06:01 +00:00
2017-07-04 01:25:01 +00:00
type State = {
2017-07-04 03:21:19 +00:00
expanded: boolean
};
2017-07-04 01:25:01 +00:00
2017-07-04 03:21:19 +00:00
export default class DropdownComponent<T: *> extends Component<
void,
Props<T>,
State
> {
props: Props<T>;
2017-05-23 23:06:01 +00:00
2017-07-02 05:49:06 +00:00
state = {
expanded: false
};
2017-05-23 23:06:01 +00:00
2017-07-02 05:49:06 +00:00
render() {
const { options, value, ariaLabel, extra } = this.props;
const { expanded } = this.state;
2017-05-23 23:06:01 +00:00
2017-07-02 05:49:06 +00:00
return (
<span className={`dropdown ${expanded ? 'open' : ''}`}>
2017-07-02 05:49:06 +00:00
<a
tabIndex="0"
aria-haspopup="true"
aria-expanded="false"
aria-label={ariaLabel}
className="dropdown-toggle"
onClick={this.toggleExpanded}
>
{this.formatTitle(value)}
<i className="caret" />
</a>
{expanded &&
2017-07-02 05:49:06 +00:00
<ul className="dropdown-menu">
{options.map((option, i) => {
return (
<li key={i}>
<a
className={option === value ? 'active' : ''}
onClick={this.onChange.bind(null, option)}
>
{this.formatTitle(option)}
</a>
</li>
);
})}
{extra}
</ul>}
</span>
);
}
2017-05-23 23:06:01 +00:00
2017-07-02 05:49:06 +00:00
formatTitle(option: any) {
return this.props.formatTitle(option);
}
2017-05-23 23:06:01 +00:00
2017-07-02 05:49:06 +00:00
toggleExpanded = () => {
this.setState(state => {
return {
expanded: !state.expanded
};
});
};
2017-05-23 23:06:01 +00:00
2017-07-02 05:49:06 +00:00
onChange = (value: any) => {
this.props.onChange(value);
this.setState({ expanded: false });
};
2017-05-23 23:06:01 +00:00
}