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.91k stars 32.26k forks source link

[material-ui][Autocomplete] Passing `slotProps` to the `TextField` in `renderInput` throws an error #43573

Closed ClementDreptin closed 4 days ago

ClementDreptin commented 2 months ago

Steps to reproduce

Link to live example: https://stackblitz.com/edit/react-1qmjam?file=Demo.tsx

Steps:

  1. Click in the Autocomplete to see the error

Current behavior

I found 2 strange behaviors

Expected behavior

I expect to be able to use slotProps.input the same way I was using InputProps and slotProps.htmlInput the same way I was using inputProps.

Context

In our app we have an Autocomplete with a custom endAdornment. We are adding another adornment before the existing one to be exact. I was trying to migrate from InputProps and inputProps to slotProps since they became deprecated in MUI v6.

Before migrating the code looked like this (which is still working in v6 but won't in v7):

<Autocomplete
  ...
  renderInput={(params) => (
    <TextField
      {...params}
      InputProps={{
        endAdornment: (
          <>
            <MyCustomIcon />
            {params.InputProps?.endAdornment}
          </>
        ),
      }}
    />
  )}
/>

After the migration the code looks like this:

<Autocomplete
  renderInput={(params) => (
    <TextField
      {...params}
      slotProps={{
        input: {
          endAdornment: (
            <>
              <MyCustomIcon />
              {params.InputProps?.endAdornment}
            </>
          ),
        },
      }}
    />
  )}
/>

Both adornments disappeared and the list of options isn't displaying on focus anymore.

Your environment

npx @mui/envinfo ``` System: OS: Linux 6.8 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat) Binaries: Node: 20.17.0 - ~/.volta/tools/image/node/20.17.0/bin/node npm: 10.8.2 - ~/.volta/tools/image/node/20.17.0/bin/npm pnpm: Not Found Browsers: Chrome: 128.0.6613.113 npmPackages: @emotion/react: 11.13.3 => 11.13.3 @emotion/styled: 11.13.0 => 11.13.0 @mui/core-downloads-tracker: 6.0.1 @mui/icons-material: 6.0.1 => 6.0.1 @mui/material: 6.0.1 => 6.0.1 @mui/material-nextjs: ^6.0.0 => 6.0.1 @mui/private-theming: 6.0.1 @mui/styled-engine: 6.0.1 @mui/system: 6.0.1 @mui/types: 7.2.16 @mui/utils: 6.0.1 @types/react: ^18.3.3 => 18.3.5 react: 18.3.1 => 18.3.1 react-dom: 18.3.1 => 18.3.1 typescript: ^5.4.5 => 5.5.4 ```

Search keywords: Autocomplete slotProps

sai6855 commented 1 month ago

@DiegoAndai do you think this issue should be added to Material-UI v6 issues board?

Cc @aarongarciah

aarongarciah commented 1 month ago

@sai6855 I just added it to the v6 issues board.

mjkstudios commented 1 month ago

@ClementDreptin - I am definitely experiencing some odd behaviors since upgrading to v6. In general, I feel like what is being passed as params from the Autocomplete component needs to be updated to reflect the v6 changes with regards to slotProps.

However, I've had some luck by spreading the params.InputProps as follows:

<Autocomplete
  renderInput={(params) => (
    <TextField
      {...params}
      slotProps={{
        input: {
          ...params.InputProps, // <-- ADD THIS LINE
          endAdornment: (
            <>
              <MyCustomIcon />
              {params.InputProps?.endAdornment}
            </>
          ),
        },
      }}
    />
  )}
/>
jonesmac commented 1 month ago

for what its worth, this seems to fail on all TextField input adornment props. Autocomplete uses TextField so that's why there's an issue here.

See the problem here - https://codesandbox.io/p/sandbox/broken-text-field-adornment-8zhlqc?file=%2Fsrc%2FApp.tsx%3A53%2C72&workspaceId=bdebcbbe-982a-40d5-9c2e-b543cf24c982

MonstraG commented 1 month ago

I had same problem with autocomplete throwing, and @mjkstudios solution worked.

DatePickers also broke silently, and were also fixed by the same change, I think they also pass old InputProps/inputProps and need to be updated to slots

DiegoAndai commented 1 month ago

Hey everyone, sorry for the late reply.

About the bug

It's important to note that when overriding InputProps or slotProps.input for the Autocomplete's TextField, params.InputProps must be spread. This is true in v5 as well as v6, here are the examples:

So the issues should be fixed by correctly spreading params.InputProps (or params.inputProps when using inputProps or slotProps.htmlInput)

About slots pattern consistency

I agree that "Autocomplete component needs to be updated to reflect the v6 changes with regards to slotProps", as mentioned above. This should be possible:

<Autocomplete
  disablePortal
  options={options}
  sx={{ width: 300 }}
  renderInput={(params) => (
    <TextField
      {...params}
      label="Correct override slotProps"
      placeholder="Correct override slotProps"
      slotProps={{
        ...params.slotProps,
        input: {
          ...params.slotProps.input,
          endAdornment: (
            <>
              <div>icon</div>
              {params.slotProps?.input?.endAdornment}
            </>
          ),
        },
      }}
    />
  )}
/>

Which is currently not the case.

Summary

I don't think there's a bug besides the consistency issue. If you can confirm that the bug you're experiencing is fixed by spreading params.InputProps (or params.inputProps), then we can move forward with making the slotProps usage consistent, as mentioned above.

Please confirm if this fixes the issue, or correct me if I'm wrong or missed something in my demos.

ClementDreptin commented 1 month ago

@DiegoAndai I confirm that spreading params.InputProps in slotProps.input or params.inputProps in slotProps.htmlInput fixes the error being thrown, the actual issue is just the slots pattern inconsistency.

Thank you for pointing the missing spreads in the original examples, I don't know how we never ran into any issues in our app.

aarongarciah commented 4 days ago

Closing since it's not a bug and we already have an issue to standardize the slots API across components: https://github.com/mui/material-ui/issues/41281