diff --git a/packages/mui-base/src/useAutocomplete/useAutocomplete.js b/packages/mui-base/src/useAutocomplete/useAutocomplete.js index 78bbfc0b11d436..13d846b468d9c5 100644 --- a/packages/mui-base/src/useAutocomplete/useAutocomplete.js +++ b/packages/mui-base/src/useAutocomplete/useAutocomplete.js @@ -478,7 +478,7 @@ export function useAutocomplete(props) { }, ); - const checkHighlightedOptionExists = () => { + const getPreviousHighlightedOptionIndex = () => { const isSameValue = (value1, value2) => { const label1 = value1 ? getOptionLabel(value1) : ''; const label2 = value2 ? getOptionLabel(value2) : ''; @@ -498,16 +498,12 @@ export function useAutocomplete(props) { const previousHighlightedOption = previousProps.filteredOptions[highlightedIndexRef.current]; if (previousHighlightedOption) { - const previousHighlightedOptionExists = filteredOptions.some((option) => { + return findIndex(filteredOptions, (option) => { return getOptionLabel(option) === getOptionLabel(previousHighlightedOption); }); - - if (previousHighlightedOptionExists) { - return true; - } } } - return false; + return -1; }; const syncHighlightedIndex = React.useCallback(() => { @@ -516,8 +512,10 @@ export function useAutocomplete(props) { } // Check if the previously highlighted option still exists in the updated filtered options list and if the value and inputValue haven't changed - // If it exists and the value and the inputValue haven't changed, return, otherwise continue execution - if (checkHighlightedOptionExists()) { + // If it exists and the value and the inputValue haven't changed, just update its index, otherwise continue execution + const previousHighlightedOptionIndex = getPreviousHighlightedOptionIndex(); + if (previousHighlightedOptionIndex !== -1) { + highlightedIndexRef.current = previousHighlightedOptionIndex; return; } diff --git a/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx b/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx index 44b0ce311cb53f..17447b87ab68e4 100644 --- a/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx +++ b/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx @@ -1402,9 +1402,15 @@ describe('Joy ', () => { checkHighlightIs(listbox, 'two'); - // three option is added and autocomplete re-renders, restore the highlight - setProps({ options: [{ label: 'one' }, { label: 'two' }, { label: 'three' }] }); + // zero and three options are added and autocomplete re-renders, restore the highlight + setProps({ + options: [{ label: 'zero' }, { label: 'one' }, { label: 'two' }, { label: 'three' }], + }); checkHighlightIs(listbox, 'two'); + + // check that the highlighted option is still in sync with the internal highlighted index + fireEvent.keyDown(textbox, { key: 'ArrowDown' }); // goes to 'three' + checkHighlightIs(listbox, 'three'); }); it("should reset the highlight when previously highlighted option doesn't exists in new options", () => { diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.test.js b/packages/mui-material/src/Autocomplete/Autocomplete.test.js index c20e977925918e..a306ea4fc262c4 100644 --- a/packages/mui-material/src/Autocomplete/Autocomplete.test.js +++ b/packages/mui-material/src/Autocomplete/Autocomplete.test.js @@ -1836,9 +1836,15 @@ describe('', () => { checkHighlightIs(listbox, 'two'); - // three option is added and autocomplete re-renders, restore the highlight - setProps({ options: [{ label: 'one' }, { label: 'two' }, { label: 'three' }] }); + // zero and three options are added and autocomplete re-renders, restore the highlight + setProps({ + options: [{ label: 'zero' }, { label: 'one' }, { label: 'two' }, { label: 'three' }], + }); checkHighlightIs(listbox, 'two'); + + // check that the highlighted option is still in sync with the internal highlighted index + fireEvent.keyDown(textbox, { key: 'ArrowDown' }); // goes to 'three' + checkHighlightIs(listbox, 'three'); }); it('should reset the highlight when the input changed', () => {