From 6372930c086b94f2fa5f717c04bff1b7ffacbc1a Mon Sep 17 00:00:00 2001 From: mehmet turac Date: Fri, 19 Jun 2026 19:39:49 +0300 Subject: [PATCH] Fix dropdown keyboard submenu dismissal --- js/src/dropdown.js | 4 +++ js/tests/unit/dropdown.spec.js | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 96094a3e6577..34c4bc5751af 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -420,6 +420,10 @@ class Dropdown extends BaseComponent { if (isUpOrDownEvent) { event.stopPropagation() + if (this.matches(SELECTOR_DATA_TOGGLE)) { + Dropdown.clearMenus(event) + } + instance.show() instance._selectMenuItem(event) return diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 63ae4bd102bc..8c5fe55e4722 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -1763,6 +1763,60 @@ describe('Dropdown', () => { }) }) + it('should close sibling submenus when opening nested dropdowns with keyboard navigation', () => { + return new Promise(resolve => { + fixtureEl.innerHTML = [ + '' + ].join('') + + const menuDemo = fixtureEl.querySelector('#menuDemo') + const subMenuDemo2 = fixtureEl.querySelector('#subMenuDemo2') + const subMenuDemo2Menu = fixtureEl.querySelector('#subMenuDemo2Menu') + const subMenuDemo3 = fixtureEl.querySelector('#subMenuDemo3') + const subMenuDemo3Menu = fixtureEl.querySelector('#subMenuDemo3Menu') + + subMenuDemo3.addEventListener('shown.bs.dropdown', () => { + setTimeout(() => { + subMenuDemo2.focus() + + const keydownArrowDown = createEvent('keydown', { bubbles: true }) + keydownArrowDown.key = 'ArrowDown' + subMenuDemo2.dispatchEvent(keydownArrowDown) + + setTimeout(() => { + expect(subMenuDemo2).toHaveClass('show') + expect(subMenuDemo2Menu).toHaveClass('show') + expect(subMenuDemo3).not.toHaveClass('show') + expect(subMenuDemo3Menu).not.toHaveClass('show') + resolve() + }) + }) + }) + + menuDemo.addEventListener('shown.bs.dropdown', () => { + subMenuDemo3.click() + }) + + menuDemo.click() + }) + }) + it('should open the dropdown and focus on the last item when using ArrowUp for the first time', () => { return new Promise(resolve => { fixtureEl.innerHTML = [