Fix sticky hover state by listening for hover on the document

pull/21833/head
Travis Ralston 2019-03-06 16:27:29 -07:00
parent bd887e177f
commit 5b49584d79
1 changed files with 30 additions and 15 deletions

View File

@ -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) { shouldComponentUpdate: function(nextProps, nextState) {
if (this.state.hover !== nextState.hover) return true; if (this.state.hover !== nextState.hover) return true;
return this.props.shouldComponentUpdate(nextProps, nextState); return this.props.shouldComponentUpdate(nextProps, nextState);
}, },
mouseEnter: function(e) { mouseEnter: function(ev) {
this.setState({ 'hover': true }); let targetHover = false;
}, if (this.container && (this.container === ev.target || this.container.contains(ev.target))) {
targetHover = true;
}
mouseLeave: function(e) { if (targetHover !== this.state.hover) {
this.setState({ 'hover': false }); this.setState({hover: targetHover});
}
}, },
render: function() { render: function() {
@ -183,10 +197,10 @@ const EntityTile = React.createClass({
const av = this.props.avatarJsx || <BaseAvatar name={this.props.name} width={36} height={36} />; const av = this.props.avatarJsx || <BaseAvatar name={this.props.name} width={36} height={36} />;
// The wrapping div is required to make the magic mouse listener work, for some reason.
return ( return (
<AccessibleButton className={mainClassName} title={this.props.title} <div ref={(c) => this.container = c} >
onClick={this.props.onClick} onMouseEnter={this.mouseEnter} <AccessibleButton className={mainClassName} title={this.props.title} onClick={this.props.onClick}>
onMouseLeave={this.mouseLeave}>
<div className="mx_EntityTile_avatar"> <div className="mx_EntityTile_avatar">
{ av } { av }
{ power } { power }
@ -194,6 +208,7 @@ const EntityTile = React.createClass({
{ nameEl } { nameEl }
{ inviteButton } { inviteButton }
</AccessibleButton> </AccessibleButton>
</div>
); );
}, },
}); });