右键菜单
查看源代码显示位于指针处的菜单,通过右键单击或长按触发。
导入
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuGroup,
ContextMenuLabel,
ContextMenuSeparator,
ContextMenuItem,
ContextMenuItemIndicator,
ContextMenuCheckboxItem,
ContextMenuRadioGroup,
ContextMenuRadioItem,
ContextMenuSubTrigger,
} from "@resolid/react-ui";
ContextMenu
: 包含菜单的所有部分。ContextMenuTrigger
: 包装将打开右键菜单的控件。ContextMenuContent
: 打开菜单时弹出的组件。ContextMenuGroup
: 用于对多个ContextMenuItem
进行分组。ContextMenuLabel
: 用于渲染标签。使用方向键无法聚焦。ContextMenuSeparator
: 菜单项和组之间的可视分隔符。ContextMenuItem
: 包含菜单项的组件。ContextMenuRadioGroup
: 用于对多个ContextMenuRadioItem
进行分组。ContextMenuRadioItem
: 一个可以像单选按钮一样进行控制和渲染的项目。ContextMenuCheckboxItem
: 一个可以像复选框一样进行控制和渲染的项目。ContextMenuItemIndicator
: 在父级ContextMenuCheckboxItem
或ContextMenuRadioItem
被选中项目时呈现的视觉指示器。ContextMenuSubTrigger
: 包装将打开子菜单的控件。
演示
当指针是笔或触摸时,在大约 700ms
的长压期间,右键菜单也会打开。
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger,
} from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex flex-row justify-center gap-3"}>
<ContextMenu>
<ContextMenuTrigger
className={
"border-bd-normal flex h-32 select-none items-center rounded-md border border-dashed p-6"
}
>
右键点击显示菜单
</ContextMenuTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem>
新标签页
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+T</span>
</ContextMenuItem>
<ContextMenuItem>
打开新窗口
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+N</span>
</ContextMenuItem>
<ContextMenuItem disabled>
打开新的无痕式窗口
<span className={"ml-auto pl-5 text-xs tracking-widest"}>⇧+⌘+N</span>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>
关闭窗口
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⇧+⌘+W</span>
</ContextMenuItem>
<ContextMenuItem>
关闭标签页
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+W</span>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</div>
);
}
举例
多级菜单
要显示多级菜单,请渲染另一个 ContextMenu
组件并使用 ContextMenuSubTrigger
组件打开子菜单。
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuSubTrigger,
} from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex flex-row justify-center gap-3"}>
<ContextMenu>
<ContextMenuTrigger
className={
"border-bd-normal flex h-32 select-none items-center rounded-md border border-dashed p-6"
}
>
右键点击显示菜单
</ContextMenuTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem label={"New Tab"}>新建标签页</ContextMenuItem>
<ContextMenuItem label={"New Window"}>打开新窗口</ContextMenuItem>
<ContextMenuItem>打开新的无痕式窗口</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenu>
<ContextMenuSubTrigger label={"Share"}>分享</ContextMenuSubTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem label={"Email"}>邮件</ContextMenuItem>
<ContextMenuItem label={"SMS"}>短信</ContextMenuItem>
<ContextMenu>
<ContextMenuSubTrigger>社交媒体</ContextMenuSubTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenu>
<ContextMenuSubTrigger>微信</ContextMenuSubTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem>聊天</ContextMenuItem>
<ContextMenuItem>朋友圈</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
<ContextMenuItem>微博</ContextMenuItem>
<ContextMenuItem>抖音</ContextMenuItem>
<ContextMenuItem>知乎</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</ContextMenuContent>
</ContextMenu>
<ContextMenuSeparator />
<ContextMenu>
<ContextMenuSubTrigger label={"Tools"}>更多工具</ContextMenuSubTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem>保存页面为...</ContextMenuItem>
<ContextMenuItem>创建快捷方式</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>开发者工具</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</ContextMenuContent>
</ContextMenu>
</div>
);
}
分组菜单
使用 ContextMenuGroup
组件对相关菜单项进行分组。
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuGroup,
ContextMenuLabel,
ContextMenuSeparator,
} from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex flex-row justify-center gap-3"}>
<ContextMenu>
<ContextMenuTrigger
className={
"border-bd-normal flex h-32 select-none items-center rounded-md border border-dashed p-6"
}
>
右键点击显示菜单
</ContextMenuTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuGroup>
<ContextMenuLabel>Sort</ContextMenuLabel>
<ContextMenuItem>Date</ContextMenuItem>
<ContextMenuItem>Name</ContextMenuItem>
<ContextMenuItem>Type</ContextMenuItem>
</ContextMenuGroup>
<ContextMenuSeparator />
<ContextMenuGroup>
<ContextMenuLabel>Workspace</ContextMenuLabel>
<ContextMenuItem>Minimap</ContextMenuItem>
<ContextMenuItem>Search</ContextMenuItem>
<ContextMenuItem>Sidebar</ContextMenuItem>
</ContextMenuGroup>
</ContextMenuContent>
</ContextMenu>
</div>
);
}
复杂菜单
import {
ContextMenu,
ContextMenuCheckboxItem,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger,
ContextMenuItemIndicator,
ContextMenuSubTrigger,
ContextMenuRadioGroup,
ContextMenuLabel,
ContextMenuRadioItem,
} from "@resolid/react-ui";
import { useState } from "react";
import { SpriteIcon } from "~/components/sprite-icon";
export default function App() {
const [bookmarksChecked, setBookmarksChecked] = useState(true);
const [urlsChecked, setUrlsChecked] = useState(false);
const [account, setAccount] = useState("张三");
return (
<div className={"flex flex-row justify-center gap-3"}>
<ContextMenu>
<ContextMenuTrigger
className={
"border-bd-normal flex h-32 select-none items-center rounded-md border border-dashed p-6"
}
>
右键点击显示菜单
</ContextMenuTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem>
新标签页
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+T</span>
</ContextMenuItem>
<ContextMenuItem>
打开新窗口
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+N</span>
</ContextMenuItem>
<ContextMenuItem disabled>
打开新的无痕式窗口
<span className={"ml-auto pl-5 text-xs tracking-widest"}>⇧+⌘+N</span>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>
关闭窗口
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⇧+⌘+W</span>
</ContextMenuItem>
<ContextMenuItem>
关闭标签页
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+W</span>
</ContextMenuItem>
<ContextMenuItem>
页面存储为...
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+S</span>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenu>
<ContextMenuSubTrigger>分享</ContextMenuSubTrigger>
<ContextMenuContent className={"text-sm"}>
<ContextMenuItem>电子邮件</ContextMenuItem>
<ContextMenuItem>手机短信</ContextMenuItem>
<ContextMenuItem>隔空投送</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
<ContextMenuSeparator />
<ContextMenuItem>
打印
<span className={"text-fg-subtle ml-auto pl-5 text-xs tracking-widest"}>⌘+P</span>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuCheckboxItem checked={bookmarksChecked} onChange={setBookmarksChecked}>
<ContextMenuItemIndicator>
<SpriteIcon size={"1rem"} name={"check"} />
</ContextMenuItemIndicator>
显示书签栏
<div className="text-fg-subtle ml-auto pl-5 text-xs tracking-widest">⌘+B</div>
</ContextMenuCheckboxItem>
<ContextMenuCheckboxItem checked={urlsChecked} onChange={setUrlsChecked}>
<ContextMenuItemIndicator>
<SpriteIcon size={"1rem"} name={"check"} />
</ContextMenuItemIndicator>
显示路径
</ContextMenuCheckboxItem>
<ContextMenuSeparator />
<ContextMenuRadioGroup value={account} onChange={setAccount}>
<ContextMenuLabel>账号</ContextMenuLabel>
<ContextMenuRadioItem value={"张三"}>
<ContextMenuItemIndicator>
<SpriteIcon size={"1rem"} name={"dot"} />
</ContextMenuItemIndicator>
张三
</ContextMenuRadioItem>
<ContextMenuRadioItem value={"李四"}>
<ContextMenuItemIndicator>
<SpriteIcon size={"1rem"} name={"dot"} />
</ContextMenuItemIndicator>
李四
</ContextMenuRadioItem>
</ContextMenuRadioGroup>
<ContextMenuSeparator />
<ContextMenuItem>其他操作</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</div>
);
}
属性
ContextMenu
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性open | 简介 受控打开状态 | 类型boolean | 默认值- | 必须false |
属性defaultOpen | 简介 初始渲染时的默认打开状态 | 类型boolean | 默认值false | 必须false |
属性onOpenChange | 简介 打开状态改变时调用 | 类型(open: boolean) => void | 默认值- | 必须false |
属性closeOnSelect | 简介 选择项目后, 菜单将关闭 | 类型boolean | 默认值true | 必须false |
属性duration | 简介 动画持续时间 | 类型number | 默认值250 | 必须false |
Item
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性label | 简介 用于菜单的提前导航文本。如果未提供,将使用菜单项的文本内容 | 类型string | 默认值- | 必须false |
属性disabled | 简介 该项目是否被禁用 | 类型boolean | 默认值false | 必须false |
属性closeOnSelect | 简介 选择项目后, 菜单将关闭 | 类型boolean | 默认值- | 必须false |
属性onSelect | 简介 当用户选择一个项目(通过鼠标或键盘)时调用事件处理程序 | 类型() => void | 默认值- | 必须false |
CheckboxItem
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性label | 简介 用于菜单的提前导航文本。如果未提供,将使用菜单项的文本内容 | 类型string | 默认值- | 必须false |
属性disabled | 简介 该项目是否被禁用 | 类型boolean | 默认值false | 必须false |
属性closeOnSelect | 简介 选择项目后, 菜单将关闭 | 类型boolean | 默认值- | 必须false |
属性onSelect | 简介 当用户选择一个项目(通过鼠标或键盘)时调用事件处理程序 | 类型() => void | 默认值- | 必须false |
属性checked | 简介 项目的受控选中状态 | 类型false | true | "indeterminate" | 默认值- | 必须false |
属性onChange | 简介 项目选中状态更改时调用的事件处理程序 | 类型(checked: CheckedState) => void | 默认值- | 必须false |
RadioGroup
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性value | 简介 要选中的菜单单选项目的控制值 | 类型string | number | 默认值- | 必须false |
属性onChange | 简介 值更改时调用的事件处理程序 | 类型((value: string | number) => void) | 默认值- | 必须false |
RadioItem
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性value | 简介 菜单单选项的价值 | 类型string | number | 默认值- | 必须true |
属性label | 简介 用于菜单的提前导航文本。如果未提供,将使用菜单项的文本内容 | 类型string | 默认值- | 必须false |
属性disabled | 简介 该项目是否被禁用 | 类型boolean | 默认值false | 必须false |
属性closeOnSelect | 简介 选择项目后, 菜单将关闭 | 类型boolean | 默认值- | 必须false |
属性onSelect | 简介 当用户选择一个项目(通过鼠标或键盘)时调用事件处理程序 | 类型() => void | 默认值- | 必须false |