Skip to content
fandhe-frontendcore v0.4.3
GitHub

Toolbar

ボタン・リンク・ToggleGroup を横方向(または縦方向)にグループ化する操作バーです。fandhe-frontend-headless-ui の toolbar mod が構造・アクセシビリティ(WAI-ARIA・キーボード操作)・表示状態(data-*)のみを提供する unstyled 部品であり、Themes 版と異なりスタイル(CSS)は一切持ちません。roving tabindex により disabled 項目もフォーカス順序から除外しない WAI-ARIA APG 準拠の設計です。

スタイル済みの表示例は Toolbar を参照してください。

キーボード操作

キー対象効果
Tab / Shift+TabRootroving tabindex により focused 項目(tabindex="0")のみが Tab 順序に含まれます(ネイティブ button/a 要素の暗黙挙動、実装済み)。
Space / EnterButton / ToggleItemネイティブ button 要素の暗黙アクティベーション(実装済み)。
ArrowRight / ArrowLeft(horizontal)・ArrowDown / ArrowUp(vertical)、Home、End項目間Toolbar(ToolbarAction::Next/Prev/First/Last/Focus)として状態遷移 API のみを提供します。fandhe-frontend-wasm-full に本モジュールの keydown 配線は現状存在せず未実装です(イシュー #1657 時点で確認済み、別 Issue の起票対象)。呼び出し側が独自に配線するまで実 DOM 上では矢印キー等は機能しません。

参考サイトとの差分

イシュー #1657 で Radix Primitives Toolbar(ark-ui・chakra-ui には Toolbar 相当が存在しません)と突合しました。

  • data-orientation の欠落を是正: Radix の data-* 表(root/button/toggle-group/toggle-item に data-orientation)と一致するよう、button/link/toggle_group/toggle_item の自由関数へ先頭引数 orientation: Orientation を追加し data-orientation を出力するようにしました(separator は既存の直交 aria-orientation と同値の data-orientation を追加)。link への追加は Radix の data-* 表には載りませんが、実 DOM(RovingFocusGroup.Item 経由)では出力される値であり、button/toggle_item との対称性を優先した superset です。
  • 予約キーなりすまし除去を追加: 呼び出し側 attrs が role/aria-*/data-*/type/tabindex 等の固定付与属性を偽装・重複出力できないよう drop_reserved を導入しました(tabs/nav-list 等と同型のパターン)。

一方で以下は意図的に Radix と合わせていません。

  • Radix Button の native disabled 透過: RovingFocus が focusable={!disabled} でフォーカス順序から除外しますが、本実装は WAI-ARIA APG 推奨(disabled もフォーカス可能)に従い aria-disabled="true" + data-disabled + tabindex を維持します。
  • dir(RTL): 本リポジトリ横断で未採用です。
  • asChild・loop 既定値 true: 本実装は loop_focus を呼び出し側が明示する設計です。

関連 API: fandhe-frontend-headless-ui API

自前 CSS の最小例

Themes 版を使わず本部品を直接使う場合、[data-scope="toolbar"][data-part="..."] セレクタと data-state/data-disabled/data-orientation で見た目を組み立てます。

CSS
[data-scope="toolbar"][data-part="root"] {
  display: flex;
  gap: 0.25rem;
}

[data-scope="toolbar"][data-orientation="vertical"] {
  flex-direction: column;
}

[data-scope="toolbar"][data-part="separator"][data-orientation="vertical"] {
  width: 1px;
  align-self: stretch;
}

[data-scope="toolbar"][data-part="toggle-item"][data-state="on"] {
  background: #dbeafe;
}

[data-scope="toolbar"] [data-disabled] {
  opacity: 0.5;
}

[data-scope="toolbar"] :focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}

Demo

枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。

Edited 2 hours ago

Features

  • ボタン・リンク・セパレータ・ToggleGroup を横方向(または縦方向)にグループ化する操作バー。Root / Button / Link / Separator / ToggleGroup / ToggleItem の 6 anatomy パーツを持つ(toolbar.rs モジュール doc)。
  • roving tabindex(focused/item_count/loop_focus/orientation の複合状態機械 Toolbar)。フォーカス対象の項目のみ tabindex="0"、それ以外は tabindex="-1" になる。
  • disabled 項目もフォーカス順序から除外しない(WAI-ARIA APG の toolbar パターン推奨に従う意図的な設計。aria-disabled/data-disabled で操作不能のみを表す)。
  • link パーツは既存の link::root へ完全委譲し、external 時の target="_blank"/rel="noopener noreferrer" の不可分付与ロジックを再導出しない。
  • separator は toolbar 自身の向きと直交する aria-orientation を出力する(横向き toolbar のセパレータは縦線になる)。

