DropdownMenu

現在の対象に関する補助の操作をまとめます。

アイコン・説明・補助表記・区切り・危険操作

補助表記は表示のみです。削除を含め、この例ではデータを変更しません。

サブメニュー・多段の階層・無効なサブメニュー
複数選択・一部選択・単一選択

チェック・単一選択は開いたまま更新します。完了またはEscapeで閉じます。

リンク・別タブ・無効なリンク
トリガーのサイズ・アイコンのみ・主要操作との組み合わせ
無効・処理中・空・全項目が無効
右寄せ・右から左・長文・スクロール
選択後も開く操作・選択後に閉じるチェック

使いどころ

  • 今見ている対象への補助の操作(複製・書き出し・削除など)を、一つの操作の中にしまう時に使います。
  • 表示の切り替えや並び順のように、開いたままオン・オフを切り替えたり一つを選んだりする設定にも使えます(checkbox・radio)。
  • 文字を入力して絞り込みながら選ぶ時は FilterMenu、フォームの値として一つを選ぶ時は Select を使います。
  • 主操作にほかのやり方を▾で添える時は SplitButton を使います。
  • 説明の文やフォームを載せる時は、白いパネルの Popover を使います。

使い方

DropdownMenuController を dropdown-menu として登録します。id は画面内で一意にし、items に項目を並べます。開く操作は共通の Button で、variant・size・disabled・busy は開く操作にかかります。

項目は kind で分けます。省略または action は通常の操作、link はページの移動、checkbox はオン・オフ、radio は単一選択、submenu は下の階層、separator は区切り線、group は見出し付きのまとまりです。submenu と group は items を持ち、入れ子にできます。radio の name は、同じ階層の中の選択のまとまりを表します。

項目には icon・description・shortcut を添えられ、通常の操作は danger で赤い文字にできます(ホバーした時と選んでいる時は、淡い赤の面に赤い文字にします)。shortcut は表示だけで、キーの登録は利用側が行います。

通常の操作は選ぶと閉じ、チェックと単一選択は開いたままチェックマークを更新します。closeOnSelect でこの既定を変えられます。リンクは標準のページ移動を行い、選択のイベントを発火しません。

選んだ項目は dropdown-menu:select の detail で受け取ります。action に dropdown-menu:select->editor#apply のようなStimulusのactionを渡すと、ルートの data-action になり、利用側のcontrollerへつなげます。選んだ後の処理(保存・通信・画面の更新)は利用側が行います。

