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-partattribute 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'
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 id="framework">
              <Combobox.ItemGroupLabel htmlFor="framework">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 { Combobox } from '@ark-ui/solid'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'
const Basic = () => {
  const items = ['React', 'Solid', 'Vue']
  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 id="framework">
              <Combobox.ItemGroupLabel for="framework">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 basicItems = ref(['React', 'Solid', '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="basicItems">
    <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 id="framework">
            <Combobox.ItemGroupLabel htmlFor="framework">Frameworks</Combobox.ItemGroupLabel>
            <Combobox.Item v-for="item in basicItems" :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'
const Advanced = () => {
  const items: Item[] = [
    { 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 id="framework">
              <Combobox.ItemGroupLabel htmlFor="framework">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 { Combobox } from '@ark-ui/solid'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'
const Advanced = () => {
  const items: Item[] = [
    { 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 id="framework">
              <Combobox.ItemGroupLabel for="framework">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 basicItems = ref(['React', 'Solid', '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">
    <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 id="framework">
            <Combobox.ItemGroupLabel htmlFor="framework">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>
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | |
| item | any | 
| Prop | Type | Default | 
|---|---|---|
| itemsThe options of the select | T[] | readonly T[] | |
| allowCustomValueWhether to allow custom values or free values in the input | boolean | |
| asChildRender as a different element type. | boolean | |
| autoFocusWhether to autofocus the input on mount | boolean | |
| closeOnSelectWhether to close the combobox when an item is selected. | boolean | |
| defaultValuethe initial value of the combobox | string[] | |
| dirThe document's text/writing direction. | 'ltr' | 'rtl' | "ltr" | 
| disabledWhether the combobox is disabled | boolean | |
| formThe associate form of the combobox. | string | |
| getRootNodeA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
| highlightedValueThe active item's id. Used to set the `aria-activedescendant` attribute | string | |
| idThe unique identifier of the machine. | string | |
| idsThe 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
}> | |
| inputBehaviorDefines 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' | |
| inputValueThe current value of the combobox's input | string | |
| invalidWhether the combobox is required | boolean | |
| isItemDisabledWhether the item is disabled | (item: T) => boolean | |
| itemToStringThe label of the item | (item: T) => string | |
| itemToValueThe value of the item | (item: T) => string | |
| lazyMountWhether to enable lazy mounting | boolean | false | 
| loopWhether to loop the keyboard navigation through the items | boolean | |
| multipleWhether to allow multiple selection | boolean | |
| nameThe `name` attribute of the combobox's input. Useful for form submission | string | |
| onExitCompleteFunction called when the animation ends in the closed state. | () => void | |
| onFocusOutsideFunction called when the focus is moved outside the component | (event: FocusOutsideEvent) => void | |
| onHighlightChangeFunction called when an item is highlighted using the pointer or keyboard navigation. | (details: HighlightChangeDetails<T>) => void | |
| onInputValueChangeFunction called when the input's value changes | (details: InputValueChangeDetails) => void | |
| onInteractOutsideFunction called when an interaction happens outside the component | (event: InteractOutsideEvent) => void | |
| onOpenChangeFunction called when the popup is opened | (details: OpenChangeDetails) => void | |
| onPointerDownOutsideFunction called when the pointer is pressed down outside the component | (event: PointerDownOutsideEvent) => void | |
| onValueChangeFunction called when a new item is selected | (details: ValueChangeDetails<T>) => void | |
| openOnClickWhether to open the combobox popup on initial click on the input | boolean | |
| placeholderThe placeholder text of the combobox's input | string | |
| positioningThe positioning options to dynamically position the menu | PositioningOptions | |
| presentWhether the node is present (controlled by the user) | boolean | |
| readOnlyWhether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | boolean | |
| selectionBehaviorThe 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' | |
| selectOnBlurWhether to select the higlighted item on interaction outside the combobox | boolean | |
| translationsSpecifies the localized strings that identifies the accessibility elements and their states | IntlTranslations | |
| unmountOnExitWhether to unmount on exit. | boolean | false | 
| valueThe keys of the selected items | string[] | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| id | string | |
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| htmlFor | string | |
| asChildRender as a different element type. | boolean | 
Previous
Color PickerNext
Context Menu