55 lines
1.2 KiB
TypeScript
55 lines
1.2 KiB
TypeScript
import { MoreHorizontal } from 'lucide-react';
|
|
import { IconButton } from './IconButton';
|
|
|
|
export interface ActionMenuItem {
|
|
label: string;
|
|
onClick: () => void;
|
|
danger?: boolean;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export interface ActionMenuProps {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
label: string;
|
|
items: ActionMenuItem[];
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export function ActionMenu({
|
|
open,
|
|
onOpenChange,
|
|
label,
|
|
items,
|
|
disabled,
|
|
}: ActionMenuProps) {
|
|
return (
|
|
<div className="ui-action-menu">
|
|
<IconButton
|
|
label={label}
|
|
icon={<MoreHorizontal size={20} strokeWidth={2} />}
|
|
onClick={() => onOpenChange(!open)}
|
|
disabled={disabled}
|
|
aria-expanded={open}
|
|
/>
|
|
{open ? (
|
|
<div className="ui-action-menu-popover" role="menu">
|
|
{items.map((item) => (
|
|
<button
|
|
type="button"
|
|
role="menuitem"
|
|
className={item.danger ? 'is-danger' : ''}
|
|
onClick={item.onClick}
|
|
disabled={item.disabled}
|
|
key={item.label}
|
|
>
|
|
{item.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|
|
|