From 80e6cd6d7c75280e494cfdaca4ef2bc01547cb6c Mon Sep 17 00:00:00 2001 From: wmwragg Date: Sat, 3 Sep 2016 12:44:09 +0100 Subject: [PATCH] Further tweaks to the tooltip to better handle its position, and simplify it's use --- src/components/views/rooms/RoomTooltip.js | 87 ++++++++++++++----- .../vector-web/views/rooms/RoomTooltip.css | 2 +- 2 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/components/views/rooms/RoomTooltip.js b/src/components/views/rooms/RoomTooltip.js index d055551bd..49a1a7ddf 100644 --- a/src/components/views/rooms/RoomTooltip.js +++ b/src/components/views/rooms/RoomTooltip.js @@ -25,36 +25,31 @@ module.exports = React.createClass({ displayName: 'RoomTooltip', propTypes: { + // The 'parent' can either be a React component or a DOM element parent: React.PropTypes.object.isRequired, + + // The tooltip is derived from either the room name or a label room: React.PropTypes.object, 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() { this.tooltipContainer = document.createElement("div"); this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper"; document.body.appendChild(this.tooltipContainer); - // don't render tooltip if parent is undefined - if (this.props.parent) { - this._renderTooltip(); - - // tell the roomlist about us so it can position us - dis.dispatch({ - action: 'view_tooltip', - tooltip: this.tooltip, - parent: this.props.parent, - }); - } + this._renderTooltip(); }, componentDidUpdate: function() { - dis.dispatch({ - action: 'view_tooltip', - tooltip: this.tooltip, - parent: this.props.parent, - }); + this._renderTooltip(); }, // Remove the wrapper element, as the tooltip has finished using it @@ -69,16 +64,60 @@ module.exports = React.createClass({ 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() { var label = this.props.room ? this.props.room.name : this.props.label; - var tooltip = ( -
- - { 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; } - this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer); + 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 = ( +
+ + { label } +
+ ); + + // Render the tooltip manually, as we wish it to not be render within the parent + 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() { diff --git a/src/skins/vector/css/vector-web/views/rooms/RoomTooltip.css b/src/skins/vector/css/vector-web/views/rooms/RoomTooltip.css index 22ec9e231..8de89d64f 100644 --- a/src/skins/vector/css/vector-web/views/rooms/RoomTooltip.css +++ b/src/skins/vector/css/vector-web/views/rooms/RoomTooltip.css @@ -28,9 +28,9 @@ limitations under the License. border-radius: 8px; background-color: #fff; z-index: 2000; - left: 52px; padding: 6px; pointer-events: none; + line-height: 18px; } mx_RoomToolTip_placeholder {