コマンドパレットCommandPaletteExperimental

ナビゲーションやアクション用のグローバルコマンドパレットです。

プレビュー

状態とバリエーション

標準表示

グローバルな移動先とアクションをまとめ、キーボードショートカットでも開けるようにします。

キーボードから開く場合は ⌘K

少数コマンド

小さなアプリではグループを絞り、空状態や検索文言だけを用途に合わせます。

キーボードから開く場合は ⌘K

プロパティ

表は横にスクロールできます
プロパティ初期値説明
openboolean-パレットの開閉状態。
onOpenChange(open: boolean) => void-開閉状態が変わった時に呼ばれるハンドラ。
groupsCommandPaletteGroup[][]見出しとコマンド項目の配列。
placeholderstring"Type a command or search..."検索入力のプレースホルダー。
emptyMessageReactNode"No results found."検索結果がない時に表示する文言。
dialogTitleReactNode"Command Menu"ダイアログのアクセシブルタイトル。
clearLabelstring"Clear search"検索クリアボタンの aria-label とツールチップ文言。
portalContainerHTMLElement | null-docs プレビューや擬似ブラウザ内にパレットを閉じ込めたい時のポータル先。

使い方

"use client"

import { Button, CommandPalette, Kbd } from "@gunjo/ui"
import { IconCalculator as Calculator, IconCalendar as Calendar, IconCreditCard as CreditCard, IconFileText as FileText, IconMoodSmile as Smile, IconSearch as Search, IconSettings as Settings, IconUserCircle as UserRound } from "@tabler/icons-react"
import { useEffect, useMemo, useState } from "react"

export function CommandPaletteExample() {
  const [open, setOpen] = useState(false)

  useEffect(() => {
    const down = (event: KeyboardEvent) => {
      if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
        event.preventDefault()
        setOpen((current) => !current)
      }
    }
    document.addEventListener("keydown", down)
    return () => document.removeEventListener("keydown", down)
  }, [])

  const groups = useMemo(
    () => [
      {
        heading: "移動",
        items: [
          { id: "search", label: "ドキュメントを検索", icon: <Search />, shortcut: "⌘K", action: () => setOpen(false) },
          { id: "files", label: "最近のファイル", icon: <FileText />, action: () => setOpen(false) },
        ],
      },
      {
        heading: "ツール",
        items: [
          { id: "calendar", label: "カレンダー", icon: <Calendar />, action: () => setOpen(false) },
          { id: "emoji", label: "絵文字を検索", icon: <Smile />, action: () => setOpen(false) },
          { id: "calculator", label: "計算機", icon: <Calculator />, action: () => setOpen(false) },
        ],
      },
      {
        heading: "設定",
        items: [
          { id: "profile", label: "プロフィール", icon: <UserRound />, shortcut: "⌘P", action: () => setOpen(false) },
          { id: "billing", label: "請求", icon: <CreditCard />, shortcut: "⌘B", action: () => setOpen(false) },
          { id: "settings", label: "環境設定", icon: <Settings />, shortcut: "⌘S", action: () => setOpen(false) },
        ],
      },
    ],
    []
  )

  return (
    <div className="flex flex-col items-center gap-3">
      <p className="text-sm text-muted-foreground">
        キーボードから開く場合は <Kbd>⌘K</Kbd>
      </p>
      <Button type="button" variant="outline" onClick={() => setOpen(true)}>
        コマンドパレットを開く
      </Button>
      <CommandPalette
        open={open}
        onOpenChange={setOpen}
        dialogTitle="コマンドパレット"
        placeholder="コマンドまたはページを検索..."
        emptyMessage="一致するコマンドがありません。"
        clearLabel="検索をクリア"
        groups={groups}
      />
    </div>
  )
}

使用コンポーネント

設計の判断(UIXHERO)

「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。