Command Palette
⌘K 喚起的命令面板,即時模糊搜尋、指令分組與鍵盤巡覽,高亮列以共享 layout 滑動。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<CommandPalette />
安裝
npx shadcn@latest add https://webberui.com/r/command-palette.json或在 components.json 設定 registries 後,改用 @webberui/command-palette 安裝。
安裝依賴後,從 registry JSON(/r/command-palette.json 的 files[0].content)複製 command-palette.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
import * as React from "react";
import { Home, Plus } from "lucide-react";
import { CommandPalette } from "@/components/ui/command-palette";
export function Example() {
const [open, setOpen] = React.useState(false);
const groups = [
{
heading: "導覽",
items: [
{
id: "home",
label: "前往首頁",
icon: <Home className="size-4" />,
shortcut: "G H",
onSelect: () => console.log("home"),
},
],
},
{
heading: "動作",
items: [
{
id: "new",
label: "新增文件",
icon: <Plus className="size-4" />,
shortcut: "⌘ N",
onSelect: () => console.log("new"),
},
],
},
];
return <CommandPalette open={open} onOpenChange={setOpen} groups={groups} />;
}按下 ⌘K(macOS)或 Ctrl+K(Windows/Linux)即可隨時喚起面板;也可透過 open / onOpenChange 由外部按鈕控制。
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
open | boolean | — | 受控模式的開啟狀態,不傳則由元件內部管理 |
onOpenChange | (open: boolean) => void | — | 開啟狀態變更時的回呼(受控與非受控皆會觸發) |
groups | CommandPaletteGroup[] | — | 指令分組資料,依序渲染每組標題與項目 |
placeholder | string | "輸入指令或搜尋⋯" | 搜尋框的 placeholder 文字 |
className | string | — | 追加到面板容器的 className |
CommandPaletteGroup
| 欄位 | 型別 | 說明 |
|---|---|---|
heading | string | 分組標題 |
items | CommandPaletteItem[] | 該分組的指令項目 |
CommandPaletteItem
| 欄位 | 型別 | 說明 |
|---|---|---|
id | string | 唯一識別碼,作為 option 的 DOM id 與 React key |
label | string | 顯示文字,同時是搜尋過濾的比對來源 |
icon | React.ReactNode | 選填的前導圖示 |
shortcut | string | 選填的快捷鍵提示,顯示在項目右側 |
onSelect | () => void | 選取(點擊或 Enter)此項目時執行的動作 |
細節
- 全域監聽
⌘K/Ctrl+K切換開關;面板以createPortal掛到document.body。 - 遮罩淡入、面板縮放淡入置中偏上;搜尋框自動聚焦,輸入即時做子序列模糊過濾。
- 上下鍵在過濾後的項目間循環移動高亮、
Enter執行、Esc關閉、點擊遮罩關閉。 - 高亮列的背景以共享
layoutId在項目間平滑滑動。
可及性
- 面板為
role="dialog"且aria-modal="true",開啟時鎖住 body 捲動、關閉後把焦點歸還給開啟前的元素。 - 搜尋框為
role="combobox",以aria-activedescendant指向目前高亮的項目;結果為role="listbox"、項目為role="option"並帶aria-selected。 - 使用者系統開啟「減少動態效果」時,面板僅以透明度淡入淡出、高亮列瞬間到位,不做縮放與滑動。