elastic / eui

Elastic UI Framework 🙌
https://eui.elastic.co/
Other
6.08k stars 829 forks source link

EuiTooltip stuck open when clicking button that changes state to disabled or loading #6488

Closed rachelhathaway closed 1 year ago

rachelhathaway commented 1 year ago

Hi, our team has encountered a scenario where the EuiTooltip will become stuck in its visible state.

Issue When clicking an EuiButton that is

  1. a child of a tooltip and
  2. has a state change to either disabled or loading on click

the tooltip content will display as expected, but it will remain stuck open until you navigate away from or refresh the page.

Expected behavior The tooltip content should be hidden once the button loses focus, with the user either clicking outside of it, tabbing away, etc.

Examples https://codesandbox.io/s/wizardly-fermi-8jujr8 The first two tooltip/button combos exhibit the reported behavior, the third example behaves as expected. This was reproduced in both FF 106 and Chrome 108, macOS 12.6, but not in Safari.

cee-chen commented 1 year ago

Unfortunately after digging into this, it looks like this is a React and possibly even a browser-level issue that EUI will be hard-pressed to solve: https://github.com/facebook/react/issues/9142

I attempted to add a native addEventListener('blur') workaround as suggested in several comments in the linked thread, but this only produced an effect in Chrome. Firefox did not report a native blur event for me on disabled elements. I'm honestly not sure that we can solve this at the EUI level (vs. waiting for either browsers to standardize this behavior or for React to polyfill/standardize it for us).

It will likely be our very strong suggestion to not use tooltips on buttons that can flip to disabled, as that breaks our accessibility recommendations of anchoring tooltips to non-interactive elements (b/c those tooltips are accessible to mouse users but not to keyboard users).

Another workaround could be to conditionally wrap your tooltip based on disabled status:

const sometimesDisabledButton = (
  <EuiButton disabled={isDisabled}>
    Button
  </EuiButton>
);

return (
  <>
    {isDisabled ? (
      sometimesDisabledButton
    ) : (
      <EuiToolTip content="Tooltip content">
        {sometimesDisabledButton}
      </EuiToolTip>
    )}
  </>
)

EDIT: https://github.com/elastic/eui/issues/5666 would resolve this issue.

rachelhathaway commented 1 year ago

@cee-chen Thanks for the response, I totally forgot I reported this. 🙂

We landed on the same workaround you suggested in the code snippet above at the time of the report, but I'll be sure to follow the linked issue.

cee-chen commented 1 year ago

Thanks Rachel! I'll close this issue in favor of https://github.com/elastic/eui/issues/5666 for now, but unfortunately we have a pretty large backlog so it may be a while before it gets prioritized. Definitely feel free to ping us anytime with any follow-ups or with any other super helpful bug reports! 🎉

github-actions[bot] commented 1 year ago

👋 This issue hasn't seen activity in 3 days, so we're automatically closing this issue as answered. Please leave a comment if that's not the case, or if you have any remaining questions or issues.