Calling hide breaks focus restoration when window is blurred
Bug description
Tippy manually blurs the active element when the window is blurred, if a tooltip is attached to it and if the tooltip is hidden:
https://github.com/atomiks/tippyjs/blob/ad85f6feb79cf6c5853c43bf1b2a50c4fa98e7a1/src/bindGlobalEventListeners.ts#L42-L58
This is breaking the browser's focus restoration when switching back to the window.
Reproduction
StackBlitz link: https://stackblitz.com/edit/web-platform-briuf1?file=index.html
- Click in the input with a tooltip, the tooltip is shown
- Press alt+tab to switch to another window
- Press alt+tab again to switch back to the window with the input
The input should be focused but it's not the case. The reproduction includes an input without a tooltip so you can compare the behaviour.
It seems that this was initially implemented as a fix to #72. It would argue that it goes against the browser's behaviour and what's reported in #72 is not an issue but what is expected. But there might be other valid reasons I am not aware of.
Let me know what you think and I'd be happy to submit a PR.
A solution that wouldn't run the risk of breaking current users' expectations would be to add an option that defaults to the current behaviour. With a way to turn it off.
I agree it's expected in this case, what it was trying to fix was the case where the ref has focus but the tippy is hidden (due to the hideOnClick: true behavior), coming back to the window would show it unexpectedly. Probably instead it should be checking to see if it's visible at the time the window is blurred.
EDIT: okay, it checks isVisible but the ref gets blurred when the window is blurred so that's why the check is failing I guess? I wonder if this behavior has changed in browsers somewhat recently? Checking isMounted instead would work, provided it has an animation/transition. If not it would also fail in this case.
okay, it checks
isVisiblebut the ref gets blurred when the window is blurred so that's why the check is failing I guess?
What do you mean by the check is failing? The input receives a blur event, isVisible is false so it blurs the focused element. Seems fine.
When switching window, the input receives a blur event but it's still the activeElement. We could leverage that to set a ignoreNextFocusEvent to true. Alternatively we could store a reference of the new activeElement on blur and then compare it with the reference on focus. If it's the same then ignore the focus event. But that's more work and data to store in memory.
What do you mean by the check is failing? The input receives a blur event, isVisible is false so it blurs the focused element. Seems fine.
If the tippy was visible at the time the window blurred and the input lost focus, it shouldn't close. But the check fails here because the trigger blur event is firing right before the window blur event (I think), so it thinks it's not visible at the time the window blurred even though it was.
But yeah open to a PR with a better solution 👍
I wanted to help with this and submit a PR but I can't install tippy locally. I have a MacBook with an Apple M1 processor and ran into these issues:
- When running
yarn test: failed to build docker-chromium, probably https://github.com/gidztech/jest-puppeteer-docker/issues/47 - When running
yarn dev: too many open files, probably https://github.com/facebook/watchman/issues/923