bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/dropdown/component.jsx

102 lines
2.6 KiB
React
Raw Normal View History

2016-09-02 04:19:37 +08:00
import React, { Component, PropTypes } from 'react';
import { findDOMNode } from 'react-dom';
2016-08-20 05:20:17 +08:00
import styles from './styles';
2016-09-02 04:19:37 +08:00
import DropdownTrigger from './trigger/component';
import DropdownContent from './content/component';
const propTypes = {
children: (props, propName, componentName) => {
const children = props[propName];
if (!children || children.length < 2) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
const trigger = children.find(x => x.type === DropdownTrigger);
const content = children.find(x => x.type === DropdownContent);
2016-08-20 05:20:17 +08:00
2016-09-02 04:19:37 +08:00
if (!trigger) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Missing `DropdownTrigger`. Validation failed.'
);
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
if (!content) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Missing `DropdownContent`. Validation failed.'
);
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
},
};
2016-08-20 05:20:17 +08:00
2016-09-02 04:19:37 +08:00
export default class Dropdown extends Component {
constructor(props) {
super(props);
this.state = { isOpen: false, };
this.handleShow = this.handleShow.bind(this);
this.handleHide = this.handleHide.bind(this);
this.handleToggle = this.handleToggle.bind(this);
this.handleWindowClick = this.handleWindowClick.bind(this);
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
handleShow() {
this.setState({ isOpen: true });
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
handleHide() {
this.setState({ isOpen: false });
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
componentDidMount () {
const { addEventListener } = window;
addEventListener('click', this.handleWindowClick, false);
2016-08-20 05:20:17 +08:00
}
2016-09-02 04:19:37 +08:00
componentWillUnmount () {
const { removeEventListener } = window;
removeEventListener('click', this.handleWindowClick, false);
2016-08-24 06:19:13 +08:00
}
2016-09-02 04:19:37 +08:00
handleWindowClick(event) {
const dropdownElement = findDOMNode(this);
const shouldUpdateState = event.target !== dropdownElement &&
!dropdownElement.contains(event.target) &&
this.state.isOpen;
2016-09-02 04:19:37 +08:00
if (shouldUpdateState) {
this.handleHide();
}
}
2016-08-24 06:19:13 +08:00
2016-09-02 04:19:37 +08:00
handleToggle() {
this.state.isOpen ?
this.handleHide() :
this.handleShow();
2016-08-20 05:20:17 +08:00
}
render() {
2016-09-02 04:19:37 +08:00
const { children } = this.props;
2016-08-24 06:19:13 +08:00
2016-09-02 04:19:37 +08:00
let trigger = children.find(x => x.type === DropdownTrigger);
const content = children.find(x => x.type === DropdownContent);
2016-08-24 06:19:13 +08:00
2016-09-02 04:19:37 +08:00
trigger = React.cloneElement(trigger, {
handleToggle: this.handleToggle,
});
2016-08-24 06:19:13 +08:00
2016-09-02 04:19:37 +08:00
return (
<div className={styles.dropdown}>
{trigger}
{this.state.isOpen ? content : null}
2016-08-20 05:20:17 +08:00
</div>
);
}
}
2016-09-02 04:19:37 +08:00
Dropdown.propTypes = propTypes;