コンテンツにスキップ

コマンド

hc-command はコマンドパレットで、shadcn の Command / cmdk に相当 します。アクションランチャーとして使われる WAI-ARIA コンボボックス パターンです: 入力してグループ化されたリストを絞り込み、矢印で ハイライトし、Enter で実行。installCommand がフィルタリング、 aria-activedescendant によるキーボードナビゲーション、選択イベント、 任意の ⌘K オープナーを配線します。

古典的な中央のパレットにはネイティブの <dialog> の中で使ってください — フォーカストラップ、Escape で閉じる、バックドロップが無料で付いてき ます。インラインでも使えます。

別名: コマンドパレット。

Navigation
Go homeG H
Open profileG P
Actions
New document⌘ N
Search files
<dialog class="hc-command-dialog" data-hotkey="k">
<div class="hc-command">
<input class="hc-command__input" type="text" role="combobox" autofocus
aria-label="Command menu" placeholder="Type a command…">
<div class="hc-command__list" role="listbox">
<div class="hc-command__group" role="group" aria-labelledby="g-nav">
<div class="hc-command__group-heading" id="g-nav">Navigation</div>
<div class="hc-command__item" role="option" data-value="home">
<span>Go home</span>
<kbd class="hc-command__shortcut">G H</kbd>
</div>
<div class="hc-command__item" role="option" data-value="profile">
<span>Open profile</span>
</div>
</div>
</div>
<div class="hc-command__empty" hidden>No results.</div>
</div>
</dialog>

リストは role="listbox" で、role="option" の項目が role="group" の見出しの下にグループ化されます(cmdk / Radix の 構造)。各項目の data-value が、選択イベントの報告値であり、 フィルタの照合対象です(.hc-command__shortcut のテキストは照合から 除外されます)。

import { installCommand } from '@hypermedia-components/core';
installCommand(); // idempotent; returns an uninstaller

ゼロ設定の @hypermedia-components/core/behaviors エントリは自動で インストールします。

<dialog>data-hotkey="k" を置くと(任意の 1 キー。デフォルト k)、ビヘイビアが /Ctrl + そのキーで開閉し、 開くときに入力へフォーカスしてフィルタをリセットします:

<dialog class="hc-command-dialog" data-hotkey="k"></dialog>

ハンドラは preventDefault() を呼ぶため、ブラウザ自身の Ctrl+K ショートカットは同時に発火しません。 ボタンから dialog.showModal() で開くこともできます — 入力の autofocus がカーソルを検索ボックスに置きます。

入力すると項目をファジーに絞り込んで並べ替えます: クエリの文字は 順番どおりに(部分列として)現れる必要があり、文字が連続している か、単語 / camelCase の境界に載っている一致ほど高くスコアされ ます。項目はスコア順に並び替わります — 最良の一致がグループを越えてでも 先頭に浮かび、同点は書かれた順を保ちます。クエリを消すと元の並びが 戻ります。フィルタリングは常にクライアントサイドです — パレットが ネットワークに触れることはありません。

以前の素朴な挙動 — 並べ替えなしの大文字小文字を無視した部分文字列 一致 — を保つには、.hc-commanddata-filter="substring" を設定 します:

<div class="hc-command" data-filter="substring"></div>

.hc-command__shortcut のテキストは照合から除外されます(検索される のは項目のラベルだけです)。

キー動作
入力ファジーに絞り込んで並べ替え。空になったグループとその見出しは隠れ、何も一致しなければ空状態が表示されます。
/ ハイライトを移動(ラップし、無効な項目をスキップ)。
Home / End最初 / 最後の見えている項目。
Enterハイライト中の項目を実行。
Escape閉じる(ネイティブ <dialog>)。

DOM のフォーカスは入力に留まります。ハイライト中の項目は WAI-ARIA コンボボックスパターンに従い aria-activedescendant で追跡されます。

項目を実行すると、.hc-command ルート上でバブリングする hc:commandselect が発火し、(<dialog> の中にいれば)ダイアログが 閉じます:

command.addEventListener('hc:commandselect', (e) => {
const { item, value } = e.detail; // value = item's data-value
routeTo(value);
});

イベントから直接、アクションをサーバサイドで実行します:

<div class="hc-command"
data-hx-post="/commands/run"
data-hx-trigger="hc:commandselect"
data-hx-vals='js:{ command: event.detail.value }'>
</div>

JS を配線する代わりに、選ばれたコマンドをインラインで実行します:

<div class="hc-command"
_="on hc:commandselect call runCommand(event.detail.value)">
</div>

さらなるパターン: Hyperscript → コンポーネントイベントへの反応

  • 入力は aria-expandedaria-controlsaria-activedescendant を 持つ role="combobox"。リストは role="listbox"、グループは aria-labelledby の見出しつき role="group"、項目は role="option" です。
  • showModal() で開いた <dialog> の中では、フォーカスはトラップされ Escape で閉じます — どちらもネイティブです。開いたときに検索 フィールドが使えるよう、入力の autofocus を保ってください。
  • 入力には常にアクセシブルな名前(aria-label またはラベル)を与えて ください。
  • 無効な項目(aria-disabled="true")はキーボードからスキップされ、 クリックでも無視されます。
トークンパス用途
command.bg / fg / border / radiusパレットの面。
command.input-* / placeholder-fg検索行。
command.list-max-height / list-padding-blockスクロール可能なリスト。
command.heading-*グループ見出し。
command.item-*項目の行。item-active-bg ハイライト(data-color に追従)を含む。
command.shortcut-*ショートカットのチップ。
command.empty-*空状態。
command.dialog-width / dialog-offset / backdrop.hc-command-dialog ラッパー。
生成される CSS 変数を表示
--hc-command-bg | -fg | -border | -radius
--hc-command-input-height | -input-padding-x | -input-font-size | -placeholder-fg
--hc-command-list-padding-block | -list-max-height
--hc-command-heading-fg | -heading-font-size | -heading-font-weight | -heading-padding-y
--hc-command-item-padding-x | -item-padding-y | -item-gap | -item-font-size
--hc-command-item-fg | -item-hover-bg | -item-active-bg | -item-active-fg | -item-disabled-fg
--hc-command-shortcut-fg | -shortcut-font-size | -shortcut-padding-x
--hc-command-empty-fg | -empty-padding-y
--hc-command-dialog-width | -dialog-offset | -backdrop
  • コンボボックス — 同じ 入力絞り込みパターンを単一のフォーム値にバインドしたもの。
  • メニュー — トリガーボタン からのドロップダウンアクションメニュー。
  • ダイアログ — パレットが 載るネイティブの <dialog> の面。