-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Autocomplete] Invalid highlighted index when selecting last item with filterSelectedOptions #19637
Comments
The best fix I could find so far is diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
index 19cea91d7..e3ee398af 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -464,6 +464,10 @@ export default function useAutocomplete(props) {
}
}
+ if (filterSelectedOptions && highlightedIndexRef.current === filteredOptions.length - 1) {
+ setHighlightedIndex(highlightedIndexRef.current - 1);
+ }
+
resetInputValue(event, newValue);
handleValue(event, newValue); However, it's related to #19779 and #19705. I suspect we can use a single solution for these 3. (I'm not sure that a reset of the index to -1 after selection is an option. It seems quite disruptive for keyboard users with |
Looks like a good solution to me! Not sure how this relates to #19779, as it has to do with initial scroll position, not highlight. For #19705 I'd say it makes sense to introduce |
Here is a proposed solution for #19637, #19779, and #19637. Let us know if it works for your use case! diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
index bd9dc472f..c71b1b88f 100644
--- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
+++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
@@ -757,7 +757,6 @@ describe('<Autocomplete />', () => {
/>,
);
- fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' });
fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' });
fireEvent.keyDown(document.activeElement, { key: 'Enter' });
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
index 9957ed76d..2200b20c1 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -396,6 +396,32 @@ export default function useAutocomplete(props) {
changeHighlightedIndex('reset', 'next');
}, [inputValue]); // eslint-disable-line react-hooks/exhaustive-deps
+ React.useEffect(() => {
+ if (!open) {
+ return;
+ }
+
+ const valueItem = multiple ? value[0] : value;
+
+ if (filteredOptions.length === 0 || valueItem == null) {
+ changeHighlightedIndex('reset', 'next');
+ return;
+ }
+
+ if (!filterSelectedOptions && valueItem != null) {
+ const itemIndex = findIndex(filteredOptions, optionItem =>
+ getOptionSelected(optionItem, valueItem),
+ );
+
+ setHighlightedIndex(itemIndex);
+ return;
+ }
+
+ if (highlightedIndexRef.current >= filteredOptions.length - 1) {
+ setHighlightedIndex(filteredOptions.length - 1);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [value, open, filterSelectedOptions, multiple]);
+
const handleOpen = event => {
if (open) {
return; We will probably need to add one test case per issue for this logic (corresponding to each issue). |
Definitely works for me! The following test passes after applying the fix: describe('prop: filterSelectedOptions', () => {
it('when the last item is selected, highlights the new last item', () => {
const { getByRole } = render(
<Autocomplete
{...defaultProps}
filterSelectedOptions
options={['one', 'two', 'three']}
renderInput={params => <TextField {...params} autoFocus />}
/>,
);
function checkHighlightIs(expected) {
expect(getByRole('listbox').querySelector('li[data-focus]')).to.have.text(expected);
}
fireEvent.keyDown(document.activeElement, { key: 'ArrowUp' });
checkHighlightIs('three');
fireEvent.keyDown(document.activeElement, { key: 'Enter' }); // selects the last option
const input = getByRole('textbox');
input.blur();
input.focus(); // opens the listbox again
checkHighlightIs('two');
});
}); |
@jonatanklosko I want to double check my PR. Could you please checkout on my branch and check if code is working as expected? |
Works as expected, thanks! |
Current Behavior 😯
When
filterSelectedOptions
is enabled, selecting the last item means it disappears from the list, yet the highlight is not updated.Expected Behavior 🤔
Not entirely sure, I can imagine one of the following:
-1
)-1
)Steps to Reproduce 🕹
Steps:
undefined
).Notes
One simple solution is to reset the highlighted index when a new value is selected and
filterSelectedOptions
is used. Adding the following codebelow this: https://github.com/mui-org/material-ui/blob/f567b384f509d36b7e10f691e6b58538e7db8869/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L453-L456
does the job, although as mentioned above, it's not necessarily the expected behavior.
The text was updated successfully, but these errors were encountered: