import { DropdownMenu, Button } from "@lark-ui/core";
import { PlusIcon } from "@phosphor-icons/react";
export function DropdownBasicDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button icon={PlusIcon}>添加</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item>Worker</DropdownMenu.Item>
<DropdownMenu.Item>Pages</DropdownMenu.Item>
<DropdownMenu.Item>KV 命名空间</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}安装
统一导出
import { DropdownMenu } from "@lark-ui/core";按需导出
import { DropdownMenu } from "@lark-ui/core/components/dropdown";用法
import { DropdownMenu, Button } from "@lark-ui/core";
export default function Example() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>Menu</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item onClick={() => console.log("edit")}>
Edit
</DropdownMenu.Item>
<DropdownMenu.Item onClick={() => console.log("duplicate")}>
Duplicate
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item
variant="danger"
onClick={() => console.log("delete")}
>
Delete
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}示例
基础下拉菜单
import { DropdownMenu, Button } from "@lark-ui/core";
import { PlusIcon } from "@phosphor-icons/react";
export function DropdownBasicDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button icon={PlusIcon}>添加</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item>Worker</DropdownMenu.Item>
<DropdownMenu.Item>Pages</DropdownMenu.Item>
<DropdownMenu.Item>KV 命名空间</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}缩进对齐的菜单项
当菜单中任意一项带有图标时,没有图标的项(包括标签)会自动缩进对齐,使文本排版整齐。当自动检测无法识别图标时(例如菜单项通过 render 渲染自己的内容),可使用 inset 强制缩进对齐。
import { DropdownMenu, Button } from "@lark-ui/core";
import { CopyIcon, PencilSimpleIcon, TrashIcon } from "@phosphor-icons/react";
/**
* 当同一菜单中的其他条目带有图标时,无图标的条目会自动缩进,
* 使文字对齐。
*/
export function DropdownInsetDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>编辑</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item icon={PencilSimpleIcon}>重命名</DropdownMenu.Item>
<DropdownMenu.Item icon={CopyIcon}>创建副本</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item>移动到文件夹</DropdownMenu.Item>
<DropdownMenu.Item>添加到收藏夹</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={TrashIcon} variant="danger">
删除
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}处理菜单项点击
在 DropdownMenu.Item 上使用 onClick 处理操作。每个菜单项都会接收到标准的 React 鼠标事件处理器。
import { useState } from "react";
import { DropdownMenu, Button } from "@lark-ui/core";
import { ArrowsClockwiseIcon, CopyIcon, PencilSimpleIcon, TrashIcon } from "@phosphor-icons/react";
/**
* 在 `DropdownMenu.Item` 上使用 `onClick` 处理条目操作。
* 每个条目都会收到标准的 React 鼠标事件处理函数。
*/
export function DropdownOnClickDemo() {
const [lastAction, setLastAction] = useState<string | null>(null);
return (
<div className="flex flex-col items-start gap-2">
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>操作</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item
icon={CopyIcon}
onClick={() => setLastAction("已创建副本")}
>
创建副本
</DropdownMenu.Item>
<DropdownMenu.Item
icon={PencilSimpleIcon}
onClick={() => setLastAction("已重命名")}
>
重命名
</DropdownMenu.Item>
<DropdownMenu.Item
icon={<ArrowsClockwiseIcon className="animate-spin" />}
onClick={() => setLastAction("已刷新")}
>
刷新
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item
icon={TrashIcon}
variant="danger"
onClick={() => setLastAction("已删除")}
>
删除
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
{lastAction && (
<p className="text-sm text-lark-subtle">
最近操作:<span className="text-lark-default">{lastAction}</span>
</p>
)}
</div>
);
}复选框菜单项
使用 DropdownMenu.CheckboxItem 表示可切换、可独立勾选或取消勾选的选项。
import { useState } from "react";
import { DropdownMenu, Button } from "@lark-ui/core";
export function DropdownCheckboxDemo() {
const [showSidebar, setShowSidebar] = useState(true);
const [showLineNumbers, setShowLineNumbers] = useState(false);
const [wordWrap, setWordWrap] = useState(true);
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>查看选项</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>显示</DropdownMenu.Label>
<DropdownMenu.CheckboxItem
checked={showSidebar}
onCheckedChange={setShowSidebar}
>
显示侧边栏
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem
checked={showLineNumbers}
onCheckedChange={setShowLineNumbers}
>
显示行号
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem
checked={wordWrap}
onCheckedChange={setWordWrap}
>
自动换行
</DropdownMenu.CheckboxItem>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu>
);
}带单选选择的嵌套菜单
使用 DropdownMenu.Sub、DropdownMenu.SubTrigger 和
DropdownMenu.SubContent 创建嵌套子菜单。对于语言、时区这类单选列表,请使用
DropdownMenu.RadioGroup 和 DropdownMenu.RadioItem。
import { useState } from "react";
import { DropdownMenu, Button } from "@lark-ui/core";
import { UserIcon, CreditCardIcon, MoonIcon, SignOutIcon, GlobeIcon, ClockIcon } from "@phosphor-icons/react";
export function DropdownNestedDemo() {
const [language, setLanguage] = useState("en");
const [timezone, setTimezone] = useState("America/Los_Angeles");
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button icon={UserIcon}>账户</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item icon={UserIcon}>个人资料</DropdownMenu.Item>
<DropdownMenu.Item icon={CreditCardIcon}>账单</DropdownMenu.Item>
<DropdownMenu.Item icon={MoonIcon}>深色模式</DropdownMenu.Item>
{/* Language submenu with RadioGroup */}
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger icon={GlobeIcon}>
语言
</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Group>
<DropdownMenu.RadioGroup
value={language}
onValueChange={setLanguage}
>
{languages.map((lang) => (
<DropdownMenu.RadioItem key={lang.code} value={lang.code}>
{lang.label}
<DropdownMenu.RadioItemIndicator />
</DropdownMenu.RadioItem>
))}
</DropdownMenu.RadioGroup>
</DropdownMenu.Group>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
{/* Timezone submenu with RadioGroup */}
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger icon={<ClockIcon weight="duotone" />}>
设置时区
</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Group>
<DropdownMenu.RadioGroup
value={timezone}
onValueChange={setTimezone}
>
{timezones.map((tz) => (
<DropdownMenu.RadioItem key={tz.value} value={tz.value}>
{tz.label}
<DropdownMenu.RadioItemIndicator />
</DropdownMenu.RadioItem>
))}
</DropdownMenu.RadioGroup>
</DropdownMenu.Group>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={SignOutIcon} variant="danger">
退出登录
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}使用头像的自定义触发器
使用 render 属性自定义触发元素,同时把子元素渲染到其内部。当触发器不是按钮(例如头像),但又需要包裹在具备无障碍语义的按钮元素中时,这非常有用。
import { DropdownMenu } from "@lark-ui/core";
import { UserIcon, SignOutIcon, GearIcon } from "@phosphor-icons/react";
/**
* 演示结合 render 属性与 children 组合出包含其他元素的自定义触发器。
* render 属性提供触发器元素,children 则渲染在其内部。
*/
export function DropdownAvatarTriggerDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger
render={<button type="button" className="rounded-full" />}
>
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-lark-brand text-sm font-medium text-white">
MR
</span>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item icon={UserIcon}>个人资料</DropdownMenu.Item>
<DropdownMenu.Item icon={GearIcon}>设置</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={SignOutIcon} variant="danger">
退出登录
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}导航链接
对于跳转到 URL 的菜单项,请使用 DropdownMenu.LinkItem。它会渲染语义化的 <a> 元素,并完整支持 target、rel 等链接属性。
import { DropdownMenu, Button } from "@lark-ui/core";
import { GearIcon, BookOpenIcon, ArrowSquareOutIcon } from "@phosphor-icons/react";
/**
* 演示用于导航链接的 LinkItem 组件。
* 使用带 href 的 Item 时改用 LinkItem,可获得更简洁、语义更明确的链接。
*/
export function DropdownLinkItemDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>资源</Button>} />
<DropdownMenu.Content>
<DropdownMenu.LinkItem href="/settings" icon={GearIcon}>
设置
</DropdownMenu.LinkItem>
<DropdownMenu.LinkItem href="/docs" icon={BookOpenIcon}>
文档
</DropdownMenu.LinkItem>
<DropdownMenu.Separator />
<DropdownMenu.LinkItem
href="https://developers.cloudflare.com"
target="_blank"
icon={ArrowSquareOutIcon}
>
开发者文档
</DropdownMenu.LinkItem>
</DropdownMenu.Content>
</DropdownMenu>
);
}长列表
当下拉菜单包含大量菜单项时,内容会自动将高度限制在可用的视口空间内,并支持滚动。
import { DropdownMenu, Button } from "@lark-ui/core";
/**
* 包含超长条目列表的下拉菜单,用于演示最大高度行为——当内容超出可用视口空间时
* 会滚动显示。
*/
export function DropdownLongListDemo() {
const items = Array.from({ length: 30 }, (_, i) => `选项 ${i + 1}`);
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>打开长列表</Button>} />
<DropdownMenu.Content>
{items.map((item) => (
<DropdownMenu.Item key={item}>{item}</DropdownMenu.Item>
))}
</DropdownMenu.Content>
</DropdownMenu>
);
}API 参考
DropdownMenu
管理下拉菜单状态的根组件。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| variant | "default" | "danger" | "default" | 下拉菜单项的视觉样式。 - `"default"` — 标准菜单项外观 - `"danger"` — 红色文字的危险操作 |
DropdownMenu.Trigger
点击时打开下拉菜单的按钮。
| 属性 | 类型 | 默认值 |
|---|
该组件没有专有属性,支持标准 HTML 属性。
DropdownMenu.Content
菜单弹层。由 Portal、Positioner 和 Popup 组合而成:side、align、sideOffset、alignOffset 等定位属性作用于 Positioner,className 作用于 Popup。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| sideOffset | number | 8 | 与触发元素之间的距离(像素)。 |
| container | PortalContainer | - | 传送层的容器元素。可用于在 Shadow DOM 或自定义容器内渲染。 |
DropdownMenu.Portal、Positioner 和 Popup
组成 Content 的各个部件。当你需要分别设置 Positioner 和 Popup 的样式或配置时,可以直接组合它们。Portal 会遵循 LarkPortalProvider 的设置,Popup 则承载菜单的表面样式和展开/收起动画。
<DropdownMenu.Portal>
<DropdownMenu.Positioner side="top" align="end">
<DropdownMenu.Popup className="min-w-56">
<DropdownMenu.Item>Edit</DropdownMenu.Item>
</DropdownMenu.Popup>
</DropdownMenu.Positioner>
</DropdownMenu.Portal>两者接受的属性与 Base UI 的 Menu.Positioner 和 Menu.Popup 相同。完整列表请参阅 Base UI Menu 文档。
DropdownMenu.Item
用于执行操作的单个菜单项。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| icon | Icon | ReactNode | - | 显示在标签前的图标。 |
| variant | "default" | "danger" | "default" | 菜单项的视觉样式。 |
| selected | boolean | - | 为 true 时显示勾选标记。 |
| inset | boolean | - | 增加左侧内边距,以便与带图标的菜单项对齐。 |
| onClick | (event: React.MouseEvent) => void | - | 点击菜单项时的回调。 |
| closeOnClick | boolean | true | 点击该菜单项后菜单是否关闭。 |
| disabled | boolean | - | 为 true 时该菜单项无法交互。 |
DropdownMenu.LinkItem
跳转到 URL 的菜单项。渲染语义化的 <a> 元素。导航链接请使用它而不是 Item。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| href | string | - | 点击后跳转的 URL。 |
| icon | Icon | ReactNode | - | 显示在标签前的图标。 |
| variant | "default" | "danger" | "default" | 菜单项的视觉样式。 |
| inset | boolean | - | 增加左侧内边距,以便与带图标的菜单项对齐。 |
| target | string | - | 链接的 target 属性(例如用 “_blank” 在新标签页打开)。 |
| render | ReactElement | ((props, state) => ReactElement) | - | 渲染为链接的自定义元素。用于接入框架路由(例如 Next.js 的 Link)。 |
DropdownMenu.CheckboxItem
可切换开关状态的菜单项。适用于相互独立的布尔选项。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| checked | boolean | - | 该菜单项是否选中。 |
| defaultChecked | boolean | false | 该菜单项初始是否选中(非受控)。 |
| onCheckedChange | (checked: boolean, event: ChangeEventDetails) => void | - | 选中状态变化时的回调。 |
| closeOnClick | boolean | false | 点击该菜单项后菜单是否关闭。 |
| disabled | boolean | - | 为 true 时该菜单项无法交互。 |
DropdownMenu.Sub
嵌套子菜单的根组件。请将 SubTrigger 和 SubContent 包裹在其中。
| 属性 | 类型 | 默认值 |
|---|
该组件没有专有属性,支持标准 HTML 属性。
DropdownMenu.SubTrigger
悬停或点击时打开嵌套子菜单的菜单项。会自动显示一个箭头图标,并在子菜单展开时保持高亮。与 Item 一样,它的 icon 属性接受 Phosphor 图标组件或已渲染的元素。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| icon | Icon | - | 显示在标签前的图标。 |
| inset | boolean | - | 增加左侧内边距,以便与带图标的菜单项对齐。 |
DropdownMenu.SubContent
子菜单项的容器。相对于 SubTrigger 定位。当子菜单位于触发器旁边时,会取消弹层内边距,使第一项与触发器对齐并略微覆盖父菜单。若空间不足而移动到触发器上方或下方,则使用与顶级菜单相同的间距。可通过 sideOffset 或 alignOffset(数字,或根据最终 side 计算的函数)覆盖该行为。
| 属性 | 类型 | 默认值 |
|---|
该组件没有专有属性,支持标准 HTML 属性。
DropdownMenu.Separator
菜单项之间的视觉分隔线。
| 属性 | 类型 | 默认值 |
|---|
该组件没有专有属性,支持标准 HTML 属性。
DropdownMenu.RadioGroup
将单选项组织成一组,实现单选行为。同一时间只能选中一项。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | any | - | 当前选中单选项的受控值。 |
| defaultValue | any | - | 初始选中的值(非受控)。 |
| onValueChange | (value: any, event: ChangeEventDetails) => void | - | 选中值变化时的回调。 |
| disabled | boolean | - | 为 true 时分组内所有单选项均禁用。 |
DropdownMenu.RadioItem
行为类似单选按钮的菜单项。必须放在 RadioGroup 内部使用。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value* | any | - | 该单选项的值。 |
| icon | Icon | ReactNode | - | 显示在标签前的图标。 |
| inset | boolean | - | 增加左侧内边距,以便与带图标的菜单项对齐。 |
| closeOnClick | boolean | false | 点击该菜单项后菜单是否关闭。 |
| disabled | boolean | - | 为 true 时该菜单项无法交互。 |
DropdownMenu.RadioItemIndicator
展示 RadioItem 的选中状态。默认显示对勾标记。
| 属性 | 类型 | 默认值 |
|---|
该组件没有专有属性,支持标准 HTML 属性。