From b376a3d80d3ce7a9106bf42b890167ecc992f912 Mon Sep 17 00:00:00 2001 From: Siju Samson Date: Thu, 4 Feb 2021 01:33:21 +0530 Subject: [PATCH] Fix dropdown keys to open menu (#32750) Co-authored-by: XhmikosR --- js/src/dropdown.js | 6 +++++ js/tests/unit/dropdown.spec.js | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 69b99e628c..3667fa1113 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -468,6 +468,12 @@ class Dropdown extends BaseComponent { return } + if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) { + const button = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] + button.click() + return + } + if (!isActive || event.key === SPACE_KEY) { Dropdown.clearMenus() return diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index bb137efed8..47775678f8 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -1626,4 +1626,52 @@ describe('Dropdown', () => { expect(Dropdown.getInstance(div)).toEqual(null) }) }) + + it('should open dropdown when pressing keydown or keyup', done => { + fixtureEl.innerHTML = [ + '' + ].join('') + + const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') + const dropdown = fixtureEl.querySelector('.dropdown') + + const keydown = createEvent('keydown') + keydown.key = 'ArrowDown' + + const keyup = createEvent('keyup') + keyup.key = 'ArrowUp' + + const handleArrowDown = () => { + expect(triggerDropdown.classList.contains('show')).toEqual(true) + expect(triggerDropdown.getAttribute('aria-expanded')).toEqual('true') + setTimeout(() => { + dropdown.hide() + keydown.key = 'ArrowUp' + triggerDropdown.dispatchEvent(keyup) + }, 20) + } + + const handleArrowUp = () => { + expect(triggerDropdown.classList.contains('show')).toEqual(true) + expect(triggerDropdown.getAttribute('aria-expanded')).toEqual('true') + done() + } + + dropdown.addEventListener('shown.bs.dropdown', event => { + if (event.target.key === 'ArrowDown') { + handleArrowDown() + } else { + handleArrowUp() + } + }) + + triggerDropdown.dispatchEvent(keydown) + }) })