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

Outsideclick is not working #139

Open
amitsingh-quotient opened this issue Sep 22, 2021 · 2 comments
Open

Outsideclick is not working #139

amitsingh-quotient opened this issue Sep 22, 2021 · 2 comments

Comments

@amitsingh-quotient
Copy link

amitsingh-quotient commented Sep 22, 2021

I have implemented popover on a modal that is created using react portals. The issue is i am not able to close popover when clicked outside. Below is the code.

<Popover
      isOpen={isPopoverOpen}
      onClickOutside={() => setIsPopoverOpen(false)}
      positions={['right', 'bottom', 'top']} // preferred positions by priority
      content={({ position, childRect, popoverRect }) => (
        <ArrowContainer // if you'd like an arrow, you can import the ArrowContainer!
        position={position}
        childRect={childRect}
        popoverRect={popoverRect}
        arrowColor={'white'}
        arrowSize={15}
        arrowStyle={{ opacity: 1 }}>some content</ArrowContainer>
      )}>
      <button
        aria-haspopup="true"
        style={{
          border: '1px solid #cccccc',
          width: '35px',
          borderRadius: '99px',
          height: '35px',
          textAlign: 'center',
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          padding: '5px',
          backgroundColor: 'white'
        }}
        onClick={handleShareClick}>
        <img src="/share-icon.png" alt="share" height="30" width="30" />
      </button>
    </Popover>

Below is attched screenshot
Screenshot 2021-09-22 at 9 14 27 PM

Also sometimes i am not able to see the popover when i reopen the modal.

@amitsingh-quotient amitsingh-quotient changed the title Outsideclik is not working Outsideclick is not working Sep 22, 2021
@gabriel-dehan
Copy link

gabriel-dehan commented Dec 13, 2021

Having the same issue, solution so far has been to handle the click outside myself with the ref being a div surrounding the popover.

Also, you need to set the "outside click" event handler to the portal and not to the document, and do it post portal rendering.

Example:
Portal setup:

// When creating portal:
 const div = document.createElement('div');
 div.classList.add('portal');
// ...

Outer click hook

// useOuterClick hook

import { useEffect, useRef } from 'react';

export const useOuterClick = (callback: (e: CustomEvent) => void) => {
  const innerRef = useRef<HTMLDivElement | null>(null);
  const callbackRef = useRef<(e: CustomEvent) => void>();

  // set current callback in ref, before second useEffect uses it
  useEffect(() => {
    // useEffect wrapper to be safe for concurrent mode
    callbackRef.current = callback;
  });

  useEffect(() => {
    // Target closest portal if there is one, otherwise the event handler is ignored in portals
    const rootEl = innerRef.current?.closest('.portal') || document;

    rootEl.addEventListener('click', handleClick as EventListener);
    return () =>
      rootEl.removeEventListener('click', handleClick as EventListener);

    // read most recent callback and innerRef dom node from refs
    function handleClick(e: CustomEvent) {
      if (
        e?.target &&
        innerRef.current &&
        callbackRef.current &&
        !innerRef.current.contains(e.target as Node)
      ) {
        callbackRef.current(e);
      }
    }
  }, []); // no need for callback + innerRef dep

  return innerRef; // return ref; client can omit `useRef`
};

When setting up the popover

const innerRef = useOuterClick(() => console.log('it works'));

return (
  <div ref={innerRef}>
    <Popover />
  </div>
)

Could definitely find a way to handle it in the library if the lib searched for the closest portal instead of setting the outside click event handler on the document.
For now this should suffice if you come across the issue though :)

@Aeners
Copy link

Aeners commented May 25, 2022

Thanks @gabriel-dehan, just saved me hours of painful search.
Still would be nice to be able to handle it with the lib, but your solution did the trick.
You made my day 🍾

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

3 participants