Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Déramond <juderamond@gmail.com>2022-06-25 22:33:41 +0300
committerJulien Déramond <juderamond@gmail.com>2022-06-25 22:33:41 +0300
commitec11c05f1a2e45a2befe5bd99de10483b0653769 (patch)
treea24b270eb10450828744d73376c21930a8fff2f1
parent8de048833049f8b6af2c07df2d44d98c1ee095db (diff)
Fix arrown navigation in dropdown with inputmain-jd-fix-up-down-keyboard-with-search-input-and-dropdown
-rw-r--r--js/src/dropdown.js6
-rw-r--r--js/tests/unit/dropdown.spec.js28
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', () => {