Skyroc UI
弹层覆盖

DropdownMenu

点击触发的下拉菜单,支持嵌套子菜单、复选框组和单选组

下拉菜单(DropdownMenu)通过点击触发元素弹出,提供操作列表。组件基于 Radix DropdownMenu 封装,通过 items 数组数据驱动渲染,支持普通选项、子菜单、标签、分隔线、复选框组和单选组。

import {
  DropdownMenu,
  DropdownMenuCheckbox,
  DropdownMenuRadio
} from '@skyroc/web-ui';

架构说明

DropdownMenu 提供三个主入口组件,适应不同场景:

  • DropdownMenu:通用下拉菜单,items 支持混合使用普通选项、子菜单、复选框组和单选组。
  • DropdownMenuCheckbox:专用复选框菜单,当菜单仅包含复选项时使用,API 更简洁。
  • DropdownMenuRadio:专用单选菜单,当菜单仅包含单选项时使用。

三者均为数据驱动:传入 items 数组,组件自动渲染对应的菜单结构。

内部子组件基于共享的 menu/ 基础层,注入 Radix DropdownMenu 原语(ItemCheckboxItemRadioItemSub 等),确保样式和交互与其他菜单类组件(如 ContextMenu)保持一致。

何时使用

  • 需要通过按钮点击展开操作列表时(如工具栏、更多操作)。
  • 操作项较多且需要分组、嵌套时。
  • 需要在菜单中提供状态切换(复选、单选)。
  • 与 ContextMenu 的区分:DropdownMenu 由按钮点击触发,ContextMenu 由右键触发。

基础用法

children 作为触发元素,点击后弹出菜单。items 支持普通选项、标签、分隔线和嵌套子菜单,通过 type 字段区分。

Preview
Code
Loading...
<DropdownMenu
  items={[
    { label: '编辑', leading: <Pencil className="size-4" /> },
    { label: '复制', shortcut: '⌘C' },
    { type: 'separator' },
    {
      type: 'sub',
      label: '更多',
      children: [
        { label: '设置' },
        { label: '偏好' }
      ]
    }
  ]}
>
  <button>操作</button>
</DropdownMenu>

箭头

通过 contentProps.showArrow 显示指向触发元素的箭头。箭头样式可通过 classNames.arrow 或内容属性中的箭头 class 配置覆盖。

Preview
Code
Loading...
<DropdownMenu
  contentProps={{ showArrow: true }}
  items={items}
>
  <Button>操作</Button>
</DropdownMenu>

复选框组

通过 type: 'checkbox' 在菜单中嵌入复选框组,checksonChecksChange 控制勾选状态。也可直接使用 DropdownMenuCheckbox 便捷组件。

Preview
Code
Loading...
<DropdownMenuCheckbox
  items={[
    { label: '加粗', value: 'bold' },
    { label: '斜体', value: 'italic' },
    { type: 'separator' },
    { label: '删除线', value: 'strikethrough' }
  ]}
  checks={checks}
  onChecksChange={setChecks}
>
  <button>文本格式</button>
</DropdownMenuCheckbox>

单选组

通过 type: 'radio' 在菜单中嵌入单选组,valueonValueChange 控制选中状态。也可直接使用 DropdownMenuRadio 便捷组件。

Preview
Code
Loading...
<DropdownMenuRadio
  items={[
    { label: '小', value: 'sm' },
    { label: '中', value: 'md' },
    { label: '大', value: 'lg' }
  ]}
  value={size}
  onValueChange={setSize}
>
  <button>字号</button>
</DropdownMenuRadio>

混合模式

普通选项、子菜单、复选框组和单选组可以在同一个 items 数组中混合使用。

Preview
Code
Loading...
<DropdownMenu
  items={[
    { label: '新建文件' },
    { label: '打开文件', shortcut: '⌘O' },
    { type: 'separator' },
    {
      type: 'checkbox',
      checks: viewOptions,
      onChecksChange: setViewOptions,
      children: [
        { type: 'label', label: '视图选项' },
        { label: '显示行号', value: 'lineNumbers' },
        { label: '自动换行', value: 'wordWrap' }
      ]
    },
    { type: 'separator' },
    {
      type: 'radio',
      value: theme,
      onValueChange: setTheme,
      children: [
        { type: 'label', label: '主题' },
        { label: '浅色', value: 'light' },
        { label: '深色', value: 'dark' },
        { label: '跟随系统', value: 'system' }
      ]
    }
  ]}
>
  <button>菜单</button>
</DropdownMenu>

API

通用属性参考:支持 Radix DropdownMenu Root 的 dirmodalopendefaultOpenonOpenChange 属性。

属性说明类型默认值
children触发元素,点击后弹出菜单ReactNode-
items*菜单项数据数组,支持普通选项、子菜单、复选框组、单选组、标签和分隔线DropdownMenuOption[]-
className菜单内容容器的 classClassValue-
classNames各 slot 的自定义 classMenuClassNames-
size尺寸,影响所有菜单项的字号与间距'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
contentProps传递给菜单内容容器的额外属性DropdownMenuContentProps-
open受控模式下的打开状态boolean-
defaultOpen非受控模式下的初始打开状态boolean-
onOpenChange菜单打开/关闭状态变化回调(open: boolean) => void-
dir文本方向'ltr' | 'rtl'-
modal是否以模态模式打开boolean-

