Skip to content
fandhe-frontend
GitHub

Menubar

fandhe-frontend-pre-styled-uimenubar mod が提供するスタイル済み Menubar 部品です。

複数の Menu を水平(または垂直)に並べるコンテナです。role="menubar" を持つルートの配下に、role="none" の Menu ラッパーと role="menuitem" のトリガーが並び、roving tabindex(フォーカスが常に 1 トリガーのみに当たる状態)の状態機械を提供します。Menubar 特有の挙動として、ある Menu が開いた状態でフォーカスを隣のトリガーへ移動すると、開く Menu も一緒に移動します。既存の Menu の anatomy はそのまま再利用せず、開閉状態機械・値語彙のみを再利用します。矢印キーによる実際のフォーカス移動(DOM 配線)はクライアントランタイム(fandhe-frontend-wasm-full)側の後続実装です。

関連 API: fandhe-frontend-pre-styled-ui API / fandhe-frontend-headless-ui API

Demo

headless-ui の Menubar(role="menubar")に pre-styled-ui の recipe CSS を適用した静的掲示です。File / Edit の 2 Menu を水平配置し、File Menu を開いた状態(open=Some(0))で表示しています。Item Group(Recent)・Separator・SubTrigger/SubContent(Export → PDF)の入れ子構造も含みます。roving tabindex(focused=0)により先頭の File トリガーのみ tabindex="0" です。

Features

  • 複数 Menu を水平(または垂直)に並べるコンテナ。Root / Menu / Trigger / Positioner / Content / Item / ItemGroup / ItemGroupLabel / Separator / SubTrigger / SubContent の 11 anatomy パーツを持つ。
  • roving tabindex(focused/trigger_count/open/loop_focus/orientation の複合状態機械 Menubar)。フォーカス対象のトリガーのみ tabindex="0"、それ以外は tabindex="-1" になる。
  • 開いている Menu を跨いだ左右移動: ある Menu が開いた状態で Next/Prev/First/Last/Focus アクションを送ると、フォーカス移動と同時に開く Menu も隣へ移る(menubar 特有の挙動、Toolbar の roving tabindex には無い)。
  • menu パーツは role="none" を固定付与し、role="menubar" の子として menuitem/group 以外の要素を挟まないようにする(WAI-ARIA APG の menubar パターン)。
  • サブメニューの開閉状態は Menubar 自身ではなく、呼び出し側が別途持つ Menu インスタンス(Disclosure 埋め込み)から SubTrigger/SubContent へ注入する。
  • 既存の menu モジュールの anatomy はそのまま再利用しない(data-scope="menubar" を独自に持つ)。状態機械・値語彙(OpenState/aria/data-* ヘルパ)のみを再利用する。

Anatomy

root
  menu
    trigger
    positioner
      content
        item-group
          item-group-label
          item
        separator
        sub-trigger
        sub-content

API Reference

Arguments

NameTypeDefaultDescription
orientationOrientationOrientation::Horizontalroot の role="menubar" に付与する向き(Horizontal/Vertical)。aria-orientation/data-orientation の両方へ反映される。
label&strroot に付与する aria-label(空文字列のときは省略)。
focusedbooltrigger に付与。true のとき tabindex="0"、false のとき tabindex="-1"(roving tabindex)。
stateOpenStatetrigger/positioner/content/sub_trigger/sub_content の開閉状態(Open/Closed)。

Data Attributes

PartAttributeObserved Values
contentdata-stateopen
itemdata-highlighted
itemdata-valuepdf, report.md
menudata-stateclosed, open
positionerdata-stateopen
rootdata-orientationhorizontal
sub-contentdata-stateclosed
sub-triggerdata-stateclosed
triggerdata-stateclosed, open
triggerdata-value0, 1

Accessibility

Keyboard Interactions

KeyDescription
ArrowRight / ArrowLeft次/前のトリガーへフォーカスを移動する。ある Menu が開いていれば、開く Menu も追随する(MenubarAction::Next/Prev、wasm 層実装)。
Home / End先頭/末尾のトリガーへフォーカスを移動する(MenubarAction::First/Last、wasm 層実装)。
Enter / Space / ArrowDownフォーカス中のトリガーの Menu を開く(MenubarAction::Open、wasm 層実装)。
Escape開いている Menu を閉じる(MenubarAction::Close、wasm 層実装)。

WAI-ARIA

AttributeDescription
role="menubar" / aria-orientationroot に付与。orientation 引数の値(horizontal/vertical)を反映する。
role="none"menu に付与。role="menubar" の子として menuitem/group 以外を挟まないための WAI-ARIA APG 慣行。
role="menuitem" / aria-haspopup="menu" / aria-expandedtrigger/sub-trigger に付与。開閉状態(this Menu の state、もしくはサブメニュー側の sub_state)を反映する。
role="menu"content/sub-content に固定付与。aria-labelledby は labelledby 引数が Some のときのみ出力される。
role="menuitem"item に固定付与。disabled 時のみ aria-disabled="true" が付与される。
role="group"item-group に固定付与。labelledby が Some のときのみ aria-labelledby が付与される。