
「Command Palette Pattern」は、最近の開発ツール(VSCodeやFigmaなど)にも多く採用されている、
ユーザー操作を「コマンド」として抽象化し、検索・実行できるUI設計パターンです。
このデザインパターンの目的は、
ユーザーが「やりたいこと」を直接検索して実行できるようにすることです。
メニュー階層やボタンをたどらなくても、コマンド単位でアクセスできるようにするのが特徴ですね。
SPAなどのツールやアプリの開発に役に立つでしょう。
構成要素
| 役割 |
説明 |
| Command(コマンド) |
実行可能なアクションをオブジェクトとして定義する(例:ファイルを開く、保存する) |
| Palette(パレット) |
コマンドの一覧を管理し、検索・選択UIを提供する |
| Invoker(実行者) |
選ばれたコマンドを実行する(Undoなどをサポートする場合もある) |
| Receiver(受信者) |
実際の処理対象(例:エディタ、キャンバス、ドキュメント) |
サンプルコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<style>
body { font-family: sans-serif; padding: 40px; }
#palette {
border: 1px solid #ccc; width: 300px; padding: 10px;
display: none; position: absolute; top: 50px; background: #fff;
}
#palette input { width: 100%; padding: 5px; }
#list { margin-top: 10px; }
.item { padding: 5px; cursor: pointer; }
.item:hover { background: #eee; }
</style>
</head>
<body>
<h2>Command Palette Pattern</h2>
<button id="open">Open Palette</button>
<div id="palette">
<input type="text" id="search" placeholder="Type a command..." />
<div id="list"></div>
</div>
<script>
// === Command 定義 ===
const commands = [
{ name: 'Open File', execute: () => alert('File opened!') },
{ name: 'Save File', execute: () => alert('File saved!') },
{ name: 'Close File', execute: () => alert('File closed!') },
];
// === Palette管理 ===
const palette = document.getElementById('palette');
const list = document.getElementById('list');
const search = document.getElementById('search');
function renderList(filter = '') {
list.innerHTML = '';
commands
.filter(c => c.name.toLowerCase().includes(filter.toLowerCase()))
.forEach(cmd => {
const item = document.createElement('div');
item.className = 'item';
item.textContent = cmd.name;
item.onclick = () => {
cmd.execute();
palette.style.display = 'none';
};
list.appendChild(item);
});
}
// === イベント ===
document.getElementById('open').onclick = () => {
palette.style.display = 'block';
search.focus();
renderList();
};
search.oninput = e => renderList(e.target.value);
document.addEventListener('keydown', e => {
if (e.key === 'Escape') palette.style.display = 'none';
});
</script>
</body>
</html>
処理フロー
1. 「Open Pallet」をクリックするとパレットを開く
2. パレットが登録済みコマンドのリストを表示
3. ユーザーが文字を入力してフィルタリング
4. コマンドを選択するとInvokerが対応する処理を呼び出す
デモ
メリット
・UIがシンプル(すべての操作を検索して実行できる)
・新しい機能を追加しても、UI変更なしでパレットに登録できる
・コマンドパターンと親和性が高く、Undo/Redoやマクロ実行も容易
デメリット
・コマンド定義の設計が煩雑になりやすい
・初心者には「どんなコマンドがあるか」が分かりづらい
あとがき
Webツールでは、毎回非常にたくさんの処理を行うパターンです。
いろいろな処理が発生すると思いますが、それぞれに対して、単一のパターンで記述できると非常に効率的なコードになるし、
更新や機能追加もかなり楽になることがわかりますね。
他のパターンとも組み合わせることで、安定性がますでしょう。
0 件のコメント:
コメントを投稿