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

Can't close dropdown when clicking outside its container #238

Open
anjolaoluwaakindipe opened this issue May 17, 2022 · 3 comments
Open

Comments

@anjolaoluwaakindipe
Copy link

I feel the dropdown should be able to close when clicking on another element, or outside its container.

@saini8686
Copy link

I have the same problem, how can we fix this?

@msubham193
Copy link

can i work on this issue @anjolaoluwaakindipe

@amamenko
Copy link

amamenko commented Jan 8, 2024

I managed to implement this behavior with a custom useClickOutside ref like this:

import { RefObject, useEffect } from "react";

export const useClickOutside = (ref: RefObject<any>, callback?: Function) => {
  useEffect(() => {
    const listener = (event: Event) => {
      if (!ref.current || ref.current?.contains(event.target)) return;
      if (callback) callback(event);
    };

    document.addEventListener("mousedown", listener);
    document.addEventListener("touchstart", listener);

    return () => {
      document.removeEventListener("mousedown", listener);
      document.removeEventListener("touchstart", listener);
    };
  }, [ref, callback]);
};

Then I set two refs, one on the Dropdown component itself (to manipulate the Dropdown component programmatically) and one on a wrapper div to keep track of outside click events. I then used the useClickOutside hook to listen to click events outside of the wrapper div and fired off a callback function that sets the isOpen state of the Dropdown component to false:

import Dropdown from "react-dropdown";
import { useRef } from "react";
import { useClickOutside } from "@/hooks/useClickOutside";
import "react-dropdown/style.css";

export const SomeComponent = () => {
  const dropdownContainerRef = useRef(null);
  const dropdownRef = useRef<Dropdown>(null);

  useClickOutside(dropdownContainerRef, () => {
    const currentRef = dropdownRef.current;
    if (currentRef) {
      const dropdownState = currentRef.state as {
        selected: {
          label: string;
          value: string;
        };
        isOpen: boolean;
      };
      if (dropdownState.isOpen) {
        currentRef.setState({
          ...dropdownState,
          isOpen: false,
        });
      }
    }
  });

  return (
    <div ref={dropdownContainerRef}>
      <Dropdown
        ref={dropdownRef}
        options={options}
        onChange={({ value }) => handleToggleCollapse(value)}
        value={options.find((option) => option.value === currentCollapseId)}
        placeholder="Select an option"
      />
    </div>
  );
};

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

4 participants