Use mouseleave instead of mouseout for hover events. Fix tooltip flicker

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
pull/21833/head
Michael Telatynski 2020-07-18 12:01:51 +01:00
parent 58532f2ac4
commit e9633b2e3b
8 changed files with 29 additions and 24 deletions

View File

@ -35,11 +35,6 @@ limitations under the License.
border-color: $reaction-row-button-selected-border-color; border-color: $reaction-row-button-selected-border-color;
} }
// ignore mouse events for all children, treat it as one entire hoverable entity
* {
pointer-events: none;
}
.mx_ReactionsRowButton_content { .mx_ReactionsRowButton_content {
max-width: 100px; max-width: 100px;
overflow: hidden; overflow: hidden;

View File

@ -45,7 +45,7 @@ export default class AccessibleTooltipButton extends React.PureComponent<IToolti
}); });
}; };
onMouseOut = () => { onMouseLeave = () => {
this.setState({ this.setState({
hover: false, hover: false,
}); });
@ -60,7 +60,12 @@ export default class AccessibleTooltipButton extends React.PureComponent<IToolti
label={tooltip || title} label={tooltip || title}
/> : <div />; /> : <div />;
return ( return (
<AccessibleButton {...props} onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} aria-label={title}> <AccessibleButton
{...props}
onMouseOver={this.onMouseOver}
onMouseLeave={this.onMouseLeave}
aria-label={title}
>
{ children } { children }
{ tip } { tip }
</AccessibleButton> </AccessibleButton>

View File

@ -29,6 +29,7 @@ import FlairStore from '../../../stores/FlairStore';
import GroupStore from '../../../stores/GroupStore'; import GroupStore from '../../../stores/GroupStore';
import TagOrderStore from '../../../stores/TagOrderStore'; import TagOrderStore from '../../../stores/TagOrderStore';
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
import AccessibleButton from "./AccessibleButton";
// A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents // A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents
// a thing to click on for the user to filter the visible rooms in the RoomList to: // a thing to click on for the user to filter the visible rooms in the RoomList to:
@ -114,7 +115,7 @@ export default createReactClass({
this.setState({ hover: true }); this.setState({ hover: true });
}, },
onMouseOut: function() { onMouseLeave: function() {
this.setState({ hover: false }); this.setState({ hover: false });
}, },
@ -151,11 +152,14 @@ export default createReactClass({
badgeElement = (<div className={badgeClasses}>{FormattingUtils.formatCount(badge.count)}</div>); badgeElement = (<div className={badgeClasses}>{FormattingUtils.formatCount(badge.count)}</div>);
} }
// FIXME: this ought to use AccessibleButton for a11y but that causes onMouseOut/onMouseOver to fire too much
const contextButton = this.state.hover || this.props.menuDisplayed ? const contextButton = this.state.hover || this.props.menuDisplayed ?
<div className="mx_TagTile_context_button" onClick={this.openMenu} ref={this.props.contextMenuButtonRef}> <AccessibleButton
className="mx_TagTile_context_button"
onClick={this.openMenu}
ref={this.props.contextMenuButtonRef}
>
{"\u00B7\u00B7\u00B7"} {"\u00B7\u00B7\u00B7"}
</div> : <div ref={this.props.contextMenuButtonRef} />; </AccessibleButton> : <div ref={this.props.contextMenuButtonRef} />;
const AccessibleTooltipButton = sdk.getComponent("elements.AccessibleTooltipButton"); const AccessibleTooltipButton = sdk.getComponent("elements.AccessibleTooltipButton");
@ -168,7 +172,7 @@ export default createReactClass({
<div <div
className="mx_TagTile_avatar" className="mx_TagTile_avatar"
onMouseOver={this.onMouseOver} onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut} onMouseLeave={this.onMouseLeave}
> >
<BaseAvatar <BaseAvatar
name={name} name={name}

View File

@ -37,7 +37,7 @@ export default class TextWithTooltip extends React.Component {
this.setState({hover: true}); this.setState({hover: true});
}; };
onMouseOut = () => { onMouseLeave = () => {
this.setState({hover: false}); this.setState({hover: false});
}; };
@ -45,7 +45,7 @@ export default class TextWithTooltip extends React.Component {
const Tooltip = sdk.getComponent("elements.Tooltip"); const Tooltip = sdk.getComponent("elements.Tooltip");
return ( return (
<span onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} className={this.props.class}> <span onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} className={this.props.class}>
{this.props.children} {this.props.children}
<Tooltip <Tooltip
label={this.props.tooltip} label={this.props.tooltip}

View File

@ -26,7 +26,7 @@ const MIN_TOOLTIP_HEIGHT = 25;
interface IProps { interface IProps {
// Class applied to the element used to position the tooltip // Class applied to the element used to position the tooltip
className: string; className?: string;
// Class applied to the tooltip itself // Class applied to the tooltip itself
tooltipClassName?: string; tooltipClassName?: string;
// Whether the tooltip is visible or hidden. // Whether the tooltip is visible or hidden.
@ -120,7 +120,7 @@ export default class Tooltip extends React.Component<IProps> {
public render() { public render() {
// Render a placeholder // Render a placeholder
return ( return (
<div className={this.props.className} > <div className={this.props.className}>
</div> </div>
); );
} }

View File

@ -34,7 +34,7 @@ export default createReactClass({
}); });
}, },
onMouseOut: function() { onMouseLeave: function() {
this.setState({ this.setState({
hover: false, hover: false,
}); });
@ -48,7 +48,7 @@ export default createReactClass({
label={this.props.helpText} label={this.props.helpText}
/> : <div />; /> : <div />;
return ( return (
<div className="mx_TooltipButton" onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} > <div className="mx_TooltipButton" onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave}>
? ?
{ tip } { tip }
</div> </div>

View File

@ -74,7 +74,7 @@ export default class ReactionsRowButton extends React.PureComponent {
}); });
} }
onMouseOut = () => { onMouseLeave = () => {
this.setState({ this.setState({
tooltipVisible: false, tooltipVisible: false,
}); });
@ -129,11 +129,12 @@ export default class ReactionsRowButton extends React.PureComponent {
} }
const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
return <AccessibleButton className={classes} return <AccessibleButton
className={classes}
aria-label={label} aria-label={label}
onClick={this.onClick} onClick={this.onClick}
onMouseOver={this.onMouseOver} onMouseOver={this.onMouseOver}
onMouseOut={this.onMouseOut} onMouseLeave={this.onMouseLeave}
> >
<span className="mx_ReactionsRowButton_content" aria-hidden="true"> <span className="mx_ReactionsRowButton_content" aria-hidden="true">
{content} {content}

View File

@ -66,7 +66,7 @@ const E2EIcon = ({isUser, status, className, size, onClick, hideTooltip, bordere
} }
const onMouseOver = () => setHover(true); const onMouseOver = () => setHover(true);
const onMouseOut = () => setHover(false); const onMouseLeave = () => setHover(false);
let tip; let tip;
if (hover && !hideTooltip) { if (hover && !hideTooltip) {
@ -78,7 +78,7 @@ const E2EIcon = ({isUser, status, className, size, onClick, hideTooltip, bordere
<AccessibleButton <AccessibleButton
onClick={onClick} onClick={onClick}
onMouseOver={onMouseOver} onMouseOver={onMouseOver}
onMouseOut={onMouseOut} onMouseLeave={onMouseLeave}
className={classes} className={classes}
style={style} style={style}
> >
@ -87,7 +87,7 @@ const E2EIcon = ({isUser, status, className, size, onClick, hideTooltip, bordere
); );
} }
return <div onMouseOver={onMouseOver} onMouseOut={onMouseOut} className={classes} style={style}> return <div onMouseOver={onMouseOver} onMouseLeave={onMouseLeave} className={classes} style={style}>
{ tip } { tip }
</div>; </div>;
}; };