import React from 'react'; import PropTypes from 'prop-types'; import Icon from 'component/icon'; import Link from 'component/link'; export class DropDownMenuItem extends React.PureComponent { static propTypes = { href: PropTypes.string, label: PropTypes.string, icon: PropTypes.string, onClick: PropTypes.func, }; static defaultProps = { iconPosition: 'left', }; render() { const icon = this.props.icon ? : null; return ( {this.props.iconPosition == 'left' ? icon : null} {this.props.label} {this.props.iconPosition == 'left' ? null : icon} ); } } export class DropDownMenu extends React.PureComponent { constructor(props) { super(props); this._isWindowClickBound = false; this._menuDiv = null; this.state = { menuOpen: false, }; } componentWillUnmount() { if (this._isWindowClickBound) { window.removeEventListener('click', this.handleWindowClick, false); } } handleMenuIconClick(e) { this.setState({ menuOpen: !this.state.menuOpen, }); if (!this.state.menuOpen && !this._isWindowClickBound) { this._isWindowClickBound = true; window.addEventListener('click', this.handleWindowClick, false); e.stopPropagation(); } return false; } handleMenuClick(e) { // Event bubbles up to the menu after a link is clicked this.setState({ menuOpen: false, }); } /* this will force "this" to always be the class, even when passed to an event listener */ handleWindowClick = e => { if (this.state.menuOpen && (!this._menuDiv || !this._menuDiv.contains(e.target))) { this.setState({ menuOpen: false, }); } }; render() { if (!this.state.menuOpen && this._isWindowClickBound) { this._isWindowClickBound = false; window.removeEventListener('click', this.handleWindowClick, false); } return (
(this._menuButton = span)} button="text" icon="icon-ellipsis-v" onClick={event => { this.handleMenuIconClick(event); }} /> {this.state.menuOpen ? (
(this._menuDiv = div)} className="menu" onClick={event => { this.handleMenuClick(event); }} > {this.props.children}
) : null}
); } }