Reakit: Inconsistent behavior of tooltip on disabled buttons

Created on 30 Oct 2019  路  3Comments  路  Source: reakit/reakit

馃悰 Bug report

Current behavior

Tooltip on disabled buttons fails to hide properly on chromium based browsers ( chrome, brave...) Tested only on linux.

On Firefox works as expected :+1:

Steps to reproduce the bug

Provide a repo or sandbox with the bug and describe the steps to reproduce it.

  1. Open sandbox: https://codesandbox.io/embed/reakit-menu-with-tooltip-1fvz3
  2. Hover disabled button.

Expected behavior

I'm not sure if this is the intended behavior or if it should just work as expected ( show on hover, hide on click outside or mouse leave etc...)

Possible solution

Should I just hide the tooltip on a disabled component ? what is the popper way to handle this ?

Environment

Chrome 78.0.3904.70
Firefox 71.0b4
Brave "Version 0.70.121 Chromium: 78.0.3904.70"
$ npx envinfo --system --binaries --npmPackages

Environment:
  OS:  Linux 4.15
  Node:  10.15.3
  Yarn:  1.19.1
  npm:  6.12.0
  Watchman:  Not Found
  Xcode:  N/A
  Android Studio:  Not Found

bug

Most helpful comment

Looks like onMouseEnter is fired on React disabled buttons, but not onMouseLeave:

<button
  disabled
  onMouseEnter={() => console.log("enter")}
  onMouseLeave={() => console.log("leave")}
>
  Button
</button>

TooltipReference uses onMouseEnter and onMouseLeave to show/hide the tooltip:
https://github.com/reakit/reakit/blob/65650b3730a4ebcb6c47280277393cc793d5b44a/packages/reakit/src/Tooltip/TooltipReference.ts#L44-L45

Not sure if it's a bug on React or something. The right behavior is to not fire any of these events. That's the way the DOM works when you use addEventListener("mouseenter").

One solution we could do on our side would be using onMouseOver and onMouseOut instead. They won't fire on <Button disabled>. If we want a disabled button to show the tooltip, we can simply use <Button disabled focusable>.

All 3 comments

Looks like onMouseEnter is fired on React disabled buttons, but not onMouseLeave:

<button
  disabled
  onMouseEnter={() => console.log("enter")}
  onMouseLeave={() => console.log("leave")}
>
  Button
</button>

TooltipReference uses onMouseEnter and onMouseLeave to show/hide the tooltip:
https://github.com/reakit/reakit/blob/65650b3730a4ebcb6c47280277393cc793d5b44a/packages/reakit/src/Tooltip/TooltipReference.ts#L44-L45

Not sure if it's a bug on React or something. The right behavior is to not fire any of these events. That's the way the DOM works when you use addEventListener("mouseenter").

One solution we could do on our side would be using onMouseOver and onMouseOut instead. They won't fire on <Button disabled>. If we want a disabled button to show the tooltip, we can simply use <Button disabled focusable>.

I've opened an issue on React: https://github.com/facebook/react/issues/17229

By the way, temporarily, you can fix it by grabbing the onMouseEnter and onMouseLeave props and re-assigning them to onMouseOver and onMouseOut:

<TooltipReference {...tooltip}>
  {({ onMouseEnter, onMouseLeave, ...props }) => (
    <button onMouseOver={onMouseEnter} onMouseOut={onMouseLeave} {...props}>
      Button
    </button>
  )}
</TooltipReference>

Things to note:

  • Put {...props} last so, if things change later, your code will not break.
  • This will not show the tooltip on disabled buttons since they're not focusable and non-pointer users wouldn't be able to activate it. To make that work, as I mentioned before, just pass a focusable prop to Button (the Reakit one).
  • onMouseOver is different from onMouseEnter. The former bubbles up, so, if you have child elements within the button, the event will be triggered more times. This shouldn't be a problem for this particular case, but that's something to keep in mind.

@edwincoronado @diegohaz @btzr-io

I have identified the fix to this issue/Bug, just testing it.I am proceeding to it, please let me know if any issues.

Was this page helpful?
0 / 5 - 0 ratings