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.92k stars 32.27k forks source link

[material-ui][Autocomplete] `ListboxComponent` differs with `slots.listbox` #44329

Closed joshkel closed 1 day ago

joshkel commented 1 week ago

Steps to reproduce

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

Steps:

  1. Open the "ListboxComponent" autocomplete. Note that the drop-down list has functionality such as pointer cursor and highlight on hover.
  2. Open the "slots.listbox" autocomplete. Note that the drop-down list has minimal styling and feedback.

Current behavior

A listbox component that's provided via slots.listbox, as in the virtualization demo, is missing styling and interactivity affordances, and it behaves very differently than a listbox component that's provided via ListboxComponent.

Expected behavior

The demo's recommended approach should provide styling and interactivity affordances. It's my understanding that slots.listbox and ListboxComponent are supposed to be equivalent.

Context

This behavior appears to be new in 6.1.5. It may be related to #43994.

Your environment

npx @mui/envinfo ``` System: OS: macOS 15.0.1 Binaries: Node: 18.20.4 - ~/.nvm/versions/node/v18.20.4/bin/node npm: 10.7.0 - ~/.nvm/versions/node/v18.20.4/bin/npm pnpm: Not Found Browsers: Chrome: 130.0.6723.92 * Edge: 130.0.2849.68 Safari: 18.0.1 npmPackages: @emotion/react: 11.13.3 @emotion/styled: 11.13.0 @mui/base: 5.0.0-beta.61 @mui/core-downloads-tracker: 6.1.6 @mui/icons-material: 6.1.6 @mui/lab: 6.0.0-beta.14 @mui/material: 6.1.6 @mui/private-theming: 6.1.6 @mui/styled-engine: 6.1.6 @mui/system: 6.1.6 @mui/types: 7.2.19 @mui/utils: 6.1.6 @mui/x-date-pickers: 7.22.1 @mui/x-internals: 7.21.0 @mui/x-tree-view: 7.22.1 @types/react: ^18.3.12 => 18.3.12 react: ^18.3.1 => 18.3.1 react-dom: ^18.3.1 => 18.3.1 typescript: ^5.6.3 => 5.6.3 ```

Search keywords: autocomplete listboxcomponent

DiegoAndai commented 4 days ago

Hey @joshkel! Thanks for the report.

You're correct, there's a difference between the functionality of these APIs, as described here. This is due to ListboxComponent originally being inconsistent with other component override props. Because ListboxComponent is deprecated, we're not correcting this, as it would be a breaking change.

The recommended API is slots.listbox. If you provide a description of what you're trying to achieve, I can help you achieve it with that API.

Next week I'll create a PR to add this explanation to the docs.

joshkel commented 4 days ago

Thanks for the explanation, @DiegoAndai. I had overlooked that comment and didn't realize that this behavior was intentional.

What I'm trying to achieve - virtualization, as in the virtualization demo, with good UX. A normal Autocomplete provides UX features such as highlighting the current selection, highlighting whatever item the mouse cursor is hovered over, and using a pointer cursor instead of default cursor when hovering over a clickable item. Prior to 6.1.5, using slots.listbox provided these UX features; now it doesn't.

If the virtualization demo were updated to show these features, I'd really appreciate it.

Maybe the solution would be to have the demo's ListboxComponent react-window wrapper render an AutocompleteListbox itself? But AutocompleteListbox isn't exported... (I'm not sure that I understand the slots system / as props well enough; I apologize.)

DiegoAndai commented 1 day ago

What I'm trying to achieve - virtualization, as in the virtualization demo, with good UX. A normal Autocomplete provides UX features such as highlighting the current selection, highlighting whatever item the mouse cursor is hovered over, and using a pointer cursor instead of default cursor when hovering over a clickable item. Prior to 6.1.5, using slots.listbox provided these UX features; now it doesn't.

@joshkel you're correct, the virtualization demo wasn't updated correctly, I created #44382 to correct this. I also created #44383 to bring back the ListboxComponent deprecation messages, updated to point to slotProps.listbox.component. This should improve the confusion around the migration.

Give slotProps.listbox.component a try, I think it fits your use case of maintaining the style while being able to virtualize the list, here's the updated demo: https://deploy-preview-44382--material-ui.netlify.app/material-ui/react-autocomplete/#virtualization

joshkel commented 1 day ago

Switching to slotProps.listbox.component seems to work. That plus your docs updates should take care of this issue.

Thanks for all your help and the thorough follow-up.

github-actions[bot] commented 1 day ago

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

[!NOTE] @joshkel How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.