跳到主要内容

Menu 菜单

为页面和功能提供导航的菜单列表。

何时使用

  • 导航菜单是一个网站的灵魂,用户依赖导航在各个页面中进行跳转
  • 一般分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构
  • Menu 可以单独使用,也可以配合 Dropdown 组件使用

在 Kube Design 中,Menu 组件提供了灵活的菜单功能:

  • 图标支持:菜单项可以包含图标
  • 分组标签:使用 MenuLabel 对菜单项进行分组
  • 禁用状态:支持禁用单个菜单项
  • 链接支持:菜单项可以作为链接使用
  • 主题切换:支持浅色和深色主题

示例

基础用法

最基本的菜单用法。

实时编辑器
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuItem icon={<Add />}>创建</MenuItem>
        <MenuItem icon={<Stop />}>停止</MenuItem>
        <MenuItem icon={<Pen />}>编辑</MenuItem>
        <MenuItem icon={<Trash />}>删除</MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

带标签分组

使用 MenuLabel 对菜单项进行分组。

实时编辑器
function Demo() {
  const { Add, Pen, Stop, Trash, Download, Upload } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuLabel>编辑操作</MenuLabel>
        <MenuItem icon={<Add />}>创建</MenuItem>
        <MenuItem icon={<Pen />}>编辑</MenuItem>
        <Divider />
        <MenuLabel>文件操作</MenuLabel>
        <MenuItem icon={<Upload />}>上传</MenuItem>
        <MenuItem icon={<Download />}>下载</MenuItem>
        <Divider />
        <MenuLabel>危险操作</MenuLabel>
        <MenuItem icon={<Stop />}>停止</MenuItem>
        <MenuItem icon={<Trash />}>删除</MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

禁用菜单项

菜单项可以设置为禁用状态。

实时编辑器
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuItem icon={<Add />}>创建</MenuItem>
        <MenuItem icon={<Pen />} disabled>
          编辑(禁用)
        </MenuItem>
        <MenuItem icon={<Stop />}>停止</MenuItem>
        <MenuItem icon={<Trash />} disabled>
          删除(禁用)
        </MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

点击事件

菜单项支持点击事件。

实时编辑器
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;
  const [action, setAction] = React.useState('');

  return (
    <Group direction="column" spacing="md">
      {action && <Text>您点击了: {action}</Text>}
      <Card style={{ width: '220px' }}>
        <Menu>
          <MenuItem icon={<Add />} onClick={() => setAction('创建')}>
            创建
          </MenuItem>
          <MenuItem icon={<Pen />} onClick={() => setAction('编辑')}>
            编辑
          </MenuItem>
          <MenuItem icon={<Stop />} onClick={() => setAction('停止')}>
            停止
          </MenuItem>
          <MenuItem icon={<Trash />} onClick={() => setAction('删除')}>
            删除
          </MenuItem>
        </Menu>
      </Card>
    </Group>
  );
}
结果
Loading...

链接菜单项

菜单项可以作为链接使用。

实时编辑器
function Demo() {
  const { Home, User, Setting, Logout } = KubedIcons;

  return (
    <Card style={{ width: '220px' }}>
      <Menu>
        <MenuItem icon={<Home />} as="a" href="#home">
          首页
        </MenuItem>
        <MenuItem icon={<User />} as="a" href="#profile">
          个人信息
        </MenuItem>
        <MenuItem icon={<Setting />} as="a" href="#settings">
          设置
        </MenuItem>
        <Divider />
        <MenuItem icon={<Logout />} as="a" href="#logout">
          退出登录
        </MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

自定义宽度

通过 width 属性设置菜单宽度。

实时编辑器
function Demo() {
  const { Add, Pen, Trash } = KubedIcons;

  return (
    <Group spacing="md">
      <Card style={{ width: '180px' }}>
        <Menu width={180}>
          <MenuLabel>宽度 180px</MenuLabel>
          <MenuItem icon={<Add />}>创建</MenuItem>
          <MenuItem icon={<Pen />}>编辑</MenuItem>
          <MenuItem icon={<Trash />}>删除</MenuItem>
        </Menu>
      </Card>
      <Card style={{ width: '260px' }}>
        <Menu width={260}>
          <MenuLabel>宽度 260px</MenuLabel>
          <MenuItem icon={<Add />}>创建资源</MenuItem>
          <MenuItem icon={<Pen />}>编辑配置</MenuItem>
          <MenuItem icon={<Trash />}>删除资源</MenuItem>
        </Menu>
      </Card>
    </Group>
  );
}
结果
Loading...

仅图标

菜单项可以只显示图标,不显示文字。

实时编辑器
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '60px' }}>
      <Menu width={60}>
        <MenuItem icon={<Add />} />
        <MenuItem icon={<Pen />} />
        <MenuItem icon={<Stop />} />
        <MenuItem icon={<Trash />} />
      </Menu>
    </Card>
  );
}
结果
Loading...

