material-ui: [Autocomplete] 'renderTags' ignored when 'multiple' is false

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

On v5 alpha, when passing renderTags to Autocomplete when multiple is false the renderTags prop will be ignored.

Expected Behavior 🤔

renderTags should be used to render the selected item(s) in the Input no matter what multiple is set to.

Steps to Reproduce 🕹

Comment line 11 of this code sandbox

Context 🔦

We have a single select Autocomplete where we set the renderOption prop to render a custom element that includes a small profile pic. However once one option is selected there is currently no way to render this custom element in the Input of the Autocomplete

Your Environment 🌎

`npx @material-ui/envinfo`
  System:
    OS: Linux 5.8 Pop!_OS 20.04 LTS
  Binaries:
    Node: 14.15.1 - ~/.nvm/versions/node/v14.15.1/bin/node
    Yarn: 1.22.5 - /usr/bin/yarn
    npm: 6.14.10 - ~/Projects/clinical-dashboard-v2/node_modules/.bin/npm
  Browsers:
    Chrome: 89.0.4389.82 <--- using this one
    Firefox: 86.0
  npmPackages:
    @emotion/react: ^11.0.0 => 11.1.4 
    @emotion/styled: ^11.0.0 => 11.0.0 
    @material-ui/core: 5.0.0-alpha.34 => 5.0.0-alpha.34 
    @material-ui/lab: 5.0.0-alpha.34 => 5.0.0-alpha.34 
    @material-ui/private-theming:  5.0.0-alpha.33 
    @material-ui/styled-engine:  5.0.0-alpha.34 
    @material-ui/styles:  5.0.0-alpha.33 
    @material-ui/system:  5.0.0-alpha.34 
    @material-ui/types:  6.0.0 
    @material-ui/unstyled:  5.0.0-alpha.34 
    @material-ui/utils:  5.0.0-alpha.33 
    @types/react: ^17.0.3 => 17.0.3 
    react: ^17.0.1 => 17.0.1 
    react-dom: ^17.0.1 => 17.0.1 
    styled-components: ^5.2.1 => 5.2.1 
    typescript: ^4.2.0 => 4.2.4 

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 19
  • Comments: 18 (4 by maintainers)

Most upvoted comments

I can think of the following approaches:

  1. We could have a renderTag or renderSingleValue API prop for this.
  2. We can have a components prop with SingleValue slot like what react-select does in https://codesandbox.io/s/s0yc5?module=/example.tsx&file=/example.tsx.

We should also update the API docs for renderTags that it works only when multiple is true.

@oliviertassinari @michaldudak What do you guys think?

Thanks for the response @eps1lon . That makes a lot of sense. Looking at it now everything inside the getTagProps passed to the renderTags function wouldn’t apply to a single select.

To describe a bit further our use case, we have a custom component, <EntityLabel/> that renders formatted text with a profile pic. It is trivially easy to render these components as the list of options for the Autocomplete using renderOption. However once one is selected and displayed in the input, there is no render- prop in the Autocomplete API for a custom component like there is for multiple selected values.

Is there any solution for this? The workaround that i am doing now is to add a startAdornment in the textfield and display whatever is needed. Then i hide the label of the autocomplete component using getOptionLabel: () => "",

I also wonder if this was perhaps intentional. Regardless, I believe there is enough of a use case to either allow renderTags to work with multiple={false} or add some other prop to override the display of a single selected option.

I’m curious what your workaround was @degzhaus. Were you able to do it somehow inside the renderInput prop?

The gmail to field would be something that supports renderTags and freeSolo={true}?

From a UI POV I personally prefer the latter solution where backspace removes the selected value and completely clears the input. This aligns with Autocomplete behavior when multiple={true}. Once an item has been selected a single backspace to remove selected item feels intuitive and desired.

The case where users instead want to view similar items to the one they just removed (search results for ‘re’) seems less likely. One caveat to that may be if freeSolo={true}? I struggle to think of a real world use case where renderTags and freeSolo are used together.

I see how this may be useful.

A thing to note, though, is that rendering anything else than a default string will break the current autocompletion logic.

Let’s say we have a list of colors and when selected, we display a swatch before the color name in the textbox:

🟥 red
--------
red
green
blue

When we now focus the textbox and press <kbd>Backspace</kbd>, we are left with 🟥 re, which does not match any of the options.

We could overcome this by disallowing to edit the selected value and clearing the input completely when <kbd>Backspace</kbd>, <kbd>Delete</kbd>, or any character key is pressed, similar to how react-select does it. This logic would kick in only if we override what is displayed in the textbox. Alternatively, we could display the custom value only if the textbox is not focused. Doing so would let us leave the current autocompletion logic.

Do you have any preferences in this matter?

cc @mnajdova

This would be an incredibly helpful change for us also. We need to show a device status icon - and ideally also a device class icon - not only on the options, but also for the selected value. We use this type of device select for both single and multiselection. IIUC one can only render a string unless multiselection is enabled, which results in an inconsistent UI in our case. And since we cannot omit the status icon, we currently add it to the textfield label, which is of course very undesirable.

screenshots

CleanShot 2021-08-09 at 16 08 26

CleanShot 2021-08-09 at 16 24 53