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

Allow passing an array of refs to useClickAway #1036

Open
matthova opened this issue Mar 11, 2020 · 7 comments
Open

Allow passing an array of refs to useClickAway #1036

matthova opened this issue Mar 11, 2020 · 7 comments

Comments

@matthova
Copy link

Is your feature request related to a problem? Please describe.
For my use case I have a button that opens a modal. Once the modal is open, I want clicking away to close the modal, but if I click on the modal toggle button, I get two conflicting commands - from the modal useClickAway event and from the button's onClick event.

Describe the solution you'd like
If I could pass an array of refs then I could prevent the behavior described above by passing a ref for the modal as well as the button.

Describe alternatives you've considered
I had tried making the modal toggle button only fire when the modal is closed, however that still ran into a race-condition, even when setting the mouse events to ['mouseup', 'touchend']. Another alternate solution would be to use a setTimeout, however I'd prefer to not use that.

@idfunctor
Copy link

Oh man, I can't tell you the number of times this has happened to me outside of this library! I'll try to fix this weekend, feel the pain!

@matthova
Copy link
Author

@blnk-space any luck? I've run into a second instance where this would be nice: I'm using a portal and need to ref the portal as well. May try to timebox a solution tomorrow

@matthova
Copy link
Author

PR: #1125

@Afgan0r
Copy link

Afgan0r commented Oct 2, 2020

For those who are looking for a solution to this problem
You can check if your dropdown is already open and then close it

Example:

Wrong:

const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const ref = useRef();

useClickAway(ref, () => setIsDropdownOpen(false));

<div className="container" ref={ref}>
    <div className="dropdown" />
</div>

Correct:

const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const ref = useRef();

useClickAway(ref, () => isDropdownOpen ? setIsDropdownOpen(false) : null);

<div className="container" ref={ref}>
    <div className="dropdown" />
</div>

@sangdth
Copy link

sangdth commented Dec 27, 2020

I'm facing exactly this problem and it always takes like 3-4 additional internal state checking just to close a modal correctly, especially when I have to move modal to portal.

Really looking forward to the PR.

Many thanks.

@sarahdayan
Copy link

I have a similar use case, and for now, I'm using a ref on the element to ignore to work around it.

If the element contains children you'll need to prevent clicks on them, for example using pointer-events: none.

const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const navRef = useRef(null);
const navButtonRef = useRef(null);

useClickAway(navRef, (event) => {
  const clickedNavButton = event.target === navButtonRef.current;

  if (!clickedNavButton) {
    setIsSidebarOpen(false);
  }
});

@philipprus
Copy link

philipprus commented Aug 29, 2024

Hi, everyone. I added this feature to useClickAway (#2593). Waiting review.

@matthova I saw your PR, but I don't understand why it still hasn't merged.

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

6 participants