Skip to content

Commit

Permalink
Extend comboboxes to allow for arbitrary entries (#2296)
Browse files Browse the repository at this point in the history
* Add functionality: users can now type new entries into comboboxes
* Refactor firewall forms
* Improve TS error messages
* Refactor comboboxes
  • Loading branch information
charliepark authored Sep 9, 2024
1 parent af42e70 commit 93bcef9
Show file tree
Hide file tree
Showing 10 changed files with 577 additions and 414 deletions.
20 changes: 17 additions & 3 deletions app/components/form/fields/ComboboxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export type ComboboxFieldProps<
name: TName
control: Control<TFieldValues>
onChange?: (value: string | null | undefined) => void
disabled?: boolean
} & ComboboxBaseProps

export function ComboboxField<
Expand All @@ -38,22 +37,37 @@ export function ComboboxField<
label = capitalize(name),
required,
onChange,
disabled,
allowArbitraryValues,
placeholder,
// Intent is to not show both a placeholder and a description, while still having good defaults; prefer a description to a placeholder
/*
* If description is provided, use it.
* If not, but a placeholder is provided, the default description should be undefined.
* If no placeholder is provided and arbitrary values are allowed, the default description should be 'Select an option or enter a custom value'.
* If no placeholder is provided and arbitrary values are not allowed, the default description should be 'Select an option'.
*/
description = placeholder
? undefined
: allowArbitraryValues
? 'Select an option or enter a custom value'
: 'Select an option',
...props
}: ComboboxFieldProps<TFieldValues, TName>) {
const { field, fieldState } = useController({ name, control, rules: { required } })
return (
<div className="max-w-lg">
<Combobox
isDisabled={disabled}
label={label}
placeholder={placeholder}
description={description}
required={required}
selected={field.value || null}
hasError={fieldState.error !== undefined}
onChange={(value) => {
field.onChange(value)
onChange?.(value)
}}
allowArbitraryValues={allowArbitraryValues}
{...props}
/>
<ErrorMessage error={fieldState.error} label={label} />
Expand Down
3 changes: 3 additions & 0 deletions app/components/form/fields/ListboxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type ListboxFieldProps<
onChange?: (value: string | null | undefined) => void
isLoading?: boolean
noItemsPlaceholder?: string
hideOptionalTag?: boolean
}

export function ListboxField<
Expand All @@ -54,6 +55,7 @@ export function ListboxField<
onChange,
isLoading,
noItemsPlaceholder,
hideOptionalTag,
}: ListboxFieldProps<TFieldValues, TName>) {
// TODO: recreate this logic
// validate: (v) => (required && !v ? `${name} is required` : undefined),
Expand All @@ -80,6 +82,7 @@ export function ListboxField<
hasError={fieldState.error !== undefined}
isLoading={isLoading}
buttonRef={field.ref}
hideOptionalTag={hideOptionalTag}
/>
<ErrorMessage error={fieldState.error} label={label} />
</div>
Expand Down
Loading

0 comments on commit 93bcef9

Please sign in to comment.