Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useButton stopping propagation #4517

Closed
csantos-nydig opened this issue May 12, 2023 · 2 comments
Closed

useButton stopping propagation #4517

csantos-nydig opened this issue May 12, 2023 · 2 comments

Comments

@csantos-nydig
Copy link

csantos-nydig commented May 12, 2023

🐛 Bug Report

I need to globally listen for click events that happen in any component to close a floating element.

🤔 Expected Behavior

window.document.addEventListener("pointerdown", listener);

This should be called when clicking on any component, including react-aria buttons

😯 Current Behavior

react-aria buttons stop propagation of events, making global listeners not work as expected.

💁 Possible Solution

probably related to #2100 and #2525

🔦 Context

Here is an example with both useButton (from react-aria) and useFloating (from floating-ui)
https://codesandbox.io/s/use-button-floating-ui-eo3joc?file=/src/App.tsx

The floating menu from the last button ("Show context menu") isn't closing when "React aria-button" is closed

💻 Code Sample

https://codesandbox.io/s/use-button-global-listeners-r6rg6x?file=/src/App.tsx

  • Clicking anywhere in the page (title, body, text, native button, links, etc) trigger the global pointerdown listener
  • Clicking on the react-aria button doesn't trigger the global listener 😞

🌍 Your Environment

Software Version(s)
@react-aria/button 3.7.0
@snowystinger
Copy link
Member

That outside press listener should probably be a capturing listener. There are many reasons something might stop propagation. I doubt we are the only instance where this would be problematic for closing the overlay on a click outside.

We do this ourselves in our useInteractOutside

document.addEventListener('pointerdown', onPointerDown, true);

@csantos-nydig
Copy link
Author

Thanks for the quick response @snowystinger - I ended up using their hook for partial stuff:

useDismiss(context, { outsidePress: false, referencePress: false })

And your hook for the other "clicking outside"

  useInteractOutside({
    ref: floatingRef,
    isDisabled: !isOpen,
    onInteractOutside: useCallback(({ target }) => {
      // skips the button reference because its onPress already swaps the open state
      if (referenceRef.current?.contains(target)) {
        return;
      }

      setIsOpen(false);
    }, [])
  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants