For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/v/0.6.0/components/menu.md.
  • 简体中文
  • Menu 菜单

    按层级组织页面导航。

    基本用法

    basic.tsx
    import { Menu } from '@ifhover/leaf-ui';
    
    import { FolderKanban, House, Palette, Rocket, Settings, Users } from 'lucide-react';
    
    export function MenuBasic() {
      return (
        <Menu
          mode="inline"
          defaultSelectedKey="design"
          defaultOpenKeys={['projects']}
          items={[
            { key: 'home', label: '工作台', icon: <House /> },
            {
              key: 'projects',
              label: '项目管理',
              icon: <FolderKanban />,
              children: [
                { key: 'design', label: '设计资源', icon: <Palette /> },
                { key: 'release', label: '发布管理', icon: <Rocket /> },
              ],
            },
            { key: 'team', label: '团队成员', icon: <Users /> },
            { key: 'settings', label: '设置', icon: <Settings /> },
          ]}
        />
      );
    }
    

    更多用法

    横向导航
    可折叠侧栏
    advanced.tsx
    import type { MenuItem } from '@ifhover/leaf-ui';
    
    import { Button, Flex, Menu, Text } from '@ifhover/leaf-ui';
    
    import { BookOpen, Folder, House, Palette, Settings } from 'lucide-react';
    
    import { useState } from 'react';
    
    const items: MenuItem[] = [
      { key: 'home', label: '概览', icon: <House /> },
      {
        key: 'resources',
        label: '资源',
        icon: <Folder />,
        children: [
          { key: 'components', label: '组件', icon: <BookOpen /> },
          { key: 'themes', label: '主题', icon: <Palette /> },
        ],
      },
      { key: 'settings', label: '设置', icon: <Settings /> },
    ];
    
    export function MenuHorizontal() {
      const [collapsed, setCollapsed] = useState(false);
      return (
        <Flex direction="column" gap={20}>
          <Flex direction="column" gap="sm" align="center">
            <Text tone="muted">横向导航</Text>
            <Menu mode="horizontal" items={items} defaultSelectedKey="home" />
          </Flex>
          <Flex direction="column" gap="sm" align="center">
            <Text tone="muted">可折叠侧栏</Text>
            <Button variant="ghost" size="sm" onClick={() => setCollapsed((value) => !value)}>
              切换折叠
            </Button>
            <Menu collapsed={collapsed} items={items} defaultSelectedKey="home" />
          </Flex>
        </Flex>
      );
    }
    

    受控导航与路由

    selectedKey 跟随当前路由。linkRender 可替换默认链接,例如 React Router 或 Next.js 的 Link;保留传入链接的事件、类名和 ARIA 属性。

    当前页面:overview。示例切换本地状态;接入路由时使用自己的 Link,并保留传入属性。
    capabilities.tsx
    import type { MenuItem } from '@ifhover/leaf-ui';
    
    import { Menu, Space, Text } from '@ifhover/leaf-ui';
    
    import { BookOpen, House, Settings } from 'lucide-react';
    
    import { type AnchorHTMLAttributes, cloneElement, isValidElement, type ReactElement, useState } from 'react';
    
    export function MenuRouting() {
      const [selected, setSelected] = useState('overview');
      const items: MenuItem[] = [
        { key: 'overview', label: '概览', href: '#overview', icon: <House /> },
        {
          key: 'resources',
          label: '资源',
          icon: <BookOpen />,
          children: [
            { key: 'guides', label: '使用指南', href: '#guides' },
            {
              key: 'settings',
              label: '设置',
              href: '#settings',
              icon: <Settings />,
            },
          ],
        },
      ];
      return (
        <Space direction="vertical" align="center">
          <Menu
            aria-label={'应用导航'}
            items={items}
            selectedKey={selected}
            defaultOpenKeys={['resources']}
            onSelect={setSelected}
            linkRender={(_item, link) => {
              if (!isValidElement(link)) return link;
              const element = link as ReactElement<AnchorHTMLAttributes<HTMLAnchorElement>>;
              return cloneElement(element, {
                onClick: (event) => {
                  element.props.onClick?.(event);
                  event.preventDefault();
                },
              });
            }}
          />
          <Text tone="muted">
            {`当前页面:${selected}。示例切换本地状态;接入路由时使用自己的 Link,并保留传入属性。`}
          </Text>
        </Space>
      );
    }
    

    使用说明

    纵向菜单默认 240px,折叠时 60px,可通过 style.width 调整。items 支持嵌套、分组、分隔线与链接。selectedKey 管理当前选中项,openKeys 管理展开项;横向模式与折叠模式使用浮层展示子菜单。

    子菜单展开、收起以及侧栏宽度变化均带有过渡。收起的子项不会参与键盘导航;系统开启减少动态效果时,过渡会自动关闭。

    菜单项、悬停背景和选中高亮与按钮共用基础圆角。通过 ConfigProvider 的 theme.borderRadius 统一调整,也可用 theme.components.Menu.borderRadius 单独设置菜单圆角。

    类型

    组装数据、定义回调和使用 ref 时,可以导入这些类型。

    import type { MenuItem, MenuProps } from '@ifhover/leaf-ui';
    属性类型默认值说明
    keystring必填必需。唯一且稳定的标识
    labelReactNode必填必需。显示内容
    iconReactNode—自定义图标
    hrefstring—目标链接
    disabledboolean—禁用交互。
    dangerboolean—危险操作颜色
    childrenreadonly MenuItem[]—内容或下级项目
    type'item' | 'group' | 'divider'—显示或选项类型
    属性类型默认值说明
    itemsreadonly MenuItem[]必填必需。数据项目,保持 key 唯一且稳定
    mode'vertical' | 'horizontal' | 'inline''vertical'菜单排列方式
    selectedKeystring—受控选中项目
    defaultSelectedKeystring''初始选中项目
    onSelect(key: string, item: MenuItem) => void—选择项目
    openKeysreadonly string[]—受控展开项目
    defaultOpenKeysreadonly string[][]初始展开项目
    onOpenChange(keys: string[]) => void—展开状态变化
    collapsedbooleanfalse受控收起状态
    itemRender(item: MenuItem, content: ReactNode) => ReactNode—自定义条目内容。
    linkRender(item: MenuItem, link: ReactNode) => ReactNode—接入路由链接时保留传入的可访问性和事件属性。
    itemClassNamestring | ((item: MenuItem) => string)—条目类名或按条目计算的类名。