ドロップダウンのキーボード操作時に選択項目を自動スクロール
キーボードでドロップダウンメニューをナビゲートする際、スクロール可能なリスト内で選択肢が画面外に隠れる問題を解消し、常に選択中の項目が可視になるようにしました。
背景
キーボードで handleDocumentKeyDown ハンドラを通じて項目を切り替えると、メニューが overflow: auto でスクロール可能な場合でも、選択された要素がビューポート外に残るケースがありました。
この挙動は長いリストを持つドロップダウンで特に顕著で、ユーザーは現在選択中の項目がどこにあるか把握できず操作性が低下していました。既存の実装では focus({ preventScroll: true }) だけでスクロールは行われませんでした。
したがって、キーボードナビゲーション中に選択項目を自動的に可視化する処理が求められました。
技術的な変更
この PR は itemToSelect.scrollIntoView({ block: 'nearest' }) を新たに呼び出す一点の追加で、選択項目がビューに入るようにしました。
@@ -452,6 +452,7 @@ export default class WaDropdown extends WebAwesomeElement {
event.stopPropagation();
items.forEach(item => (item.active = item === itemToSelect));
itemToSelect.focus({ preventScroll: true });
+ itemToSelect.scrollIntoView({ block: 'nearest' });
return;
}
追加された行は handleDocumentKeyDown 内の if (itemToSelect) ブロック直後に配置され、フォーカス後にネイティブの scrollIntoView API を用いて最小限のロジックでスクロールを実現しています。既存の挙動に影響を与えることなく、選択項目が自動で表示領域に収まります。
設計判断
今回の実装は scrollIntoView というブラウザ組み込みのメソッドを利用することで、独自のスクロール計算やスタイル調整を回避し、コードベースへの侵入度を最小化しています。
PR の議論ではカスタムスクロールロジックやアニメーションの追加も検討されましたが、標準 API の block: 'nearest' オプションで既に要件を満たすことが確認され、保守性とパフォーマンスの観点からシンプルなアプローチが採用されました。
この選択により、既存のキーボードハンドラロジックはそのまま保持され、将来的な UI 変更やアクセシビリティ要件への拡張も容易な状態です。
まとめ
itemToSelect.scrollIntoView({ block: 'nearest' }) の追加は、スクロール可能なドロップダウンメニューでのキーボードナビゲーション時に選択項目を常に可視化し、操作性とアクセシビリティを向上させます。最小限のコード変更で後方互換性を保ちつつ、ブラウザの標準機能を効果的に活用した設計判断と言えるでしょう。