Command
始终展开的操作列表,上方是搜索框:输入文字缩小范围,方向键切换选项,Enter 执行。CommandDialog 让它浮在变暗的页面之上。
安装
# once per project: where @zzzui items come frompnpm dlx shadcn@latest registry add @zzzui=https://zzzui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zzzui/command示例
内嵌,以及 ⌘K 命令面板
Take the job⌘T
Hand in
Abandon
Job board
District map
Drivers
import { useEffect, useState } from "react";import { Button } from "@/components/zero/button";import { Command, CommandCollection, CommandDialog, CommandEmpty, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandShortcut,} from "@/components/zero/command";type Action = { value: string; label: string; keys?: string };const groups: { value: string; items: Action[] }[] = [ { value: "Jobs", items: [ { value: "take", label: "Take the job", keys: "⌘T" }, { value: "hand-in", label: "Hand in" }, { value: "abandon", label: "Abandon" }, ], }, { value: "Go to", items: [ { value: "board", label: "Job board" }, { value: "map", label: "District map" }, { value: "drivers", label: "Drivers" }, ], },];function Palette({ onRun }: { onRun?: () => void }) { return ( <Command items={groups}> <CommandInput placeholder="Type a command" aria-label="Command" /> <CommandList> {(group: (typeof groups)[number]) => ( <CommandGroup key={group.value} items={group.items}> <CommandGroupLabel>{group.value}</CommandGroupLabel> <CommandCollection> {(item: Action) => ( <CommandItem key={item.value} value={item} onClick={onRun}> {item.label} {item.keys ? ( <CommandShortcut>{item.keys}</CommandShortcut> ) : null} </CommandItem> )} </CommandCollection> </CommandGroup> )} </CommandList> <CommandEmpty>Nothing matches.</CommandEmpty> </Command> );}export default function CommandPalette() { const [open, setOpen] = useState(false); useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { if (event.key === "k" && (event.metaKey || event.ctrlKey)) { event.preventDefault(); setOpen((current) => !current); } }; window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, []); return ( <div className="grid w-full max-w-md justify-items-start gap-4"> <Palette /> <Button variant="secondary" onClick={() => setOpen(true)}> Open the palette (⌘K) </Button> <CommandDialog open={open} onOpenChange={setOpen}> <Palette onRun={() => setOpen(false)} /> </CommandDialog> </div> );}行为
第一个匹配项始终处于高亮状态,按 Enter 即可执行。搜索框位于黑色横条上;列表行沿用 Dropdown menu 的样式,高亮时填充强调色。将条目或条目分组传给 Command,并在 CommandList 的函数子元素中渲染;输入的文字与条目的 label 匹配。
组件基于 Base UI 的 Autocomplete 构建,无需其他依赖库。⌘K 快捷键需自行绑定,做法见示例。
属性
Command
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| items | Item[] | Group[] | — | 列出的条目,每项都需要 label。 |
| filter | (item, query) => boolean | — | 替换内置的匹配逻辑。 |
另可传入 Base UI Autocomplete.Root 的全部属性。
CommandDialog
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| open / onOpenChange | boolean / (open) => void | — | 是否打开,受控。 |
| title | string | "Command palette" | 对话框的可访问名称。 |
CommandInput, CommandList, CommandEmpty, CommandGroup, CommandGroupLabel, CommandCollection, CommandItem, CommandSeparator, CommandShortcut
另可传入 Base UI Autocomplete.Input 的全部属性。