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,17 +197,18 @@ 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 } </div>
</div> { nameEl }
{ nameEl } { inviteButton }
{ inviteButton } </AccessibleButton>
</AccessibleButton> </div>
); );
}, },
}); });