侧边导航菜单

作为侧边导航使用的菜单。

实时编辑器
function Demo() {
  const { Cluster, Project, Pod, Service, ConfigMap } = KubedIcons;
  const [active, setActive] = React.useState('clusters');

  return (
    <Card style={{ width: '240px' }}>
      <Menu width={240}>
        <MenuLabel>工作负载</MenuLabel>
        <MenuItem
          icon={<Pod />}
          onClick={() => setActive('pods')}
          style={{
            backgroundColor: active === 'pods' ? '#e8f4ff' : 'transparent',
          }}
        >
          容器组 (Pods)
        </MenuItem>
        <MenuItem
          icon={<Service />}
          onClick={() => setActive('services')}
          style={{
            backgroundColor: active === 'services' ? '#e8f4ff' : 'transparent',
          }}
        >
          服务 (Services)
        </MenuItem>
        <Divider />
        <MenuLabel>配置</MenuLabel>
        <MenuItem
          icon={<ConfigMap />}
          onClick={() => setActive('configmaps')}
          style={{
            backgroundColor: active === 'configmaps' ? '#e8f4ff' : 'transparent',
          }}
        >
          配置字典 (ConfigMaps)
        </MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

深色主题

Menu 支持深色主题。

实时编辑器
function Demo() {
  const { Add, Stop, Pen, Trash } = KubedIcons;

  return (
    <Card style={{ width: '220px', backgroundColor: '#242e42' }}>
      <Menu themeType="dark">
        <MenuLabel>菜单标题</MenuLabel>
        <MenuItem icon={<Add />}>创建</MenuItem>
        <MenuItem icon={<Pen />}>编辑</MenuItem>
        <MenuItem icon={<Stop />}>停止</MenuItem>
        <Divider />
        <MenuItem icon={<Trash />}>删除</MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

紧凑模式

减小菜单项间距,适合空间有限的场景。

实时编辑器
function Demo() {
  const { Add, Pen, Stop, Trash } = KubedIcons;

  return (
    <Card style={{ width: '200px' }}>
      <Menu width={200} style={{ padding: '4px 0' }}>
        <MenuItem icon={<Add />} style={{ padding: '6px 12px' }}>
          创建
        </MenuItem>
        <MenuItem icon={<Pen />} style={{ padding: '6px 12px' }}>
          编辑
        </MenuItem>
        <MenuItem icon={<Stop />} style={{ padding: '6px 12px' }}>
          停止
        </MenuItem>
        <MenuItem icon={<Trash />} style={{ padding: '6px 12px' }}>
          删除
        </MenuItem>
      </Menu>
    </Card>
  );
}
结果
Loading...

结合 Dropdown 使用

Menu 最常见的用法是配合 Dropdown 组件使用。

实时编辑器
function Demo() {
  const { More, Add, Pen, Stop, Trash } = KubedIcons;

  const menu = (
    <Menu>
      <MenuLabel>操作</MenuLabel>
      <MenuItem icon={<Add />}>创建</MenuItem>
      <MenuItem icon={<Pen />}>编辑</MenuItem>
      <MenuItem icon={<Stop />}>停止</MenuItem>
      <Divider />
      <MenuItem icon={<Trash />}>删除</MenuItem>
    </Menu>
  );

  return (
    <Dropdown content={menu}>
      <Button>
        <More size={16} style={{ marginRight: '4px' }} />
        更多操作
      </Button>
    </Dropdown>
  );
}
结果
Loading...

API

属性说明类型默认值
width菜单宽度number210
themeType主题类型'light' | 'dark'-
className自定义类名string-
style自定义样式CSSProperties-
children菜单项ReactNode-

MenuItem 实际上是一个占位符组件,真正的渲染由 MenuButton 完成。以下是可用的属性:

属性说明类型默认值
icon菜单项图标ReactNode-
disabled是否禁用booleanfalse
color菜单项颜色string-
rightSection右侧内容区域(如快捷键)ReactNode-
as渲染为指定的 HTML 元素any'button'
onClick点击事件回调(e: MouseEvent) => void-
className自定义类名string-
style自定义样式CSSProperties-
themeType主题类型'light' | 'dark'-
children菜单项内容ReactNode-

MenuLabel 是一个占位符组件,实际渲染为 Text 组件。

属性说明类型默认值
children标签内容ReactNode-
className自定义类名string-
style自定义样式CSSProperties-
themeType主题类型'light' | 'dark'-
信息

关于菜单组成:

  • Menu 是菜单容器,包含 MenuItem、MenuLabel 和 Divider
  • MenuItem 是占位符组件,实际由 MenuButton 渲染
  • MenuLabel 是占位符组件,实际渲染为 Text 组件,用于分组标签
  • Divider 是分隔线,用于分隔不同的菜单组
  • Menu 组件内部会过滤并只渲染 MenuItem、MenuLabel 和 Divider 类型的子元素

关于主题:

  • 默认使用浅色主题
  • 设置 themeType="dark" 使用深色主题
  • 深色主题适合暗色背景下使用
  • themeType 会从 Menu 传递到 MenuItem 和 MenuLabel

关于菜单项类型:

  • 默认 as="button",渲染为按钮元素
  • 设置 as="a" 可以渲染为链接,需配合 href 属性使用
  • 可以使用其他 HTML 元素,如 divspan
  • as 属性通过 MenuButton 组件的 styled-components 实现

关于宽度:

  • Menu 的 width 属性控制整个菜单的宽度
  • 所有菜单项会继承这个宽度
  • 默认宽度为 210px

关于 rightSection:

  • rightSection 可用于显示快捷键、徽章、图标等额外内容
  • 内容会显示在菜单项的右侧
  • 常用于显示键盘快捷键提示(如 ⌘K)或状态标识

使用建议

菜单项数量

保持菜单项数量适中:

// 推荐: 5-8 个菜单项
<Menu>
<MenuItem>选项 1</MenuItem>
<MenuItem>选项 2</MenuItem>
<MenuItem>选项 3</MenuItem>
<MenuItem>选项 4</MenuItem>
<MenuItem>选项 5</MenuItem>
</Menu>

// 如果菜单项过多,考虑使用分组
<Menu>
<MenuLabel>第一组</MenuLabel>
<MenuItem>选项 1-1</MenuItem>
<MenuItem>选项 1-2</MenuItem>
<Divider />
<MenuLabel>第二组</MenuLabel>
<MenuItem>选项 2-1</MenuItem>
<MenuItem>选项 2-2</MenuItem>
</Menu>

使用图标增强识别

为菜单项添加图标:

import { Add, Pen, Trash } from '@kubed/icons';

<Menu>
<MenuItem icon={<Add />}>创建</MenuItem>
<MenuItem icon={<Pen />}>编辑</MenuItem>
<MenuItem icon={<Trash />}>删除</MenuItem>
</Menu>;

分组组织菜单

使用 MenuLabel 和 Divider 组织菜单:

<Menu>
<MenuLabel>基础操作</MenuLabel>
<MenuItem>创建</MenuItem>
<MenuItem>编辑</MenuItem>
<Divider />
<MenuLabel>危险操作</MenuLabel>
<MenuItem>删除</MenuItem>
</Menu>

危险操作的位置

将危险操作放在菜单底部:

<Menu>
<MenuItem>查看</MenuItem>
<MenuItem>编辑</MenuItem>
<MenuItem>复制</MenuItem>
<Divider />
<MenuItem icon={<Trash />}>删除</MenuItem>
</Menu>

禁用而非隐藏

禁用不可用的菜单项,而不是隐藏:

<Menu>
<MenuItem>启动</MenuItem>
<MenuItem disabled>停止(Pod 未运行)</MenuItem>
<MenuItem>重启</MenuItem>
</Menu>

作为导航菜单

作为侧边导航时,突出显示当前选中项:

const [active, setActive] = useState('pods');

<Menu>
<MenuItem
icon={<Pod />}
onClick={() => setActive('pods')}
style={{
backgroundColor: active === 'pods' ? '#e8f4ff' : 'transparent',
fontWeight: active === 'pods' ? 600 : 400,
}}
>
容器组
</MenuItem>
<MenuItem
icon={<Service />}
onClick={() => setActive('services')}
style={{
backgroundColor: active === 'services' ? '#e8f4ff' : 'transparent',
fontWeight: active === 'services' ? 600 : 400,
}}
>
服务
</MenuItem>
</Menu>;

链接菜单项

使用链接时指定 href 属性:

<Menu>
<MenuItem as="a" href="/home">
首页
</MenuItem>
<MenuItem as="a" href="/profile">
个人中心
</MenuItem>
<MenuItem as="a" href="/settings">
设置
</MenuItem>
</Menu>

配合 Dropdown 使用

Menu 常与 Dropdown 配合使用:

<Dropdown content={<Menu>...</Menu>}>
<Button>操作</Button>
</Dropdown>

主题选择

根据背景选择合适的主题:

// 浅色背景: 使用默认主题
<Card>
<Menu>...</Menu>
</Card>

// 深色背景: 使用深色主题
<Card style={{ backgroundColor: '#242e42' }}>
<Menu themeType="dark">...</Menu>
</Card>

菜单宽度设置

根据内容设置合适的宽度:

// 短文本: 较小宽度
<Menu width={180}>
<MenuItem>创建</MenuItem>
<MenuItem>编辑</MenuItem>
</Menu>

// 长文本: 较大宽度
<Menu width={260}>
<MenuItem>创建 Kubernetes 资源</MenuItem>
<MenuItem>编辑 YAML 配置</MenuItem>
</Menu>