Fix v6 menu keyboard navigation for nested submenus#42699
Conversation
Include submenu triggers when collecting keyboard-navigable items so arrow keys work with the supported .menu > .submenu > .menu-item markup. When focus moves to another item at the same level, close open sibling submenus that no longer relate to focus (aligned with click/hover behavior).
There was a problem hiding this comment.
Pull request overview
Fixes Bootstrap v6 Menu keyboard navigation in nested submenu layouts by ensuring arrow-key focus traversal includes submenu triggers and by closing open sibling submenus when focus moves to an unrelated item at the same menu level (aligning keyboard behavior with existing click/hover behavior).
Changes:
- Expand keyboard-navigable item collection to include both direct
.menu-itemchildren and top-level submenu triggers. - Close open sibling submenus during ↑/↓ and Home/End navigation when focus moves to a different item at the same level.
- Add unit tests covering sibling submenu closure during keyboard navigation and navigation across submenu triggers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
js/src/menu.js |
Adjusts keyboard navigation item collection and adds logic to close unrelated open sibling submenus when focus changes via keyboard. |
js/tests/unit/menu.spec.js |
Adds tests for keyboard navigation across submenu triggers and for closing open sibling submenus on focus movement. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| _getItemsInMenu(menu) { | ||
| // Items may be direct children of `.menu`, or submenu triggers nested as | ||
| // `.menu > .submenu > .menu-item` (see menu-submenu visual tests / docs). | ||
| return SelectorEngine.find( | ||
| `:scope > ${SELECTOR_VISIBLE_ITEMS}, :scope > ${SELECTOR_SUBMENU_TOGGLE}`, | ||
| menu | ||
| ).filter(element => isVisible(element)) | ||
| } |
Apply the same :not(.disabled):not(:disabled) filter used for direct menu items when collecting submenu triggers, so arrow keys do not land on disabled nested menu entries.
|
Addressed Copilot's review: disabled submenu triggers are now filtered with the same |
|
DEPLOY PREVIEW URL: https://deploy-preview-42699--twbs-bootstrap.netlify.app/docs/6.0/components/menu/#nested I had a quick look at this and keyboard works well for the first menu (an improvement over v6-dev branch as it stands), but once you're in the submenu you can't use arrow keys to move up and down the submenu. You can use Tab to navigate, so it is possible to navigate with just keyboard but I expected to be able to use arrow up/down keys for submenus too. |
Keydown handlers on nested .menu panels could not resolve the owning Menu toggle (they only looked for sibling toggles), so arrow keys did nothing inside open submenus. Resolve the instance from open menus that contain the event target, and add a regression test.
|
Thanks @coliff for testing the deploy preview — great catch. Root cause: keydown inside a nested Pushed a fix that resolves the open Menu instance from the event target, plus a regression test for arrow navigation inside an open nested submenu. Would appreciate another look when you have a moment. |
yeah! did a quick test on Edge / Windows 11 and works great. nice work :-) |
|
Thanks @coliff — really appreciate you re-testing! |
Description
Bootstrap v6’s Menu component supports nested submenus (
.menu > .submenu > .menu-item), but keyboard arrow navigation only collected direct.menu-itemchildren of.menu. That skipped submenu triggers, so ↑/↓ could not move between them.This PR:
_closeSiblingSubmenus).Motivation & Context
@mdo invited exploring nested-menu improvements on
v6-devafter closing the v5-only nested dropdown PR (#42694): nested menus are supported in v6.This is the keyboard counterpart of existing click/hover sibling-close behavior already covered in unit tests.
Type of changes
Checklist
Tests
npm run js-test-karma→ 1131/1131 SUCCESS