#Overview
Dropdowns are used with Forms (Code).
Show codeHide code
export const DropdownFieldDemo = () => {
const form = useForm<{ fruits: ISelectOption<string> | null }>();
return (
<form onSubmit={form.handleSubmit(() => {})}>
<DropdownField
form={form}
name="fruits"
label="Favourite Fruit"
items={fruitOptions}
disableDialogOption={false}
options={{
required: {
value: true,
message: "Please provide a value",
},
}}
/>
<ButtonGroup>
<Button onClick={() => form.reset()}>Reset value</Button>
<Button variant="primary" type="submit">
Send
</Button>
</ButtonGroup>
</form>
);
};
| Name | Type | Default | Description |
|---|---|---|---|
| form * | UseFormReturn<TFieldValues> | - | The connected form that the form field is part of |
| items * | Array<ISelectOption> | - | The selectable items |
| name * | TFieldName | - | The name of the input being registered from the form |
| value * | ISelectOption | null | undefined | - | The value of the input field |
| dialogLabel | ReactNode | - | The title that is shown in the dialog option |
| disableDialogOption | boolean | - | If true, the dialog option is not shown on mobile and tablet viewports |
| disabled | boolean | - | If true, the input field is disabled |
| hasError | boolean | - | If true, turns the border red |
| helpText | ReactNode | - | A help text that can be displayed below the dropdown field |
| hideHelpAndValidation | boolean | - | Hides the help text and validation message |
| labelOptionalAppendix | ReactNode | - | Marker inside the label, when the field is optional |
| labelRequiredAppendix | ReactNode | - | Marker inside the label, when the field is required |
| noWrap | boolean | - | |
| onBlur | FocusEventHandler<HTMLDropdownElement> | - | Callback the field is blurred |
| onChange | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes |
| onMenuClose | () => void | - | Callback when the menu closes |
| onMenuOpen | () => void | - | Callback when the menu opens |
| onSelect | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes |
| options | UseControllerProps<TFieldValues, TFieldName>["rules"] |
| The options that can be set for the registration of the field |
| placeholder | string | - | A hint for the expected value |
#Interface ISelectOption
The interface ISelectOption<T> is used to define the items of the dropdown. It is generic typed and will receive the interface of your actual data definition.
It has the following properties:
| Name | Type | Default | Description |
|---|---|---|---|
| label * | string | - | A label as string, this is required for internal matching or search (AutocompleteDropdown) |
| value * | T | - | The value of the option |
| disabled | boolean | - | If the option is disabled |
| labelComponent | ReactNode | - | Optional JSX to render complex layout (e.g. with Icon) |
#Customize option rendering
You can render custom JSX as option label, just use the optional prop labelComponent for that purpose.
import { FlagCh16Icon } from "@blocks/icons";
import type { ISelectOption } from "@segments/dropdown";
const items: ISelectOption[] = [
{
labelComponent: (
<>
<FlagCh16Icon noColor />
Switzerland
</>
),
label: "Switzerland",
value: "switzerland",
},
// ...
];
#Autocomplete Dropdown
A Dropdown that lets you search for items by keyboard input.
Show codeHide code
export const AutocompleteDropdownFieldDemo = () => {
const form = useForm<{ fruits: ISelectOption<string> | null }>();
const [result, setResult] = useState<ISelectOption<string> | null>(null);
return (
<>
<form
onSubmit={form.handleSubmit(() => {
setResult(form.getValues().fruits);
})}
>
<AutocompleteDropdownField
clearable
form={form}
name="fruits"
label="Favourite Fruit"
items={fruitOptions}
options={{
required: {
value: true,
message: "Please provide a value",
},
}}
/>
<ButtonGroup>
<Button onClick={() => form.reset()}>Reset value</Button>
<Button variant="primary" type="submit">
Send
</Button>
</ButtonGroup>
</form>
{result && <div>{`Submitted: ${result.value}`}</div>}
</>
);
};
| Name | Type | Default | Description |
|---|---|---|---|
| form * | UseFormReturn<TFieldValues> | - | The connected form that the form field is part of |
| items * | Array<ISelectOption> | - | The selectable items |
| value * | ISelectOption | null | undefined | - | The value of the input field |
| clearable | boolean | - | If a selected item can be cleared again, default false |
| createNewValueMessage | string | - | The label that is shown above the creatable option |
| disabled | boolean | - | If true, the input field is disabled |
| hasError | boolean | - | If true, turns the border red |
| helpText | ReactNode | - | A help text that can be displayed below the input field |
| hideHelpAndValidation | boolean | - | Hides the help text and validation message |
| id | string | - | The id of the input field |
| label | ReactNode | - | The label of the input field |
| labelOptionalAppendix | ReactNode | - | Marker inside the label, when the field is optional |
| labelRequiredAppendix | ReactNode | - | Marker inside the label, when the field is required |
| name | string | - | The name of the input field |
| noItemsMessage | string | - | The message that will show when there are no results left after filtering |
| noWrap | boolean | - | |
| onBlur | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the input field is blurred |
| onChange | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes and when input changes |
| onCreateItem | (inputValue: string) => Promise<ISelectOption | undefined | void> | - | Async callback to create new items. An option for that is shown when the user types something that is not present as an item |
| onInputValueChange | (inputValue: string) => Promise<void> | - | An optional callback to filter items asynchronous - useful to fetch an API again |
| onMenuClose | () => void | - | Callback when the menu closes |
| onMenuOpen | () => void | - | Callback when the menu opens |
| onSelect | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes |
| options | UseControllerProps<TFieldValues, TFieldName>["rules"] |
| The options that can be set for the registration of the field |
| placeholder | string | - | A hint for the expected value |
| ref | Ref<HTMLButtonElement> | - | Ref of the dropdown |
#Creating new items
When you pass an onCreateItem callback function, users can create and add new items to the dropdown that don't exist in the original list. This is useful for fields where users might need custom values.
Show codeHide code
export const CreatableAutocompleteDropdownFieldDemo = () => {
const [creatableOptions, setCreatableOptions] = useState(fruitOptions);
const [result, setResult] = useState<ISelectOption<string> | null>(null);
const form = useForm<{ fruits: ISelectOption<string> }>();
return (
<>
<form
onSubmit={form.handleSubmit(() => {
setResult(form.getValues().fruits);
})}
>
<AutocompleteDropdownField
form={form}
name="fruits"
label="Favourite Fruit"
items={creatableOptions}
onCreateItem={async (inputValue: string) => {
const newValue = { label: inputValue, value: inputValue };
setCreatableOptions([...fruitOptions, newValue]);
return newValue;
}}
options={{
required: {
value: true,
message: "Please provide a value",
},
}}
/>
<Button type="submit">Send</Button>
</form>
{result && <div>{`Submitted: ${result.value}`}</div>}
</>
);
};
#Lazy loading items
If you're using an <AutocompleteDropdown /> or <MultiselectDropdown />, then you can implement the callback onInputValueChange to filter/fetch items.
This is useful for data sources that can't be fully loaded initially.
So you can use this callback to fetch the items with a new API request. The callback will be called on every keystroke - so it is recommended
to implement this with a debounce function to avoid too many requests.
#Multiselect Dropdown
A Dropdown that let you select multiple items and also search for them by keyboard input.
Show codeHide code
export const MultiSelectDropdownFieldDemo = () => {
const form = useForm<{ fruits: ISelectOption[] }>();
const [result, setResult] = useState<ISelectOption[] | null>(null);
return (
<>
<form
onSubmit={form.handleSubmit(() => {
setResult(form.getValues().fruits);
})}
>
<MultiSelectDropdownField
form={form}
name="fruits"
label="Favourite Fruit"
items={fruitOptions}
options={{
required: {
value: true,
message: "Please provide a value",
},
}}
/>
<ButtonGroup>
<Button onClick={() => form.reset()}>Reset value</Button>
<Button variant="primary" type="submit">
Send
</Button>
</ButtonGroup>
</form>
{result && (
<div>{`Submitted: ${result.map((item) => item.value).join(", ")}`}</div>
)}
</>
);
};
| Name | Type | Default | Description |
|---|---|---|---|
| form * | UseFormReturn<TFieldValues> | - | The connected form that the form field is part of |
| items * | Array<ISelectOption> | - | The selectable items |
| name * | TFieldName | - | The name of the input being registered from the form |
| value * | Array<ISelectOption> | null | undefined | - | The value of the mutli select dropdown |
| createNewValueMessage | string | - | The label that is shown above the creatable option |
| disabled | boolean | - | If true, the input field is disabled |
| hasError | boolean | - | If true, turns the border red |
| helpText | ReactNode | - | A help text that can be displayed below the input field |
| hideHelpAndValidation | boolean | - | Hides the help text and validation message |
| itemToString | (item: ISelectOption,null) => string |
| Parse function to convert the selected into into a string to show inside the input field |
| label | ReactNode | - | The label of the input field |
| labelOptionalAppendix | ReactNode | - | Marker inside the label, when the field is optional |
| labelRequiredAppendix | ReactNode | - | Marker inside the label, when the field is required |
| noItemsMessage | string | - | The message that will show when there are no results left after filtering |
| noOptionsMessage | string | - | The message that will show when all items have been selected |
| noWrap | boolean | - | |
| onBlur | ChangeEventHandler<HTMLMultiSelectDropdownElement> | - | Callback the input field is blurred |
| onChange | ChangeEventHandler<HTMLMultiSelectDropdownElement> | - | Callback when the selected item changes and when input changes |
| onCreateItem | (inputValue: string) => Promise<ISelectOption | undefined | void> | - | Async callback to create new items. An option for that is shown when the user types something that is not present as an item |
| onInputValueChange | (inputValue: string) => Promise<void> | - | An optional callback to filter items asynchronous - useful to fetch an API again |
| options | UseControllerProps<TFieldValues, TFieldName>["rules"] |
| The options that can be set for the registration of the field |
| placeholder | string | - | A hint for the expected value |
| ref | Ref<HTMLButtonElement> | - | the ref of the mutli select dropdown |
#Outside of a form
#Dropdown
| Name | Type | Default | Description | Controls |
|---|---|---|---|---|
| items * | Array<ISelectOption> | - | The selectable items | - |
| value * | ISelectOption | null | undefined | - | The value of the input field | - |
| dialogLabel | ReactNode | - | The title that is shown in the dialog option | - |
| disableDialogOption | boolean | - | If true, the dialog option is not shown on mobile and tablet viewports | |
| disabled | boolean | - | If true, the input field is disabled | |
| hasError | boolean | - | If true, turns the border red | |
| onBlur | FocusEventHandler<HTMLDropdownElement> | - | Callback the field is blurred | - |
| onChange | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes | - |
| onMenuClose | () => void | - | Callback when the menu closes | - |
| onMenuOpen | () => void | - | Callback when the menu opens | - |
| onSelect | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes | - |
| placeholder | string | - | A hint for the expected value |
#Autocomplete Dropdown
| Name | Type | Default | Description | Controls |
|---|---|---|---|---|
| items * | Array<ISelectOption> | - | The selectable items | - |
| value * | ISelectOption | null | undefined | - | The value of the input field | - |
| clearable | boolean | - | If a selected item can be cleared again, default false | |
| createNewValueMessage | string | - | The label that is shown above the creatable option | |
| disabled | boolean | - | If true, the input field is disabled | |
| hasError | boolean | - | If true, turns the border red | |
| id | string | - | The id of the input field | |
| name | string | - | The name of the input field | |
| noItemsMessage | string | - | The message that will show when there are no results left after filtering | |
| onBlur | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the input field is blurred | - |
| onChange | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes and when input changes | - |
| onCreateItem | (inputValue: string) => Promise<ISelectOption | undefined | void> | - | Async callback to create new items. An option for that is shown when the user types something that is not present as an item | - |
| onInputValueChange | (inputValue: string) => Promise<void> | - | An optional callback to filter items asynchronous - useful to fetch an API again | - |
| onMenuClose | () => void | - | Callback when the menu closes | - |
| onMenuOpen | () => void | - | Callback when the menu opens | - |
| onSelect | ChangeEventHandler<HTMLDropdownElement> | - | Callback when the selected item changes | - |
| placeholder | string | - | A hint for the expected value | |
| ref | Ref<HTMLButtonElement> | - | Ref of the dropdown | - |
#Multiselect Dropdown
| Name | Type | Default | Description | Controls |
|---|---|---|---|---|
| items * | Array<ISelectOption> | - | The selectable items | - |
| value * | Array<ISelectOption> | null | undefined | - | The value of the mutli select dropdown | - |
| createNewValueMessage | string | - | The label that is shown above the creatable option | |
| disabled | boolean | - | If true, the input field is disabled | |
| hasError | boolean | - | If true, turns the border red | |
| itemToString | (item: ISelectOption,null) => string |
| Parse function to convert the selected into into a string to show inside the input field | - |
| noItemsMessage | string | - | The message that will show when there are no results left after filtering | |
| noOptionsMessage | string | - | The message that will show when all items have been selected | |
| onBlur | ChangeEventHandler<HTMLMultiSelectDropdownElement> | - | Callback the input field is blurred | - |
| onChange | ChangeEventHandler<HTMLMultiSelectDropdownElement> | - | Callback when the selected item changes and when input changes | - |
| onCreateItem | (inputValue: string) => Promise<ISelectOption | undefined | void> | - | Async callback to create new items. An option for that is shown when the user types something that is not present as an item | - |
| onInputValueChange | (inputValue: string) => Promise<void> | - | An optional callback to filter items asynchronous - useful to fetch an API again | - |
| placeholder | string | - | A hint for the expected value | |
| ref | Ref<HTMLButtonElement> | - | the ref of the mutli select dropdown | - |
#Colors
- Token
CHEVRON#000d#fffb#000d#fffbCHEVRON_DISABLED#0004#fff4#0004#fff4CHEVRON_ERROR#000d#fffb#000d#fffbCHEVRON_FILLED#000d#fffb#000d#fffbFIELD_BACKGROUND#fff#111#fff#111FIELD_BACKGROUND_DISABLED#0000#fff1#0000#fff1FIELD_BACKGROUND_ERROR#fff#111#fff#111FIELD_BACKGROUND_FILLED#fff#111#fff#111FIELD_BACKGROUND_FOCUS#fff#111#fff#111FIELD_BORDER#bbb#fff4#bbb#fff4FIELD_BORDER_DISABLED#0001#fff1#0001#fff1FIELD_BORDER_ERROR#f75#f75#e02#f55FIELD_BORDER_FILLED#555#fff#059#fffFIELD_BORDER_FOCUS#bbb#fff4#bbb#fff4HELP_TEXT#0009#fffb#0009#fffbHELP_TEXT_DISABLED#0009#fffb#0009#fffbHELP_TEXT_ERROR#c42#f75#e02#f44HELP_TEXT_FILLED#0009#fffb#0009#fffbHELP_TEXT_FOCUS#0009#fffb#0009#fffbICONAFTER_BACKGROUND#000d#fffb#000d#fffbICONAFTER_BACKGROUND_DISABLED#0004#fff4#0004#fff4ICONAFTER_BACKGROUND_ERROR#000d#fffb#000d#fffbICONAFTER_BACKGROUND_FILLED#000d#fffb#000d#fffbICONAFTER_BACKGROUND_FOCUS#000d#fffb#000d#fffbICON_SHAPE#000d#fffb#000d#fffbICON_SHAPE_DISABLED#0004#fff4#0004#fff4ICON_SHAPE_ERROR#000d#fffb#000d#fffbICON_SHAPE_FILLED#000d#fffb#000d#fffbLABEL_TEXT#0009#fffb#0009#fffbLABEL_TEXT_DISABLED#0009#fffb#0009#fffbLABEL_TEXT_ERROR#0009#fffb#0009#fffbLABEL_TEXT_FILLED#0009#fffb#0009#fffbLABEL_TEXT_FOCUS#0009#fffb#0009#fffbVALUE_TEXT#0004#fff4#0004#fff4VALUE_TEXT_DISABLED#0004#fff4#0004#fff4VALUE_TEXT_ERROR#0004#fff4#0004#fff4VALUE_TEXT_FILLED#000#fff#000#fffVALUE_TEXT_FOCUS#0004#fff4#0004#fff4