メニューは白いパネル(1px #bbb の枠、角丸5px、外への柔らかい影)に黒い12pxの文字で、Popover APIのトップレイヤーに出します。開閉はその場で切り替え、アニメーションはしません。項目は28pxの間隔で並べます。ホバーした項目と矢印キーで選んでいる項目は、行の幅いっぱいの角の無い淡い青(--rx-option-active、#ddeefe)に黒い文字にし、ピルで囲みません。まとまりの見出しは灰色の小さな太字(11px)、区切りは1px #dedede の罫線です。使えない項目は文字だけを灰色にします。開く操作の下に出し、下に空きが無ければ上に出します。サブメニューは行の末尾側に開き、空きが無ければ反対側に開きます。どちらも画面の端から8pxの内側に収め、幅は20rem、高さは384pxを上限にして、あふれる分はスクロールします。

メニューの背後には透明な層を置き、層を押すとメニューを閉じます。背後のボタンやリンクは押されません。メニューの外へフォーカスが移った時と、別の DropdownMenu を開いた時も閉じます。

項目は上揃えです。一行の時は対称な上下の余白で中央に見え、説明が付いて複数行になると、同じ上端から下へ伸びます。項目の中身全体を align-items: center で中央へ寄せないでください。指で操作する環境では、一行の高さを2.75remにします。

items が空の時は「利用できる操作はありません」と出します。JavaScriptなしではメニューは開きません。

キーボード

DropdownMenuのキーボード操作
キー動作
↓ / Enter / Space(開く操作)メニューを開き、最初の有効な項目へ移ります。
↑(開く操作)メニューを開き、最後の有効な項目へ移ります。
↓ / ↑次・前の有効な項目へ移ります。端では反対の端へ戻ります。
Home / End最初・最後の有効な項目へ移ります。
→(右から左では←)サブメニューの項目では、サブメニューを開いて最初の項目へ移ります。
←(右から左では→)サブメニューを閉じ、親の項目へ戻ります。
Enter / Space項目を選びます。リンクは移動し、サブメニューの項目は下の階層を開きます。
Escape一段戻ります。一番上の階層では閉じて、開く操作へフォーカスを戻します。
Tabメニューを全て閉じ、開く操作から次(Shift+Tabなら前)の要素へ進みます。
文字項目名がその文字で始まる次の項目へ移ります。続けて打った文字(0.6秒以内)は一続きの語として探します。

アクセシビリティ

  • 開く操作は aria-haspopup="menu"・aria-expanded・aria-controls を持ち、メニューは role="menu" で開く操作の文言を名前にします。iconOnly の時は label を開く操作の aria-label にします。
  • 項目は menuitem・menuitemcheckbox・menuitemradio で、チェックと単一選択は aria-checked(mixed を含む)で状態を伝えます。サブメニューの項目は aria-haspopup・aria-expanded・aria-controls を持ちます。
  • 項目名は aria-label、description は aria-description として読み上げます。選べない項目は aria-disabled="true" にし、矢印の移動で飛ばします。
  • group は見出しを名前にした role="group"、separator は role="separator" です。
  • shortcut の表記は読み上げから外します(aria-hidden)。
  • 日本語の変換中のキーと、Ctrl・Alt・Commandを押しながらのキーは奪いません。サブメニューをマウスで開くのは、項目にホバーして150ms後です。

イベント

DropdownMenuが発火するイベント
イベント内容
dropdown-menu:open一番上のメニューを開いた時。detail は空です。
dropdown-menu:closeメニューを閉じた時。detail は空です。
dropdown-menu:beforeselect項目を選ぶ直前。取り消せます(preventDefault() でチェックを変えず、閉じません)。detail は value・kind、チェックと単一選択では選んだ後の checked、単一選択では name です。
dropdown-menu:select項目を選んだ後。detail は dropdown-menu:beforeselect と同じです。リンクとサブメニューの項目では出しません。

API

DropdownMenu

選択結果はdropdown-menu:select。チェック項目はcheckedも通知する。

DropdownMenuのprops
名前型既定値説明
disabledboolean開く操作を押せなくする。
size"default" | "compact" | "large" | "tag"大きさ。compactは同じ高さで左右の余白を狭め、largeはフォーム末尾などの大きな操作に使う。 tagはTagの中の解除操作用で、タッチ環境でも小さなタグの高さを保つ。
variantButtonVariant見た目の役割。primaryは画面の主操作、secondaryは通常の操作、 dangerは取り返しのつかない操作、linkは文字だけの軽い操作。
busyboolean処理中にする。押せなくし、aria-busyを付け、ポインターを待ちの形にする(控えめな操作は面を淡い灰色にする)。内容はbusyLabelに置き換える。アイコンだけの操作(data-icon-only="true")は形を保つためアイコンのまま残す。
id必須stringメニューのid。画面内で一意にする。開く操作は<id>-trigger、項目は<id>-<番号>-itemになる。
label必須string開く操作の文言。iconOnlyの時はaria-labelとして読み上げる。
items必須readonly MenuItem[]メニューの項目。空ならメニューに「利用できる操作はありません」と出す。
actionstringルートのdata-actionに渡すStimulusのaction。 dropdown-menu:select->editor#applyのように、選択のイベントを利用側のcontrollerへつなぐ。
align"start" | "end""start"メニューを開く操作のどちらの端に揃えるか。endは行の末尾側に置いた操作に使う。
dir"ltr" | "rtl"文字の向き。rtlでは左右の矢印キーとサブメニューの開く向きが反転する。
iconIconName開く操作の文言の前に置くアイコン。
iconOnlybooleanfalse開く操作をアイコンだけの正方形にする。iconが無ければ▾だけを出す。

登録するcontroller:dropdown-menu(DropdownMenuController)

読み込むCSS:layers.css、reset.css、tokens.css、base.css、layout.css、components/button.css、components/overlay.css、components/dropdown-menu.css、components/icon.css、components/keycap.css

ButtonVariant

操作の見た目の役割。primaryは平らな緑の塗りに白い太字(角丸4px)、secondaryは平らな白い面と1pxの灰色の枠(角丸5px)、 dangerは平らな赤の塗りに白い文字(角丸4px)、linkは面も枠も持たない青緑の文字に下線。

値:"primary" | "secondary" | "danger" | "link"

MenuItem

MenuItem(kind: "action")
名前型既定値説明
label必須string項目名。文字を打って項目を探す時は、この名前の先頭で探す。
disabledboolean選べない項目にする。矢印の移動でも飛ばす。リンクは移動せず、サブメニューは開かない。
iconIconName項目名の前に置くアイコン。
descriptionstring項目名の下に添える補足。読み上げではaria-descriptionになる。
shortcutstring表示用の補助表記。ショートカットの登録は利用側で行う。
kind"action"通常の操作。省略してもよい。
value必須string選んだ時に発火するdropdown-menu:selectのdetail.valueに入る値。
dangerboolean削除など取り返しのつかない操作として、赤い文字で分ける。
closeOnSelectboolean選んだ後に閉じるか。通常の操作は既定で閉じる。falseで開いたままにする。
MenuItem(kind: "link")
名前型既定値説明
label必須string項目名。文字を打って項目を探す時は、この名前の先頭で探す。
disabledboolean選べない項目にする。矢印の移動でも飛ばす。リンクは移動せず、サブメニューは開かない。
iconIconName項目名の前に置くアイコン。
descriptionstring項目名の下に添える補足。読み上げではaria-descriptionになる。
shortcutstring表示用の補助表記。ショートカットの登録は利用側で行う。
kind必須"link"ページの移動。選ぶと標準のページ移動を行い、選択のイベントは発火しない。
href必須string移動先。
target"_blank" | "_self"リンクを開く場所。_blankではrel="noopener noreferrer"を付ける。
MenuItem(kind: "checkbox")
名前型既定値説明
label必須string項目名。文字を打って項目を探す時は、この名前の先頭で探す。
disabledboolean選べない項目にする。矢印の移動でも飛ばす。リンクは移動せず、サブメニューは開かない。
iconIconName項目名の前に置くアイコン。
descriptionstring項目名の下に添える補足。読み上げではaria-descriptionになる。
shortcutstring表示用の補助表記。ショートカットの登録は利用側で行う。
kind必須"checkbox"オン・オフを切り替える複数選択の項目。
value必須string選んだ時に発火するdropdown-menu:selectのdetail.valueに入る値。
checkedboolean | "mixed"チェックマークの初期状態。mixedは一部だけ選んだ状態。選ぶたびにcontrollerが切り替え、切り替えた後の値をdetail.checkedで渡す(mixedから選ぶとtrue)。
closeOnSelectboolean選んだ後に閉じるか。チェックは既定で開いたまま更新する。trueで閉じる。
MenuItem(kind: "radio")
名前型既定値説明
label必須string項目名。文字を打って項目を探す時は、この名前の先頭で探す。
disabledboolean選べない項目にする。矢印の移動でも飛ばす。リンクは移動せず、サブメニューは開かない。
iconIconName項目名の前に置くアイコン。
descriptionstring項目名の下に添える補足。読み上げではaria-descriptionになる。
shortcutstring表示用の補助表記。ショートカットの登録は利用側で行う。
kind必須"radio"同じnameの中から一つを選ぶ単一選択の項目。
value必須string選んだ時に発火するdropdown-menu:selectのdetail.valueに入る値。
name必須string選択のまとまりの名前。同じ階層で同じnameを持つ項目から一つだけを選ぶ。
checkedboolean最初に選んでおく項目。
closeOnSelectboolean選んだ後に閉じるか。単一選択は既定で開いたまま更新する。trueで閉じる。
MenuItem(kind: "submenu")
名前型既定値説明
label必須string項目名。文字を打って項目を探す時は、この名前の先頭で探す。
disabledboolean選べない項目にする。矢印の移動でも飛ばす。リンクは移動せず、サブメニューは開かない。
iconIconName項目名の前に置くアイコン。
descriptionstring項目名の下に添える補足。読み上げではaria-descriptionになる。
shortcutstring表示用の補助表記。ショートカットの登録は利用側で行う。
kind必須"submenu"下の階層を開く項目。
items必須readonly MenuItem[]下の階層の項目。入れ子にできる。
MenuItem(kind: "separator")
名前型既定値説明
kind必須"separator"区切り線。
MenuItem(kind: "group")
名前型既定値説明
kind必須"group"見出し付きのまとまり。見出しは選べない。
label必須stringまとまりの見出し。中の項目のrole="group"の名前にもなる。
items必須readonly MenuItem[]まとまりに入れる項目。

IconName

値:Iconの見本

コード

HTML
Hono JSX