diff options
author | Julien Déramond <juderamond@gmail.com> | 2022-06-25 22:33:41 +0300 |
---|---|---|
committer | Julien Déramond <juderamond@gmail.com> | 2022-06-25 22:33:41 +0300 |
commit | ec11c05f1a2e45a2befe5bd99de10483b0653769 (patch) | |
tree | a24b270eb10450828744d73376c21930a8fff2f1 | |
parent | 8de048833049f8b6af2c07df2d44d98c1ee095db (diff) |
Fix arrown navigation in dropdown with inputmain-jd-fix-up-down-keyboard-with-search-input-and-dropdown
-rw-r--r-- | js/src/dropdown.js | 6 | ||||
-rw-r--r-- | js/tests/unit/dropdown.spec.js | 28 |
2 files changed, 32 insertions, 2 deletions
diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 1646362d0a..d4cae11edc 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -389,7 +389,9 @@ class Dropdown extends BaseComponent { static dataApiKeydownHandler(event) { // If not an UP | DOWN | ESCAPE key => not a dropdown command - // If input/textarea && if key is other than ESCAPE => not a dropdown command + // If input/textarea && if key is other than ESCAPE + // - If key is not UP or DOWN => not a dropdown command + // - If trigger inside the menu => not a dropdown command const isInput = /input|textarea/i.test(event.target.tagName) const isEscapeEvent = event.key === ESCAPE_KEY @@ -399,7 +401,7 @@ class Dropdown extends BaseComponent { return } - if (isInput && !isEscapeEvent) { + if (isInput && !isEscapeEvent && (!isUpOrDownEvent || event.target.closest(SELECTOR_MENU))) { return } diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 56ac4ff494..370da250d3 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -2127,6 +2127,34 @@ describe('Dropdown', () => { dropdownMenu.click() expect(spy).toHaveBeenCalledWith(dropdownToggle) }) + + it('should open the dropdown and focus on the first item when using ArrowDown for the first time on an input search', () => { + return new Promise(resolve => { + fixtureEl.innerHTML = [ + '<div class="dropdown">', + ' <input id="search" class="form-control dropdown-toggle" type="text" placeholder="Search..." data-bs-toggle="dropdown" aria-expanded="false" aria-label="Search...">', + ' <ul class="dropdown-menu mt-1 dropdown-menu-end" aria-labelledby="search">', + ' <a id="item1" class="dropdown-item" href="#">A link</a>', + ' <a id="item2" class="dropdown-item" href="#">Another link</a>', + ' </ul>', + '</div>' + ].join('') + + const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') + const firstItem = fixtureEl.querySelector('#item1') + + triggerDropdown.addEventListener('shown.bs.dropdown', () => { + setTimeout(() => { + expect(document.activeElement).toEqual(firstItem, 'item1 is focused') + resolve() + }) + }) + + const keydown = createEvent('keydown') + keydown.key = 'ArrowDown' + triggerDropdown.dispatchEvent(keydown) + }) + }) }) describe('jQueryInterface', () => { |