import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { findDOMNode } from 'react-dom'; import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; export default class MenuDroppoComponent extends Component { static propTypes = { isOpen: PropTypes.bool.isRequired, innerStyle: PropTypes.object, children: PropTypes.node.isRequired, onClickOutside: PropTypes.func, containerClassName: PropTypes.string, zIndex: PropTypes.number, style: PropTypes.object.isRequired, useCssTransition: PropTypes.bool, speed: PropTypes.string, }; renderPrimary() { const { isOpen } = this.props; if (!isOpen) { return null; } const innerStyle = this.props.innerStyle || {}; return (
{this.props.children}
); } globalClickOccurred = (event) => { const { target } = event; // eslint-disable-next-line react/no-find-dom-node const container = findDOMNode(this); if ( this.props.isOpen && target !== container && !isDescendant(this.container, event.target) && this.props.onClickOutside ) { this.props.onClickOutside(event); } }; componentDidMount() { if (this && document.body) { document.body.addEventListener('click', this.globalClickOccurred); // eslint-disable-next-line react/no-find-dom-node const container = findDOMNode(this); this.container = container; } } componentWillUnmount() { if (this && document.body) { document.body.removeEventListener('click', this.globalClickOccurred); } } render() { const { containerClassName = '', style } = this.props; const speed = this.props.speed || '300ms'; const { useCssTransition } = this.props; const zIndex = 'zIndex' in this.props ? this.props.zIndex : 0; const baseStyle = { position: 'fixed', ...style, zIndex, }; return (
{useCssTransition ? ( {this.renderPrimary()} ) : ( this.renderPrimary() )}
); } } function isDescendant(parent, child) { let node = child.parentNode; while (node !== null) { if (node === parent) { return true; } node = node.parentNode; } return false; }