71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
import { useState, useRef, useEffect } from "react";
|
|
import Button from "./Button";
|
|
import MoreIcon from "../icons/MoreIcon";
|
|
import PopoverWrapper from "./PopoverWrapper";
|
|
|
|
interface ActionsPopoverProps {
|
|
options: {
|
|
label: string;
|
|
onClick: () => void;
|
|
icon?: React.ReactNode;
|
|
disabled?: boolean;
|
|
}[];
|
|
}
|
|
|
|
export default function ActionsPopover({ options }: ActionsPopoverProps) {
|
|
const [isOpened, setIsOpened] = useState(false);
|
|
|
|
const popoverRef = useRef<HTMLDivElement>(null);
|
|
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
|
|
useEffect(() => {
|
|
const handleClickOutside = (event: MouseEvent | TouchEvent) => {
|
|
if (
|
|
popoverRef.current &&
|
|
!popoverRef.current.contains(event.target as Node)
|
|
) {
|
|
setIsOpened(false);
|
|
}
|
|
};
|
|
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
document.addEventListener("touchstart", handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
document.removeEventListener("touchstart", handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div className="relative" ref={popoverRef}>
|
|
<button
|
|
ref={buttonRef}
|
|
className="flex items-center justify-center gap-[0.139vw] size-[1.667vw] rounded-[0.556vw] text-[#CCCCCC] hover:text-[#7D7D7D] hover:bg-[#F3F3F3] active:text-[#141414] "
|
|
onClick={() => setIsOpened(!isOpened)}
|
|
>
|
|
<div className="2xl:size-[1.111vw] size-4 2xl:rounded-[0.556vw] rounded-2xl">
|
|
<MoreIcon />
|
|
</div>
|
|
</button>
|
|
<PopoverWrapper
|
|
isOpened={isOpened}
|
|
buttonRef={buttonRef}
|
|
className="w-[17.222vw]"
|
|
>
|
|
{options.map((option) => (
|
|
<Button
|
|
variant="tertiary"
|
|
className="w-full !justify-start"
|
|
key={option.label}
|
|
onClick={option.onClick}
|
|
disabled={option.disabled}
|
|
>
|
|
<div className="size-[1.111vw] ">{option.icon}</div>
|
|
{option.label}
|
|
</Button>
|
|
))}
|
|
</PopoverWrapper>
|
|
</div>
|
|
);
|
|
}
|