Rate my React dropdown that auto closes when the user clicks outside of it. This is an example in Typescript that I did for practice.
import React, {useEffect, useRef, useState} from "react";
import "./Dropdown.css";
import classNames from "classnames";
interface DropdownProps {
label: string;
}
const Dropdown: React.FC<DropdownProps> = ({children, label}) => {
const [showDropdown, setShowDropdown] = useState<boolean>(false);
const dropdownContents = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleClick = (event: MouseEvent) => {
if (
dropdownContents.current &&
event.target instanceof Node &&
!dropdownContents.current.contains(event.target)) {
setShowDropdown(false);
}
};
document.addEventListener("click", handleClick);
return () => document.removeEventListener("click", handleClick);
}, []);
return (
<div ref={dropdownContents} className="dropdown-wrapper">
<button className="dropdown-btn" onClick={() => setShowDropdown((show) => !show)}>{label}</button>
<div className={classNames(["dropdown-contents"], {visible: showDropdown})}>
{children}
</div>
</div>
)
}
export default Dropdown;
.dropdown-wrapper {
position: relative;
}
.dropdown-btn {
border-radius: 0;
border: 1px solid black;
padding: 0.5rem 1rem;
background: #fff;
font-weight: bold;
}
.dropdown-btn:focus {
outline: 1px solid blue;
}
.dropdown-btn:hover {
background: #efefef;
}
.dropdown-btn:active {
background: #bbb;
}
.dropdown-contents {
position: absolute;
left: 0;
top: 100%;
display: none;
-webkit-box-shadow: 5px 5px 15px 5px #000000;
box-shadow: 5px 5px 15px 5px #a8a8a8;
padding: 0.5rem;
}
.visible {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import React, {useEffect, useRef, useState} from "react";
toconst {useEffect, useRef, useState} - React;
. See this MSO post for more information. \$\endgroup\$