Cmd-K コマンドパレットを60行で再構築してみた

Linear、Raycast、VS Codeといったアプリでは、コマンドパレットが採用されています。⌘Kを押し、数文字入力してEnterを押すだけ。複雑に思えるかもしれませんが、実はわずか60行のJavaScriptで実現できます。

構築方法は以下の通りです:

  1. キーボードリスナー グローバルなリスナーが必要です。ブラウザではCtrl+Kが検索機能に割り当てられているため、preventDefault を使ってこれを阻止する必要があります。
document.addEventListener("keydown", e => {
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
    e.preventDefault();
    openPalette();
  }
});
  1. コマンドデータ すべての操作をオブジェクトとして保存します。これによりUIはシンプルに保たれます。UIはこれらのオブジェクトをリスト化し、選択された関数を実行します。新しい機能を追加するには、リストに1行追加するだけです。
const COMMANDS = [
  { icon: "🌙", label: "Toggle dark mode", group: "Theme", run: toggleDark },
  { icon: "📄", label: "New file",         group: "File",  run: newFile },
];
  1. ファジー検索 優れたパレットは、部分一致(subsequence matching)を利用します。これは、文字が順番に現れる必要があるものの、連続している必要はないという意味です。「tgldk」と入力すれば「Toggle dark mode」が見つかるようにします。
function fuzzy(q, text) {
  let i = 0;
  for (const ch of text.toLowerCase()) {
    if (ch === q[i]) i++;
  }
  return i === q.length;
}
  1. キーボードナビゲーション マウスを使わないことが目的です。矢印キーで選択インデックスを変更し、Enterでコマンドを実行、Escapeでメニューを閉じます。

  2. 即時性のある操作感 パレットが開いた瞬間に、入力フィールドにフォーカスを当てます。これにより、クリックの手間なくすぐにタイピングできます。

コマンドパレットに必要な要素は4つです:

モダンなパワーユーザー向けツールがどのように動作しているのかを理解するために、ぜひ一度作ってみてください。

ライブデモ: https://dev48v.infy.uk/design/day10-command-palette.html

ソース: https://dev.to/dev48v/i-rebuilt-the-cmd-k-command-palette-in-60-lines-of-javascript-3a1l