import classnames from 'classnames'; import React from 'react'; import ReactDOM from 'react-dom'; import UIActions from '../../actions/UIActions'; export default class ContextMenu extends React.Component { constructor() { super(); this.state = { menuPosition: {}, isMenuPositionIdeal: false }; } componentDidMount() { document.addEventListener('click', UIActions.dismissContextMenu); if (this.props.onMenuOpen) { this.props.onMenuOpen(); } this.checkMenuPosition(); } componentDidUpdate() { this.checkMenuPosition(); } componentWillUnmount() { document.removeEventListener('click', UIActions.dismissContextMenu); if (this.props.onMenuClose) { this.props.onMenuClose(); } } componentWillUpdate(nextProps) { if (nextProps.clickPosition.x !== this.props.clickPosition.x || nextProps.clickPosition.y !== this.props.clickPosition.y) { this.setState({ isMenuPositionIdeal: false, menuPosition: this.getMenuPosition() }); } } checkMenuPosition() { if (!this.state.isMenuPositionIdeal) { this.setState({ isMenuPositionIdeal: true, menuPosition: this.getMenuPosition() }); } } getMenuPosition() { let menuBorderBox = this.getRenderedMenuBorderBox(); let viewportDimensions = this.getViewportDimensions(); let menuPosition = {}; if (menuBorderBox.left + menuBorderBox.width > viewportDimensions.width) { menuPosition.right = viewportDimensions.width - this.props.clickPosition.x; } else { menuPosition.left = menuBorderBox.left; } if (menuBorderBox.height + this.props.clickPosition.y > viewportDimensions.height) { menuPosition.bottom = viewportDimensions.height - this.props.clickPosition.y; } else { menuPosition.top = menuBorderBox.top; } return menuPosition; } getViewportDimensions() { let height = global.window.innerHeight; let width = global.window.innerWidth; return {height, width}; } getRenderedMenuBorderBox() { let menuDOMNode = ReactDOM.findDOMNode(this); if (menuDOMNode) { return menuDOMNode.getBoundingClientRect(); } return null; } getMenuItems(items) { return items.map((item, index) => { let labelAction, labelSecondary, menuItemContent; let menuItemClasses = classnames('menu__item', { 'is-selectable': item.clickHandler, 'menu__item--separator': item.type === 'separator' }); let primaryLabelClasses = classnames('menu__item__label--primary', { 'has-action': item.labelAction }); if (item.labelSecondary) { labelSecondary = ( {item.labelSecondary} ); } if (item.labelAction) { labelAction = ( {item.labelAction} ); } if (item.type !== 'separator') { menuItemContent = ( {item.label} {labelAction} {labelSecondary} ); } return (