diff options
-rw-r--r-- | js/src/dropdown.js | 14 | ||||
-rw-r--r-- | js/tests/unit/dropdown.spec.js | 30 |
2 files changed, 32 insertions, 12 deletions
diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 8bd3f01e70..f56ab201b7 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -408,14 +408,8 @@ class Dropdown extends BaseComponent { } static clearMenus(event) { - if (event) { - if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) { - return - } - - if (/input|select|option|textarea|form/i.test(event.target.tagName)) { - return - } + if (event && (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY))) { + return } const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE) @@ -445,8 +439,8 @@ class Dropdown extends BaseComponent { continue } - // Tab navigation through the dropdown menu shouldn't close the menu - if (event.type === 'keyup' && event.key === TAB_KEY && context._menu.contains(event.target)) { + // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu + if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) { continue } diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 57989059d1..1c3e8652f3 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -1587,7 +1587,7 @@ describe('Dropdown', () => { triggerDropdown.click() }) - it('should not close the dropdown if the user clicks on a text field', done => { + it('should not close the dropdown if the user clicks on a text field within dropdown-menu', done => { fixtureEl.innerHTML = [ '<div class="dropdown">', ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>', @@ -1613,7 +1613,7 @@ describe('Dropdown', () => { triggerDropdown.click() }) - it('should not close the dropdown if the user clicks on a textarea', done => { + it('should not close the dropdown if the user clicks on a textarea within dropdown-menu', done => { fixtureEl.innerHTML = [ '<div class="dropdown">', ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>', @@ -1639,6 +1639,32 @@ describe('Dropdown', () => { triggerDropdown.click() }) + it('should close the dropdown if the user clicks on a text field that is not contained within dropdown-menu', done => { + fixtureEl.innerHTML = [ + '<div class="dropdown">', + ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>', + ' <div class="dropdown-menu">', + ' </div>', + '</div>', + '<input type="text">' + ] + + const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') + const input = fixtureEl.querySelector('input') + + triggerDropdown.addEventListener('hidden.bs.dropdown', () => { + done() + }) + + triggerDropdown.addEventListener('shown.bs.dropdown', () => { + input.dispatchEvent(createEvent('click', { + bubbles: true + })) + }) + + triggerDropdown.click() + }) + it('should ignore keyboard events for <input>s and <textarea>s within dropdown-menu, except for escape key', done => { fixtureEl.innerHTML = [ '<div class="dropdown">', |