From 5b49584d79fd709712817f07ab833f958de09549 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Mar 2019 16:27:29 -0700 Subject: [PATCH] Fix sticky hover state by listening for hover on the document --- src/components/views/rooms/EntityTile.js | 45 ++++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/components/views/rooms/EntityTile.js b/src/components/views/rooms/EntityTile.js index 009da0ebd4..e99f0a6746 100644 --- a/src/components/views/rooms/EntityTile.js +++ b/src/components/views/rooms/EntityTile.js @@ -92,17 +92,31 @@ const EntityTile = React.createClass({ }; }, + componentWillMount: function() { + // We use a listener on the document so we can find out when the cursor leaves the element more + // safely. This is a workaround for https://github.com/facebook/react/issues/4492 and + // https://github.com/vector-im/riot-web/issues/1997 + document.addEventListener("mouseover", this.mouseEnter); + }, + + componentWillUnmount: function() { + document.removeEventListener("mouseover", this.mouseEnter); + }, + shouldComponentUpdate: function(nextProps, nextState) { if (this.state.hover !== nextState.hover) return true; return this.props.shouldComponentUpdate(nextProps, nextState); }, - mouseEnter: function(e) { - this.setState({ 'hover': true }); - }, + mouseEnter: function(ev) { + let targetHover = false; + if (this.container && (this.container === ev.target || this.container.contains(ev.target))) { + targetHover = true; + } - mouseLeave: function(e) { - this.setState({ 'hover': false }); + if (targetHover !== this.state.hover) { + this.setState({hover: targetHover}); + } }, render: function() { @@ -183,17 +197,18 @@ const EntityTile = React.createClass({ const av = this.props.avatarJsx || ; + // The wrapping div is required to make the magic mouse listener work, for some reason. return ( - -
- { av } - { power } -
- { nameEl } - { inviteButton } -
+
this.container = c} > + +
+ { av } + { power } +
+ { nameEl } + { inviteButton } +
+
); }, });