mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.89k stars 32.26k forks source link

[material-ui][Autocomplete] `freeSolo` prop not working #41133

Closed MPavaoDS closed 8 months ago

MPavaoDS commented 8 months ago

The problem in depth

I have a MUI Autocomplete Component wrapped in an react-hook-form Controller. I want the Autocomplete to behave like Select and Text Field: meaning that the user either chooses an option from a list or if it doesn't exist in the list, the user can type a new option that will be later added to the database where the list comes from. For that, I added the props "freeSolo" and "autoSelect" to the Autocomplete.

So far I have managed to make the Select part work, but not the text input one. I have searched in several places but I didn't find a solution to my problem. Here's my code:

<Controller
                  name='userName'
                  control={control}
                  rules={{
                    required: 'This field cannot be empty',
                  }}
                  render={({ field, fieldState: { error } }) => {
                    const { onChange, value, ref } = field;
                    return (
                      <>
                        <Autocomplete
                          id='controlled-autocomplete'
                          size='small'
                          freeSolo
                          autoSelect
                          options={users}
                          getOptionLabel={(user) =>
                            user.name ? user.name : ''
                          }
                          value={
                            value
                              ? users.find((user) => {
                                  return value === user.id;
                                }) ?? null
                              : null
                          }
                          onChange={(event, newValue) => {
                            onChange(newValue ? newValue.id : null);
                          }}
                          renderInput={(params) => (
                            <TextField
                              {...params}
                              placeholder='User name'
                              color={error ? 'error' : 'secondary'}
                              inputRef={ref}
                            />
                          )}
                        />
                        {error ? (
                          <Typography color='error' variant='caption'>
                            {error.message}
                          </Typography>
                        ) : null}
                      </>
                    );
                  }}
                />

And the users list should look something like this:

const users = [
  { id: 0, name: 'John' },
  { id: 1, name: 'Carl' },
  { id: 2, name: 'Mary' },
  { id: 3, name: 'Mark' },
  { id: 4, name: 'Kate' },
  { id: 5, name: 'Rita' }
];

I tried adding the following props to the Autocomplete:

inputValue={value ? value : ''}
onInputChange={(event, newValue) => {
                  onChange(newValue ? newValue.id : null);
}}

But now, because my users list has both numbers and strings, it's throwing the error:

Warning: Failed prop type: Invalid prop `inputValue` of type `number` supplied to `ForwardRef(Autocomplete)`, expected `string`.

Your environment

`npx @mui/envinfo` ``` System: OS: Windows 10 10.0.19045 Binaries: Node: 18.13.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD npm: 8.19.3 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: Not Found Edge: Chromium (121.0.2277.112) npmPackages: @emotion/react: ^11.10.5 => 11.11.3 @emotion/styled: ^11.10.5 => 11.11.0 @mui/base: 5.0.0-beta.30 @mui/core-downloads-tracker: 5.15.3 @mui/icons-material: ^5.10.16 => 5.15.3 @mui/material: ^5.10.16 => 5.15.3 @mui/private-theming: 5.15.3 @mui/styled-engine: 5.15.3 @mui/styles: ^5.10.16 => 5.15.3 @mui/system: 5.15.3 @mui/types: 7.2.12 @mui/utils: 5.15.3 @mui/x-data-grid: 6.18.7 @mui/x-data-grid-generator: ^6.18.5 => 6.18.7 @mui/x-data-grid-premium: ^6.12.1 => 6.18.7 @mui/x-data-grid-pro: 6.18.7 @mui/x-date-pickers: ^6.8.0 => 6.18.7 @mui/x-license-pro: 6.10.2 @types/react: 18.2.47 react: ^18.1.0 => 18.2.0 react-dom: ^18.1.0 => 18.2.0 ```

Search keywords: autocomplete, freeSolo Order ID: 74223

Search keywords:

DiegoAndai commented 8 months ago

Hey @MPavaoDS, thanks for the report! May I ask you to provide a minimal reproduction test case with the latest version? This would help a lot. I tried creating a repro myself, but I wasn't able to without knowing how the react hooks form is set up.

A live example would be perfect. This StackBlitz sandbox template may be a good starting point. Thank you!

MPavaoDS commented 8 months ago

Hi @DiegoAndai, thanks your your answer. I have added the minimal reproduction test case to that Stackblitz project, let me know if you can see it.

DiegoAndai commented 8 months ago

Hey @MPavaoDS, unfortunately, I cannot see it. When you edit the sandbox, it creates a fork, which differs from the link I provided. Could you share the link to the forked one with your reproduction? Thanks!

MPavaoDS commented 8 months ago

Sorry about that, here it is: https://stackblitz.com/edit/stackblitz-starters-hyzfr1?file=src%2FApp.jsx

DiegoAndai commented 8 months ago

Does this work for you?: https://stackblitz.com/edit/stackblitz-starters-rcpccx?file=src%2FApp.jsx

This used the user.names as options, instead of the user objects.

MPavaoDS commented 8 months ago

It seems to work on my local code as well. Thank you for your help!

DiegoAndai commented 8 months ago

That's good to hear! I'll close this issue. Please reach out if you have any other questions.