ContextMenu
右键触发的上下文菜单,支持嵌套子菜单、复选框组和单选组
上下文菜单(ContextMenu)在用户右键点击触发区域时弹出,提供与当前上下文相关的操作列表。组件基于 Radix ContextMenu 封装,通过 items 数组数据驱动渲染,支持普通选项、子菜单、标签、分隔线、复选框组和单选组。
import {
ContextMenu,
ContextMenuCheckbox,
ContextMenuRadio
} from '@skyroc/web-ui';架构说明
ContextMenu 提供三个主入口组件,适应不同场景:
ContextMenu:通用上下文菜单,items支持混合使用普通选项、子菜单、复选框组和单选组。ContextMenuCheckbox:专用复选框菜单,当菜单仅包含复选项时使用,API 更简洁。ContextMenuRadio:专用单选菜单,当菜单仅包含单选项时使用。
三者均为数据驱动:传入 items 数组,组件自动渲染对应的菜单结构。
内部子组件基于共享的 menu/ 基础层,注入 Radix ContextMenu 原语(Item、CheckboxItem、RadioItem、Sub 等),确保样式和交互与其他菜单类组件(如 DropdownMenu)保持一致。
何时使用
- 需要在右键点击时提供操作列表(如文件管理器、编辑器、表格行操作)。
- 操作项较多且需要分组、嵌套时。
- 需要在菜单中提供状态切换(复选、单选)。
- 与 DropdownMenu 的区分:ContextMenu 由右键触发,DropdownMenu 由按钮点击触发。
基础用法
在触发区域右键点击弹出菜单。items 支持普通选项、标签、分隔线和嵌套子菜单,通过 type 字段区分。
复选框组
通过 type: 'checkbox' 在菜单中嵌入复选框组,checks 和 onChecksChange 控制勾选状态。
单选组
通过 type: 'radio' 在菜单中嵌入单选组,value 和 onValueChange 控制选中状态。
混合模式
普通选项、子菜单、复选框组和单选组可以在同一个 items 数组中混合使用。
API
ContextMenu
通用属性参考:支持 Radix ContextMenu Root 的 dir、modal、onOpenChange 属性。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| children | 右键触发区域的内容 | ReactNode | - |
| items* | 菜单项数据数组,支持普通选项、子菜单、复选框组、单选组、标签和分隔线 | ContextMenuOption[] | - |
| classNames | 各 slot 的自定义 class | MenuClassNames | - |
| size | 尺寸,影响所有子组件的字号与间距 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'md' |
| contentProps | 传递给菜单内容容器的额外属性 | ContextMenuContentProps | - |
| dir | 文本方向 | 'ltr' | 'rtl' | - |
| modal | 是否以模态模式打开 | boolean | - |
| onOpenChange | 菜单打开/关闭状态变化回调 | (open: boolean) => void | - |
选项数据结构
items 数组中的每个元素通过 type 字段区分类型:
| 类型 | 说明 | 必填字段 |
|---|---|---|
item | 可选择的菜单项(默认类型,可省略) | label |
label | 不可交互的分组标签 | type、label |
separator | 分隔线 | type |
sub | 子菜单,展开后显示嵌套选项 | type、children |
checkbox | 复选框组,支持多选 | type、children |
radio | 单选组,支持互斥选择 | type、children |
普通选项(item)
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 选项显示文本 | ReactNode | - |
| type | 标识为普通选项,可省略 | 'item' | - |
| onSelect | 选中时触发的回调 | (event: Event) => void | - |
| disabled | 是否禁用 | boolean | - |
| leading | 前置插槽,通常放图标 | ReactNode | - |
| trailing | 后置插槽 | ReactNode | - |
| shortcut | 关联的键盘快捷键 | string | string[] | - |
| className | 选项的 class | ClassValue | - |
| classNames | 选项内各 slot 的 class(item / shortcut) | Pick<MenuClassNames, 'item' | 'shortcut'> | - |
子菜单(sub)
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type* | 标识为子菜单 | 'sub' | - |
| label | 子菜单触发项的显示文本 | ReactNode | - |
| children* | 子菜单内的选项数组,支持嵌套 | MenuOptionData[] | - |
| leading | 前置插槽 | ReactNode | - |
| trailing | 后置插槽 | ReactNode | - |
| triggerIcon | 子菜单展开指示图标 | ReactNode | - |
| className | 触发项的 class | ClassValue | - |
| classNames | 触发项图标 slot 的 class | Pick<MenuClassNames, 'subTriggerIcon'> | - |
复选框组(checkbox)
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type* | 标识为复选框组 | 'checkbox' | - |
| children* | 复选项数组,每项包含 label 和 value | MenuCheckboxGroupItemProps[] | - |
| checks | 当前已勾选的值数组 | string[] | - |
| onChecksChange | 勾选状态变化回调 | (checks: string[]) => void | - |
单选组(radio)
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type* | 标识为单选组 | 'radio' | - |
| children* | 单选项数组,每项包含 label 和 value | MenuRadioItemOptionProps[] | - |
| value | 当前选中的值 | string | - |
| onValueChange | 选中值变化回调 | (value: string) => void | - |
ContextMenuCheckbox
纯复选框菜单的便捷组件。当菜单仅包含复选项时,可直接使用此组件代替 ContextMenu。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| children | 右键触发区域的内容 | ReactNode | - |
| items* | 复选项数组 | MenuCheckboxGroupItemProps[] | - |
| checks | 当前已勾选的值数组 | string[] | - |
| onChecksChange | 勾选状态变化回调 | (checks: string[]) => void | - |
| classNames | 各 slot 的自定义 class | MenuClassNames | - |
| size | 尺寸 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'md' |
| contentProps | 传递给菜单内容容器的额外属性 | ContextMenuContentProps | - |
ContextMenuRadio
纯单选菜单的便捷组件。当菜单仅包含单选项时,可直接使用此组件代替 ContextMenu。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| children | 右键触发区域的内容 | ReactNode | - |
| items* | 单选项数组 | MenuRadioItemOptionProps[] | - |
| value | 当前选中的值 | string | - |
| onValueChange | 选中值变化回调 | (value: string) => void | - |
| classNames | 各 slot 的自定义 class | MenuClassNames | - |
| size | 尺寸 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'md' |
| contentProps | 传递给菜单内容容器的额外属性 | ContextMenuContentProps | - |
类型
MenuClassNames
菜单各 slot 的自定义 class 配置。ContextMenu、DropdownMenu 等菜单类组件共享此类型。
| 字段 | 类型 | 说明 |
|---|---|---|
| arrow | ClassValue | 箭头。 |
| content | ClassValue | 菜单内容容器。 |
| item | ClassValue | 菜单项。 |
| itemIcon | ClassValue | 菜单项图标。 |
| itemIndicator | ClassValue | 复选/单选指示器。 |
| checkboxItem | ClassValue | 复选菜单项。 |
| radioItem | ClassValue | 单选菜单项。 |
| radioIndicatorIcon | ClassValue | 单选指示器图标。 |
| label | ClassValue | 分组标签。 |
| group | ClassValue | 分组容器。 |
| separator | ClassValue | 分隔线。 |
| shortcut | ClassValue | 快捷键展示区。 |
| subTrigger | ClassValue | 子菜单触发项。 |
| subTriggerIcon | ClassValue | 子菜单展开指示图标。 |
| subContent | ClassValue | 子菜单内容容器。 |
| itemLink | ClassValue | 链接菜单项。 |
| itemLinkIcon | ClassValue | 链接菜单项图标。 |
ContextMenuContentProps
菜单内容容器属性。继承 Radix ContextMenu Content 的定位属性(side、sideOffset、align、alignOffset 等)。
| 字段 | 类型 | 说明 |
|---|---|---|
| className | ClassValue | 内容容器 class。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 尺寸。 |
| showArrow | boolean | 是否显示箭头。 |
| arrowClass | ClassValue | 箭头 class。 |
| side | 'top' | 'right' | 'bottom' | 'left' | 弹出方向。 |
| sideOffset | number | 弹出方向偏移量(px)。 |
| align | 'start' | 'center' | 'end' | 对齐方式。 |
| alignOffset | number | 对齐方向偏移量(px)。 |
MenuCheckboxGroupItemProps
复选框组子项数据。每一项可以是复选项、标签或分隔线。
| 字段 | 类型 | 说明 |
|---|---|---|
| label | ReactNode | 复选项显示文本(复选项时使用)。 |
| value | string | 复选项值(复选项时使用)。 |
| disabled | boolean | 是否禁用。 |
| leading | ReactNode | 前置插槽。 |
| trailing | ReactNode | 后置插槽。 |
| shortcut | string | string[] | 关联键盘快捷键。 |
| indicatorIcon | ReactNode | 自定义勾选指示器图标。 |
| type | 'label' | 'separator' | 如果为 label 或 separator,则渲染为标签或分隔线而非复选项。 |
MenuRadioItemOptionProps
单选组子项数据。每一项可以是单选项、标签或分隔线。
| 字段 | 类型 | 说明 |
|---|---|---|
| label | ReactNode | 单选项显示文本(单选项时使用)。 |
| value | string | 单选项值(单选项时使用)。 |
| disabled | boolean | 是否禁用。 |
| leading | ReactNode | 前置插槽。 |
| trailing | ReactNode | 后置插槽。 |
| shortcut | string | string[] | 关联键盘快捷键。 |
| indicatorIcon | ReactNode | 自定义选中指示器图标。 |
| type | 'label' | 'separator' | 如果为 label 或 separator,则渲染为标签或分隔线而非单选项。 |
MenuOptionData
普通菜单选项数据联合类型,用于 items 和子菜单 children。通过 type 字段区分:'item'(可省略)为普通选项,'label' 为标签,'separator' 为分隔线,'sub' 为子菜单。详见上方「选项数据结构」。
ContextMenuOption
ContextMenu items 数组的元素类型。普通菜单项通过 MenuOptionData 表达(含 item / label / separator / sub 四种),复选和单选通过专用选项类型表达。
ContextMenuCheckboxOption
复选框组选项,嵌入在 ContextMenu items 中使用
ContextMenuRadioOption
单选组选项,嵌入在 ContextMenu items 中使用