Repository: mui/material-ui (TypeScript)
Date: 2020-04-17 07:54:24+00:00
Task type: Bug Fix

Issue:
[Autocomplete] AutoHighlight not always work as expect. 
<!-- Provide a general summary of the issue in the Title above -->

I'm not sure it is a bug or not. Look like the highlight index calculated based on stale `value` prop.

https://github.com/mui-org/material-ui/blob/master/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L409-L436

for uncontrolled `<Autocomplete/>` without default value, it work as expected, the highlight always get updated based on current input value. because the initial value is null, so it goes to `valueItem == null` branch.

For uncontrolled `<Autocomplete/>` with default value and  controlled `<Autocomplete/>`, The `value` prop does not update until an option get selected, the highlight index always calculated based on the stale `value` prop.

Is it make sense to calculate highlight index based on `inputValue` instead of `value`?

```
<Autocomplete/>  // Works
<Autocomplete defaultValue="a" /> // does not work
<Autocomplete value="a" onChange={()=>{...} /> // does not work
```

<!--
  Thank you very much for contributing to Material-UI by creating an issue! ❤️
  To avoid duplicate issues we ask you to check off the following list.
-->

<!-- Checked checkbox should look like this: [x] -->

- [x] The issue is present in the latest release.
- [x] I have searched the [issues](https://github.com/mui-org/material-ui/issues) of this repository and believe that this is not a duplicate.

## Current Behavior 😯
![ezgif com-video-to-gif (2)](https://user-images.githubusercontent.com/33362998/79490664-d6b8e780-7fe2-11ea-9964-4bef4e010c81.gif)

The AutoHighlight does not work for controlled <Autocomplete />, However, If you delete the whole input value, it works as expected.

![ezgif com-video-to-gif (3)](https://user-images.githubusercontent.com/33362998/79490936-43cc7d00-7fe3-11ea-8337-969edf6dc842.gif)



<!-- Describe what happens instead of the expected behavior. -->

## Expected Behavior 🤔
Automatically select the first option for controlled `<Autocomplete />`
<!-- Describe what should happen. -->

## Steps to Reproduce 🕹

<!--
  Provide a link to a live example (you can use codesandbox.io) and an unambiguous set of steps to reproduce this bug.
  Include code to reproduce, if relevant (which it most likely is).

  You should use the official codesandbox template as a starting point: https://material-ui.com/r/issue-template

  If you have an issue concerning TypeScript please start from this TypeScript playground: https://material-ui.com/r/ts-issue-template

  Issues without some form of live example have a longer response time.
-->

https://codesandbox.io/s/material-demo-h6ndb?file=/demo.js

Steps:

1. press delete 
2. press 2
3. option a2 should highlighted

## Context 🔦

<!--
  What are you trying to accomplish? How has this issue affected you?
  Providing context helps us come up with a solution that is most useful in the real world.
-->

## Your Environment 🌎

<!--
  Include as many relevant details about the environment with which you experienced the bug.
  If you encounter issues with typescript please include version and tsconfig.
-->

| Tech        | Version |
| ----------- | ------- |
| Material-UI | v4.9.10   + Lab 4.0.0 Alpha.49|
| React       |      16.13.1   |
| Browser     |     Chrome    |
| TypeScript  |         |
| etc.        |         |



Issue discussion:
@xiaoyu-tamu Thanks for reporting the issue, I can confirm it. What do you think of this patch?

```diff
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
index 3cb1ca0c5..824ed4d80 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -431,7 +431,11 @@ export default function useAutocomplete(props) {
         getOptionSelected(optionItem, valueItem),
       );

-      setHighlightedIndex(itemIndex);
+      if (itemIndex === -1) {
+        changeHighlightedIndex('reset', 'next');
+      } else {
+        setHighlightedIndex(itemIndex);
+      }
       return;
     }
```

Do you want to submit a pull request? We would also need a test to prevent a regression :)
I would love to submit PR, but I'm kind busy recently. Sorry about that.

The patch fix the CodeSandbox, but does not work with following example

<Autocomplete options={['a', 'a1', 'a2', 'a3']} defaultValue="a1" />

if press delete, the input value become 'a', we should expect 'a' get highlighted. not 'a1'.



Solution patch:
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -431,7 +431,11 @@ export default function useAutocomplete(props) {
         getOptionSelected(optionItem, valueItem),
       );
 
-      setHighlightedIndex(itemIndex);
+      if (itemIndex === -1) {
+        changeHighlightedIndex('reset', 'next');
+      } else {
+        setHighlightedIndex(itemIndex);
+      }
       return;
     }
 


Test patch:
diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
--- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
+++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
@@ -77,6 +77,27 @@ describe('<Autocomplete />', () => {
       checkHighlightIs('one');
     });
 
+    it('should keep the highlight on the first item', () => {
+      const options = ['one', 'two'];
+      const { getByRole } = render(
+        <Autocomplete
+          {...defaultProps}
+          value="one"
+          autoHighlight
+          options={options}
+          renderInput={(params) => <TextField autoFocus {...params} />}
+        />,
+      );
+
+      function checkHighlightIs(expected) {
+        expect(getByRole('listbox').querySelector('li[data-focus]')).to.have.text(expected);
+      }
+
+      checkHighlightIs('one');
+      fireEvent.change(document.activeElement, { target: { value: 'two' } });
+      checkHighlightIs('two');
+    });
+
     it('should set the highlight on selected item when dropdown is expanded', () => {
       const { getByRole, setProps } = render(
         <Autocomplete