59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
import { useRef, useEffect, ReactNode, Children } from "react";
|
|
import { DropdownProps } from "../../types/props";
|
|
|
|
const Dropdown = ({ isOpen, setIsOpen, children }: DropdownProps) => {
|
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
const childrenArray = Children.toArray(children);
|
|
|
|
if (childrenArray.length !== 2) {
|
|
console.error("ِDropDown باید دقیقاً دو فرزند داشته باشد.");
|
|
return null;
|
|
}
|
|
|
|
const [ButtonChild, DropDownChild] = childrenArray;
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
if (
|
|
dropdownRef.current &&
|
|
!dropdownRef.current.contains(event.target as Node)
|
|
) {
|
|
setIsOpen(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div className="relative inline-block text-left" ref={dropdownRef}>
|
|
{/* buttom dropdown */}
|
|
<>{ButtonChild}</>
|
|
|
|
{/* dropdown */}
|
|
<>{isOpen && DropDownChild}</>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Dropdown;
|
|
|
|
export const DropdownItem = ({
|
|
children,
|
|
widthTailwind,
|
|
}: {
|
|
children: ReactNode;
|
|
widthTailwind: string;
|
|
}) => {
|
|
return (
|
|
<div
|
|
id="dropdown"
|
|
className={`z-[100] rounded-lg shadow ${widthTailwind} bg-gray-700 absolute mt-2 p-2`}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
};
|