thinkful-ui
Version:
Shared navigation and UI resources for Thinkful.
99 lines (81 loc) • 2.3 kB
JSX
const React = require('react');
const classnames = require('classnames');
require('./dropdown.less');
/**
* Shared dropdown menu element
* @property data {Array} of items to display in the dropdown,
containing `value` and `displayName`
* @property selectedInd {Int} of the selected index in the list
* @property defaultDisplay {String} of default value that should be displayed
* @property handleChange {Function} to handle dropdown click/change
*/
const Dropdown = React.createClass({
propTypes: {
data: React.PropTypes.array.isRequired,
selectedInd: React.PropTypes.number,
defaultDisplay: React.PropTypes.string,
handleChange: React.PropTypes.func.isRequired
},
getInitialState() {
return {open: false};
},
getDefaultProps() {
return {data: []};
},
componentDidMount() {
document.addEventListener('click', (e) => this._checkClickAway(e));
},
componentWillUnmount() {
document.removeEventListener('click', (e) => this._checkClickAway(e));
},
_checkClickAway(e) {
if (!e.target.hasAttribute('data-clickable')) {
this.setState({open: false});
}
},
_generateNodes() {
const {data} = this.props;
return data.map((item, ind) => {
return (
<p
className="dropdown-item"
id={ind}
value={item.value}>
{item.displayName}
</p>
);
});
},
_toggleOpen() {
this.setState({open: !this.state.open});
},
_handleChange(event) {
let {handleChange} = this.props;
this._toggleOpen();
handleChange(event);
},
componentClickAway() {
this.setState({open: false});
},
render() {
let {selectedInd, data, defaultDisplay} = this.props;
const buttonClasses = classnames('button', 'button__white', 'dd-button');
const dropdownClasses = classnames(
'dd-open',
{'hidden': !this.state.open});
return (
<div
className={buttonClasses}
onClick={this._toggleOpen}
data-clickable>
{data[selectedInd] && data[selectedInd].displayName || defaultDisplay}
<div
className={dropdownClasses}
onClick={this._handleChange}>
{this._generateNodes()}
</div>
</div>
);
}
});
module.exports = {Dropdown};