Repository: mui/material-ui (TypeScript)
Date: 2020-05-01 17:29:35+00:00
Task type: Bug Fix

Issue:
[Autocomplete] Adding the loading prop does nothing if freeSolo is true
<!-- Provide a general summary of the issue in the Title above -->
In the Asynchronous example of Autocomplete in the docs - https://material-ui.com/components/autocomplete/#asynchronous-requests, the loading prop triggers a "Loading..." disabled option to be displayed. When you take that same example and add `freeSolo`, as demonstrated here - https://stackblitz.com/edit/ca3vpr?file=demo.js, the loading option no longer shows up. 

I found a similar issue describing this problem on StackOverflow from 4 months ago - https://stackoverflow.com/questions/59266457/using-react-material-ui-autocomplete-with-loading-and-freesolo-props.

<!--
  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 😯

<!-- Describe what happens instead of the expected behavior. -->

When the `freeSolo` prop is added, the loading option no longer appears.

## Expected Behavior 🤔

<!-- Describe what should happen. -->

When the `freeSolo` prop is added, the loading option should still appear (if loading is true).

## 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.
-->

Steps:

1. Visit https://codesandbox.io/s/dazzling-shirley-yo1qp
2. Notice the addition of `freeSolo` prop.
3. Loading option does not appear when clicking into Autocomplete input.


## 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.
-->

Would like to show this loading state while still using the freeSolo mode of Autocomplete.

## 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.12  |
| Material-UI/lab | v4.0.0-alpha.51  |
| React       |   16.13.1  |
| Browser     |    Chrome Version 81.0.4044.122 (Official Build) (64-bit)     |



Issue discussion:
What do you think @oliviertassinari? 

As far as I can see the 'fix' would be:

```diff
@@ -260,7 +261,7 @@ export default function useAutocomplete(props) {
       )
     : [];

-  popupOpen = freeSolo && filteredOptions.length === 0 ? false : popupOpen;
+  popupOpen = freeSolo && filteredOptions.length === 0 && !loading ? false : popupOpen;

   if (process.env.NODE_ENV !== 'production') {
     if (value !== null && !freeSolo && options.length > 0) {

```

But I haven't decided if this is the right thing to do :/ 
@joshwooding looks good
@Bdthomson Would you like to work on it? 🙂

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
@@ -242,7 +242,7 @@ export default function useAutocomplete(props) {
   const inputValueIsSelectedValue =
     !multiple && value != null && inputValue === getOptionLabel(value);
 
-  let popupOpen = open;
+  const popupOpen = open;
 
   const filteredOptions = popupOpen
     ? filterOptions(
@@ -263,8 +263,6 @@ export default function useAutocomplete(props) {
       )
     : [];
 
-  popupOpen = freeSolo && filteredOptions.length === 0 ? false : popupOpen;
-
   if (process.env.NODE_ENV !== 'production') {
     if (value !== null && !freeSolo && options.length > 0) {
       const missingValue = (multiple ? value : [value]).filter(
@@ -405,7 +403,7 @@ export default function useAutocomplete(props) {
   });
 
   React.useEffect(() => {
-    if (!open) {
+    if (!popupOpen) {
       return;
     }
 
@@ -451,7 +449,7 @@ export default function useAutocomplete(props) {
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [
     value,
-    open,
+    popupOpen,
     filterSelectedOptions,
     changeHighlightedIndex,
     setHighlightedIndex,


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
@@ -54,6 +54,21 @@ describe('<Autocomplete />', () => {
     });
   });
 
+  describe('prop: loading', () => {
+    it('should show a loading message when open', () => {
+      render(
+        <Autocomplete
+          {...defaultProps}
+          freeSolo
+          loading
+          renderInput={(params) => <TextField autoFocus {...params} />}
+        />,
+      );
+      fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' });
+      expect(document.querySelector(`.${classes.paper}`).textContent).to.equal('Loading…');
+    });
+  });
+
   describe('prop: autoHighlight', () => {
     it('should set the focus on the first item', () => {
       const options = ['one', 'two'];