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 = [