Skip to content

Commit

Permalink
[material-ui][joy-ui][base-ui][Autocomplete] Keep in sync highlighted…
Browse files Browse the repository at this point in the history
… index when the option still exists (#41306)

Co-authored-by: Loïc Mangeonjean <loic@coderpad.io>
  • Loading branch information
CGNonofr and Loïc Mangeonjean committed Mar 8, 2024
1 parent 91193fa commit 1aa3764
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 13 deletions.
16 changes: 7 additions & 9 deletions packages/mui-base/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) : '';
Expand All @@ -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(() => {
Expand All @@ -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;
}

Expand Down
10 changes: 8 additions & 2 deletions packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1402,9 +1402,15 @@ describe('Joy <Autocomplete />', () => {

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", () => {
Expand Down
10 changes: 8 additions & 2 deletions packages/mui-material/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1836,9 +1836,15 @@ describe('<Autocomplete />', () => {

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', () => {
Expand Down

0 comments on commit 1aa3764

Please sign in to comment.