reach / reach-ui

The Accessible Foundation for React Apps and Design Systems
https://reacttraining.com/reach-ui/
MIT License
5.96k stars 561 forks source link

Tooltips re-appear when tabbing back to page with focus #810

Open wooly opened 3 years ago

wooly commented 3 years ago

🐛 Bug report

Current Behavior

Tooltips re-appear when tabbing back to page and the underlying content wrapped by the tooltip has focus.

Expected behavior

The tooltip doesn't re-appear when changing tabs back.

Reproducible example

The first example on the Tooltip documentation page (https://reach.tech/tooltip/) exhibits this behaviour. Hover the notification bell at the bottom left and see the tooltip appear. Click on the bell which causes the tooltip to disappear, then switch to another tab and switch back. The tooltip has re-appeared and remains there until the bell loses focus.

Suggested solution(s)

I am unsure, sorry.

Additional context

This would affect tooltips over interactive elements like buttons that might open, say, a dropdown menu causing the menu to be obscured by the tooltip.

Your environment

Software Name(s) Version
Reach Package @reach/tooltip 0.15.0
React 16
Browser Firefox 89
Assistive tech
Node 12.20.0
npm/yarn 1.22.5
Operating System MacOS 10.14.6
boertel commented 3 years ago

I'm seeing the same behavior with Chrome.

Software Name(s) Version
Reach Package 0.12.1
React 16.14
Browser Chrome 91.0.4472.114 (Official Build) (arm64)
Assistive tech
Node 16.1.0
npm/yarn yarn 1.22.10
Operating System mac os 11.4
boertel commented 3 years ago

This was bothering me, so I had to dig deeper :D I realized that button don't loose focus when leaving the browser window.

You can try this behavior on this codepen:

  1. click button, border appears
  2. leaving your browser window
  3. go back
  4. button still has the border, i.e is still focused

you can actually reproduce the behavior with tooltip on the documentation page: https://reach.tech/tooltip/

  1. click the 🔔 button
  2. leave browser window (preferably move your cursor from the button area so you won't trigger onBlur once going back to the page)
  3. go back 💥 the tooltip appears.

https://user-images.githubusercontent.com/301183/126012439-16bb97a9-75b0-4919-a35e-559fc6d0bd94.mov

same as wooly, I'm not sure what is the best way to fix this (a window.addEventListener('blur', onBlur) to hide the tooltip?! or maybe this is an "expected" behavior?

boertel commented 3 years ago

in the meantime, I'm triggering blur event for each button that have a tooltip:

const ref = useRef<HTMLButtonElement>(null);

const triggerBlur = useCallback(() => {
  if (ref.current) {
    ref.current.blur()
  }
}, [ref]);

useEffect(() => {
  window.addEventListener("blur", triggerBlur);
  return () => window.removeEventListener("blur", triggerBlur);
}, [triggerBlur]);

return (
  <Tooltip label="label">
    <button ref={ref}>My button</button>
  </Tooltip>
);