import { DropdownMenu as KDropdownMenu } from "@kobalte/core/dropdown-menu";
import { splitProps, type JSX, For, Show } from "solid-js";
import { tv } from "tailwind-variants";
import { ChevronRight } from "lucide-solid";
// TODO Dropdown Menu 样式
const menuStyles = tv(
{
slots: {
trigger: "inline-block cursor-pointer",
content: [
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-light bg-white p-1 text-zinc-950 shadow-md animate-in zoom-in-95 dark:bg-zinc-950 dark:text-zinc-50",
"data-[expanded]:animate-in data-[closed]:animate-out",
],
item: "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[highlighted]:bg-zinc-100 data-[highlighted]:text-zinc-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:data-[highlighted]:bg-zinc-800 dark:data-[highlighted]:text-zinc-50",
separator: "-mx-1 my-1 h-px border-light",
subIcon: "ml-auto h-4 w-4",
},
},
{
twMerge: true,
},
);
const { content, item, separator, subIcon, trigger } = menuStyles();
// 定义菜单项配置类型
export type DropdownItemConfig = {
label: string;
onClick?: () => void;
disabled?: boolean;
separator?: boolean; // 是否作为分隔线
children?: DropdownItemConfig[]; // 子菜单
};
interface DropdownMenuProps {
trigger: JSX.Element;
items: DropdownItemConfig[];
placement?:
| "bottom"
| "bottom-start"
| "bottom-end"
| "top"
| "left"
| "right";
class?: string;
}
// 递归渲染函数:处理无限级嵌套
const RenderMenuItems = (props: { items: DropdownItemConfig[] }) => {
return (
{(config) => (
}
>
0}
fallback={
config.onClick?.()}
>
{config.label}
}
>
{/* 子菜单渲染逻辑 */}
{config.label}
)}
);
};
export const DropdownMenu = (props: DropdownMenuProps) => {
const [local] = splitProps(props, [
"trigger",
"items",
"placement",
"class",
]);
return (
{local.trigger}
);
};