98 lines
3.6 KiB
TypeScript
98 lines
3.6 KiB
TypeScript
import { Fragment, MouseEventHandler, ReactNode } from "react";
|
|
import { Menu, Transition } from "@headlessui/react";
|
|
import clsx from "clsx";
|
|
import { Link } from "react-router";
|
|
import { ChevronDownIcon } from "~/components/ui/icons/vendor";
|
|
|
|
interface Props {
|
|
right?: boolean;
|
|
title: string;
|
|
options: {
|
|
title: string;
|
|
routePath?: string;
|
|
onClick?: () => void;
|
|
disabled?: boolean;
|
|
}[];
|
|
children?: ReactNode;
|
|
className?: string;
|
|
btnClassName?: string;
|
|
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
}
|
|
|
|
export default function DropdownStyless({ title, options, right, onClick, className, btnClassName }: Props) {
|
|
return (
|
|
<Menu as="div" className={clsx(className, "relative inline-block text-left")}>
|
|
<div>
|
|
<Menu.Button
|
|
onClick={onClick}
|
|
className={
|
|
btnClassName ??
|
|
"hover:bg-surface-neutral-secondary shadow-focus bg-surface-neutral-primary text-text-neutral-secondary inline-flex w-full justify-center rounded-md text-sm font-medium focus:outline-hidden focus:ring-offset-2 focus:ring-offset-gray-100"
|
|
}
|
|
>
|
|
{title}
|
|
{!btnClassName && <ChevronDownIcon className="text-text-neutral-tertiary -mr-1 ml-2 h-5 w-5" />}
|
|
</Menu.Button>
|
|
</div>
|
|
|
|
<Transition
|
|
as={Fragment}
|
|
enter="transition ease-out duration-100"
|
|
enterFrom="transform opacity-0 scale-95"
|
|
enterTo="transform opacity-100 scale-100"
|
|
leave="transition ease-in duration-75"
|
|
leaveFrom="transform opacity-100 scale-100"
|
|
leaveTo="transform opacity-0 scale-95"
|
|
>
|
|
<Menu.Items
|
|
className={clsx(
|
|
"bg-surface-neutral-modal absolute z-40 mt-2 w-48 rounded-md shadow-lg ring-1 ring-border-default focus:outline-hidden",
|
|
right ? "left-0 origin-top-left" : "right-0 origin-top-right"
|
|
)}
|
|
>
|
|
<div className="py-1">
|
|
{options.map((item, idx) => {
|
|
return (
|
|
<Menu.Item key={idx}>
|
|
{({ active, close }) => (
|
|
<>
|
|
{item.onClick && (
|
|
<button
|
|
type="button"
|
|
className={clsx(
|
|
"hover:bg-surface-neutral-secondary w-full text-left",
|
|
item.disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
|
active ? "text-text-neutral-primary bg-surface-neutral-secondary" : "text-text-neutral-secondary",
|
|
"block px-4 py-2 text-sm"
|
|
)}
|
|
disabled={item.disabled}
|
|
onClick={() => {
|
|
if (item.onClick) {
|
|
item.onClick();
|
|
}
|
|
close();
|
|
}}
|
|
>
|
|
{item.title}
|
|
</button>
|
|
)}
|
|
{item.routePath && (
|
|
<Link
|
|
to={item.routePath}
|
|
className={clsx("w-full text-left", active ? "text-text-neutral-primary bg-surface-neutral-secondary" : "text-text-neutral-secondary", "block px-4 py-2 text-sm")}
|
|
>
|
|
{item.title}
|
|
</Link>
|
|
)}
|
|
</>
|
|
)}
|
|
</Menu.Item>
|
|
);
|
|
})}
|
|
</div>
|
|
</Menu.Items>
|
|
</Transition>
|
|
</Menu>
|
|
);
|
|
}
|