fix: handle empty strings for Select component (#18553)

resolve #18361

Its possible for a dynamic parameter option value to be an empty string
which will cause the following error in the Radix Select component. The
solution is to handle empty strings so that they are not set directly in
the component.


`Uncaught Error: A <Select.Item /> must have a value prop that is not an
empty string. This is because the Select value can be set to an empty
string to clear the selection and show the placeholder.`


```
data "coder_parameter" "radio" {
  name         = "radio"
  display_name = "An example of a radio input"
  description  = "The next parameter supports a single value."
  type         = "string"
  form_type    = "dropdown"
  order        = 1
  default      = ""

  option {
    name = "Empty"
    value = "" 
  }
}

```
This commit is contained in:
Jaayden Halko
2025-06-24 16:44:52 -04:00
committed by GitHub
parent 6ed22046af
commit 25f1b76624
@@ -379,11 +379,17 @@ const ParameterField: FC<ParameterFieldProps> = ({
id,
}) => {
switch (parameter.form_type) {
case "dropdown":
case "dropdown": {
const EMPTY_VALUE_PLACEHOLDER = "__EMPTY_STRING__";
const selectValue = value === "" ? EMPTY_VALUE_PLACEHOLDER : value;
const handleSelectChange = (newValue: string) => {
onChange(newValue === EMPTY_VALUE_PLACEHOLDER ? "" : newValue);
};
return (
<Select
onValueChange={onChange}
value={value}
onValueChange={handleSelectChange}
value={selectValue}
disabled={disabled}
required={parameter.required}
>
@@ -393,14 +399,26 @@ const ParameterField: FC<ParameterFieldProps> = ({
/>
</SelectTrigger>
<SelectContent>
{parameter.options.map((option) => (
<SelectItem key={option.value.value} value={option.value.value}>
<OptionDisplay option={option} />
</SelectItem>
))}
{parameter.options.map((option, index) => {
const optionValue =
option.value.value === ""
? EMPTY_VALUE_PLACEHOLDER
: option.value.value;
return (
<SelectItem
key={
option.value.value || `${EMPTY_VALUE_PLACEHOLDER}:${index}`
}
value={optionValue}
>
<OptionDisplay option={option} />
</SelectItem>
);
})}
</SelectContent>
</Select>
);
}
case "multi-select": {
const parsedValues = parseStringArrayValue(value ?? "");