コンテキストメニューとクイックアクション
1)目的と範囲
ショートカットメニューとクイックアクションにより、頻繁に使用される操作へのパスが短縮されます:- オブジェクト上のローカルアクション(カード、テーブル行、係数)。
- 選択のバッチアクション。
- 隠されているが重要ではないオプション(セカンダリ)。
- ルール:コンテキストメニューでのみクリティカルおよびプライマリアクションを非表示にしないでください。
2)トリガーとバリエーション
右クリック/Shift+F10/Menuキー-古典的なコンテキストキー。
アイコンボタン(ケバブ'⋮'、ミートボール'……'、context)-タッチ/デスクトップ用のユニバーサル。
ロングプレス(400-600 ms)は右クリックのモバイル相当です。
コマンドパレット(⇧⌘P/Ctrl+K)-検索付きのグローバルクイックコマンド。
スワイプ-明らかに(iOS/Androidのリスト)-クイックショートカットの数を開きます。
推奨事項:少なくとも2つのコールメソッド(アイコン+コンテキストクリック/キー)を提供します。
3)コンテンツと優先度
最初の1-3ポイントは頻繁なアクションです。それから分離器;さらに-あまり一般的に使用されません。
破壊的-最後に、色/アイコンでマークされています(および多くの場合-確認/元に戻す)。
Wording-動詞+オブジェクト(「お気に入りに追加」「、IDをコピー」)。
ラベル≠アイコンのみです。アイコンはアンプであり、テキストの置換ではありません。
4)グループ化とステータス
論理ブロックの区切り文字(表示、編集、管理、危険)。
Сосссоano-radio: 'disabled'、 'checked' ('menuitemcheckbox'/'menuitemradio')、 'destructive'。
これが混乱している場合は、アクセスできない役割を表示しないでください。または-理由のヒントとともに'disabled'として表示します。
5)空室状況(A11y)
コンテナ:'role=「menu」、要素:'role=「menuitem」'/'menuitemcheckbox'/'menuitemradio'。
ロービングtabindex:現在の要素の唯一の'tabindex=」0「'、残りの'-1'。
________________________________________________Enter/Space-activation、 Esc-close。
Typeahead:最初の文字を印刷すると、フォーカスがポイントにシフトします。
フォーカスリングが表示されます。AA ≥テキストとアイコンのコントラスト。
ボタンアイコンは"aria-haspopup="menu"と"aria-expanded"を使います。
html
<button id="more" aria-haspopup="menu" aria-expanded="false" aria-controls="menu-1">Еще</button>
<ul id="menu-1" role="menu" aria-labelledby="more" hidden>
<li role="menuitem" tabindex="0">Открыть</li>
<li role="menuitem">Скопировать ссылку</li>
<li role="menuitemcheckbox" aria-checked="true">В избранном</li>
<li role="menuitem" data-danger="true">Удалить</li>
</ul>
ナビゲーション(ロービングtabindexスキーム):
js const menu = document.getElementById('menu-1');
menu.addEventListener('keydown', e=>{
const items=[...menu.querySelectorAll('[role^="menuitem"]')];
let i=items.findIndex(n=>n.tabIndex===0);
if(e.key==='ArrowDown'){ items[i].tabIndex=-1; items[(i+1)%items.length].tabIndex=0; items[(i+1)%items.length].focus(); e.preventDefault(); }
if(e.key==='ArrowUp'){ items[i].tabIndex=-1; items[(i-1+items.length)%items.length].tabIndex=0; items[(i-1+items.length)%items.length].focus(); e.preventDefault(); }
if(e.key==='Escape'){ menu.hidden=true; document.getElementById('more').focus(); }
});
6)位置および性能
ソースでメニューを開きます(クリックポイント/アイコン)、シフト4-8 px;画面の端を見る(フリップ/シフト)。
Portal/layer over ('z-index')とclick catch out。
怠惰にレンダリングし、長いメニューでリストをリサイクルします(仮想化は必要ありませんが、何百ものアイテムを避けてください)。
アニメーションは'opacity/transform'のみで、長さは140-200ms (100-160ms)です。
「ArrowRight」でサブメニューを開き、80-120 ms(アンチフリック)の遅延でホバーします。
7)モバイルパターン
ハプティクスとロングプレス。タイミング450 ± 100ミリ秒。
コンテキストメニューの形式としてのボトムシート(thumb-reachable)。
左側-「archive/favorites」、右側-「delete」(確認/元に戻す)。
クリックゾーン≥ 44 × 44、短い署名、アイコン20-24 px。
8)確認、元に戻し、セキュリティ
破壊的なアクション:2番目の確認(モーダル/確認パターン)、または5-10秒を元に戻す。
財務/リスク-結果のコンテキストを明示的に確認します。
「無効」(「不十分な権利」「、制限に達した」)理由を表示します。
9)メニューのないクイックアクション
行のインラインショートカット(アイコン""、""、""⋯")。
Hover-reveal(デスクトップ):ホバリング時にアクションを表示しますが、明示的なトリガーを残します。
コマンドパレット:アクション、ツールチップ内のホットキー(「⌘S」、 「Ctrl+Enter」)で検索します。
10)コピーライティングとアイコン
動詞+オブジェクト、2-3単語。
名詞ではなくアクション(「エントリの削除」……)で開始します(「エントリの削除」)。
単一のセットからのアイコン;製品全体で同じアクションに同じアイコンを使用します。
あいまいな項目の説明ヒント('title '/tooltip)。
11)テレメトリーと実験
アイテム別CTR、開始からクリックまでの平均時間、キャンセル/元に戻す率。
クリックミスの数(破壊→キャンセル)。
A/B:項目の順序とグループ化、リスト内のクイックショートカットの存在。
「見えない」アイテムのログ(誰も使用しない)-削除/転送の候補。
12)システムトークンの設計(例)
json
{
"menu": {
"minWidth": 208,
"itemHeight": 36,
"gap": 4,
"padding": 8,
"radius": 12,
"elev": 8,
"anim": { "inMs": 180, "outMs": 120, "ease": "cubic-bezier(0.2,0,0.2,1)" }
},
"swipe": { "revealThresholdPx": 56, "confirmDestructive": true }
}
CSSプリセット:
css
.menu{min-width:208px;padding:8px;border-radius:12px;box-shadow:var(--elev-3);background:var(--bg-elevated)}
.menu [role^="menuitem"]{height:36px;padding:0 12px;display:flex;gap:8px;align-items:center;border-radius:10px}
.menu [role^="menuitem"]:hover,
.menu [role^="menuitem"][tabindex="0"]{background:var(--bg-hover)}
.menu [data-danger="true"]{color:var(--role-danger)}
13)コンポーネントパターン
カード/タイル:右上隅のアイコン'⋯';ホバー-表示、タッチ-常に表示されます。
テーブル行:最後の列の'⋯';複数選択の場合-上/下からのバッチアクションのパネル。
チャット/通知リスト:スワイプアクション(アーカイブ/読み取り/削除)を元に戻します。
メディアギャラリー:ロングタップ→マルチセレクトモード+ボトムアクションパネル。
14) iGamingの詳細
クイックベット:係数のコンテキストメニューで-"Put X"(事前設定)、"Add to coupon"、 "Subscribe to change the coefficient。"確認/元に戻す必要があります。
お気に入り/サブスクリプション:「お気に入りにプロバイダー/ゲームを追加する」、「トーナメントを購読する」。
キャッシュアウト:インライン確認と現在の金額;市場の状態とだけ利用できる。
モデレーション/レポート:「苦情」、「ブロックチャット」-安全、役割によって表示されます。
責任あるゲーム:「制限を設定します」、「一時停止24h」-攻撃的な色なし、結果の明確な説明と。
15)アンチパターン
クリティカルアクションはコンテキストメニューにのみ非表示になります。
テキストのないアイテム(アイコンのみ)、特にリストで。
サブメニューに切り替えるときのカーソルの誤った閉鎖(遅延/回廊なし)。
メニューがソースアイテムと重なり合うか、画面の後ろに移動します(反転/シフトなし)。
確認/元に戻すことなく破壊的です。
明白でない権利(条項は説明なしで消えます)。
16) QAチェックリスト
可用性について
- 'role=「menu「'/'menuitem'は正しく、tabindexと矢印をロービングして動作します。
- Escはメニューを閉じ、フォーカスはソースに戻ります。
- コントラストとフォーカスリングはAAに対応しています。
Behavior(ビヘイ
- 項目の順序は頻度および危険を反映します;下部に破壊的です。
- 位置決めはエッジ(フリップ/シフト)を考慮に入れます。高速アニメーション(≤ 200ms)。
- サブメニューはArrowRightによって開かれ、「震え」(hover-intent 80-120 ms)しません。
モバイル
- ハプティックス付きロングプレス。ボトムシートは親指で快適です。
- スワイプアクションは元に戻します。エリア≥ 44 × 44をクリックします。
安全性について
- 危険なアクションの確認/元に戻す。障害者の理由ははっきりしています。
- ヒント/ラベルにプライベートデータの漏洩はありません。
メトリクス
- CTR/クリック時間が削除されました。misclick/undoが監視されます。
17)実装: 開閉およびクリックアウト
js const btn=document.getElementById('more'), menu=document.getElementById('menu-1');
const open=()=>{ menu.hidden=false; btn.setAttribute('aria-expanded','true'); menu.querySelector('[role^="menuitem"]').focus(); };
const close=()=>{ menu.hidden=true; btn.setAttribute('aria-expanded','false'); btn.focus(); };
btn.addEventListener('click', e=>{ menu.hidden?open():close(); });
document.addEventListener('pointerdown', e=>{ if(!menu.hidden &&!menu.contains(e.target) && e.target!==btn) close(); });
window.addEventListener('blur', close);
18)設計システムにおけるドキュメンテーション
「コンテキストメニュー」、「メニュー項目」、「サブメニュー」、「ボトムシート」、「スワイプアクション」、「コマンドパレット」。
寸法/行高さ/半径/アニメーショントークン。
アクセシビリティガイド(ARIA、キーボード、タイプヘッド)。
「Do/Don 't」とは、グループ化、位置付け、確認の例です。
簡単な要約
コンテキストメニューとクイックアクションは、予測可能でアクセス可能で安全な作業をスピードアップします。2つのコールパス、アイコン付きのクリアラベル、合理的なグループ化、リスクの確認/取り消し、キーボードナビゲーションの正しい位置決めです。デザインシステムのトークンとパターンをキャプチャします。ユーザーは間違いを恐れずに素早く行動します。