2016-10-17 18:55:03 +00:00
|
|
|
import React, { Component, PropTypes } from 'react';
|
|
|
|
|
|
|
|
|
|
import { calculateTooltipDirection } from './helpers';
|
|
|
|
|
import ClickOutside from '../../ClickOutside';
|
2016-11-03 19:40:54 +00:00
|
|
|
|
|
|
|
|
const baseClass = 'ellipsis-menu';
|
2016-10-17 18:55:03 +00:00
|
|
|
|
2016-11-04 17:06:11 +00:00
|
|
|
export class EllipsisMenu extends Component {
|
2016-10-17 18:55:03 +00:00
|
|
|
static propTypes = {
|
|
|
|
|
children: PropTypes.node,
|
2016-10-21 23:13:41 +00:00
|
|
|
positionStyles: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
2016-10-17 18:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constructor (props) {
|
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
|
showChildren: false,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
componentDidMount () {
|
|
|
|
|
const { setTooltipDirection } = this;
|
|
|
|
|
|
|
|
|
|
global.window.addEventListener('resize', setTooltipDirection);
|
|
|
|
|
|
|
|
|
|
return setTooltipDirection();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
componentWillUnmount () {
|
|
|
|
|
const { setTooltipDirection } = this;
|
|
|
|
|
|
|
|
|
|
global.window.removeEventListener('resize', setTooltipDirection);
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onToggleChildren = () => {
|
|
|
|
|
const { showChildren } = this.state;
|
|
|
|
|
|
|
|
|
|
this.setState({ showChildren: !showChildren });
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setDOMNode = (DOMNode) => {
|
|
|
|
|
this.DOMNode = DOMNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setTooltipDirection = () => {
|
|
|
|
|
if (this.DOMNode) {
|
|
|
|
|
const tooltipDirection = calculateTooltipDirection(this.DOMNode);
|
|
|
|
|
|
|
|
|
|
this.setState({ tooltipDirection });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderChildren = () => {
|
|
|
|
|
const { children } = this.props;
|
|
|
|
|
const { showChildren, tooltipDirection } = this.state;
|
|
|
|
|
const triangleDirection = tooltipDirection === 'left' ? 'right' : 'left';
|
|
|
|
|
|
2016-10-19 20:22:18 +00:00
|
|
|
if (!showChildren) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-10-17 18:55:03 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
2016-11-03 19:40:54 +00:00
|
|
|
className={`container-triangle ${triangleDirection} ${baseClass}__triangle ${baseClass}__triangle--${tooltipDirection}`}
|
2016-10-17 18:55:03 +00:00
|
|
|
>
|
|
|
|
|
{children}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render () {
|
|
|
|
|
const { onToggleChildren, renderChildren, setDOMNode } = this;
|
|
|
|
|
const { positionStyles } = this.props;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
ref={setDOMNode}
|
2016-11-03 19:40:54 +00:00
|
|
|
className={baseClass}
|
|
|
|
|
style={positionStyles}
|
2016-10-17 18:55:03 +00:00
|
|
|
>
|
2016-10-21 23:13:41 +00:00
|
|
|
<button
|
|
|
|
|
onClick={onToggleChildren}
|
2016-11-08 14:20:35 +00:00
|
|
|
className={`${baseClass}__btn button button--unstyled`}
|
2016-10-21 23:13:41 +00:00
|
|
|
>
|
|
|
|
|
• • •
|
|
|
|
|
</button>
|
2016-10-17 18:55:03 +00:00
|
|
|
{renderChildren()}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 17:06:11 +00:00
|
|
|
export default ClickOutside(EllipsisMenu, {
|
2016-10-17 18:55:03 +00:00
|
|
|
getDOMNode: (component) => {
|
|
|
|
|
return component.DOMNode;
|
|
|
|
|
},
|
|
|
|
|
onOutsideClick: (component) => {
|
2016-11-17 17:12:41 +00:00
|
|
|
return () => {
|
2016-10-17 18:55:03 +00:00
|
|
|
component.setState({ showChildren: false });
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
});
|