UNPKG

2.31 kBJSXView Raw
1const React = require('react');
2const classnames = require('classnames');
3
4require('./dropdown.less');
5
6
7/**
8 * Shared dropdown menu element
9 * @property data {Array} of items to display in the dropdown,
10 containing `value` and `displayName`
11 * @property selectedInd {Int} of the selected index in the list
12 * @property defaultDisplay {String} of default value that should be displayed
13 * @property handleChange {Function} to handle dropdown click/change
14 */
15const Dropdown = React.createClass({
16
17 propTypes: {
18 data: React.PropTypes.array.isRequired,
19 selectedInd: React.PropTypes.number,
20 defaultDisplay: React.PropTypes.string,
21 handleChange: React.PropTypes.func.isRequired
22 },
23
24 getInitialState() {
25 return {open: false};
26 },
27
28 getDefaultProps() {
29 return {data: []};
30 },
31
32 componentDidMount() {
33 document.addEventListener('click', (e) => this._checkClickAway(e));
34 },
35
36 componentWillUnmount() {
37 document.removeEventListener('click', (e) => this._checkClickAway(e));
38 },
39
40 _checkClickAway(e) {
41 if (!e.target.hasAttribute('data-clickable')) {
42 this.setState({open: false});
43 }
44 },
45
46 _generateNodes() {
47 const {data} = this.props;
48 return data.map((item, ind) => {
49 return (
50 <p
51 className="dropdown-item"
52 id={ind}
53 value={item.value}>
54 {item.displayName}
55 </p>
56 );
57 });
58 },
59
60 _toggleOpen() {
61 this.setState({open: !this.state.open});
62 },
63
64 _handleChange(event) {
65 let {handleChange} = this.props;
66 this._toggleOpen();
67 handleChange(event);
68 },
69
70 componentClickAway() {
71 this.setState({open: false});
72 },
73
74 render() {
75 let {selectedInd, data, defaultDisplay} = this.props;
76
77 const buttonClasses = classnames('button', 'button__white', 'dd-button');
78 const dropdownClasses = classnames(
79 'dd-open',
80 {'hidden': !this.state.open});
81
82 return (
83 <button
84 className={buttonClasses}
85 onClick={this._toggleOpen}
86 data-clickable>
87 {data[selectedInd] && data[selectedInd].displayName || defaultDisplay}
88 <div
89 className={dropdownClasses}
90 onClick={this._handleChange}>
91 {this._generateNodes()}
92 </div>
93 </button>
94 );
95 }
96});
97
98module.exports = {Dropdown};