From be9141cb8b87a2235f0bc46611d0415741539e2e Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 3 Jun 2026 21:08:22 +0300 Subject: [PATCH 1/3] fix(getHighlightedIndexOnOpen): remove added check from migration --- .../getHighlightedIndexOnOpen.test.ts | 30 +++++++++++++++++++ src/hooks/utils/getHighlightedIndexOnOpen.ts | 10 ++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts b/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts index 0ace08b5..b701f7dd 100644 --- a/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts +++ b/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts @@ -186,3 +186,33 @@ test('returns -1 when no conditions match', () => { ), ).toBe(-1) }) + +test('returns -1 when defaultHighlightedIndex is -1, even when selectedItem is set', () => { + expect( + getHighlightedIndexOnOpen( + items, + undefined, + -1, + isItemDisabled, + itemToKey, + 'b', + -1, + 1, + ), + ).toBe(-1) +}) + +test('returns -1 when initialHighlightedIndex is -1 and highlightedIndex matches', () => { + expect( + getHighlightedIndexOnOpen( + items, + -1, + undefined, + isItemDisabled, + itemToKey, + 'b', + -1, + 1, + ), + ).toBe(-1) +}) diff --git a/src/hooks/utils/getHighlightedIndexOnOpen.ts b/src/hooks/utils/getHighlightedIndexOnOpen.ts index b5035bd0..ddc40260 100644 --- a/src/hooks/utils/getHighlightedIndexOnOpen.ts +++ b/src/hooks/utils/getHighlightedIndexOnOpen.ts @@ -32,16 +32,18 @@ export function getHighlightedIndexOnOpen( if ( initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex && - items[initialHighlightedIndex] && - !isItemDisabled(items[initialHighlightedIndex], initialHighlightedIndex) + (initialHighlightedIndex === -1 || + (items[initialHighlightedIndex] && + !isItemDisabled(items[initialHighlightedIndex], initialHighlightedIndex))) ) { return initialHighlightedIndex } if ( defaultHighlightedIndex !== undefined && - items[defaultHighlightedIndex] && - !isItemDisabled(items[defaultHighlightedIndex], defaultHighlightedIndex) + (defaultHighlightedIndex === -1 || + (items[defaultHighlightedIndex] && + !isItemDisabled(items[defaultHighlightedIndex], defaultHighlightedIndex))) ) { return defaultHighlightedIndex } From 2f0181cec9f0d52b1c2191e66c8149604e94c08b Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 4 Jun 2026 10:37:42 +0300 Subject: [PATCH 2/3] better fix --- src/hooks/utils/getHighlightedIndexOnOpen.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hooks/utils/getHighlightedIndexOnOpen.ts b/src/hooks/utils/getHighlightedIndexOnOpen.ts index ddc40260..e18281c0 100644 --- a/src/hooks/utils/getHighlightedIndexOnOpen.ts +++ b/src/hooks/utils/getHighlightedIndexOnOpen.ts @@ -32,9 +32,8 @@ export function getHighlightedIndexOnOpen( if ( initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex && - (initialHighlightedIndex === -1 || - (items[initialHighlightedIndex] && - !isItemDisabled(items[initialHighlightedIndex], initialHighlightedIndex))) + (items[initialHighlightedIndex] === undefined || + !isItemDisabled(items[initialHighlightedIndex], initialHighlightedIndex)) ) { return initialHighlightedIndex } @@ -42,8 +41,8 @@ export function getHighlightedIndexOnOpen( if ( defaultHighlightedIndex !== undefined && (defaultHighlightedIndex === -1 || - (items[defaultHighlightedIndex] && - !isItemDisabled(items[defaultHighlightedIndex], defaultHighlightedIndex))) + items[defaultHighlightedIndex] === undefined || + !isItemDisabled(items[defaultHighlightedIndex], defaultHighlightedIndex)) ) { return defaultHighlightedIndex } From d9e9306aa1590583447a97df41a720d6de14e915 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 4 Jun 2026 10:52:51 +0300 Subject: [PATCH 3/3] fully fix the cases --- .../getHighlightedIndexOnOpen.test.ts | 350 ++++++++++++++---- src/hooks/utils/getHighlightedIndexOnOpen.ts | 15 +- 2 files changed, 291 insertions(+), 74 deletions(-) diff --git a/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts b/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts index b701f7dd..664588f7 100644 --- a/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts +++ b/src/hooks/utils/__tests__/getHighlightedIndexOnOpen.test.ts @@ -8,211 +8,421 @@ const isLastItemDisabled = (_item: string, index: number) => const itemToKey = (item: string | null) => item test('returns -1 when items is empty', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -1 + const offset = 0 + expect( getHighlightedIndexOnOpen( [], - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - -1, - 0, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns initialHighlightedIndex when it matches state highlightedIndex and is not disabled', () => { + const initialHighlightedIndex = 1 + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = 1 + const offset = 0 + expect( getHighlightedIndexOnOpen( items, - 1, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - 1, - 0, + selectedItem, + highlightedIndex, + offset, ), ).toBe(1) }) test('skips initialHighlightedIndex when state highlightedIndex does not match', () => { + const initialHighlightedIndex = 1 + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = 0 + const offset = 0 + expect( getHighlightedIndexOnOpen( items, - 1, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - 0, - 0, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('skips initialHighlightedIndex when that item is disabled', () => { + const initialHighlightedIndex = 0 + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = 0 + const offset = 1 + expect( getHighlightedIndexOnOpen( items, - 0, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isFirstItemDisabled, itemToKey, - null, - 0, - 1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns defaultHighlightedIndex when it is not disabled', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = 2 + const selectedItem = null + const highlightedIndex = -1 + const offset = 0 + expect( getHighlightedIndexOnOpen( items, - undefined, - 2, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - -1, - 0, + selectedItem, + highlightedIndex, + offset, ), ).toBe(2) }) test('skips defaultHighlightedIndex when that item is disabled', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = 0 + const selectedItem = null + const highlightedIndex = -1 + const offset = 1 + expect( getHighlightedIndexOnOpen( items, - undefined, - 0, + initialHighlightedIndex, + defaultHighlightedIndex, isFirstItemDisabled, itemToKey, - null, - -1, - 1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns index of selectedItem when selectedItem is set', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = 'b' + const highlightedIndex = -1 + const offset = 0 + expect( getHighlightedIndexOnOpen( items, - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - 'b', - -1, - 0, + selectedItem, + highlightedIndex, + offset, ), ).toBe(1) }) test('returns last index when offset is negative and last item is not disabled', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -1 + const offset = -1 + expect( getHighlightedIndexOnOpen( items, - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - -1, - -1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(2) }) test('skips last index when offset is negative and last item is disabled', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -1 + const offset = -1 + expect( getHighlightedIndexOnOpen( items, - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isLastItemDisabled, itemToKey, - null, - -1, - -1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns 0 when offset is positive and first item is not disabled', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -1 + const offset = 1 + expect( getHighlightedIndexOnOpen( items, - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - -1, - 1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(0) }) test('skips 0 when offset is positive and first item is disabled', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -1 + const offset = 1 + expect( getHighlightedIndexOnOpen( items, - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isFirstItemDisabled, itemToKey, - null, - -1, - 1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns -1 when no conditions match', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -1 + const offset = 0 + expect( getHighlightedIndexOnOpen( items, - undefined, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - null, - -1, - 0, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns -1 when defaultHighlightedIndex is -1, even when selectedItem is set', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = -1 + const selectedItem = 'b' + const highlightedIndex = -1 + const offset = 1 + expect( getHighlightedIndexOnOpen( items, - undefined, - -1, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - 'b', - -1, - 1, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) test('returns -1 when initialHighlightedIndex is -1 and highlightedIndex matches', () => { + const initialHighlightedIndex = -1 + const defaultHighlightedIndex = undefined + const selectedItem = 'b' + const highlightedIndex = -1 + const offset = 1 + + expect( + getHighlightedIndexOnOpen( + items, + initialHighlightedIndex, + defaultHighlightedIndex, + isItemDisabled, + itemToKey, + selectedItem, + highlightedIndex, + offset, + ), + ).toBe(-1) +}) + +test('skips initialHighlightedIndex when it is out of bounds', () => { + const initialHighlightedIndex = 10 + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = 10 + const offset = 1 + + expect( + getHighlightedIndexOnOpen( + items, + initialHighlightedIndex, + defaultHighlightedIndex, + isItemDisabled, + itemToKey, + selectedItem, + highlightedIndex, + offset, + ), + ).toBe(0) +}) + +test('skips defaultHighlightedIndex when it is out of bounds', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = 10 + const selectedItem = null + const highlightedIndex = -1 + const offset = 1 + + expect( + getHighlightedIndexOnOpen( + items, + initialHighlightedIndex, + defaultHighlightedIndex, + isItemDisabled, + itemToKey, + selectedItem, + highlightedIndex, + offset, + ), + ).toBe(0) +}) + +test('skips initialHighlightedIndex when it is a large negative', () => { + const initialHighlightedIndex = -5 + const defaultHighlightedIndex = undefined + const selectedItem = null + const highlightedIndex = -5 + const offset = 1 + expect( getHighlightedIndexOnOpen( items, - -1, - undefined, + initialHighlightedIndex, + defaultHighlightedIndex, isItemDisabled, itemToKey, - 'b', - -1, - 1, + selectedItem, + highlightedIndex, + offset, + ), + ).toBe(0) +}) + +test('skips defaultHighlightedIndex when it is a large negative', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = -5 + const selectedItem = null + const highlightedIndex = -1 + const offset = 1 + + expect( + getHighlightedIndexOnOpen( + items, + initialHighlightedIndex, + defaultHighlightedIndex, + isItemDisabled, + itemToKey, + selectedItem, + highlightedIndex, + offset, + ), + ).toBe(0) +}) + +test('returns -1 when selectedItem is not found in items', () => { + const initialHighlightedIndex = undefined + const defaultHighlightedIndex = undefined + const selectedItem = 'z' + const highlightedIndex = -1 + const offset = 0 + + expect( + getHighlightedIndexOnOpen( + items, + initialHighlightedIndex, + defaultHighlightedIndex, + isItemDisabled, + itemToKey, + selectedItem, + highlightedIndex, + offset, ), ).toBe(-1) }) + +test('initialHighlightedIndex takes priority over defaultHighlightedIndex when it matches highlightedIndex', () => { + const initialHighlightedIndex = 0 + const defaultHighlightedIndex = 2 + const selectedItem = null + const highlightedIndex = 0 + const offset = 0 + + expect( + getHighlightedIndexOnOpen( + items, + initialHighlightedIndex, + defaultHighlightedIndex, + isItemDisabled, + itemToKey, + selectedItem, + highlightedIndex, + offset, + ), + ).toBe(0) +}) diff --git a/src/hooks/utils/getHighlightedIndexOnOpen.ts b/src/hooks/utils/getHighlightedIndexOnOpen.ts index e18281c0..08a19616 100644 --- a/src/hooks/utils/getHighlightedIndexOnOpen.ts +++ b/src/hooks/utils/getHighlightedIndexOnOpen.ts @@ -32,8 +32,12 @@ export function getHighlightedIndexOnOpen( if ( initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex && - (items[initialHighlightedIndex] === undefined || - !isItemDisabled(items[initialHighlightedIndex], initialHighlightedIndex)) + (initialHighlightedIndex === -1 || + (items[initialHighlightedIndex] !== undefined && + !isItemDisabled( + items[initialHighlightedIndex], + initialHighlightedIndex, + ))) ) { return initialHighlightedIndex } @@ -41,8 +45,11 @@ export function getHighlightedIndexOnOpen( if ( defaultHighlightedIndex !== undefined && (defaultHighlightedIndex === -1 || - items[defaultHighlightedIndex] === undefined || - !isItemDisabled(items[defaultHighlightedIndex], defaultHighlightedIndex)) + (items[defaultHighlightedIndex] !== undefined && + !isItemDisabled( + items[defaultHighlightedIndex], + defaultHighlightedIndex, + ))) ) { return defaultHighlightedIndex }