Combobox
A single input field that combines the functionality of a select and input.
A single input field that combines the functionality of a select and input.
To set up the combobox correctly, you’ll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Learn how to use the Combobox
component in your project. Let’s take a look at
the most basic example
import { Combobox, Portal } from '@ark-ui/react'
export const Basic = () => {
const items = ['React', 'Solid', 'Vue']
return (
<Combobox.Root items={items} lazyMount unmountOnExit>
<Combobox.Label>Framework</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.Trigger>Open</Combobox.Trigger>
<Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
</Combobox.Control>
<Portal>
<Combobox.Positioner>
<Combobox.Content>
<Combobox.ItemGroup>
<Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
{items.map((item) => (
<Combobox.Item key={item} item={item}>
<Combobox.ItemText>{item}</Combobox.ItemText>
<Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
</Combobox.Item>
))}
</Combobox.ItemGroup>
</Combobox.Content>
</Combobox.Positioner>
</Portal>
</Combobox.Root>
)
}
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'
import { Combobox } from '@ark-ui/solid'
export const Basic = () => {
const items = ['React', 'Solid', 'Vue']
return (
<Combobox.Root items={items} multiple>
<Combobox.Label>Framework</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.Trigger>Open</Combobox.Trigger>
<Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
</Combobox.Control>
<Portal>
<Combobox.Positioner>
<Combobox.Content>
<Combobox.ItemGroup>
<Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
<For each={items}>
{(item) => (
<Combobox.Item item={item}>
<Combobox.ItemText>{item}</Combobox.ItemText>
<Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
</Combobox.Item>
)}
</For>
</Combobox.ItemGroup>
</Combobox.Content>
</Combobox.Positioner>
</Portal>
</Combobox.Root>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { Combobox } from '@ark-ui/vue'
const items = ref(['React', 'Solid', 'Vue'])
</script>
<template>
<Combobox.Root :items="items">
<Combobox.Label>Framework</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.Trigger>Open</Combobox.Trigger>
<Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
</Combobox.Control>
<Teleport to="body">
<Combobox.Positioner>
<Combobox.Content>
<Combobox.ItemGroup>
<Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
<Combobox.Item v-for="item in items" :key="item" :item="item">
<Combobox.ItemText>{{ item }}</Combobox.ItemText>
<Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
</Combobox.Item>
</Combobox.ItemGroup>
</Combobox.Content>
</Combobox.Positioner>
</Teleport>
</Combobox.Root>
</template>
Extended example that shows usage with complex item objects, including disabled state for certain options.
import { Combobox, Portal } from '@ark-ui/react'
export const Advanced = () => {
const items = [
{ label: 'React', value: 'react' },
{ label: 'Solid', value: 'solid' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte', disabled: true },
]
return (
<Combobox.Root items={items} multiple>
<Combobox.Label>Framework</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.Trigger>Open</Combobox.Trigger>
<Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
</Combobox.Control>
<Portal>
<Combobox.Positioner>
<Combobox.Content>
<Combobox.ItemGroup>
<Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
{items.map((item) => (
<Combobox.Item key={item.value} item={item}>
<Combobox.ItemText>{item.label}</Combobox.ItemText>
<Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
</Combobox.Item>
))}
</Combobox.ItemGroup>
</Combobox.Content>
</Combobox.Positioner>
</Portal>
</Combobox.Root>
)
}
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'
import { Combobox } from '@ark-ui/solid'
export const Advanced = () => {
const items = [
{ label: 'React', value: 'react' },
{ label: 'Solid', value: 'solid' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte', disabled: true },
]
return (
<Combobox.Root items={items}>
<Combobox.Label>Framework</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.Trigger>Open</Combobox.Trigger>
<Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
</Combobox.Control>
<Portal>
<Combobox.Positioner>
<Combobox.Content>
<Combobox.ItemGroup>
<Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
<For each={items}>
{(item) => (
<Combobox.Item item={item}>
<Combobox.ItemText>{item.label}</Combobox.ItemText>
<Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
</Combobox.Item>
)}
</For>
</Combobox.ItemGroup>
</Combobox.Content>
</Combobox.Positioner>
</Portal>
</Combobox.Root>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { Combobox } from '@ark-ui/vue'
const advancedItems = ref([
{ label: 'React', value: 'react' },
{ label: 'Solid', value: 'solid' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte', disabled: true },
])
</script>
<template>
<Combobox.Root :items="advancedItems" multiple>
<Combobox.Label>Framework</Combobox.Label>
<Combobox.Control>
<Combobox.Input />
<Combobox.Trigger>Open</Combobox.Trigger>
<Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
</Combobox.Control>
<Teleport to="body">
<Combobox.Positioner>
<Combobox.Content>
<Combobox.ItemGroup>
<Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
<Combobox.Item v-for="item in advancedItems" :key="item.value" :item="item">
<Combobox.ItemText>{{ item.label }}</Combobox.ItemText>
<Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
</Combobox.Item>
</Combobox.ItemGroup>
</Combobox.Content>
</Combobox.Positioner>
</Teleport>
</Combobox.Root>
</template>
Under the hood for React and Solid frameworks, we supply a complex prop type
with a generic so that the type of the items
prop matches the param type in
the function signatures for props such as the isItemDisabled
prop, say. (See
the api reference table below) Unfortunately, generic typing is not supported in
Vue for components that contain props with slots and/or emits. Therefore, you
will not expect updated typing in this way.
If you have a solution or a workaround to this problem, we would love the contribution and request that you open a Github idea discussion to let us know a PoC you have to share!
Prop | Type | Default |
---|---|---|
items The options of the select | T[] | readonly T[] | |
allowCustomValue Whether to allow typing custom values in the input | boolean | |
asChild Render as a different element type. | boolean | |
autoFocus Whether to autofocus the input on mount | boolean | |
closeOnSelect Whether to close the combobox when an item is selected. | boolean | |
defaultOpen The initial open state of the combobox when it is first rendered.
Use when you do not need to control its open state. | boolean | |
defaultValue The initial value of the combobox when it is first rendered.
Use when you do not need to control the state of the combobox. | string[] | |
disabled Whether the combobox is disabled | boolean | |
dismissable Whether to register this combobox as a dismissable layer | boolean | |
form The associate form of the combobox. | string | |
getSelectionValue Function to get the display value of the selected item | (details: SelectionValueDetails<T>) => string | |
highlightedValue The active item's id. Used to set the `aria-activedescendant` attribute | string | |
id The unique identifier of the machine. | string | |
ids The ids of the elements in the combobox. Useful for composition. | Partial<{
root: string
label: string
control: string
input: string
content: string
trigger: string
clearTrigger: string
item(id: string, index?: number | undefined): string
positioner: string
itemGroup(id: string | number): string
itemGroupLabel(id: string | number): string
}> | |
inputBehavior Defines the auto-completion behavior of the combobox.
- `autohighlight`: The first focused item is highlighted as the user types
- `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | 'none' | 'autohighlight' | 'autocomplete' | |
inputValue The current value of the combobox's input | string | |
invalid Whether the combobox is required | boolean | |
isItemDisabled Whether the item is disabled | (item: T) => boolean | |
itemToString The label of the item | (item: T) => string | |
itemToValue The value of the item | (item: T) => string | |
lazyMount Whether to enable lazy mounting | boolean | false |
loopFocus Whether to loop the keyboard navigation through the items | boolean | |
multiple Whether to allow multiple selection | boolean | |
name The `name` attribute of the combobox's input. Useful for form submission | string | |
onExitComplete Function called when the animation ends in the closed state. | () => void | |
onFocusOutside Function called when the focus is moved outside the component | (event: FocusOutsideEvent) => void | |
onHighlightChange Function called when an item is highlighted using the pointer
or keyboard navigation. | (details: HighlightChangeDetails<T>) => void | |
onInputValueChange Function called when the input's value changes | (details: InputValueChangeDetails) => void | |
onInteractOutside Function called when an interaction happens outside the component | (event: InteractOutsideEvent) => void | |
onOpenChange Function called when the popup is opened | (details: OpenChangeDetails) => void | |
onPointerDownOutside Function called when the pointer is pressed down outside the component | (event: PointerDownOutsideEvent) => void | |
onValueChange Function called when a new item is selected | (details: ValueChangeDetails<T>) => void | |
open Whether the combobox is open | boolean | |
openOnChange Whether to show the combobox when the input value changes | boolean | ((details: InputValueChangeDetails) => boolean) | |
openOnClick Whether to open the combobox popup on initial click on the input | boolean | |
openOnKeyPress Whether to open the combobox on arrow key press | boolean | |
placeholder The placeholder text of the combobox's input | string | |
popup The underling `aria-haspopup` attribute to use for the combobox
- `listbox`: The combobox has a listbox popup (default)
- `dialog`: The combobox has a dialog popup. Useful when in select only mode | 'dialog' | 'listbox' | |
positioning The positioning options to dynamically position the menu | PositioningOptions | |
present Whether the node is present (controlled by the user) | boolean | |
readOnly Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
but the user can still interact with it | boolean | |
scrollToIndexFn Function to scroll to a specific index | (details: ScrollToIndexDetails) => void | |
selectionBehavior The behavior of the combobox input when an item is selected
- `replace`: The selected item string is set as the input value
- `clear`: The input value is cleared
- `preserve`: The input value is preserved | 'replace' | 'clear' | 'preserve' | |
translations Specifies the localized strings that identifies the accessibility elements and their states | IntlTranslations | |
unmountOnExit Whether to unmount on exit. | boolean | false |
value The keys of the selected items | string[] |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean | |
item The item to render | any | |
persistFocus Whether hovering outside should clear the highlighted state | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Previous
Color PickerNext
Date Picker