Combobox
Combobox presents user with a searchable set of options and allows to select one of them. The type-ahead input makes it suited to long lists.
Always pair a combobox with a form field label so the control is named for everyone, including screen reader users.
Usage
Disabled
Combobox should be disabled, when user shouldn't be allowed to interact with it.
Individual options can be disabled too.
You can also provide a custom message when an option is disabled:
Loading
Mark combobox as loading, when options are fetched on the fly and are not yet available.
Invalid
Invalid combobox indicates that current value isn't what the system expects.
Clearable
Clearable combobox should be used when empty selection is acceptable.
Description
Options can display an additional descriptive text underneath the label.
Accessories
Options can display additional accessories view before and after the label. You can show an image using an image accessory. This is useful for showing logos when selecting sources or destinations, for example.
Additionally, using the showPlaceholderIcon prop will render a dotted circle in the placeholder state.
Icons can be accessories too.
Accessories can be shown on the left or right.
Search
The combobox supports filtering options based on the input value. This state is accessible via the onSearchUpdate prop. Any change that's typed in the input will call this function.
Icon button trigger
Use an icon button trigger to open the combobox with a compact icon button. The search input will appear inside the popover.
Component trigger
Use a component trigger to open the combobox with a custom React component that receives props to spread onto the trigger element (onClick, disabled, aria-*, etc.). The search input will appear inside the popover.
Rendering the input inside of the popover
Set renderInputInControl to false to render the combobox input inside of the popover.
Disable sorting and filtering
You can disable sorting and filtering internally by setting disableSortingAndFiltering to true. This could be helpful if the options are already sorted and filtered externally.
Creatable options
Combobox allows user to create a new option on the fly, when no suitable option exists.
For that, enable supportsCreatableOptions and set an onCreateOption function that will handle creation of options.
Options can be created asynchronously, but you need to handle loading state yourself via isLoading prop.
Custom objects
You don't have to create objects with label and value keys as shown in the examples above.
Combobox supports any objects, as long as you provide a label and value for each option via optionLabel and optionValue functions.
description may be replaced with the optionDescription function.
Groups
There's a version of Combobox called GroupedCombobox, that supports groups of options.
Medium font weight
Use fontWeight="medium" to emphasize the combobox when in views with many selects or in-line with text; it combines with any variant.
Alternative variant
Use the alternative variant to deemphasize the combobox when there are many selects.
Tertiary variant
Use the tertiary variant when using the select inside another component.
Size
The size prop impacts font-size and height. Default is set to md.
To set the width, use the width prop instead.
Popover width
When rendering smaller-width comboboxes, you may end up with options that are quite tall. To make the options easier to read, pass in a specific width for the popover using popoverWidth.
It is recommended to match widths, when possible.
Header
Show a header section within the combobox when the options are displayed.
Scrolling
When there are more options than fit in the popover, the popover becomes scrollable.
Guidelines
When to use
- When single selection is required.
- When user should be able to create new options, if needed.
- When selecting from user-generated data, where searching might come handy for long lists.
When not to use
- If the list is short and fixed, use a select instead.
Content
- Use sentence case.
Props
Combobox
| Name | Default | Description |
|---|---|---|
isDisabled | — | booleanDetermines if combobox is disabled. |
isLoading | — | booleanIndicates that options are being loaded. |
isInvalid | — | booleanIndicates that combobox is in invalid state. |
isClearable | false | booleanDetermines if selection can be cleared. |
isOptionDisabled | — | (option: Option) => boolean | stringFunction to determine whether an option should be disabled. If a string is returned, it will be used as a disabled message. |
emptyOptionsMessage | "No options" | stringText to show inside a dropdown when there are no options. |
disableSortingAndFiltering | false | booleanDetermines if the options should be sorted and filtered internally. |
optionDescription | — | (option: Option) => stringFunction to extract description from an option. If it's not provided, `description` field will be used as a label. |
optionValue | — | (option: Option) => OptionValueFunction to extract value from an option. If it's not provided, `value` field will be used as a value. |
placeholder | — | stringText to show inside combobox when no option is selected. |
removePortal | false | booleanDetermines if the select dropdown should be rendered in a portal. |
showPlaceholderIcon | false | booleanDetermines if the placeholder icon should be shown. Only available when optionAccessory is defined. |
size | "md" | "sm" | "md" | "lg"Combobox height. |
value | — | OptionValue | undefinedSelected option. |
variant | "default" | "default" | "alternative" | "tertiary"Determines the appearance of the combobox. |
fontWeight | "normal" | "normal" | "medium"Determines the font weight of the value and placeholder text. |
onChange | — | (value: OptionValue | undefined) => voidCallback for when user selects a different option or clears the selection. |
onSearchUpdate | — | (inputValue: string) => voidCallback for when user changes the input value. |
comboboxRef | — | RefObject<HTMLInputElement>Reference to the combobox input element. |
headerLabel | — | stringShow a header label at the top when displaying the options. |
headerDescription | — | stringShow a header description at the top when displaying the options. |
isLazy | true | booleanDetermines if the popover content should be lazily rendered. When true, content is only rendered when the popover is opened for the first time. Note: Should be set to false when using icon trigger, or when renderInputInControl is false, to prevent scroll jumping on first open. |
supportsCreatableOptions | — | booleanDetermines if user is allowed to create a new option, if it's not present already. |
createOptionMessage | "Create "[input value]"" | (inputValue: string) => stringText to show inside dropdown when creating a new option. |
options | — | Option[]Available options. `Option` is a generic, so type of options will be inferred. |
optionLabel | — | (option: Option) => stringFunction to extract label from an option. If it's not provided, `label` field will be used as a label. |
optionAccessories | — | IconAccessoriesGetter<Option>Function to show accessories near the option label. |
trigger | { type: 'input' } | { | type?: "input"; | } | { | type: "component"; | component: (props: ComboboxTriggerComponentProps) => ReactNode; | } | { | type: "icon"; | icon: IconButtonProps["icon"]; | "aria-label": string; | shape?: IconButtonProps["shape"]; | }Configuration for the combobox trigger element. Controls whether the combobox is opened via an input field or icon button. |
popoverWidth | undefined | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg"The dropdown width. If not provided, the select width will be used. |
onCreateOption | — | (inputValue: string) => Promise<void> | voidCallback for creating a new option. It can be async. |
onClose | — | () => voidCallback for when user closes the select. |
onOpen | — | () => voidCallback for when user opens the select. |
valueLabel | — | (option: Option) => stringFunction to format a selected option's label. If not provided, `label` field will be used as a label. |
renderInputInControl | true | booleanDetermines if the input should be rendered in the control. Only applies when trigger.type is "input". |
width | "xs" | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "auto" | "fit-content" | "100%"Combobox width. |
GroupedCombobox
| Name | Default | Description |
|---|---|---|
isDisabled | — | booleanDetermines if combobox is disabled. |
isLoading | — | booleanIndicates that options are being loaded. |
isInvalid | — | booleanIndicates that combobox is in invalid state. |
isClearable | false | booleanDetermines if selection can be cleared. |
isOptionDisabled | — | (option: Option) => boolean | stringFunction to determine whether an option should be disabled. If a string is returned, it will be used as a disabled message. |
emptyOptionsMessage | "No options" | stringText to show inside a dropdown when there are no options. |
disableSortingAndFiltering | false | booleanDetermines if the options should be sorted and filtered internally. |
optionDescription | — | (option: Option) => stringFunction to extract description from an option. If it's not provided, `description` field will be used as a label. |
optionValue | — | (option: Option) => OptionValueFunction to extract value from an option. If it's not provided, `value` field will be used as a value. |
placeholder | — | stringText to show inside combobox when no option is selected. |
removePortal | false | booleanDetermines if the select dropdown should be rendered in a portal. |
showPlaceholderIcon | false | booleanDetermines if the placeholder icon should be shown. Only available when optionAccessory is defined. |
size | "md" | "sm" | "md" | "lg"Combobox height. |
value | — | OptionValue | undefinedSelected option. |
variant | "default" | "default" | "alternative" | "tertiary"Determines the appearance of the combobox. |
fontWeight | "normal" | "normal" | "medium"Determines the font weight of the value and placeholder text. |
onChange | — | (value: OptionValue | undefined) => voidCallback for when user selects a different option or clears the selection. |
onSearchUpdate | — | (inputValue: string) => voidCallback for when user changes the input value. |
comboboxRef | — | RefObject<HTMLInputElement>Reference to the combobox input element. |
isLazy | true | booleanDetermines if the popover content should be lazily rendered. When true, content is only rendered when the popover is opened for the first time. Note: Should be set to false when using icon trigger, or when renderInputInControl is false, to prevent scroll jumping on first open. |
optionGroups | — | Array<{
label: string;
options: Option[];
}>Available options. `Option` is a generic, so type of options will be inferred. |
optionLabel | — | (option: Option) => stringFunction to extract label from an option. If it's not provided, `label` field will be used as a label. |
optionAccessories | — | IconAccessoriesGetter<Option>Function to show an accessory view near the option label. |
trigger | { type: 'input' } | { | type?: "input"; | } | { | type: "component"; | component: (props: ComboboxTriggerComponentProps) => ReactNode; | } | { | type: "icon"; | icon: IconButtonProps["icon"]; | "aria-label": string; | shape?: IconButtonProps["shape"]; | }Configuration for the combobox trigger element. Controls whether the combobox is opened via an input field or icon button. |
popoverWidth | undefined | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg"The dropdown width. If not provided, the select width will be used. |
valueLabel | — | (option: Option) => stringFunction to format a selected option's label. If not provided, `label` field will be used as a label. |
renderInputInControl | true | booleanDetermines if the input should be rendered in the control. Only applies when trigger.type is "input". |
width | "xs" | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "auto" | "fit-content" | "100%"Combobox width. |