WebberUI

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.jsonfiles[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型別預設值說明
openboolean受控模式的開啟狀態,不傳則由元件內部管理
onOpenChange(open: boolean) => void開啟狀態變更時的回呼(受控與非受控皆會觸發)
groupsCommandPaletteGroup[]指令分組資料,依序渲染每組標題與項目
placeholderstring"輸入指令或搜尋⋯"搜尋框的 placeholder 文字
classNamestring追加到面板容器的 className

CommandPaletteGroup

欄位型別說明
headingstring分組標題
itemsCommandPaletteItem[]該分組的指令項目

CommandPaletteItem

欄位型別說明
idstring唯一識別碼,作為 option 的 DOM id 與 React key
labelstring顯示文字,同時是搜尋過濾的比對來源
iconReact.ReactNode選填的前導圖示
shortcutstring選填的快捷鍵提示,顯示在項目右側
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
  • 使用者系統開啟「減少動態效果」時,面板僅以透明度淡入淡出、高亮列瞬間到位,不做縮放與滑動。

On this page