115 lines
3.2 KiB
JavaScript
Executable file
115 lines
3.2 KiB
JavaScript
Executable file
import React from 'react';
|
|
import ReactDOM from 'react-dom';
|
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
|
import lodash from 'lodash';
|
|
import Flux from '../lib/flux';
|
|
import TooltipStore from '../stores/TooltipStore';
|
|
import '../styles/tooltip.styl';
|
|
|
|
const Tooltip = React.createClass({
|
|
mixins: [PureRenderMixin],
|
|
|
|
propTypes: {
|
|
text: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.array, React.PropTypes.func]).isRequired,
|
|
type: React.PropTypes.oneOf(['normal', 'error', 'success', 'warning']).isRequired,
|
|
position: React.PropTypes.oneOf(['left', 'top', 'right', 'bottom']).isRequired,
|
|
x: React.PropTypes.number.isRequired,
|
|
y: React.PropTypes.number.isRequired,
|
|
targetWidth: React.PropTypes.number.isRequired,
|
|
targetHeight: React.PropTypes.number.isRequired,
|
|
},
|
|
|
|
getInitialState() {
|
|
return {
|
|
offsetX: null,
|
|
offsetY: null,
|
|
};
|
|
},
|
|
|
|
componentDidMount() {
|
|
this.updateOffsets();
|
|
},
|
|
|
|
componentDidUpdate({text, position, x, y, targetWidth, targetHeight}) {
|
|
if (
|
|
this.props.text !== text ||
|
|
this.props.position !== position ||
|
|
this.props.x !== x ||
|
|
this.props.y !== y ||
|
|
this.props.targetWidth !== targetWidth ||
|
|
this.props.targetHeight !== targetHeight
|
|
) {
|
|
this.updateOffsets();
|
|
}
|
|
},
|
|
|
|
updateOffsets() {
|
|
const domNode = ReactDOM.findDOMNode(this);
|
|
if (domNode == null) {
|
|
return;
|
|
}
|
|
const newState = {
|
|
offsetY: -(domNode.offsetHeight / 2),
|
|
};
|
|
switch (this.props.position) {
|
|
case 'left':
|
|
newState.offsetX = -ReactDOM.findDOMNode(this).offsetWidth;
|
|
newState.offsetY += this.props.targetHeight / 2;
|
|
break;
|
|
case 'right':
|
|
newState.offsetX = this.props.targetWidth;
|
|
newState.offsetY += this.props.targetHeight / 2;
|
|
break;
|
|
case 'bottom':
|
|
newState.offsetX = (this.props.targetWidth - ReactDOM.findDOMNode(this).offsetWidth) / 2;
|
|
newState.offsetY = this.props.targetHeight;
|
|
break;
|
|
case 'top':
|
|
default:
|
|
newState.offsetX = (this.props.targetWidth - ReactDOM.findDOMNode(this).offsetWidth) / 2;
|
|
newState.offsetY = -ReactDOM.findDOMNode(this).offsetHeight;
|
|
}
|
|
this.setState(newState);
|
|
},
|
|
|
|
render() {
|
|
const text = typeof this.props.text === 'function' ? this.props.text() : this.props.text;
|
|
|
|
if (text.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
const style = {
|
|
left: this.state.offsetX === null ? null : this.props.x + this.state.offsetX,
|
|
top: this.state.offsetY === null ? null : this.props.y + this.state.offsetY,
|
|
};
|
|
|
|
return (
|
|
<div className={`tooltip tooltip-${this.props.position} tooltip-${this.props.type}`} style={style}>
|
|
{text}
|
|
</div>
|
|
);
|
|
},
|
|
});
|
|
|
|
const Tooltips = React.createClass({
|
|
mixins: [Flux.StoreListenerMixin(TooltipStore)],
|
|
|
|
getStateFromStores() {
|
|
return {
|
|
tooltips: TooltipStore.getTooltips(),
|
|
};
|
|
},
|
|
|
|
render() {
|
|
const tooltips = lodash.map(this.state.tooltips, (props, i) => <Tooltip key={i} {...props} />);
|
|
return <div className="tooltips">{tooltips}</div>;
|
|
},
|
|
});
|
|
|
|
export default Tooltips;
|
|
|
|
|
|
|
|
// WEBPACK FOOTER //
|
|
// ./discord_app/components/Tooltips.js
|