Open Idonoghue opened 3 years ago
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?
Thanks for the feedback.
What we consider a "tag" is a combination of a value and an affordance to de-select that value. There's no need to de-select a single value in a single-select Autocomplete so we don't even attempt to "render tags".
The purpose of renderTags
is not really to display a different label. That's what getOptionLabel
is for.
So we definitely do lack some clearer documentation for the Autocomplete.
As to your specific issue: Could you explain a bit more what UI you're trying to build? Then we can discuss what kind of API could solve this problem.
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.
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.
I am using Autocomplete to display the selected popup as chip and typed text as normal text
This is something that would be very helpful for us also
I can think of the following approaches:
renderTag
or renderSingleValue
API prop for this. 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?
+1 for this feature!
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 Backspace, 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 Backspace, Delete, 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
+1 for this! We would also be helped a lot if this was a feature.
Edit: found out our team is actually using this approach: https://codesandbox.io/s/material-demo-forked-ijzbt?file=/demo.js
degzhaus' suggestion didn't work but the one used on this csb did. Basically adding ...params.InputProps
to the TextField.
If we want to show a single value as we have multiple tags, what would be the approach?
Also, another idea would be to have limitValues
and instead of limitTags that hide the values, it would always allow only 1, if 1 other value were selected it would replace it.
@eps1lon @michaldudak Any news on this issue?
@michaldudak
Aren't we be able to keep the actual value somewhere else and have the rendered component not interfere with our autocompletion?
Based on your suggestion and example, when deleting the character "d", could we make it so that the swatch goes away?
Idk if I'm going to far here, but basically having a way to map a value to its renderTag, so "red" maps to "π₯ red", as soon as we deleted a single character from the input, there won't be any value that maps to that, so we go back to normal rendering the text typed.
So instead of this
π₯ re
--------
red
green
blue
We would get this: since that the tag "π₯ re" doesn't have any value mapped to it, (not a valid option)
re -------- red green blue
-edit ps. I dont know the inner workings of the AutoComplete component, so maybe I'm just talking non sense here, also maybe this approach is too expensive.
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.
The gmail to field would be something that supports renderTags and freeSolo={true}?
Aren't we be able to keep the actual value somewhere else and have the rendered component not interfere with our autocompletion?
Based on your suggestion and example, when deleting the character "d", could we make it so that the swatch goes away?
Idk if I'm going to far here, but basically having a way to map a value to its renderTag, so "red" maps to "π₯ red", as soon as we deleted a single character from the input, there won't be any value that maps to that, so we go back to normal rendering the text typed.
I think it could be confusing if the rendered value changed during editing.
I'm leaning towards a solution similar to how the Autocomplete works in multiple
mode, but as @Idonoghue noted, there are rough edges here as well.
If someone is willing to prototype a solution, I'll be happy to review it and discuss the solutions for problems that arise.
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: () => "",
Yo :)
I would need this 'feature' as well... I just want to be able to style the displayed option like I'm able to style it for the multiple=true. My example 'need' would look like this:
If this would cause too much of an overhead for the autocomplete component, does anyone has any other workaround that could be used to achieve something like this or it's just impossible for the single autocomplete to have the displayed value styled any other way?
Thanks π€
My workaround/idea is
...
const { multiple, ...props } = p
...
<MuiAutocomplete
multiple={true}
onChange={(e, d) => {
const newValue = multiple ? d : Array.from(d).slice(-1)
props.onChange?.call(null, e, newValue)
}}
...
{... props}
Still, Iβm waiting for the official solution as well.
Any news on an official solution for this? Would be extremely helpful and it's been 3 years :pray:
Yo :)
I would need this 'feature' as well... I just want to be able to style the displayed option like I'm able to style it for the multiple=true. My example 'need' would look like this:
If this would cause too much of an overhead for the autocomplete component, does anyone has any other workaround that could be used to achieve something like this or it's just impossible for the single autocomplete to have the displayed value styled any other way?
Thanks π€
Did you ever find a workaround for this?, your exact case is what i'm trying to do I want to have an autocomplete field that is a single select rather than allowing multiple but I want to style it to match my multiple selects by having the single selected option look like a chip as well.
Current Behavior π―
On v5 alpha, when passing
renderTags
to Autocomplete whenmultiple
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 whatmultiple
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 AutocompleteYour 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 ```