import { InputGroup, Toolbar } from "@lark-ui/core";
import { FunnelSimpleIcon, GearSixIcon, MagnifyingGlassIcon } from "@phosphor-icons/react";
/** 基础工具栏(Toolbar),包含一个 InputGroup 和相邻的操作按钮。 */
export function ToolbarDemo() {
return (
<Toolbar className="w-full max-w-md">
<Toolbar.InputGroup aria-label="搜索 DNS 记录" className="flex-1">
<InputGroup.Addon>
<MagnifyingGlassIcon />
</InputGroup.Addon>
<InputGroup.Input placeholder="搜索 DNS 记录" />
</Toolbar.InputGroup>
<Toolbar.Button icon={FunnelSimpleIcon} aria-label="筛选" />
<Toolbar.Button icon={GearSixIcon} aria-label="设置" />
</Toolbar>
);
}安装
统一导出
import { Toolbar } from "@lark-ui/core";按需导出
import { Toolbar } from "@lark-ui/core/components/toolbar";用法
当多个控件需要呈现为一个紧凑的工具栏(Toolbar)或筛选卡片时,请使用 Toolbar。
可直接使用 Toolbar.Button、Toolbar.Link、Toolbar.Input 和 Toolbar.InputGroup。
也可以通过 render 属性,把选择器(Select)和组合框(Combobox)的触发器与这些工具栏控件组合起来。
import { InputGroup, Toolbar } from "@lark-ui/core";
import { FunnelSimpleIcon, MagnifyingGlassIcon } from "@phosphor-icons/react";
export default function Example() {
return (
<Toolbar>
<Toolbar.InputGroup aria-label="Search DNS records">
<InputGroup.Addon>
<MagnifyingGlassIcon />
</InputGroup.Addon>
<InputGroup.Input placeholder="Search DNS records" />
</Toolbar.InputGroup>
<Toolbar.Button icon={FunnelSimpleIcon} aria-label="Filter" />
</Toolbar>
);
}行为
工具栏的条目组件有意接管分组控件的呈现方式:
- 所有
Toolbar.*控件默认使用base尺寸。 - Toolbar 的
size属性为兼容性保留,但已被弃用;请省略它以使用base尺寸。 Toolbar.Button始终以低调的工具栏按钮样式渲染。Toolbar.Link以低调的工具栏样式渲染LinkButton,并参与方向键导航。Toolbar.InputGroup会把属性直接传给InputGroup,并应用解析后的工具栏尺寸。- 为选择器(Select)传入
render={<Toolbar.Button />},即可把它的触发器组合进工具栏。 - 为
Combobox.TriggerInput传入render={<Toolbar.Input />},可得到可编辑的工具栏组合框。 - 为
Combobox.TriggerValue传入render={<Toolbar.Button />},可得到按钮样式的工具栏组合框。 - 选择器和组合框在加入工具栏方向键导航的同时,仍保留各自的值行为、弹窗挂载、筛选能力和表单输入。
- 相邻的工具栏条目共享边框,只有 Toolbar 的外角是圆角。
- 如果选择器或组合框没有渲染成 Toolbar 控件,它会保持独立的呈现方式,也不会加入工具栏的漫游焦点顺序。
示例
选择器(Select)
选择器(Select)保留常规的根属性,包括 items。它的 render 属性会替换触发器,
因此渲染为 Toolbar.Button 后,该触发器就成了一个工具栏条目,而不会替换掉 Select 的根元素。
import { Select, Toolbar } from "@lark-ui/core";
import { FunnelSimpleIcon, GearSixIcon } from "@phosphor-icons/react";
/** 选择器通过 Toolbar.Button 组合出其触发器。 */
export function ToolbarSelectDemo() {
return (
<Toolbar>
<Toolbar.Button icon={FunnelSimpleIcon}>筛选</Toolbar.Button>
<Select
aria-label="排序记录"
defaultValue="name"
items={{ name: "名称", created: "创建日期", status: "状态" }}
render={<Toolbar.Button />}
/>
<Toolbar.Button icon={GearSixIcon} aria-label="查看设置" />
</Toolbar>
);
}组合框(Combobox)
用 Toolbar.Input 组合出可编辑的组合框(Combobox)触发器。对于不可编辑的值触发器,
请从 Combobox.TriggerValue 渲染 Toolbar.Button。弹窗部分仍使用常规的 Combobox.* 组件组合。
在水平工具栏中,请把可编辑的触发器放在最后,这样左右方向键就能继续稳定地同时服务于文本光标和工具栏导航。
import { Combobox, Toolbar } from "@lark-ui/core";
import { FunnelSimpleIcon } from "@phosphor-icons/react";
/** 组合框通过 Toolbar.Input 组合出其可编辑触发器。 */
export function ToolbarComboboxDemo() {
return (
<Toolbar className="w-full max-w-md">
<Toolbar.Button icon={FunnelSimpleIcon}>状态</Toolbar.Button>
<Combobox items={toolbarComboboxItems}>
<Combobox.TriggerInput
aria-label="筛选状态"
className="flex-1"
placeholder="筛选状态……"
render={<Toolbar.Input />}
/>
<Combobox.Content>
<Combobox.List>
{(item: string) => (
<Combobox.Item key={item} value={item}>
{item}
</Combobox.Item>
)}
</Combobox.List>
<Combobox.Empty>没有匹配的状态。</Combobox.Empty>
</Combobox.Content>
</Combobox>
</Toolbar>
);
}输入框简写
对于不需要附加元素的简单文本输入,请使用 Toolbar.Input。
import { Toolbar } from "@lark-ui/core";
import { FunnelSimpleIcon, GearSixIcon } from "@phosphor-icons/react";
/** 工具栏可以使用更简洁的 Input 简写形式。 */
export function ToolbarMixedControlsDemo() {
return (
<Toolbar className="w-full max-w-md">
<Toolbar.Input
aria-label="搜索 DNS 记录"
placeholder="搜索 DNS 记录"
className="flex-1"
/>
<Toolbar.Button icon={FunnelSimpleIcon} aria-label="筛选" />
<Toolbar.Button icon={GearSixIcon} aria-label="设置" />
</Toolbar>
);
}输入框组
当某个工具栏条目需要自己的行内附加元素或后缀时,请使用 Toolbar.InputGroup。
import { InputGroup, Toolbar } from "@lark-ui/core";
/** 工具栏可以将 InputGroup 与相邻操作组合在一起。 */
export function ToolbarInputGroupDemo() {
return (
<Toolbar className="w-full max-w-lg">
<Toolbar.InputGroup aria-label="Worker 子域名" className="flex-1">
<InputGroup.Input placeholder="my-worker" />
<InputGroup.Suffix>.workers.dev</InputGroup.Suffix>
</Toolbar.InputGroup>
<Toolbar.Button>访问</Toolbar.Button>
</Toolbar>
);
}已弃用的尺寸
为兼容起见,size 属性仍支持 xs、sm、base 和 lg,但它已被弃用,
并将在未来的主版本中移除。请省略它以使用默认的 base 尺寸。
import { Toolbar } from "@lark-ui/core";
/** @deprecated 工具栏尺寸自定义仅为兼容性而保留。 */
export function ToolbarSizesDemo() {
return (
<div className="grid gap-3">
{(["xs", "sm", "base", "lg"] as const).map((size) => (
<div key={size} className="flex items-center gap-3">
<span className="w-10 text-sm text-lark-subtle">{size}</span>
<Toolbar size={size} className="w-fit">
<Toolbar.Input aria-label={`${size} 搜索`} placeholder="搜索……" />
<Toolbar.Button>应用</Toolbar.Button>
</Toolbar>
</div>
))}
</div>
);
}按钮操作
工具栏按钮使用低调的样式,让成组的操作在视觉上保持安静且一致。
import { Toolbar } from "@lark-ui/core";
import { DownloadSimpleIcon, UploadSimpleIcon } from "@phosphor-icons/react";
/** 工具栏按钮始终使用低调的工具栏样式。 */
export function ToolbarActionsDemo() {
return (
<Toolbar>
<Toolbar.Button icon={UploadSimpleIcon}>上传</Toolbar.Button>
<Toolbar.Button icon={DownloadSimpleIcon}>下载</Toolbar.Button>
</Toolbar>
);
}链接
导航类操作请使用 Toolbar.Link。它接受 LinkButton 的属性,但 size 和 variant 除外——这两者由 Toolbar 统一控制。
import { Toolbar } from "@lark-ui/core";
import { BookOpenIcon, DownloadSimpleIcon } from "@phosphor-icons/react";
/** 工具栏链接使用 LinkButton 实现导航,并采用工具栏样式。 */
export function ToolbarLinksDemo() {
return (
<Toolbar>
<Toolbar.Link href="/components/button" icon={BookOpenIcon}>
按钮文档
</Toolbar.Link>
<Toolbar.Button icon={DownloadSimpleIcon}>下载</Toolbar.Button>
</Toolbar>
);
}无障碍标签
对于没有可见标签的紧凑控件,请使用 aria-label 或 aria-labelledby。
选择器的触发器以及每个组合框触发器仍然需要具备无障碍名称。
对于可编辑输入,只有当光标已位于相应的文本边界时,工具栏焦点才会移动;当弹窗处于打开状态时,方向键会改为在弹窗选项之间导航。
import { Toolbar } from "@lark-ui/core";
import { MagnifyingGlassIcon } from "@phosphor-icons/react";
/** 工具栏条目使用 aria-label 提供紧凑的无障碍名称。 */
export function ToolbarLabelsDemo() {
return (
<Toolbar className="w-full max-w-lg">
<Toolbar.Input
aria-label="搜索记录"
className="flex-1"
placeholder="搜索"
/>
<Toolbar.Button icon={MagnifyingGlassIcon} aria-label="搜索" />
</Toolbar>
);
}API 参考
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
children | ReactNode | - | 渲染为一张分组卡片的工具栏控件。 |
size 已弃用 | ”xs” | “sm” | “base” | “lg" | "base” | 设置所有受支持条目的尺寸。请省略这个已弃用的属性,以使用默认的 base 尺寸。 |
className | string | - | 合并到工具栏根元素上的额外 CSS 类。 |
Select 的组合方式
向选择器(Select)传入 render={<Toolbar.Button />}。在渲染出的工具栏控件上配置禁用状态下的焦点行为:
<Select
aria-label="Sort records"
disabled
items={{ name: "Name" }}
render={<Toolbar.Button focusableWhenDisabled={false} />}
/>Combobox 的组合方式
向 Combobox.TriggerInput 传入 render={<Toolbar.Input />},或从 Combobox.TriggerValue 渲染 Toolbar.Button:
<Combobox items={items}>
<Combobox.TriggerInput
aria-label="Filter records"
render={<Toolbar.Input />}
/>
<Combobox.Content>...</Combobox.Content>
</Combobox>在渲染出的 Toolbar.Button 或 Toolbar.Input 上设置 focusableWhenDisabled,
用于控制被禁用的触发器是否仍留在工具栏的漫游焦点顺序中。