All files ContextMenuPopup.js

100% Statements 26/26
100% Branches 20/20
100% Functions 13/13
100% Lines 26/26
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103        13x   13x           10x   10x 5x   5x         23x 23x   23x                 23x       23x 2x     23x       23x       23x 46x 23x       23x               1x           23x 46x 23x       23x               1x           1x           1x            
import React from 'react';
 
class ContextMenuPopup extends React.Component {
	constructor () {
		super();
 
		this.state = {
			optionsVisible: false
		};
	}
 
    componentDidUpdate() {
        this.boundClickCallback = this.boundClickCallback || this.close.bind(this);
 
		if (this.state.optionsVisible) {
            document.addEventListener('click', this.boundClickCallback);
        } else {
            document.removeEventListener('click', this.boundClickCallback);
        }
    }
 
	render() {
		const Trigger = this.getTriggerElement();
		const OptionsList = this.getOptionsListElement();
 
		return (
			<div className={this.getClassName()} style={this.getStyles()}>
				{Trigger}
				{this.state.optionsVisible ? OptionsList : null}
			</div>
		)
	}
 
	getStyles() {
		const required = {
			position: 'relative'
		};
 
		if (this.props.style) {
		    Object.assign(required, this.props.style);
		}
 
		return required;
	}
 
	getClassName() {
		return this.props.className || 'context-menu-popup';
	}
 
	getTriggerElement() {
		const Trigger = React.Children.toArray(this.props.children).filter((item) => {
			if (item && item.type && item.type.name === 'ContextMenuPopupTrigger') {
			    return item;
			}
		})[0];
 
		return React.cloneElement(Trigger, {
			customOnClickHandler: Trigger.props.onClick,
			onClick: this.onTriggerClick.bind(this),
			contextMenuPopup: this
		});
	}
 
	onTriggerClick() {
		this.setState({
			optionsVisible: true
		});
	}
 
	getOptionsListElement() {
		const OptionsList = React.Children.toArray(this.props.children).filter((item) => {
			if (item && item.type && item.type.name === 'ContextMenuPopupOptions') {
				return item;
			}
		})[0];
 
		return React.cloneElement(OptionsList, {
			onMouseLeave: this.onOptionsListMouseLeave.bind(this),
			initialStyles: this.props.initialStyles,
			contextMenuPopup: this
		})
	}
 
	close() {
		this.setState({
			optionsVisible: false
		});
	}
 
	open() {
		this.setState({
			optionsVisible: true
		});
	}
 
	onOptionsListMouseLeave() {
		this.setState({
			optionsVisible: false
		});
	}
}
 
export default ContextMenuPopup;