ツリー
hc-tree はセマンティックな入れ子リストを WAI-ARIA のツリーへ
昇格させます: ファイルブラウザ、カテゴリ階層、管理画面のナビゲーション。
JavaScript なしではマークアップは素の読めるリストで、すべてのリンクが
機能し続けます。installTree() が roles、ロービングタブインデックス、
完全な APG キーボードモデルを足します。サーバからプッシュされる
サブツリーは
レイジーツリーレシピの
仕事です。
別名: ツリービュー、階層リスト。
基本の HTML
Section titled “基本の HTML”- src
- components
- button.js
- app.js
- components
- README.md
<ul class="hc-tree" aria-label="Project files"> <li class="hc-tree__item" aria-expanded="true"> <span class="hc-tree__row"> <span class="hc-tree__toggle" aria-hidden="true"></span> <span class="hc-tree__label">src</span> </span> <ul class="hc-tree__group"> <li class="hc-tree__item" aria-expanded="false"> <span class="hc-tree__row"> <span class="hc-tree__toggle" aria-hidden="true"></span> <span class="hc-tree__label">components</span> </span> <ul class="hc-tree__group"> <li class="hc-tree__item"> <span class="hc-tree__row"> <span class="hc-tree__label">button.js</span> </span> </li> </ul> </li> <li class="hc-tree__item" aria-current="true"> <span class="hc-tree__row"> <span class="hc-tree__label">app.js</span> </span> </li> </ul> </li> <li class="hc-tree__item"> <span class="hc-tree__row"> <span class="hc-tree__label">README.md</span> </span> </li></ul>枝であることは aria-expanded で宣言されます — 属性があれば
その項目は展開できます(初期値はサーバが所有し、ビヘイビアが
トグルします)。階層は入れ子から導かれ、aria-level の帳簿は
ありません。
ビヘイビア — installTree()
Section titled “ビヘイビア — installTree()”自動初期化の
./behaviors
バンドルに含まれます。role="tree" / treeitem / group" とロービング
タブインデックス(ツリーごとに 1 つのタブストップ)を適用し、htmx で
サブツリーがスワップインされたときに両方を再適用します。項目の展開は
バブリングする hc:treeexpand(detail: { item })を発火します —
レイジーツリーレシピが
その上に組むフックです。ネットワークには決して触れません。他の
ビヘイビアと同じく冪等で、アンインストーラを返します。後から htmx
スワップで追加されたツリーは自動で拾われ(MutationObserver)、
ツリーごとのオブザーバーがサブツリーのスワップインのたびにロールを
再適用します。
| キー | 動作 |
|---|---|
| ↓ / ↑ | 次 / 前の見えている項目(畳まれたサブツリーはスキップ)。 |
| → | 閉じた枝を開く。開いた枝の上では最初の子へ移動。 |
| ← | 開いた枝を閉じる。それ以外は親へ移動。 |
| Home / End | 最初 / 最後の見えている項目。 |
| Enter / Space | アクティベート: ラベルにリンクがあればそれを辿り、なければ枝をトグル。 |
| a–z | タイプアヘッド — その文字で始まる次の見えている項目へジャンプ。 |
← と → は RTL でミラーされます。
行のクリックはその項目にフォーカスを移し、ブランチであればトグルも
行います — ただしクリックが行内のインタラクティブなコントロール
(a[href]・button・input・select・textarea)に当たった場合は
除きます。それらのアクティベーションはコントロール自身のものです:
行内のアクションボタンは、操作対象のフォルダを閉じてしまうことなく
発火します。シェブロンのトグルは常にトグルします。
| 状態 | セレクタ | 効果 |
|---|---|---|
| 展開 | [aria-expanded="true"] | グループが見える。シェブロンが回転。 |
| 折りたたみ | [aria-expanded="false"] | グループが隠れる。 |
| 現在 | [aria-current] | アクセントの行(data-color に追従)— サーバの状態、「現在地」マーカー。 |
| 読み込み中 | .hc-tree__group[aria-busy="true"] | 遅延サブツリーの取得中、グループ内にスピナー(ビヘイビアが設定)。 |
選択モデル(aria-selected、複数選択、チェックボックス)は当面の
意図的な非目標です — アクティベーションは本物のリンクを辿り、現在の
ノードはサーバレンダリングされた状態です。
data-size="sm" は、密なパネル向けにインデントとフォントを詰めます。
- src
- app.js
- README.md
<ul class="hc-tree" data-size="sm" aria-label="Project files (compact)"> <!-- …the same items… --></ul>アクセシビリティ
Section titled “アクセシビリティ”- 入れ子の
<ul>/<li>+role="tree"+aria-expanded+ ロービング タブインデックスが APG のパターンです。階層は構造から読み上げられ ます。 - シェブロンのトグルは
aria-hiddenのポインタ向け操作部です — キーボードモデルがその全機能を複製します。 - ツリーには
aria-label(またはaria-labelledby)を与えてください。 - フォーカスは行の上に描かれます(
:focus-visible)。reduced motion は シェブロンのトランジションとビジースピナーを無効化します。
テーマ用トークン
Section titled “テーマ用トークン”component トークン(component.tokens.json)— 全体を通じて semantic
参照なので、テーマ、アクセント、ダークモードが自動で適用されます:
| トークンパス | 用途 |
|---|---|
tree.indent | 入れ子 1 段あたりのインデント。 |
tree.row-padding-y / row-padding-x | 行のパディング。 |
tree.row-radius | 行の角丸。 |
tree.fg | ツリーのテキスト色。 |
tree.hover-bg | ホバー行の背景。 |
tree.current-bg / current-fg | aria-current 行のアクセント(data-color に追従)。 |
tree.toggle-size | シェブロントグルのボックス。 |
tree.guide | 入れ子のガイド線(ビジースピナーのトラックでもあります)。 |
CSS 変数
Section titled “CSS 変数”生成される CSS 変数を表示
--hc-tree-indent--hc-tree-row-padding-y | -row-padding-x | -row-radius--hc-tree-fg | -hover-bg--hc-tree-current-bg | -current-fg--hc-tree-toggle-size | -guide- レイジーツリーレシピ — 初回展開時に子を読み込む枝。
- ナビゲーションメニュー — 平坦なサイトナビゲーション。ツリーは階層のためのもの。
- コラプシブル — ツリーセマンティクスのない単一のディスクロージャ。