Ark Logo

Combobox

A single input field that combines the functionality of a select and input.

Anatomy

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.

Examples

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>
  )
}

Advanced Customization

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>
  )
}

TypeScript Caveats in Vue

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!

API Reference

Root

PropDefaultType
items
T[] | readonly T[]

The options of the select

allowCustomValue
boolean

Whether to allow typing custom values in the input

asChild
boolean

Render as a different element type.

autoFocus
boolean

Whether to autofocus the input on mount

closeOnSelect
boolean

Whether to close the combobox when an item is selected.

defaultOpen
boolean

The initial open state of the combobox when it is first rendered. Use when you do not need to control its open state.

defaultValue
string[]

The initial value of the combobox when it is first rendered. Use when you do not need to control the state of the combobox.

disabled
boolean

Whether the combobox is disabled

dismissable
boolean

Whether to register this combobox as a dismissable layer

form
string

The associate form of the combobox.

getSelectionValue
(details: SelectionValueDetails<T>) => string

Function to get the display value of the selected item

highlightedValue
string

The active item's id. Used to set the `aria-activedescendant` attribute

id
string

The unique identifier of the machine.

ids
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 }>

The ids of the elements in the combobox. Useful for composition.

inputBehavior
'none' | 'autohighlight' | 'autocomplete'

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

inputValue
string

The current value of the combobox's input

invalid
boolean

Whether the combobox is required

isItemDisabled
(item: T) => boolean

Whether the item is disabled

itemToString
(item: T) => string

The label of the item

itemToValue
(item: T) => string

The value of the item

lazyMountfalse
boolean

Whether to enable lazy mounting

loopFocus
boolean

Whether to loop the keyboard navigation through the items

multiple
boolean

Whether to allow multiple selection

name
string

The `name` attribute of the combobox's input. Useful for form submission

onExitComplete
() => void

Function called when the animation ends in the closed state.

onFocusOutside
(event: FocusOutsideEvent) => void

Function called when the focus is moved outside the component

onHighlightChange
(details: HighlightChangeDetails<T>) => void

Function called when an item is highlighted using the pointer or keyboard navigation.

onInputValueChange
(details: InputValueChangeDetails) => void

Function called when the input's value changes

onInteractOutside
(event: InteractOutsideEvent) => void

Function called when an interaction happens outside the component

onOpenChange
(details: OpenChangeDetails) => void

Function called when the popup is opened

onPointerDownOutside
(event: PointerDownOutsideEvent) => void

Function called when the pointer is pressed down outside the component

onValueChange
(details: ValueChangeDetails<T>) => void

Function called when a new item is selected

open
boolean

Whether the combobox is open

openOnChange
boolean | ((details: InputValueChangeDetails) => boolean)

Whether to show the combobox when the input value changes

openOnClick
boolean

Whether to open the combobox popup on initial click on the input

openOnKeyPress
boolean

Whether to open the combobox on arrow key press

placeholder
string

The placeholder text of the combobox's input

popup
'dialog' | 'listbox'

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

positioning
PositioningOptions

The positioning options to dynamically position the menu

present
boolean

Whether the node is present (controlled by the user)

readOnly
boolean

Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it

scrollToIndexFn
(details: ScrollToIndexDetails) => void

Function to scroll to a specific index

selectionBehavior
'replace' | 'clear' | 'preserve'

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

translations
IntlTranslations

Specifies the localized strings that identifies the accessibility elements and their states

unmountOnExitfalse
boolean

Whether to unmount on exit.

value
string[]

The keys of the selected items

ClearTrigger

PropDefaultType
asChild
boolean

Render as a different element type.

Content

PropDefaultType
asChild
boolean

Render as a different element type.

Control

PropDefaultType
asChild
boolean

Render as a different element type.

Input

PropDefaultType
asChild
boolean

Render as a different element type.

ItemGroupLabel

PropDefaultType
asChild
boolean

Render as a different element type.

ItemGroup

PropDefaultType
asChild
boolean

Render as a different element type.

ItemIndicator

PropDefaultType
asChild
boolean

Render as a different element type.

Item

PropDefaultType
asChild
boolean

Render as a different element type.

item
any

The item to render

persistFocus
boolean

Whether hovering outside should clear the highlighted state

ItemText

PropDefaultType
asChild
boolean

Render as a different element type.

Label

PropDefaultType
asChild
boolean

Render as a different element type.

Positioner

PropDefaultType
asChild
boolean

Render as a different element type.

Trigger

PropDefaultType
asChild
boolean

Render as a different element type.