选项数据结构

items 数组中的每个元素通过 type 字段区分类型:

类型说明必填字段
item可选择的菜单项(默认类型,可省略)label
label不可交互的分组标签typelabel
separator分隔线type
sub子菜单,展开后显示嵌套选项typechildren
checkbox复选框组,支持多选typechildren
radio单选组,支持互斥选择typechildren

普通选项(item)

属性说明类型默认值
label选项显示文本ReactNode-
type标识为普通选项,可省略'item'-
onSelect选中时触发的回调(event: Event) => void-
disabled是否禁用boolean-
leading前置插槽,通常放图标ReactNode-
trailing后置插槽ReactNode-
shortcut关联的键盘快捷键string | string[]-
className选项的 classClassValue-
classNames选项内各 slot 的 class(item / shortcut)Pick<MenuClassNames, 'item' | 'shortcut'>-

子菜单(sub)

属性说明类型默认值
type*标识为子菜单'sub'-
label子菜单触发项的显示文本ReactNode-
children*子菜单内的选项数组,支持嵌套MenuOptionData[]-
leading前置插槽ReactNode-
trailing后置插槽ReactNode-
triggerIcon子菜单展开指示图标ReactNode-
className触发项的 classClassValue-
classNames触发项图标 slot 的 classPick<MenuClassNames, 'subTriggerIcon'>-

复选框组(checkbox)

属性说明类型默认值
type*标识为复选框组'checkbox'-
children*复选项数组,每项包含 label 和 valueMenuCheckboxGroupItemProps[]-
checks当前已勾选的值数组string[]-
onChecksChange勾选状态变化回调(checks: string[]) => void-

单选组(radio)

属性说明类型默认值
type*标识为单选组'radio'-
children*单选项数组,每项包含 label 和 valueMenuRadioItemOptionProps[]-
value当前选中的值string-
onValueChange选中值变化回调(value: string) => void-

纯复选框菜单的便捷组件。当菜单仅包含复选项时,可直接使用此组件代替 DropdownMenu

属性说明类型默认值
children触发元素,点击后弹出菜单ReactNode-
items*复选项数组MenuCheckboxGroupItemProps[]-
checks当前已勾选的值数组string[]-
onChecksChange勾选状态变化回调(checks: string[]) => void-
classNames各 slot 的自定义 classMenuClassNames-
size尺寸'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
contentProps传递给菜单内容容器的额外属性DropdownMenuContentProps-
open受控模式下的打开状态boolean-
defaultOpen非受控模式下的初始打开状态boolean-
onOpenChange菜单打开/关闭状态变化回调(open: boolean) => void-

纯单选菜单的便捷组件。当菜单仅包含单选项时,可直接使用此组件代替 DropdownMenu

属性说明类型默认值
children触发元素,点击后弹出菜单ReactNode-
items*单选项数组MenuRadioItemOptionProps[]-
value当前选中的值string-
onValueChange选中值变化回调(value: string) => void-
classNames各 slot 的自定义 classMenuClassNames-
size尺寸'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl''md'
contentProps传递给菜单内容容器的额外属性DropdownMenuContentProps-
open受控模式下的打开状态boolean-
defaultOpen非受控模式下的初始打开状态boolean-
onOpenChange菜单打开/关闭状态变化回调(open: boolean) => void-

类型

DropdownMenuContentProps

菜单内容容器属性。继承 Radix DropdownMenu Content 的定位属性(side、sideOffset、align、alignOffset 等)。

字段类型说明
classNameClassValue内容容器 class。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸。
showArrowboolean是否显示箭头。
arrowClassClassValue箭头 class。
side'top' | 'right' | 'bottom' | 'left'弹出方向。
sideOffsetnumber弹出方向偏移量(px)。
align'start' | 'center' | 'end'对齐方式。
alignOffsetnumber对齐方向偏移量(px)。

MenuOptionData

普通菜单选项数据联合类型,用于 items 和子菜单 children。通过 type 字段区分:'item'(可省略)为普通选项,'label' 为标签,'separator' 为分隔线,'sub' 为子菜单。详见上方「选项数据结构」。

{ type?: 'item' } | { type: 'label' } | { type: 'separator' } | { type: 'sub'; children: MenuOptionData[] }

DropdownMenuOption

DropdownMenu items 数组的元素类型。普通菜单项通过 MenuOptionData 表达(含 item / label / separator / sub 四种),复选和单选通过专用选项类型表达。

DropdownMenuCheckboxOption

复选框组选项,嵌入在 DropdownMenu items 中使用

{ type: 'checkbox'; checks?: string[]; onChecksChange?: (checks: string[]) => void; children: MenuCheckboxGroupItemProps[] }

DropdownMenuRadioOption

单选组选项,嵌入在 DropdownMenu items 中使用

{ type: 'radio'; value?: string; onValueChange?: (value: string) => void; children: MenuRadioItemOptionProps[] }

ClassValue

CSS 类名类型

string | null | undefined | Record<string, boolean> | ClassValue[]

On this page