From d1177e4fac92280001a072a35c11eaad5a61f4c9 Mon Sep 17 00:00:00 2001 From: terminalchai <213856599+terminalchai@users.noreply.github.com> Date: Tue, 26 May 2026 01:20:45 +0530 Subject: [PATCH] fix(choices): start arrow key navigation from selected item when no item is highlighted When a dropdown is closed without confirming a selection and then reopened, _onDirectionKey() had no highlighted item in the DOM. The fallback was to get the first selectable choice, so arrow key navigation always restarted from item 0 instead of from the currently confirmed selection. Fix: when there is no highlighted item, fall back to the currently selected item (is-selected) as the navigation reference for getAdjacentEl(). If neither exists (first open, nothing selected), the original first-item fallback is preserved. Add an e2e test to select-one.spec.ts that verifies ArrowDown after a close-without-confirm resumes navigation relative to the selected item. Fixes #1371 --- src/scripts/choices.ts | 8 +++++--- test-e2e/tests/select-one.spec.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/scripts/choices.ts b/src/scripts/choices.ts index 5ac2e7fd..9da34876 100644 --- a/src/scripts/choices.ts +++ b/src/scripts/choices.ts @@ -1845,9 +1845,11 @@ class Choices { nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); } } else { - const currentEl = this.dropdown.element.querySelector( - getClassNamesSelector(this.config.classNames.highlightedState), - ); + const currentEl = + this.dropdown.element.querySelector( + getClassNamesSelector(this.config.classNames.highlightedState), + ) ?? + this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.selectedState)); if (currentEl) { nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt); } else { diff --git a/test-e2e/tests/select-one.spec.ts b/test-e2e/tests/select-one.spec.ts index 3197f733..03156cf9 100644 --- a/test-e2e/tests/select-one.spec.ts +++ b/test-e2e/tests/select-one.spec.ts @@ -109,6 +109,32 @@ describe(`Choices - select one`, () => { await expect(suite.choices.first()).toHaveClass(/is-highlighted/); await expect(suite.choices.last()).not.toHaveClass(/is-highlighted/); }); + + test('arrow key navigation resumes from selected item after closing without confirming', async ({ + page, + bundle, + }) => { + const suite = new SelectTestSuit(page, bundle, testUrl, testId); + await suite.startWithClick(); + + // Navigate down twice so choices.nth(2) is highlighted, then escape + await suite.input.press('ArrowDown'); + await suite.input.press('ArrowDown'); + await expect(suite.choices.nth(2)).toHaveClass(/is-highlighted/); + await suite.escapeKey(); + await suite.expectHiddenDropdown(); + + // The first choice should still be the selected (confirmed) item + await expect(suite.choices.first()).toHaveClass(/is-selected/); + + // Reopen and press ArrowDown; should move relative to the selected item + await suite.startWithClick(); + await suite.input.press('ArrowDown'); + + // Navigation should continue from the selected item, not restart from item 0 + await expect(suite.choices.first()).not.toHaveClass(/is-highlighted/); + await expect(suite.choices.nth(1)).toHaveClass(/is-highlighted/); + }); }); describe('searching choices', () => {