Skip to content

Commit e58c751

Browse files
committed
šŸ› Optional fields stay controlled when cleared
1 parent e77174b commit e58c751

File tree

4 files changed

+44
-35
lines changed

4 files changed

+44
-35
lines changed

ā€Žpackages/admin/dashboard/src/components/inputs/combobox/combobox.tsxā€Ž

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,10 @@ const ComboboxImpl = <T extends Value = string>(
199199
setOpen(open)
200200
}
201201

202-
const hasValue = selectedValues?.length > 0
202+
// Treat empty string as no value for single-select
203+
const hasValue = isArrayValue
204+
? selectedValues?.length > 0
205+
: selectedValues?.length > 0 && selectedValues !== ""
203206

204207
const showTag = hasValue && isArrayValue
205208
const showSelected = showTag && !searchValue && !open
@@ -312,7 +315,7 @@ const ComboboxImpl = <T extends Value = string>(
312315
{...inputProps}
313316
/>
314317
</div>
315-
{allowClear && controlledValue && (
318+
{allowClear && controlledValue && controlledValue !== "" && (
316319
<button
317320
type="button"
318321
onClick={(e) => {

ā€Žpackages/admin/dashboard/src/components/inputs/country-select/country-select.tsxā€Ž

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,48 @@ import { Combobox } from "../combobox"
1010

1111
export const CountrySelect = forwardRef<
1212
HTMLInputElement,
13-
Omit<ComponentPropsWithoutRef<typeof Combobox>, "options" | "multiple"> & {
13+
Omit<
14+
ComponentPropsWithoutRef<typeof Combobox>,
15+
"options" | "multiple" | "value" | "onChange"
16+
> & {
1417
placeholder?: string
1518
defaultValue?: string
1619
allowClear?: boolean
20+
value?: string
21+
onChange?: (value: string | undefined) => void
1722
}
18-
>(({ placeholder, defaultValue, allowClear, onChange, value, ...props }, ref) => {
19-
const { t } = useTranslation()
20-
const innerRef = useRef<HTMLInputElement>(null)
23+
>(
24+
(
25+
{ placeholder, defaultValue, allowClear, onChange, value, ...props },
26+
ref
27+
) => {
28+
const { t } = useTranslation()
29+
const innerRef = useRef<HTMLInputElement>(null)
2130

22-
useImperativeHandle(ref, () => innerRef.current as HTMLInputElement)
31+
useImperativeHandle(ref, () => innerRef.current as HTMLInputElement)
2332

24-
// Normalize the value: convert to lowercase
25-
// Keep empty string as empty string (don't convert to undefined)
26-
const normalizedValue = typeof value === "string"
27-
? (value ? value.toLowerCase() : "")
28-
: ""
33+
// Keep empty string as empty string for Combobox controlled state
34+
const normalizedValue = value || ""
2935

30-
const handleChange = (newValue: string | undefined) => {
31-
// Convert undefined to empty string when clearing
32-
onChange?.(newValue || "")
33-
}
36+
const handleChange = (newValue: string | undefined) => {
37+
onChange?.(newValue || "")
38+
}
3439

35-
return (
36-
<Combobox
37-
{...props}
38-
ref={innerRef}
39-
value={normalizedValue}
40-
onChange={handleChange}
41-
options={countries.map((country) => ({
42-
label: country.display_name,
43-
value: country.iso_2.toLowerCase(),
44-
}))}
45-
placeholder={placeholder || t("fields.selectCountry")}
46-
allowClear={allowClear}
47-
/>
48-
)
49-
})
40+
return (
41+
<Combobox
42+
{...props}
43+
ref={innerRef}
44+
value={normalizedValue}
45+
onChange={handleChange}
46+
options={countries.map((country) => ({
47+
label: country.display_name,
48+
value: country.iso_2.toLowerCase(),
49+
}))}
50+
placeholder={placeholder || t("fields.selectCountry")}
51+
allowClear={allowClear}
52+
/>
53+
)
54+
}
55+
)
5056

5157
CountrySelect.displayName = "CountrySelect"

ā€Žpackages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsxā€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export const ProductCreateOrganizationSection = ({
9494
<Form.Control>
9595
<Combobox
9696
{...field}
97-
value={field.value || undefined}
97+
value={field.value || ""}
9898
onChange={(value) => field.onChange(value || "")}
9999
options={types.options}
100100
searchValue={types.searchValue}
@@ -120,7 +120,7 @@ export const ProductCreateOrganizationSection = ({
120120
<Form.Control>
121121
<Combobox
122122
{...field}
123-
value={field.value || undefined}
123+
value={field.value || ""}
124124
onChange={(value) => field.onChange(value || "")}
125125
options={collections.options}
126126
searchValue={collections.searchValue}

ā€Žpackages/admin/dashboard/src/routes/products/product-organization/components/product-organization-form/product-organization-form.tsxā€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export const ProductOrganizationForm = ({
123123
<Form.Control>
124124
<Combobox
125125
{...field}
126-
value={field.value || undefined}
126+
value={field.value || ""}
127127
onChange={(value) => field.onChange(value || "")}
128128
options={types.options}
129129
searchValue={types.searchValue}
@@ -149,7 +149,7 @@ export const ProductOrganizationForm = ({
149149
<Form.Control>
150150
<Combobox
151151
{...field}
152-
value={field.value || undefined}
152+
value={field.value || ""}
153153
onChange={(value) => field.onChange(value || "")}
154154
multiple={false}
155155
options={collections.options}

0 commit comments

Comments
Ā (0)
⚔