Skip to content
fandhe-frontendcore v0.4.3
GitHub

Menubar

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

複数の Menu を水平(または垂直)に並べるコンテナです。role="menubar" を持つルートの配下に、role="none" の Menu ラッパーと role="menuitem" のトリガーが並び、roving tabindex(フォーカスが常に 1 トリガーのみに当たる状態)の状態機械を提供します。Menubar 特有の挙動として、ある Menu が開いた状態でフォーカスを隣のトリガーへ移動すると、開く Menu も一緒に移動します。既存の Menu の anatomy はそのまま再利用せず、開閉状態機械・値語彙のみを再利用します。矢印キー・Home/End・typeahead による実際のフォーカス移動(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 / View / Profiles の 4 Menu を水平配置し、開いている Menu を切り替えた 3 つの静的デモ(File Menu が open=Some(0)、View Menu が open=Some(2)、Profiles Menu が open=Some(3))を並べています。1 つ目(File Menu)は Item Group(Recent)・Separator・SubTrigger/SubContent(Export → PDF)の入れ子構造を含みます。roving tabindex(focused=0)により先頭の File トリガーのみ tabindex="0" です。Edit トリガーは highlighted=true とし、trigger の data-highlighted 配色(イシュー #1702)も掲示します。File Menu の report.md item は item-text + kbd(⌘O)の合成でショートカット表示を、Print… item は disabled=true として disabled_declarations 配色を掲示します(内部パート是正はイシュー #1703)。Export sub-trigger は右端に示唆グリフ(▸)のテキストノードを添え、サブメニュー示唆を表現します。2 つ目(View Menu)は checkbox-item 2 件(Status Bar が checked)、3 つ目(Profiles Menu)は radio-item-group + radio-item 3 件(Default が checked)をそれぞれ開いた状態で掲示し、item-indicator(末尾チェックマーク、イシュー #2034 で Themes 層へ CSS 付与)による checked 表現を確認できます(イシュー #2034、PR #2164 レビュー指摘対応)。

Status Bar
Word Wrap
Default
Staging
Production

Features

  • 複数 Menu を水平(または垂直)に並べるコンテナ。headless-ui 側(fandhe_frontend_headless_ui::menubar)は Root / Menu / Trigger / Positioner / Content / Arrow / ArrowTip / Item / ItemText / ItemIndicator / ItemGroup / ItemGroupLabel / Separator / SubTrigger / SubContent / CheckboxItem / RadioItemGroup / RadioItem の 18 anatomy パーツを持つ(イシュー #1652 で参照突合し 11 → 18 パーツ)。Themes 側(本ページ)はイシュー #2034 で shadcn/ui と突合し、新設パートのうち item-text / item-indicator / checkbox-item / radio-item-group / radio-item の 5 パーツへ SLOTS/CSS 付与を追いつかせた(#1528 が申し送っていた分の解消)。arrow / arrow-tip は shadcn/ui のデモに矢印インジケータが視認できないため意図的に未着装のまま。
  • 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
            item-text
        separator
        sub-trigger
        sub-content
        checkbox-item
          item-indicator
        radio-item-group
          radio-item

API Reference

Arguments

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

Data Attributes

PartAttributeObserved Values
checkbox-itemdata-statechecked, unchecked
checkbox-itemdata-valuestatus-bar, word-wrap
contentdata-stateclosed, open
itemdata-disabled(値なし)
itemdata-highlighted(値なし)
itemdata-valuepdf, print, report.md
item-indicatordata-statechecked, unchecked
item-textdata-highlighted(値なし)
menudata-stateclosed, open
positionerdata-stateclosed, open
radio-itemdata-statechecked, unchecked
radio-itemdata-valuedefault, production, staging
rootdata-orientationhorizontal
sub-contentdata-stateclosed
sub-triggerdata-stateclosed
triggerdata-highlighted(値なし)
triggerdata-stateclosed, open
triggerdata-value0, 1, 2, 3

Examples

Keyboard shortcut suffix

shadcn/ui の Menubar デモが item 末尾に表示する ⌘T 風のキーボードショートカット表示に相当する合成パターンです。SlotRecipe は子孫セレクタを持たない(イシュー #708 で不採用確定)ため、新しい anatomy パートは追加せず、item の子として item_text(flex: 1 1 auto でラベルを引き伸ばす)と crate::kbd の kbd() を並べるだけで末尾寄せを実現しています(item 自身の CSS は変更していません)。

New Tab⌘T

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 が付与される。