Anatomy

root
  toggle-group
    toggle-item
  separator
  link
  button

API Reference

Arguments

NameTypeDefaultDescription
root(orientation)OrientationOrientation::Horizontalrole="toolbar" に付与する向き。aria-orientation/data-orientation の両方へ反映される。button/link/separator/toggle_group/toggle_item も先頭引数として同じ Orientation を受け取り data-orientation を出力する(イシュー #1657、Radix Primitives Toolbar との突合で追加)。
root(label)&str—root に付与する aria-label(空文字列のときは省略)。
button(focused)bool—true のとき tabindex="0"、false のとき tabindex="-1"(roving tabindex)。button/link/toggle_item 共通の引数。
link(external)boolfalsetrue のとき target="_blank"/rel="noopener noreferrer" を crate::link::root への完全委譲で不可分に付与する(reverse tabnabbing 対策)。
toggle_item(pressed)bool—aria-pressed/data-state(pressed_data_state 経由)へ反映される押下状態。
toggle_item(value)&str—data-value として出力する識別子(ark-ui 対応の superset、REQ-1 既定エスケープを経由)。

Data Attributes

PartAttributeObserved Values
buttondata-orientationhorizontal
linkdata-orientationhorizontal
rootdata-orientationhorizontal
separatordata-orientationvertical
toggle-groupdata-orientationhorizontal
toggle-itemdata-disabled(値なし)
toggle-itemdata-orientationhorizontal
toggle-itemdata-pressed(値なし)
toggle-itemdata-stateoff, on
toggle-itemdata-valuealign-center, align-left, align-right, bold, italic, strikethrough

Examples

Vertical orientation の構成

縦方向の Toolbar で Separator の aria-orientation が水平(直交)に切り替わる例です。

自前 CSS の最小例

headless-ui はスタイルレスのため、data-scope/data-part/data-orientation セレクタを使って呼び出し側が自由にスタイルを当てられます(そのまま貼り付けて動く最小限の CSS)。

[data-scope="toolbar"][data-part="root"] {
  display: flex;
  gap: 0.25rem;
}
[data-scope="toolbar"][data-orientation="vertical"] {
  flex-direction: column;
}
[data-scope="toolbar"][data-part="separator"][data-orientation="vertical"] {
  width: 1px;
  align-self: stretch;
}
[data-scope="toolbar"][data-part="toggle-item"][data-state="on"] {
  background: var(--accent-subtle, #dbeafe);
}
[data-scope="toolbar"] [data-disabled] {
  opacity: 0.5;
}
[data-scope="toolbar"] :focus-visible {
  outline: 2px solid var(--focus-ring, #2563eb);
}

Accessibility

Keyboard Interactions

KeyDescription
Tab / Shift+Tabネイティブ button/a 要素の暗黙フォーカス移動(roving tabindex により tabindex="0" の項目のみが Tab 順序に含まれる)。実装済み。
Space / Enterネイティブ button/a 要素の暗黙アクティベーション。実装済み。
矢印キー / Home / Endheadless-ui は ToolbarAction(Next/Prev/First/Last/Focus)として状態遷移 API のみを提供する。fandhe-frontend-wasm-full に本モジュールの keydown 配線は現状存在しない(イシュー #1657 時点で確認済み、未実装。別 Issue の起票対象)。

WAI-ARIA

AttributeDescription
role="toolbar" / aria-orientation / data-orientationroot に固定付与。orientation 引数の値を反映する。
role="separator" / aria-orientation / data-orientationseparator に固定付与。toolbar 自身の向きと直交する値になる(aria-orientation と data-orientation は同値)。
role="group" / data-orientationtoggle-group に固定付与(aria-orientation は role="group" に許可されないため付与しない)。
aria-pressed / data-orientationtoggle-item に付与。押下状態(true/false)と toolbar の向きを表す。