アクションメニュー
componentボタンを押すと開くポップアップに、その対象に対する操作(編集・複製・削除など)を並べるメニューです。ネイティブの Popover API で最前面に開くため、カードの中から開いても切れません。項目は メニュー の menu-item を再利用します。
開いて試す
クリック、またはトリガーにフォーカスして ↓ で開きます。↑ ↓ で移動、Esc で閉じます
btn トリガー(左揃え・既定)
グループ見出し+無効項目
リンク
書き出し
card-action から(右揃え .action-menu-end)
プロジェクト A
最終更新: 2026-05-25
譲渡条件の整理と、候補者との面談日程を調整しています。
項目の状態
default / hover / focus / danger / disabled。開いた状態を静的に表示(.is-static-preview)。左アイコンは任意(付けるならメニュー内で有無を揃える)
機能
このコンポーネントの用途
ボタンから開くポップアップで、その対象に対する操作(編集 / 複製 / 削除 等)を選ばせる。
画面に常に出しておく操作の一覧は menu、値を選んで送信するフォーム項目は select / selector、
ページやサイト内の移動はリンク(menu のナビ用途)、入力や確認を伴う操作は modal。
使用法
推奨される使い方と、やりがちな NG パターン
OK
- ✓トリガーは btn か icon-btn(三点アイコン等)。icon-btn なら aria-label に対象を含める(例: 『プロジェクト A』のメニュー)。
- ✓項目は button + role="menuitem"。選ぶと操作を実行してメニューを閉じ、フォーカスをトリガーに戻す。
- ✓削除など取り消せない操作は .action-menu-item-danger にし、divider で他の操作と分けて末尾に置く。
- ✓トリガーが画面の右寄り(card-action・表の行末など)なら .action-menu-end で右端に揃える。
- ✓今は実行できない操作は消さずに aria-disabled="true" で残す(何ができるかを伝えるため)。全項目が無効ならトリガー自体を disabled にする。
- ✓左アイコンは任意。付けるならメニュー内で有無を揃える(テキストの頭が揃わなくなるため)。
NG
- ✕ページ遷移のリンクを並べない → 移動は menu(nav)やリンク。action-menu は「その場の操作」専用。
- ✕値の選択(並び替え・絞り込みの選択肢)に使わない → select / selector / tab / filter-chip。 表の列の値で行を絞り込むなら data-table の列フィルター(data-table-filter)、表の並べ替えは見出しの data-table-sort。
- ✕項目に入力欄やチェックボックスを入れない → 入力を伴うなら modal やフォームにする。
- ✕操作が 1〜2 個しかないのにメニューに畳まない → btn を直接並べる方が速い。
- ✕hover で開かない → クリック(タップ)・キーボードで開く。
- ✕一部の項目だけにアイコンを付けない → 全項目に付けるか全項目で外す。混在するとラベルの 開始位置がずれて視線が乱れる。
「その場の操作」だけを並べる
遷移・値の選択は別の部品対象に対する操作を並べ、取り消せない操作は danger にして区切り線の下・末尾に置く。
ページ移動はリンク(menu のナビ)、並び替えなど値の選択は select / tab に分ける。メニューに畳むと現在の状態が見えなくなる。
アクションメニューのアクセシビリティ
relay のアクションメニューは WAI-ARIA APG の Menu Button パターン(トリガー aria-haspopup="menu" + role="menu" / menuitem)です。開閉・Esc・外側クリックでの閉じはネイティブの Popover API が担い、フォーカス移動と矢印キー操作は小さな JS で付与します。WCAG 2.2 全基準は アクセシビリティ ページを参照。
期待される配慮
Presentation / Adaptability / Interaction / Assistive Technology
メニューは影と輪郭線で背景から浮かせる。danger は色だけに頼らず「削除」などラベルで操作内容を示す。無効項目は消さずに薄く残す。
下に空きが無ければ上に開き、画面端から 16px は空ける。項目が多いときはメニュー内でスクロールする。
クリック / Enter / Space / ↓ で開き、↑ ↓ で移動、Enter で実行、Esc で閉じてトリガーに戻る。hover では開かない。
トリガーは「メニュー ポップアップ ボタン、折りたたみ / 展開」と読まれ、開くとメニュー名と項目数、各項目の名前が読まれる。
DS が担保する機能
追加実装なしで満たされる
- ✓Popover API による最前面表示・Esc と外側クリックでの閉じ・閉じた後のフォーカス復帰
- ✓フォーカスリング
--shadow-focus-ring+ フォーカス中項目の背景ハイライト - ✓danger は negative/700(白地・negative/50 地とも AA)、無効は fg-disabled で hover しない
- ✓強制カラーモードで輪郭線を CanvasText、無効項目を GrayText にする
実装時の必須対応
プロダクト側で担保する
- !トリガーに
aria-haspopup="menu"とaria-expanded、メニューにrole="menu"とaria-labelledby、項目にrole="menuitem"とtabindex="-1" - !icon-btn のトリガーは
aria-labelに対象を含めて一意化する(例: 『プロジェクト A』のメニュー) - !開閉に合わせた
aria-expandedの同期・先頭項目へのフォーカス・矢印キー移動・位置計算を JS で付与する(実装例はcatalog.jsの Action Menu ハンドラ) - !無効項目は
aria-disabled="true"(disabled 属性にしない。フォーカスを残して存在を伝える)
テスト方法
キーボード / スクリーンリーダー / 自動チェック
| キー | 動作 |
|---|---|
| Enter / Space(トリガー) | 開いて先頭の項目へフォーカス |
| ↓ / ↑(トリガー) | 開いて先頭 / 末尾の項目へフォーカス |
| ↓ / ↑(メニュー内) | 次 / 前の項目へ(端でループ) |
| Home / End | 先頭 / 末尾の項目へ |
| Enter(項目) | 操作を実行してメニューを閉じ、トリガーに戻る(無効項目は何もしない) |
| Esc | 閉じてトリガーに戻る |
| Tab | 閉じて次の要素へ進む |
- SRトリガーで「メニュー ポップアップ」「折りたたみ / 展開」、開くとメニュー名・項目名・「使用不可」(無効項目)が読まれる
- 自動axe / Lighthouse で role の親子関係(menu > menuitem)・トリガーの名前・コントラストを確認