Further tweaks to the tooltip to better handle its position, and simplify it's use
This commit is contained in:
parent
cb101b0a3b
commit
80e6cd6d7c
2 changed files with 64 additions and 25 deletions
|
@ -25,36 +25,31 @@ module.exports = React.createClass({
|
||||||
displayName: 'RoomTooltip',
|
displayName: 'RoomTooltip',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
// The 'parent' can either be a React component or a DOM element
|
||||||
parent: React.PropTypes.object.isRequired,
|
parent: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
// The tooltip is derived from either the room name or a label
|
||||||
room: React.PropTypes.object,
|
room: React.PropTypes.object,
|
||||||
label: React.PropTypes.string,
|
label: React.PropTypes.string,
|
||||||
|
|
||||||
|
// The tooltip position can be tweaked by passing in additional positional information
|
||||||
|
top: React.PropTypes.number,
|
||||||
|
botom: React.PropTypes.number,
|
||||||
|
left: React.PropTypes.number,
|
||||||
|
right: React.PropTypes.number,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Create a wrapper for the tooltip outside the main matrix element
|
// Create a wrapper for the tooltip outside the parent and attach to the body element
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this.tooltipContainer = document.createElement("div");
|
this.tooltipContainer = document.createElement("div");
|
||||||
this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper";
|
this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper";
|
||||||
document.body.appendChild(this.tooltipContainer);
|
document.body.appendChild(this.tooltipContainer);
|
||||||
|
|
||||||
// don't render tooltip if parent is undefined
|
|
||||||
if (this.props.parent) {
|
|
||||||
this._renderTooltip();
|
this._renderTooltip();
|
||||||
|
|
||||||
// tell the roomlist about us so it can position us
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'view_tooltip',
|
|
||||||
tooltip: this.tooltip,
|
|
||||||
parent: this.props.parent,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
dis.dispatch({
|
this._renderTooltip();
|
||||||
action: 'view_tooltip',
|
|
||||||
tooltip: this.tooltip,
|
|
||||||
parent: this.props.parent,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Remove the wrapper element, as the tooltip has finished using it
|
// Remove the wrapper element, as the tooltip has finished using it
|
||||||
|
@ -69,16 +64,60 @@ module.exports = React.createClass({
|
||||||
document.body.removeChild(this.tooltipContainer);
|
document.body.removeChild(this.tooltipContainer);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_isDOMElement: function(obj) {
|
||||||
|
return (obj && typeof obj === "object" && obj instanceof HTMLElement);
|
||||||
|
},
|
||||||
|
|
||||||
|
_isReactComponent: function(obj) {
|
||||||
|
var ReactComponentPrototype = React.Component.prototype;
|
||||||
|
var ReactClassComponentPrototype = (Object.getPrototypeOf(Object.getPrototypeOf(new (React.createClass({ render () {} }))())));
|
||||||
|
|
||||||
|
return (obj && typeof obj === "object" && (ReactComponentPrototype.isPrototypeOf(obj) || ReactClassComponentPrototype.isPrototypeOf(obj)));
|
||||||
|
},
|
||||||
|
|
||||||
_renderTooltip: function() {
|
_renderTooltip: function() {
|
||||||
var label = this.props.room ? this.props.room.name : this.props.label;
|
var label = this.props.room ? this.props.room.name : this.props.label;
|
||||||
|
var style = {};
|
||||||
|
if (this.props.top) { style.top = this.props.top; }
|
||||||
|
if (this.props.bottom) { style.bottom = this.props.bottom; }
|
||||||
|
if (this.props.left) { style.left = this.props.left; }
|
||||||
|
if (this.props.right) { style.right = this.props.right; }
|
||||||
|
|
||||||
|
let parent;
|
||||||
|
if (this._isDOMElement(this.props.parent)) {
|
||||||
|
parent = this.props.parent;
|
||||||
|
} else if (this._isReactComponent(this.props.parent)) {
|
||||||
|
parent = ReactDOM.findDOMNode(this.props.parent);
|
||||||
|
} else {
|
||||||
|
parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a parent exist, add the parents position to the tooltips, so it's correctly
|
||||||
|
// positioned, also taking into account any window zoom
|
||||||
|
// NOTE: The additional 6 pixels for the left position, is to take account of the
|
||||||
|
// tooltips chevron
|
||||||
|
if (parent) {
|
||||||
|
style.top = (+style.top || 0) + parent.getBoundingClientRect().top + window.pageYOffset;
|
||||||
|
style.left = (+style.left || 0) + 6 + parent.getBoundingClientRect().right + window.pageXOffset;
|
||||||
|
style.display = "block";
|
||||||
|
|
||||||
var tooltip = (
|
var tooltip = (
|
||||||
<div className="mx_RoomTooltip">
|
<div className="mx_RoomTooltip" style={style} >
|
||||||
<img className="mx_RoomTooltip_chevron" src="img/chevron-left.png" width="9" height="16"/>
|
<img className="mx_RoomTooltip_chevron" src="img/chevron-left.png" width="9" height="16"/>
|
||||||
{ label }
|
{ label }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Render the tooltip manually, as we wish it to not be render within the parent
|
||||||
this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer);
|
this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer);
|
||||||
|
|
||||||
|
// tell the roomlist about us so it can position us
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_tooltip',
|
||||||
|
tooltip: this.tooltip,
|
||||||
|
parent: parent,
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
|
@ -28,9 +28,9 @@ limitations under the License.
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
left: 52px;
|
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
mx_RoomToolTip_placeholder {
|
mx_RoomToolTip_placeholder {
|
||||||
|
|
Loading…
Reference in a new issue