react-toolbox/components/dropdown/Dropdown.jsx

85 lines
2.4 KiB
JavaScript

import React from 'react';
import style from './style';
class Dropdown extends React.Component {
static propTypes = {
auto: React.PropTypes.bool,
className: React.PropTypes.string,
disabled: React.PropTypes.bool,
label: React.PropTypes.string,
onChange: React.PropTypes.func,
source: React.PropTypes.array.isRequired,
template: React.PropTypes.func,
value: React.PropTypes.string
};
static defaultProps = {
auto: true,
className: '',
disabled: false
};
state = {
active: false,
up: false
};
handleClick = (event) => {
const client = event.target.getBoundingClientRect();
const screen_height = window.innerHeight || document.documentElement.offsetHeight;
const up = this.props.auto ? client.top > ((screen_height / 2) + client.height) : false;
this.setState({active: true, up});
};
handleSelect = (item) => {
if (!this.props.disabled && this.props.onChange) {
this.props.onChange(item);
this.setState({active: false});
}
};
getSelectedItem = () => {
if (this.props.value) {
for (const item of this.props.source) {
if (item.value === this.props.value) return item;
}
} else {
return this.props.source[0];
}
};
renderItem (item, idx) {
const className = item.value === this.props.value ? style.selected : null;
return (
<li key={idx} className={className} onMouseDown={this.handleSelect.bind(this, item.value)}>
{this.props.template ? this.props.template(item) : item.label}
</li>
);
}
render () {
let className = style.root;
const selected = this.getSelectedItem();
if (this.state.up) className += ` ${style.up}`;
if (this.state.active) className += ` ${style.active}`;
if (this.props.disabled) className += ` ${style.disabled}`;
if (this.props.className) className += ` ${this.props.className}`;
return (
<div data-react-toolbox='dropdown' className={className}>
{this.props.label ? <label className={style.label}>{this.props.label}</label> : null}
<ul ref='values' className={style.values}>
{this.props.source.map(this.renderItem.bind(this))}
</ul>
<div ref='value' className={style.value} onClick={this.handleClick}>
{this.props.template ? this.props.template(selected) : <span>{selected.label}</span>}
</div>
</div>
);
}
}
export default Dropdown;