primitives
primitives copied to clipboard
User is no longer able to reset optional `<Select/>` value
Bug report
Current Behavior
As far as I can tell, there is no way for a user to reset a <Select/> to its original (empty) state, even if it is optional.
Expected behavior
Ability to clear the currently selected value on optional <Select/>s.
Reproducible example
Hero example on https://www.radix-ui.com/primitives/docs/components/select:
- Select an entry
- Unable to clear the selection even though it is not
required
Suggested solution
Add an empty/placeholder record for optional <Select/>s, or at least allow adding one manually, like it was before #2174.
Additional context
This seems to have been broken by #2174, which now actively forbids adding an empty item. It is now only possible to clear by adding additional control for unsetting a <Select/>.
I believe it is an anti-pattern to not allow the user to undo an erroneous change they might have made. This control currently only allows a one-way change from the placeholder, as opposed to how it worked before.
Your environment
@radix-ui/[email protected]
I'm happy to provide a PR if there is a consensus on how to address this.
Having the same issue.
chiming in. This constrain does not really make sense to me. When i add a select item with an empty value its exactly the point to reset it back to the placeholder. 🫠
chiming in. This constrain does not really make sense to me. When i add a select item with an empty value its exactly the point to reset it back to the placeholder.
Totally agree with this. We end up coming up with a contrived string ID and using a custom change handler to deselect when it encounters that ID. For optional selects (those not requiring a value), a user ought to be able to unset their selection.
We are facing the same problem and are happy to hear a functioning solution that does not include the usage of a proxy value like "none".
This change unnecessarily bloats otherwise straightforward implementations. This breaks standards and will hurt adoption of RadixUI.
Consider the following example. Message model has optional property templateId. Empty string is nullish, so no extra transformations are required:
const templateId = Boolean(value) ? BigInt(value) : undefined;
This fits naturally with validation libraries like Yup and Zod. Even the W3C's <select> tag example uses empty string for "no selection", and this is what I hate the most about this change.
I will sound rude, and I mean it. We got a whole bag of problems to deal with because one bright mind couldn't figure out how to set value to undefined. Cool stuff
Have the same issue. In our case the value is directly used as a filter. So now we need to somehow workaround the fact that "none" is ""...
Facing the same Issue. Just like how native select allows to deselect the value being selected, Radix Select should also allow
This would be useful. It would be great if clicking an already-selected value would deselect it and set the value to "".
This would be useful. It would be great if clicking an already-selected value would deselect it and set the value to
"".
The standard way to clear a <select/> is to provide an <option/> without a value (i.e. an empty string). This issue is about restoring that particular functionality.
What you're describing seems less like a direct <select/> replacement and more like a drop-down version of a toggle group.
maybe a <Select.Clear> component could help with this?
maybe a
<Select.Clear>component could help with this?
I would like to avoid adding extra steps for standard functionality that should "just work"™. I still haven't seen a compelling reason for why this would be forbidden in the first place. It seem like a very arbitrary decision.
While it throws a type error, it appears that setting the value to null has the same effect as previous setting the value to "", e.g:
<Select.Item value={null}>Clear</Select.Item>
I'm not sure if this is intended behavior or not though...
I am having this same struggle. The Mozilla docs for the select element shows a simple example of an empty value for a select option. The user can select an option and return to the placeholder state if they would like. I don't see why Radix does not support that simple scenario.
In my case, I need the user to be able to return to the disabled state. I am working on migrating to Radix from native HTML elements, and many parts of my codebase use the empty value. I could assign an actual value to the disabled state, but then I need to refactor my logic to repopulate the form and the logic to submit to my API. It looks like @linden-dg's solution will work, but it feels bad to cast to any to satisfy the string type value={null as any}. It also comes with the small side effect of a missing checked icon.
value={null as any} (Check missing)
value="encryption" (Check working as normal)
Ideally my code would be this
<SelectInput name={inputs.PROCESSING_TYPE} title="Processing Type">
<SelectItem value="">Disabled</SelectItem>
<SelectItem value={processingTypes.ENCRYPTION}>Encryption</SelectItem>
<SelectItem value={processingTypes.DECRYPTION}>Decryption</SelectItem>
<SelectItem value={processingTypes.COMPRESSION}>Compression</SelectItem>
<SelectItem value={processingTypes.DECOMPRESSION}>Decompression</SelectItem>
</SelectInput>
Currently I am doing this
<SelectInput name={inputs.PROCESSING_TYPE} title="Processing Type" placeholder="Disabled">
<SelectItem value={null as any}>Disabled</SelectItem>
<SelectItem value={processingTypes.ENCRYPTION}>Encryption</SelectItem>
<SelectItem value={processingTypes.DECRYPTION}>Decryption</SelectItem>
<SelectItem value={processingTypes.COMPRESSION}>Compression</SelectItem>
<SelectItem value={processingTypes.DECOMPRESSION}>Decompression</SelectItem>
</SelectInput>
I agree that there should also be a way to deselect and return to a placeholder state.
This change unnecessarily bloats otherwise straightforward implementations. This breaks standards and will hurt adoption of RadixUI. Consider the following example.
Messagemodel has optional propertytemplateId. Empty string is nullish, so no extra transformations are required:const templateId = Boolean(value) ? BigInt(value) : undefined;This fits naturally with validation libraries like Yup and Zod. Even the W3C's
<select>tag example uses empty string for "no selection", and this is what I hate the most about this change. I will sound rude, and I mean it. We got a whole bag of problems to deal with because one bright mind couldn't figure out how to set value toundefined. Cool stuff
The browser API for getting FormData from a Form element is really annoying because undefined might work for POST if you then send that FormData over the wire, but it doesn't work for PATCH. Undefined means omitted from form data.
So if you actually want to take something was previously a truthy value and unset it, you have a problem. Everything is a string so there is no concept of null it would be "null" as a string. One solution is sending a value of empty string over the wire, it is then included in FormData, and your server using something like Zod can transform that literal empty string and only that literal empty string to null or whatever you need it to be. Allowing empty string in this scenario would be really useful.