Skip to content

Stop Home and End on a Menu toggle from throwing - #43376

Open
kwy404 wants to merge 1 commit into
twbs:mainfrom
kwy404:fix-menu-home-end-toggle
Open

kwy404 wants to merge 1 commit into
twbs:mainfrom
kwy404:fix-menu-home-end-toggle

Conversation

@kwy404

@kwy404 kwy404 commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

Description

  • Root cause: Menu#_handleSubmenuKeydown() handles Home and End for any key target. When the target is the toggle, closest('.menu') returns null, because the toggle is outside the menu. The handler calls preventDefault() and then passes null to _getItemsInMenu(), which throws TypeError: Illegal invocation.
  • Fix: return early when the key target is not inside a .menu. Home and End keep their default action on the toggle, and nothing throws. Inside a menu (items, submenu toggles, a menu moved to container), Home and End still move focus to the first or last item.
  • Test: should leave Home and End to the browser on the toggle in js/tests/unit/menu.spec.js presses Home and End on the toggle with the menu closed and open. Before the fix it fails with expected true to be exactly false and Vitest reports TypeError: Illegal invocation. After the fix it passes.
  • Ran npm run js-test (37 files, 1471 tests pass; 1470 on main), npm run js-lint (0 errors, same 15 warnings as main) and npm run js-typecheck.

Motivation & Context

To reproduce: focus any [data-bs-toggle="menu"] button, then press Home or End. Chrome logs Uncaught TypeError: Illegal invocation (other browsers word it differently), and the key does nothing because its default action is prevented. This also happens on nav links that toggle a menu.

I kept Home and End as plain browser keys on the toggle instead of making them jump into the open menu. The docs list them as moving between menu items, the v5 Dropdown never handled them on the toggle, and the ARIA menu button pattern only gives the button Enter, Space and the arrow keys. Happy to switch to focusing the first or last item if you prefer that.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would change existing functionality)

Checklist

  • I have read the contributing guidelines
  • My code follows the code style of the project (using npm run lint)
  • My change introduces changes to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Live previews

Not applicable, JavaScript only change.

Related issues

None.

The Menu keydown handler runs for Home and End on the toggle too. The
toggle is outside the `.menu`, so `closest('.menu')` returns null. The
handler then called `preventDefault()` and passed null to
`_getItemsInMenu()`, which threw "TypeError: Illegal invocation".

Return early when the key target is not inside a menu. Home and End now
keep their default action on the toggle, and nothing throws. Inside a
menu, they still move focus to the first or last item.
@kwy404
kwy404 requested a review from a team as a code owner November 14, 2026 03:06
@julien-deramond julien-deramond added v6 v6, the main branch accessibility Keyboard, screen readers, contrast, ARIA bug Something does not work as documented js JavaScript or TypeScript sources and plugins labels Nov 14, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility Keyboard, screen readers, contrast, ARIA bug Something does not work as documented js JavaScript or TypeScript sources and plugins v6 v6, the main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants