# Combobox

URL: https://ark-ui.com/docs/components/combobox
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/combobox.mdx

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

---

<ComponentPreview id="Combobox" />

## 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.

<Anatomy id="combobox" />

## Examples

Learn how to use the `Combobox` component in your project. Let's take a look at the most basic example

**Example: basic**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'

export const Basic = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
    filter: contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection} onInputValueChange={handleInputChange}>
      <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>
              {collection.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>
  )
}

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

const initialItems = ['React', 'Solid', 'Vue', 'Svelte']

export const Basic = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: filterFn().contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection()} onInputValueChange={handleInputChange}>
      <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={collection().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>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { useFilter } from '@ark-ui/vue/locale'

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
  filter: filters.value.contains,
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  filter(details.inputValue)
}
</script>

<template>
  <Combobox.Root :collection="collection" @input-value-change="handleInputChange">
    <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 collection.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>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { useFilter } from '@ark-ui/svelte/locale'
  import { Portal } from '@ark-ui/svelte/portal'

  const filters = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
    filter(itemString, filterText) {
      return filters().contains(itemString, filterText)
    },
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
</script>

<Combobox.Root {collection} onInputValueChange={handleInputChange}>
  <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>
          {#each collection().items as item (item)}
            <Combobox.Item {item}>
              <Combobox.ItemText>{item}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          {/each}
        </Combobox.ItemGroup>
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.Root>

```

### Grouping

To group related combobox items, use the `groupBy` prop on the collection and `collection.group()` to iterate the
groups.

**Example: grouping**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'

export const Grouping = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: contains,
    groupBy: (item) => item.type,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection} onInputValueChange={handleInputChange}>
      <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>
            {collection.group().map(([type, group]) => (
              <Combobox.ItemGroup key={type}>
                <Combobox.ItemGroupLabel>{type}</Combobox.ItemGroupLabel>
                {group.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>
  )
}

const initialItems = [
  { label: 'React', value: 'react', type: 'JS' },
  { label: 'Solid', value: 'solid', type: 'JS' },
  { label: 'Vue', value: 'vue', type: 'JS' },
  { label: 'Svelte', value: 'svelte', type: 'JS' },
  { label: 'Panda', value: 'panda', type: 'CSS' },
  { label: 'Tailwind', value: 'tailwind', type: 'CSS' },
]

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

export const Grouping = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: filterFn().contains,
    groupBy: (item) => item.type,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
  return (
    <Combobox.Root collection={collection()} onInputValueChange={handleInputChange}>
      <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>
            <For each={collection().group()}>
              {([type, group]) => (
                <Combobox.ItemGroup>
                  <Combobox.ItemGroupLabel>{type}</Combobox.ItemGroupLabel>
                  <For each={group}>
                    {(item) => (
                      <Combobox.Item item={item}>
                        <Combobox.ItemText>{item.label}</Combobox.ItemText>
                        <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                      </Combobox.Item>
                    )}
                  </For>
                </Combobox.ItemGroup>
              )}
            </For>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

const initialItems = [
  { label: 'React', value: 'react', type: 'JS' },
  { label: 'Solid', value: 'solid', type: 'JS' },
  { label: 'Vue', value: 'vue', type: 'JS' },
  { label: 'Panda', value: 'panda', type: 'CSS' },
  { label: 'Tailwind', value: 'tailwind', type: 'CSS' },
]

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { useFilter } from '@ark-ui/vue/locale'

const initialItems = [
  { label: 'React', value: 'react', type: 'JS' },
  { label: 'Solid', value: 'solid', type: 'JS' },
  { label: 'Vue', value: 'vue', type: 'JS' },
  { label: 'Panda', value: 'panda', type: 'CSS' },
  { label: 'Tailwind', value: 'tailwind', type: 'CSS' },
]

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems,
  groupBy: (item) => item.type,
  filter: filters.value.contains,
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  filter(details.inputValue)
}
</script>

<template>
  <Combobox.Root :collection="collection" @input-value-change="handleInputChange">
    <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 :key="type" v-for="[type, group] in collection.group()">
            <Combobox.ItemGroupLabel>{{ type }}</Combobox.ItemGroupLabel>
            <Combobox.Item v-for="item in group" :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>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox } from '@ark-ui/svelte/combobox'
  import { useListCollection } from '@ark-ui/svelte/collection'
  import { useFilter } from '@ark-ui/svelte/locale'
  import { Portal } from '@ark-ui/svelte/portal'

  const filters = useFilter({ sensitivity: 'base' })

  const initialItems = [
    { label: 'React', value: 'react', type: 'JS' },
    { label: 'Solid', value: 'solid', type: 'JS' },
    { label: 'Vue', value: 'vue', type: 'JS' },
    { label: 'Svelte', value: 'svelte', type: 'JS' },
    { label: 'Panda', value: 'panda', type: 'CSS' },
    { label: 'Tailwind', value: 'tailwind', type: 'CSS' },
  ]

  const { collection, filter } = useListCollection({
    initialItems,
    filter(itemString, filterText) {
      return filters().contains(itemString, filterText)
    },
    groupBy: (item) => item.type,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
</script>

<div>
  <Combobox.Root {collection} onInputValueChange={handleInputChange}>
    <Combobox.Label>Framework</Combobox.Label>
    <Combobox.Control>
      <Combobox.Input placeholder="Select framework..." />
      <Combobox.Trigger>Open</Combobox.Trigger>
      <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
    </Combobox.Control>
    <Portal>
      <Combobox.Positioner>
        <Combobox.Content>
          {#each collection().group() as [type, group]}
            <Combobox.ItemGroup>
              <Combobox.ItemGroupLabel>{type}</Combobox.ItemGroupLabel>
              {#each group as item}
                <Combobox.Item {item}>
                  <Combobox.ItemText>{item.label}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </Combobox.Item>
              {/each}
            </Combobox.ItemGroup>
          {/each}
        </Combobox.Content>
      </Combobox.Positioner>
    </Portal>
  </Combobox.Root>
</div>

```

### Field

The `Field` component helps manage form-related state and accessibility attributes of a combobox. It includes handling
ARIA labels, helper text, and error text to ensure proper accessibility.

**Example: with-field**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { Field } from '@ark-ui/react/field'
import { useFilter } from '@ark-ui/react/locale'

export const WithField = (props: Field.RootProps) => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Field.Root {...props}>
      <Combobox.Root collection={collection} onInputValueChange={handleInputChange}>
        <Combobox.Label>Label</Combobox.Label>
        <Combobox.Control>
          <Combobox.Input />
          <Combobox.Trigger>Open</Combobox.Trigger>
          <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
        </Combobox.Control>
        <Combobox.Positioner>
          <Combobox.Content>
            {collection.items.map((item) => (
              <Combobox.Item key={item} item={item}>
                <Combobox.ItemText>{item}</Combobox.ItemText>
                <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
              </Combobox.Item>
            ))}
          </Combobox.Content>
        </Combobox.Positioner>
      </Combobox.Root>
      <Field.HelperText>Additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}

const initialItems = ['React', 'Solid', 'Vue', 'Svelte']

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { Field } from '@ark-ui/solid/field'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'

const initialItems = ['React', 'Solid', 'Vue', 'Svelte']

export const WithField = (props: Field.RootProps) => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: filterFn().contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Field.Root {...props}>
      <Combobox.Root collection={collection()} onInputValueChange={handleInputChange}>
        <Combobox.Label>Label</Combobox.Label>
        <Combobox.Control>
          <Combobox.Input />
          <Combobox.Trigger>Open</Combobox.Trigger>
          <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
        </Combobox.Control>
        <Combobox.Positioner>
          <Combobox.Content>
            <For each={collection().items}>
              {(item) => (
                <Combobox.Item item={item}>
                  <Combobox.ItemText>{item}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </Combobox.Item>
              )}
            </For>
          </Combobox.Content>
        </Combobox.Positioner>
      </Combobox.Root>
      <Field.HelperText>Additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { Field, type FieldRootProps } from '@ark-ui/vue/field'
import { useFilter } from '@ark-ui/vue/locale'

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
  filter: filters.value.contains,
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  filter(details.inputValue)
}

const props = defineProps<FieldRootProps>()
</script>

<template>
  <Field.Root v-bind="props">
    <Combobox.Root :collection="collection" @input-value-change="handleInputChange">
      <Combobox.Label>Label</Combobox.Label>
      <Combobox.Control>
        <Combobox.Input />
        <Combobox.Trigger>Open</Combobox.Trigger>
        <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
      </Combobox.Control>
      <Combobox.Positioner>
        <Combobox.Content>
          <Combobox.ItemGroup>
            <Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
            <Combobox.Item v-for="item in collection.items" :key="item" :item="item">
              <Combobox.ItemText>{{ item }}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          </Combobox.ItemGroup>
        </Combobox.Content>
      </Combobox.Positioner>
    </Combobox.Root>
    <Field.HelperText>Additional Info</Field.HelperText>
    <Field.ErrorText>Error Info</Field.ErrorText>
  </Field.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { Field } from '@ark-ui/svelte/field'
  import { useFilter } from '@ark-ui/svelte/locale'

  const filters = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
    filter(itemString, filterText) {
      return filters().contains(itemString, filterText)
    },
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
</script>

<Field.Root>
  <Combobox.Root {collection} onInputValueChange={handleInputChange}>
    <Combobox.Label>Framework</Combobox.Label>
    <Combobox.Control>
      <Combobox.Input />
      <Combobox.Trigger>Open</Combobox.Trigger>
      <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
    </Combobox.Control>
    <Combobox.Positioner>
      <Combobox.Content>
        {#each collection().items as item (item)}
          <Combobox.Item {item}>
            <Combobox.ItemText>{item}</Combobox.ItemText>
            <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
          </Combobox.Item>
        {/each}
      </Combobox.Content>
    </Combobox.Positioner>
  </Combobox.Root>
  <Field.HelperText>Additional Info</Field.HelperText>
  <Field.ErrorText>Error Info</Field.ErrorText>
</Field.Root>

```

### Root Provider

Use the `useCombobox` hook to create the combobox store and pass it to the `Combobox.RootProvider` component. This
allows you to have maximum control over the combobox programmatically.

**Example: root-provider**

#### React

```tsx
import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'

const initialItems = ['React', 'Solid', 'Vue', 'Svelte']

export const RootProvider = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: contains,
  })

  const combobox = useCombobox({
    collection,
    onInputValueChange(details) {
      filter(details.inputValue)
    },
  })

  return (
    <>
      <button onClick={() => combobox.focus()}>Focus</button>

      <Combobox.RootProvider value={combobox}>
        <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>
                {collection.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.RootProvider>
    </>
  )
}

```

#### Solid

```tsx
import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

export const RootProvider = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
    filter: filterFn().contains,
  })

  const combobox = useCombobox({
    get collection() {
      return collection()
    },
    onInputValueChange(details) {
      filter(details.inputValue)
    },
  })

  return (
    <>
      <button onClick={() => combobox().focus()}>Focus</button>

      <Combobox.RootProvider value={combobox}>
        <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={collection().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.RootProvider>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Combobox, useCombobox, useListCollection } from '@ark-ui/vue/combobox'
import { useFilter } from '@ark-ui/vue/locale'

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
  filter: filters.value.contains,
})

const combobox = useCombobox({
  get collection() {
    return collection.value
  },
  onInputValueChange(details) {
    filter(details.inputValue)
  },
})
</script>

<template>
  <button @click="combobox.focus()">Focus</button>

  <Combobox.RootProvider :value="combobox">
    <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 collection.items" :key="item" :item="item">
              <Combobox.ItemText>{{ item }}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          </Combobox.ItemGroup>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Combobox, useCombobox } from '@ark-ui/svelte/combobox'
  import { Portal } from '@ark-ui/svelte/portal'
  import { createListCollection } from '@ark-ui/svelte/collection'

  const collection = createListCollection({
    items: ['React', 'Solid', 'Svelte', 'Vue'],
  })

  const id = $props.id()
  const combobox = useCombobox({ collection, id })
</script>

<Combobox.RootProvider value={combobox}>
  <Combobox.Label>Framework</Combobox.Label>
  <Combobox.Control>
    <Combobox.Input placeholder="Select a Framework" />
    <Combobox.Trigger>Open</Combobox.Trigger>
    <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
  </Combobox.Control>
  <Portal>
    <Combobox.Positioner>
      <Combobox.Content>
        <Combobox.List>
          {#each collection.items as item}
            <Combobox.Item {item}>
              <Combobox.ItemText>{item}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          {/each}
        </Combobox.List>
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.RootProvider>

```

> If you're using the `Combobox.RootProvider` component, you don't need to use the `Combobox.Root` component.

### Links

Use the `asChild` prop to render the combobox items as links.

**Example: links**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'

export const Links = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection} onInputValueChange={handleInputChange} selectionBehavior="preserve">
      <Combobox.Label>Framework</Combobox.Label>
      <Combobox.Control>
        <Combobox.Input />
      </Combobox.Control>
      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            {collection.items.map((item) => (
              <Combobox.Item key={item.value} item={item} asChild>
                <a href={item.href}>
                  <Combobox.ItemText>{item.label}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </a>
              </Combobox.Item>
            ))}
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

const initialItems = [
  { label: 'React', href: 'https://react.dev', value: 'react' },
  { label: 'Solid', href: 'https://solidjs.com', value: 'solid' },
  { label: 'Vue', href: 'https://vuejs.org', value: 'vue' },
  { label: 'Svelte', href: 'https://svelte.dev', value: 'svelte' },
  { label: 'Angular', href: 'https://angular.io', value: 'angular' },
  { label: 'Ember', href: 'https://emberjs.com', value: 'ember' },
  { label: 'Backbone', href: 'https://backbonejs.org', value: 'backbone' },
  { label: 'Polymer', href: 'https://polymer-project.org', value: 'polymer' },
  { label: 'Preact', href: 'https://preactjs.com', value: 'preact' },
  { label: 'Alpine', href: 'https://alpinejs.dev', value: 'alpine' },
  { label: 'Lit', href: 'https://lit.dev', value: 'lit' },
  { label: 'Qwik', href: 'https://qwik.builder.io', value: 'qwik' },
  { label: 'Astro', href: 'https://astro.build', value: 'astro' },
]

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

export const Links = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: filterFn().contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection()} onInputValueChange={handleInputChange} selectionBehavior="preserve">
      <Combobox.Label>Framework</Combobox.Label>
      <Combobox.Control>
        <Combobox.Input />
      </Combobox.Control>
      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            <For each={collection().items}>
              {(item) => (
                <Combobox.Item item={item} asChild={(props) => <a href={item.href} {...props} />}>
                  <Combobox.ItemText>{item.label}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </Combobox.Item>
              )}
            </For>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

const initialItems = [
  { label: 'React', href: 'https://react.dev', value: 'react' },
  { label: 'Solid', href: 'https://solidjs.com', value: 'solid' },
  { label: 'Vue', href: 'https://vuejs.org', value: 'vue' },
  { label: 'Svelte', href: 'https://svelte.dev', value: 'svelte' },
  { label: 'Angular', href: 'https://angular.io', value: 'angular' },
  { label: 'Ember', href: 'https://emberjs.com', value: 'ember' },
  { label: 'Backbone', href: 'https://backbonejs.org', value: 'backbone' },
  { label: 'Polymer', href: 'https://polymer-project.org', value: 'polymer' },
  { label: 'Preact', href: 'https://preactjs.com', value: 'preact' },
  { label: 'Alpine', href: 'https://alpinejs.dev', value: 'alpine' },
  { label: 'Lit', href: 'https://lit.dev', value: 'lit' },
  { label: 'Qwik', href: 'https://qwik.builder.io', value: 'qwik' },
  { label: 'Astro', href: 'https://astro.build', value: 'astro' },
]

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { useFilter } from '@ark-ui/vue/locale'

const initialItems = [
  { label: 'React', href: 'https://react.dev', value: 'react' },
  { label: 'Solid', href: 'https://solidjs.com', value: 'solid' },
  { label: 'Vue', href: 'https://vuejs.org', value: 'vue' },
  { label: 'Svelte', href: 'https://svelte.dev', value: 'svelte' },
  { label: 'Angular', href: 'https://angular.io', value: 'angular' },
  { label: 'Ember', href: 'https://emberjs.com', value: 'ember' },
  { label: 'Backbone', href: 'https://backbonejs.org', value: 'backbone' },
  { label: 'Polymer', href: 'https://polymer-project.org', value: 'polymer' },
  { label: 'Preact', href: 'https://preactjs.com', value: 'preact' },
  { label: 'Alpine', href: 'https://alpinejs.dev', value: 'alpine' },
  { label: 'Lit', href: 'https://lit.dev', value: 'lit' },
  { label: 'Qwik', href: 'https://qwik.builder.io', value: 'qwik' },
  { label: 'Astro', href: 'https://astro.build', value: 'astro' },
]

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems,
  filter: filters.value.contains,
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  filter(details.inputValue)
}
</script>

<template>
  <Combobox.Root :collection="collection" @input-value-change="handleInputChange" selection-behavior="preserve">
    <Combobox.Label>Framework</Combobox.Label>
    <Combobox.Control>
      <Combobox.Input />
    </Combobox.Control>
    <Teleport to="body">
      <Combobox.Positioner>
        <Combobox.Content>
          <Combobox.Item v-for="item in collection.items" :key="item.value" :item="item" :as-child="true">
            <a :href="item.href">
              <Combobox.ItemText>{{ item.label }}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </a>
          </Combobox.Item>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox } from '@ark-ui/svelte/combobox'
  import { useListCollection } from '@ark-ui/svelte/collection'
  import { useFilter } from '@ark-ui/svelte/locale'
  import { Portal } from '@ark-ui/svelte/portal'

  const filters = useFilter({ sensitivity: 'base' })

  const initialItems = [
    { label: 'React', href: 'https://react.dev', value: 'react' },
    { label: 'Solid', href: 'https://solidjs.com', value: 'solid' },
    { label: 'Vue', href: 'https://vuejs.org', value: 'vue' },
    { label: 'Svelte', href: 'https://svelte.dev', value: 'svelte' },
    { label: 'Angular', href: 'https://angular.io', value: 'angular' },
    { label: 'Ember', href: 'https://emberjs.com', value: 'ember' },
    { label: 'Backbone', href: 'https://backbonejs.org', value: 'backbone' },
    { label: 'Polymer', href: 'https://polymer-project.org', value: 'polymer' },
    { label: 'Preact', href: 'https://preactjs.com', value: 'preact' },
    { label: 'Alpine', href: 'https://alpinejs.dev', value: 'alpine' },
    { label: 'Lit', href: 'https://lit.dev', value: 'lit' },
    { label: 'Qwik', href: 'https://qwik.builder.io', value: 'qwik' },
    { label: 'Astro', href: 'https://astro.build', value: 'astro' },
  ]

  const { collection, filter } = useListCollection({
    initialItems,
    filter(itemString, filterText) {
      return filters().contains(itemString, filterText)
    },
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
</script>

<div>
  <Combobox.Root {collection} onInputValueChange={handleInputChange} selectionBehavior="preserve">
    <Combobox.Label>Framework</Combobox.Label>
    <Combobox.Control>
      <Combobox.Input />
    </Combobox.Control>
    <Portal>
      <Combobox.Positioner>
        <Combobox.Content>
          {#each collection().items as item (item.value)}
            <Combobox.Item {item}>
              {#snippet asChild(props)}
                <a {...props()} href={item.href}>
                  <Combobox.ItemText>{item.label}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </a>
              {/snippet}
            </Combobox.Item>
          {/each}
        </Combobox.Content>
      </Combobox.Positioner>
    </Portal>
  </Combobox.Root>
</div>

```

### Rehydrate Value

In some cases, where a combobox has a `defaultValue` or `value` but the `collection` is not loaded yet, here's how to
rehydrate the value and populate the input value.

**Example: rehydrate-value**

#### React

```tsx
import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/react/combobox'
import { Portal } from '@ark-ui/react/portal'
import { useRef, useState } from 'react'
import { useAsync } from 'react-use'

// The meat of the example is here.
// It rehydrates the input value when the combobox is mounted.
function ComboboxRehydrateValue() {
  const combobox = useComboboxContext()
  const hydrated = useRef(false)
  if (combobox.value.length && combobox.collection.size && !hydrated.current) {
    combobox.syncSelectedItems()
    hydrated.current = true
  }
  return null
}

export const RehydrateValue = () => {
  const [inputValue, setInputValue] = useState('')

  const { collection, set } = useListCollection<Character>({
    initialItems: [],
    itemToString: (item) => item.name,
    itemToValue: (item) => item.name,
  })

  const combobox = useCombobox({
    collection,
    defaultValue: ['C-3PO'],
    placeholder: 'Example: Dexter',
    inputValue,
    onInputValueChange: (e) => setInputValue(e.inputValue),
  })

  const state = useAsync(async () => {
    const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue}`)
    const data = await response.json()
    set(data.results)
  }, [inputValue, set])

  return (
    <Combobox.RootProvider value={combobox}>
      <Combobox.Label>Search Star Wars Characters</Combobox.Label>
      <ComboboxRehydrateValue />
      <Combobox.Control>
        <Combobox.Input placeholder="Type to search" />
      </Combobox.Control>

      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            {state.loading ? (
              <span>Loading...</span>
            ) : state.error ? (
              <span>{state.error.message}</span>
            ) : (
              collection.items.map((item) => (
                <Combobox.Item key={item.name} item={item}>
                  <span>
                    {item.name} - {item.height}cm / {item.mass}kg
                  </span>
                  <Combobox.ItemIndicator />
                </Combobox.Item>
              ))
            )}
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.RootProvider>
  )
}

interface Character {
  name: string
  height: string
  mass: string
  created: string
  edited: string
  url: string
}

```

#### Solid

```tsx
import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/solid/combobox'
import { For, createEffect, createRenderEffect, createSignal, on } from 'solid-js'
import { Portal } from 'solid-js/web'
import { useAsync } from './use-async'

// The meat of the example is here.
// It rehydrates the input value when the combobox is mounted.
function ComboboxRehydrateValue() {
  const combobox = useComboboxContext()
  let hydrated = false

  createRenderEffect(() => {
    if (combobox().value.length && combobox().collection.size && !hydrated) {
      combobox().syncSelectedItems()
      hydrated = true
    }
  })

  return null
}

export const RehydrateValue = () => {
  const [inputValue, setInputValue] = createSignal('')

  const { collection, set } = useListCollection<Character>({
    initialItems: [],
    itemToString: (item) => item.name,
    itemToValue: (item) => item.name,
  })

  const combobox = useCombobox(() => ({
    collection: collection(),
    defaultValue: ['C-3PO'],
    placeholder: 'Example: Dexter',
    inputValue: inputValue(),
    onInputValueChange: (e) => setInputValue(e.inputValue),
  }))

  const state = useAsync(async (signal) => {
    const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue()}`, { signal })
    const data = await response.json()
    set(data.results)
  })

  createEffect(on(inputValue, () => state.load()))

  return (
    <Combobox.RootProvider value={combobox}>
      <Combobox.Label>Search Star Wars Characters</Combobox.Label>
      <ComboboxRehydrateValue />
      <Combobox.Control>
        <Combobox.Input placeholder="Type to search" />
      </Combobox.Control>

      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            {state.loading() ? (
              <span>Loading...</span>
            ) : state.error() ? (
              <span>{state.error()?.message}</span>
            ) : (
              <For each={collection().items}>
                {(item) => (
                  <Combobox.Item item={item}>
                    <span>
                      {item.name} - {item.height}cm / {item.mass}kg
                    </span>
                    <Combobox.ItemIndicator />
                  </Combobox.Item>
                )}
              </For>
            )}
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.RootProvider>
  )
}

interface Character {
  name: string
  height: string
  mass: string
  created: string
  edited: string
  url: string
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, type UseComboboxProps, useCombobox, useListCollection } from '@ark-ui/vue/combobox'
import { computed, ref, watch, watchEffect } from 'vue'
import { useAsync } from './use-async'

interface Character {
  name: string
  height: string
  mass: string
  created: string
  edited: string
  url: string
}

const inputValue = ref('')

const { collection, set } = useListCollection<Character>({
  initialItems: [],
  itemToString: (item) => item.name,
  itemToValue: (item) => item.name,
})

const combobox = useCombobox(
  computed<UseComboboxProps<Character>>(() => ({
    collection: collection.value,
    defaultValue: ['C-3PO'],
    placeholder: 'Example: Dexter',
    inputValue: inputValue.value,
    onInputValueChange: (e) => {
      inputValue.value = e.inputValue
    },
  })),
)

const fetchData = computed(() => async (signal: AbortSignal | null) => {
  const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue.value}`, { signal })
  const data = await response.json()
  set(data.results)
})

const state = useAsync(fetchData)

watch(inputValue, () => {
  state.load()
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  inputValue.value = details.inputValue
}

// The meat of the example is here.
// It rehydrates the input value when the combobox is mounted.
let hydrated = false
watchEffect(() => {
  if (combobox.value.value.length && combobox.value.collection.size && !hydrated) {
    combobox.value.syncSelectedItems()
    hydrated = true
  }
})
</script>

<template>
  <Combobox.Root
    :collection="collection"
    :default-value="['C-3PO']"
    placeholder="Example: Dexter"
    :input-value="inputValue"
    @input-value-change="handleInputChange"
  >
    <Combobox.Label>Search Star Wars Characters</Combobox.Label>
    <Combobox.Control>
      <Combobox.Input placeholder="Type to search" />
    </Combobox.Control>

    <Teleport to="body">
      <Combobox.Positioner>
        <Combobox.Content>
          <span v-if="state.loading.value">Loading...</span>
          <span v-else-if="state.error.value">{{ state.error.value.message }}</span>
          <template v-else>
            <Combobox.Item v-for="item in collection.items" :key="item.name" :item="item">
              <span>{{ item.name }} - {{ item.height }}cm / {{ item.mass }}kg</span>
              <Combobox.ItemIndicator />
            </Combobox.Item>
          </template>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Combobox, useCombobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { Portal } from '@ark-ui/svelte/portal'
  import { useAsync } from './use-async.svelte'

  interface Character {
    name: string
    height: string
    mass: string
    created: string
    edited: string
    url: string
  }

  const { collection, set } = useListCollection<Character>({
    initialItems: [],
    itemToString: (item) => item.name,
    itemToValue: (item) => item.name,
  })

  let inputValue = $state('')

  const combobox = useCombobox(() => ({
    collection: collection(),
    defaultValue: ['C-3PO'],
    placeholder: 'Example: Dexter',
    inputValue,
    onInputValueChange: (e) => {
      inputValue = e.inputValue
    },
  }))

  const fetchData = $derived(async (signal: AbortSignal | null) => {
    const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue}`, { signal })
    const data = await response.json()
    set(data.results)
  })

  const _state = useAsync(() => fetchData)

  $effect(() => {
    void inputValue
    void _state.load()
  })

  // The meat of the example is here.
  // It rehydrates the input value when the combobox is mounted.
  let hydrated = false
  $effect.pre(() => {
    if (combobox().value.length && combobox().collection.size && !hydrated) {
      combobox().syncSelectedItems()
      hydrated = true
    }
  })
</script>

<Combobox.RootProvider value={combobox}>
  <Combobox.Label>Search Star Wars Characters</Combobox.Label>
  <Combobox.Control>
    <Combobox.Input placeholder="Type to search" />
  </Combobox.Control>

  <Portal>
    <Combobox.Positioner>
      <Combobox.Content>
        {#if _state.loading()}
          <span>Loading...</span>
        {:else if _state.error()}
          <span>{_state.error()?.message}</span>
        {:else}
          {#each collection().items as item (item.name)}
            <Combobox.Item {item}>
              <span>
                {item.name} - {item.height}cm / {item.mass}kg
              </span>
              <Combobox.ItemIndicator />
            </Combobox.Item>
          {/each}
        {/if}
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.RootProvider>

```

### Highlight Matching Text

Here's an example of highlighting the search text in combobox items based on the user's input.

**Example: with-highlight**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { Highlight } from '@ark-ui/react/highlight'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'

export const WithHighlight = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
    filter: contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection} onInputValueChange={handleInputChange}>
      <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>
              {collection.items.map((item) => (
                <Combobox.Item key={item} item={item}>
                  <Combobox.ItemText>
                    <Combobox.Context>
                      {(context) => <Highlight text={item} query={context.inputValue} ignoreCase />}
                    </Combobox.Context>
                  </Combobox.ItemText>
                </Combobox.Item>
              ))}
            </Combobox.ItemGroup>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { Highlight } from '@ark-ui/solid/highlight'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

const initialItems = ['React', 'Solid', 'Vue', 'Svelte']

export const WithHighlight = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems,
    filter: filterFn().contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection()} onInputValueChange={handleInputChange}>
      <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={collection().items}>
                {(item) => (
                  <Combobox.Item item={item}>
                    <Combobox.ItemText>
                      <Combobox.Context>
                        {(context) => <Highlight text={item} query={context().inputValue} ignoreCase />}
                      </Combobox.Context>
                    </Combobox.ItemText>
                  </Combobox.Item>
                )}
              </For>
            </Combobox.ItemGroup>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { Highlight } from '@ark-ui/vue/highlight'
import { useFilter } from '@ark-ui/vue/locale'

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
  filter: filters.value.contains,
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  filter(details.inputValue)
}
</script>

<template>
  <Combobox.Root :collection="collection" @input-value-change="handleInputChange">
    <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 collection.items" :key="item" :item="item">
              <Combobox.ItemText>
                <Combobox.Context v-slot="context">
                  <Highlight :text="item" :query="context.inputValue" ignore-case>
                    {{ item }}
                  </Highlight>
                </Combobox.Context>
              </Combobox.ItemText>
            </Combobox.Item>
          </Combobox.ItemGroup>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { Highlight } from '@ark-ui/svelte/highlight'
  import { useFilter } from '@ark-ui/svelte/locale'
  import { Portal } from '@ark-ui/svelte/portal'

  const filters = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: ['React', 'Solid', 'Vue', 'Svelte'],
    filter(itemString, filterText) {
      return filters().contains(itemString, filterText)
    },
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
</script>

<Combobox.Root {collection} onInputValueChange={handleInputChange}>
  <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>
          {#each collection().items as item (item)}
            <Combobox.Item {item}>
              <Combobox.ItemText>
                <Combobox.Context>
                  {#snippet render(context)}
                    <Highlight text={item} query={context().inputValue} ignoreCase />
                  {/snippet}
                </Combobox.Context>
              </Combobox.ItemText>
            </Combobox.Item>
          {/each}
        </Combobox.ItemGroup>
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.Root>

```

### Dynamic Items

Generate combobox items dynamically based on user input. This is useful for creating suggestions or autocomplete
functionality.

**Example: dynamic**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { Portal } from '@ark-ui/react/portal'

const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com']

export const Dynamic = () => {
  const { collection, set } = useListCollection<string>({
    initialItems: [],
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    if (details.reason === 'input-change') {
      const items = suggestList.map((item) => `${details.inputValue}@${item}`)
      set(items)
    }
  }

  return (
    <Combobox.Root collection={collection} onInputValueChange={handleInputChange}>
      <Combobox.Label>Framework</Combobox.Label>
      <Combobox.Control>
        <Combobox.Input />
        <Combobox.Trigger>Open</Combobox.Trigger>
      </Combobox.Control>
      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            {collection.items.map((item) => (
              <Combobox.Item key={item} item={item}>
                <Combobox.ItemText>{item}</Combobox.ItemText>
                <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
              </Combobox.Item>
            ))}
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com']

export const Dynamic = () => {
  const { collection, set } = useListCollection<string>({
    initialItems: [],
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    if (details.reason === 'input-change') {
      const items = suggestList.map((item) => `${details.inputValue}@${item}`)
      set(items)
    }
  }

  return (
    <Combobox.Root collection={collection()} onInputValueChange={handleInputChange}>
      <Combobox.Label>Framework</Combobox.Label>
      <Combobox.Control>
        <Combobox.Input />
        <Combobox.Trigger>Open</Combobox.Trigger>
      </Combobox.Control>
      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            <For each={collection().items}>
              {(item) => (
                <Combobox.Item item={item}>
                  <Combobox.ItemText>{item}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </Combobox.Item>
              )}
            </For>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'

const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com']

const { collection, set } = useListCollection<string>({
  initialItems: [],
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  if (details.reason === 'input-change') {
    const items = suggestList.map((item) => `${details.inputValue}@${item}`)
    set(items)
  }
}
</script>

<template>
  <Combobox.Root :collection="collection" @input-value-change="handleInputChange">
    <Combobox.Label>Framework</Combobox.Label>
    <Combobox.Control>
      <Combobox.Input />
      <Combobox.Trigger>Open</Combobox.Trigger>
    </Combobox.Control>
    <Teleport to="body">
      <Combobox.Positioner>
        <Combobox.Content>
          <Combobox.Item v-for="item in collection.items" :key="item" :item="item">
            <Combobox.ItemText>{{ item }}</Combobox.ItemText>
            <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
          </Combobox.Item>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { Portal } from '@ark-ui/svelte/portal'

  const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com']

  const { collection, set } = useListCollection<string>({
    initialItems: [],
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    if (details.reason === 'input-change') {
      const items = suggestList.map((item) => `${details.inputValue}@${item}`)
      set(items)
    }
  }
</script>

<Combobox.Root {collection} onInputValueChange={handleInputChange}>
  <Combobox.Label>Framework</Combobox.Label>
  <Combobox.Control>
    <Combobox.Input />
    <Combobox.Trigger>Open</Combobox.Trigger>
  </Combobox.Control>
  <Portal>
    <Combobox.Positioner>
      <Combobox.Content>
        {#each collection().items as item (item)}
          <Combobox.Item {item}>
            <Combobox.ItemText>{item}</Combobox.ItemText>
            <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
          </Combobox.Item>
        {/each}
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.Root>

```

### Creatable Options

Allow users to create new options when their search doesn't match any existing items. This is useful for tags,
categories, or other custom values.

**Example: creatable**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'
import { useState } from 'react'
import { flushSync } from 'react-dom'

interface Item {
  label: string
  value: string
  __new__?: boolean
}

const NEW_OPTION_VALUE = '[[new]]'
const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE })
const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE
const replaceNewOptionValue = (values: string[], value: string) =>
  values.map((v) => (v === NEW_OPTION_VALUE ? value : v))
const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true })

export const Creatable = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter, upsert, update, remove } = useListCollection<Item>({
    initialItems: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
    filter: contains,
  })

  const isValidNewOption = (inputValue: string) => {
    const exactOptionMatch = collection.filter((item) => item.toLowerCase() === inputValue.toLowerCase()).size > 0
    return !exactOptionMatch && inputValue.trim().length > 0
  }

  const [selectedValue, setSelectedValue] = useState<string[]>([])
  const [inputValue, setInputValue] = useState('')

  const handleInputChange = ({ inputValue, reason }: Combobox.InputValueChangeDetails) => {
    if (reason === 'input-change' || reason === 'item-select') {
      flushSync(() => {
        if (isValidNewOption(inputValue)) {
          upsert(NEW_OPTION_VALUE, createNewOption(inputValue))
        } else if (inputValue.trim().length === 0) {
          remove(NEW_OPTION_VALUE)
        }
      })
      filter(inputValue)
    }
    setInputValue(inputValue)
  }

  const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => {
    if (reason === 'trigger-click') {
      filter('')
    }
  }

  const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => {
    setSelectedValue(replaceNewOptionValue(value, inputValue))
    if (value.includes(NEW_OPTION_VALUE)) {
      console.log('New Option Created', inputValue)
      update(NEW_OPTION_VALUE, getNewOptionData(inputValue))
    }
  }

  return (
    <Combobox.Root
      collection={collection}
      onInputValueChange={handleInputChange}
      onOpenChange={handleOpenChange}
      value={selectedValue}
      onValueChange={handleValueChange}
      allowCustomValue
    >
      <Combobox.Control>
        <Combobox.Input placeholder="Search..." />
        <Combobox.Trigger>Open</Combobox.Trigger>
        <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
      </Combobox.Control>
      <Portal>
        <Combobox.Positioner>
          <Combobox.Content>
            <Combobox.ItemGroup>
              <Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
              {collection.items.map((item) => (
                <Combobox.Item key={item.value} item={item}>
                  {isNewOptionValue(item.value) ? (
                    <Combobox.ItemText>+ Create "{item.label}"</Combobox.ItemText>
                  ) : (
                    <Combobox.ItemText>
                      {item.label} {item.__new__ ? NEW_OPTION_VALUE : ''}
                    </Combobox.ItemText>
                  )}
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </Combobox.Item>
              ))}
            </Combobox.ItemGroup>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { useFilter } from '@ark-ui/solid/locale'
import { createSignal, For } from 'solid-js'
import { Portal } from 'solid-js/web'

interface Item {
  label: string
  value: string
  __new__?: boolean
}

const NEW_OPTION_VALUE = '[[new]]'
const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE })
const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE
const replaceNewOptionValue = (values: string[], value: string) =>
  values.map((v) => (v === NEW_OPTION_VALUE ? value : v))
const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true })

export const Creatable = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter, upsert, update, remove } = useListCollection<Item>({
    initialItems: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
    filter: filterFn().contains,
  })

  const isValidNewOption = (inputValue: string) => {
    const exactOptionMatch =
      collection().items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0
    return !exactOptionMatch && inputValue.trim().length > 0
  }

  const [selectedValue, setSelectedValue] = createSignal<string[]>([])
  const [inputValue, setInputValue] = createSignal('')

  const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => {
    if (reason === 'input-change' || reason === 'item-select') {
      if (isValidNewOption(newInputValue)) {
        upsert(NEW_OPTION_VALUE, createNewOption(newInputValue))
      } else if (newInputValue.trim().length === 0) {
        remove(NEW_OPTION_VALUE)
      }
      filter(newInputValue)
    }
    setInputValue(newInputValue)
  }

  const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => {
    if (reason === 'trigger-click') {
      filter('')
    }
  }

  const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => {
    setSelectedValue(replaceNewOptionValue(value, inputValue()))
    if (value.includes(NEW_OPTION_VALUE)) {
      console.log('New Option Created', inputValue())
      update(NEW_OPTION_VALUE, getNewOptionData(inputValue()))
    }
  }

  return (
    <Combobox.Root
      collection={collection()}
      onInputValueChange={handleInputChange}
      onOpenChange={handleOpenChange}
      value={selectedValue()}
      onValueChange={handleValueChange}
      allowCustomValue
    >
      <Combobox.Control>
        <Combobox.Input placeholder="Search..." />
        <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={collection().items}>
                {(item) => (
                  <Combobox.Item item={item}>
                    {isNewOptionValue(item.value) ? (
                      <Combobox.ItemText>+ Create "{item.label}"</Combobox.ItemText>
                    ) : (
                      <Combobox.ItemText>
                        {item.label} {item.__new__ ? NEW_OPTION_VALUE : ''}
                      </Combobox.ItemText>
                    )}
                    <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                  </Combobox.Item>
                )}
              </For>
            </Combobox.ItemGroup>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { useFilter } from '@ark-ui/vue/locale'
import { nextTick, ref, Teleport } from 'vue'

interface Item {
  label: string
  value: string
  __new__?: boolean
}

const NEW_OPTION_VALUE = '[[new]]'
const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE })
const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE
const replaceNewOptionValue = (values: string[], value: string) =>
  values.map((v) => (v === NEW_OPTION_VALUE ? value : v))
const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true })

const filterFn = useFilter({ sensitivity: 'base' })

const { collection, filter, upsert, update, remove } = useListCollection<Item>({
  initialItems: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
  filter: filterFn.value.contains,
})

const isValidNewOption = (inputValue: string) => {
  const exactOptionMatch =
    collection.value.items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0
  return !exactOptionMatch && inputValue.trim().length > 0
}

const selectedValue = ref<string[]>([])
const inputValue = ref('')

const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => {
  if (reason === 'input-change' || reason === 'item-select') {
    if (isValidNewOption(newInputValue)) {
      upsert(NEW_OPTION_VALUE, createNewOption(newInputValue))
    } else if (newInputValue.trim().length === 0) {
      remove(NEW_OPTION_VALUE)
    }
    filter(newInputValue)
  }
  inputValue.value = newInputValue
}

const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => {
  if (reason === 'trigger-click') {
    filter('')
  }
}

const handleValueChange = async ({ value }: Combobox.ValueChangeDetails) => {
  await nextTick()
  selectedValue.value = replaceNewOptionValue(value, inputValue.value)
  if (value.includes(NEW_OPTION_VALUE)) {
    console.log('New Option Created', inputValue.value)
    update(NEW_OPTION_VALUE, getNewOptionData(inputValue.value))
  }
}
</script>

<template>
  <Combobox.Root
    :collection="collection"
    :model-value="selectedValue"
    :onInputValueChange="handleInputChange"
    :onOpenChange="handleOpenChange"
    :onValueChange="handleValueChange"
    allowCustomValue
  >
    <Combobox.Control>
      <Combobox.Input placeholder="Search..." />
      <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 collection.items" :key="item.value" :item="item">
              <Combobox.ItemText v-if="isNewOptionValue(item.value)">+ Create "{{ item.label }}"</Combobox.ItemText>
              <Combobox.ItemText v-else>{{ item.label }} {{ item.__new__ ? NEW_OPTION_VALUE : '' }}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          </Combobox.ItemGroup>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Combobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { useFilter } from '@ark-ui/svelte/locale'
  import { Portal } from '@ark-ui/svelte/portal'
  import { tick } from 'svelte'

  interface Item {
    label: string
    value: string
    __new__?: boolean
  }

  const NEW_OPTION_VALUE = '[[new]]'
  const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE })
  const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE
  const replaceNewOptionValue = (values: string[], value: string) =>
    values.map((v) => (v === NEW_OPTION_VALUE ? value : v))
  const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true })

  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter, upsert, update, remove } = useListCollection<Item>({
    initialItems: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
    filter: filterFn().contains,
  })

  const isValidNewOption = (inputValue: string) => {
    const exactOptionMatch =
      collection().items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0
    return !exactOptionMatch && inputValue.trim().length > 0
  }

  let selectedValue: string[] = $state([])
  let inputValue: string = $state('')

  const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => {
    if (reason === 'input-change' || reason === 'item-select') {
      if (isValidNewOption(newInputValue)) {
        upsert(NEW_OPTION_VALUE, createNewOption(newInputValue))
      } else if (newInputValue.trim().length === 0) {
        remove(NEW_OPTION_VALUE)
      }
      filter(newInputValue)
    }
    inputValue = newInputValue
  }

  const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => {
    if (reason === 'trigger-click') {
      filter('')
    }
  }

  const handleValueChange = async ({ value }: Combobox.ValueChangeDetails) => {
    await tick()
    selectedValue = replaceNewOptionValue(value, inputValue)
    if (value.includes(NEW_OPTION_VALUE)) {
      console.log('New Option Created', inputValue)
      update(NEW_OPTION_VALUE, getNewOptionData(inputValue))
    }
  }
</script>

<Combobox.Root
  {collection}
  onInputValueChange={handleInputChange}
  onOpenChange={handleOpenChange}
  value={selectedValue}
  onValueChange={handleValueChange}
  allowCustomValue
>
  <Combobox.Control>
    <Combobox.Input placeholder="Search..." />
    <Combobox.Trigger>Open</Combobox.Trigger>
    <Combobox.ClearTrigger>Clear</Combobox.ClearTrigger>
  </Combobox.Control>
  <Portal>
    <Combobox.Positioner>
      <Combobox.Content>
        <Combobox.ItemGroup>
          <Combobox.ItemGroupLabel>Frameworks</Combobox.ItemGroupLabel>
          {#each collection().items as item (item.value)}
            <Combobox.Item {item}>
              {#if isNewOptionValue(item.value)}
                <Combobox.ItemText>+ Create "{item.label}"</Combobox.ItemText>
              {:else}
                <Combobox.ItemText>
                  {item.label}
                  {item.__new__ ? NEW_OPTION_VALUE : ''}
                </Combobox.ItemText>
              {/if}
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          {/each}
        </Combobox.ItemGroup>
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.Root>

```

**Example: custom-object**

#### React

```tsx
import { Combobox, useListCollection } from '@ark-ui/react/combobox'
import { useFilter } from '@ark-ui/react/locale'
import { Portal } from '@ark-ui/react/portal'

export const CustomObject = () => {
  const { contains } = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: [
      { country: 'United States', code: 'US', flag: '🇺🇸' },
      { country: 'Canada', code: 'CA', flag: '🇨🇦' },
      { country: 'Australia', code: 'AU', flag: '🇦🇺' },
    ],
    itemToString: (item) => item.country,
    itemToValue: (item) => item.code,
    filter: contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection} onInputValueChange={handleInputChange}>
      <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>
              {collection.items.map((item) => (
                <Combobox.Item key={item.country} item={item}>
                  <Combobox.ItemText>{item.country}</Combobox.ItemText>
                  <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                </Combobox.Item>
              ))}
            </Combobox.ItemGroup>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Solid

```tsx
import { Combobox, useListCollection } from '@ark-ui/solid/combobox'
import { useFilter } from '@ark-ui/solid/locale'
import { For } from 'solid-js'
import { Portal } from 'solid-js/web'

export const CustomObject = () => {
  const filterFn = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: [
      { country: 'United States', code: 'US', flag: '🇺🇸' },
      { country: 'Canada', code: 'CA', flag: '🇨🇦' },
      { country: 'Australia', code: 'AU', flag: '🇦🇺' },
    ],
    itemToString: (item) => item.country,
    itemToValue: (item) => item.code,
    filter: filterFn().contains,
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }

  return (
    <Combobox.Root collection={collection()} onInputValueChange={handleInputChange}>
      <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>Countries</Combobox.ItemGroupLabel>
              <For each={collection().items}>
                {(item) => (
                  <Combobox.Item item={item}>
                    <Combobox.ItemText>{item.country}</Combobox.ItemText>
                    <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
                  </Combobox.Item>
                )}
              </For>
            </Combobox.ItemGroup>
          </Combobox.Content>
        </Combobox.Positioner>
      </Portal>
    </Combobox.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Combobox, useListCollection } from '@ark-ui/vue/combobox'
import { useFilter } from '@ark-ui/vue/locale'

const filters = useFilter({ sensitivity: 'base' })

const { collection, filter } = useListCollection({
  initialItems: [
    { country: 'United States', code: 'US', flag: '🇺🇸' },
    { country: 'Canada', code: 'CA', flag: '🇨🇦' },
    { country: 'Australia', code: 'AU', flag: '🇦🇺' },
  ],
  itemToString: (item) => item.country,
  itemToValue: (item) => item.code,
  filter: filters.value.contains,
})

const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
  filter(details.inputValue)
}
</script>

<template>
  <Combobox.Root :collection="collection" @input-value-change="handleInputChange">
    <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>Countries</Combobox.ItemGroupLabel>
            <Combobox.Item v-for="item in collection.items" :key="item.code" :item="item">
              <Combobox.ItemText>{{ item.country }}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          </Combobox.ItemGroup>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  // biome-ignore lint/style/useImportType: intentional
  import { Combobox, useListCollection } from '@ark-ui/svelte/combobox'
  import { useFilter } from '@ark-ui/svelte/locale'
  import { Portal } from '@ark-ui/svelte/portal'

  const filters = useFilter({ sensitivity: 'base' })

  const { collection, filter } = useListCollection({
    initialItems: [
      { country: 'United States', code: 'US', flag: '🇺🇸' },
      { country: 'Canada', code: 'CA', flag: '🇨🇦' },
      { country: 'Australia', code: 'AU', flag: '🇦🇺' },
    ],
    itemToString: (item) => item.country,
    itemToValue: (item) => item.code,
    filter(itemString, filterText) {
      return filters().contains(itemString, filterText)
    },
  })

  const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
    filter(details.inputValue)
  }
</script>

<Combobox.Root {collection} onInputValueChange={handleInputChange}>
  <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>Countries</Combobox.ItemGroupLabel>
          {#each collection().items as item (item.code)}
            <Combobox.Item {item}>
              <Combobox.ItemText>{item.country}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          {/each}
        </Combobox.ItemGroup>
      </Combobox.Content>
    </Combobox.Positioner>
  </Portal>
</Combobox.Root>

```

## Guides

### Custom Router Links

For custom router links, you can customize the `navigate` prop on the `Combobox.Root` component.

Here's an example of using the Tanstack Router.

```tsx
import { Combobox } from '@ark-ui/react/combobox'
import { useNavigate } from '@tanstack/react-router'

function Demo() {
  const navigate = useNavigate()
  return (
    <Combobox.Root
      navigate={(e) => {
        navigate({ to: e.node.href })
      }}
    >
      {/* ... */}
    </Combobox.Root>
  )
}
```

### Custom Objects

By default, the combobox collection expects an array of objects with `label` and `value` properties. In some cases, you
may need to deal with custom objects.

Use the `itemToString` and `itemToValue` props to map the custom object to the required interface.

```tsx
const items = [
  { country: 'United States', code: 'US', flag: '🇺🇸' },
  { country: 'Canada', code: 'CA', flag: '🇨🇦' },
  { country: 'Australia', code: 'AU', flag: '🇦🇺' },
  // ...
]

const { collection } = useListCollection({
  initialItems: items,
  itemToString: (item) => item.country,
  itemToValue: (item) => item.code,
})
```

### Type-Safety

The `Combobox.RootComponent` type enables you to create closed, strongly typed wrapper components that maintain full
type safety for collection items.

This is particularly useful when building reusable combobox components with custom props and consistent styling.

```tsx
import { Combobox as ArkCombobox, type CollectionItem } from '@ark-ui/react/combobox'
import { useListCollection } from '@ark-ui/react/collection'

interface ComboboxProps<T extends CollectionItem> extends ArkCombobox.RootProps<T> {}

const Combobox: ArkCombobox.RootComponent = (props) => {
  return <ArkCombobox.Root {...props}>{/* ... */}</ArkCombobox.Root>
}
```

Then, you can use the `Combobox` component as follows:

```tsx
const App = () => {
  const { collection } = useListCollection({
    initialItems: [
      { label: 'React', value: 'react' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
  })
  return (
    <Combobox
      collection={collection}
      onValueChange={(e) => {
        // this will be strongly typed Array<{ label: string, value: string }>
        console.log(e.items)
      }}
    >
      {/* ... */}
    </Combobox>
  )
}
```

### Limit Large Datasets

The recommended way of managing large lists is to use the `limit` property on the `useListCollection` hook. This will
limit the number of rendered items in the DOM to improve performance.

```tsx {3}
const { collection } = useListCollection({
  initialItems: items,
  limit: 10,
})
```

### Available height and width

The following css variables are exposed to the `Combobox.Positioner` which you can use to style the `Combobox.Content`

```css
/* width of the combobox control */
--reference-width: <pixel-value>;
/* width of the available viewport */
--available-width: <pixel-value>;
/* height of the available viewport */
--available-height: <pixel-value>;
```

For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following:

```css
[data-scope='combobox'][data-part='content'] {
  max-height: calc(var(--available-height) - 100px);
}
```

## API Reference

### Props

**Component API Reference**

#### React

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `collection` | `ListCollection<T>` | Yes | The collection of items |
| `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoFocus` | `boolean` | No | Whether to autofocus the input on mount |
| `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. |
| `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs |
| `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered.
Use when you don't need to control the highlighted value of the combobox. |
| `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered.
Use when you don't need to control the value of the combobox's input. |
| `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered.
Use when you don't need to control the open state of the combobox. |
| `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered.
Use when you don't need to control the value of the combobox's selected items. |
| `disabled` | `boolean` | No | Whether the combobox is disabled |
| `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer |
| `form` | `string` | No | The associate form of the combobox. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the combobox |
| `id` | `string` | No | 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
}>` | No | The ids of the elements in the combobox. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | 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` | No | The controlled value of the combobox's input |
| `invalid` | `boolean` | No | Whether the combobox is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items |
| `multiple` | `boolean` | No | Whether to allow multiple selection.

**Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`.
It is recommended to render the selected items in a separate container. |
| `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onHighlightChange` | `(details: HighlightChangeDetails<T>) => void` | No | Function called when an item is highlighted using the pointer
or keyboard navigation. |
| `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected |
| `onValueChange` | `(details: ValueChangeDetails<T>) => void` | No | Function called when a new item is selected |
| `open` | `boolean` | No | The controlled open state of the combobox |
| `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes |
| `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input |
| `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press |
| `placeholder` | `string` | No | The placeholder text of the combobox's input |
| `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
but the user can still interact with it |
| `required` | `boolean` | No | Whether the combobox is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | 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 |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string[]` | No | The controlled value of the combobox's selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | root |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |


**ClearTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ClearTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | clear-trigger |
| `[data-invalid]` | Present when invalid |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-empty]` | Present when the content is empty |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**Empty Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Input Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Input Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | input |
| `[data-invalid]` | Present when invalid |
| `[data-autofocus]` |  |
| `[data-state]` | "open" | "closed" |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-group |
| `[data-empty]` | Present when the content is empty |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-indicator |
| `[data-state]` | "checked" | "unchecked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `item` | `any` | No | The item to render |
| `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-value]` | The value of the item |


**ItemText Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-text |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |


**Label Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Label Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | label |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


**List Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**List Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | list |
| `[data-empty]` | Present when the content is empty |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseComboboxReturn<T>` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `focusable` | `boolean` | No | Whether the trigger is focusable |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-invalid]` | Present when invalid |
| `[data-focusable]` |  |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |


#### Solid

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `collection` | `ListCollection<T>` | Yes | The collection of items |
| `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoFocus` | `boolean` | No | Whether to autofocus the input on mount |
| `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. |
| `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs |
| `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered.
Use when you don't need to control the highlighted value of the combobox. |
| `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered.
Use when you don't need to control the value of the combobox's input. |
| `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered.
Use when you don't need to control the open state of the combobox. |
| `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered.
Use when you don't need to control the value of the combobox's selected items. |
| `disabled` | `boolean` | No | Whether the combobox is disabled |
| `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer |
| `form` | `string` | No | The associate form of the combobox. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the combobox |
| `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
}>` | No | The ids of the elements in the combobox. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | 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` | No | The controlled value of the combobox's input |
| `invalid` | `boolean` | No | Whether the combobox is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items |
| `multiple` | `boolean` | No | Whether to allow multiple selection.

**Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`.
It is recommended to render the selected items in a separate container. |
| `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onHighlightChange` | `(details: HighlightChangeDetails<T>) => void` | No | Function called when an item is highlighted using the pointer
or keyboard navigation. |
| `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected |
| `onValueChange` | `(details: ValueChangeDetails<T>) => void` | No | Function called when a new item is selected |
| `open` | `boolean` | No | The controlled open state of the combobox |
| `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes |
| `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input |
| `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press |
| `placeholder` | `string` | No | The placeholder text of the combobox's input |
| `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
but the user can still interact with it |
| `required` | `boolean` | No | Whether the combobox is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | 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 |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string[]` | No | The controlled value of the combobox's selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | root |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |


**ClearTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ClearTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | clear-trigger |
| `[data-invalid]` | Present when invalid |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-empty]` | Present when the content is empty |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**Empty Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Input Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Input Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | input |
| `[data-invalid]` | Present when invalid |
| `[data-autofocus]` |  |
| `[data-state]` | "open" | "closed" |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-group |
| `[data-empty]` | Present when the content is empty |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-indicator |
| `[data-state]` | "checked" | "unchecked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `item` | `any` | No | The item to render |
| `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-value]` | The value of the item |


**ItemText Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-text |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |


**Label Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Label Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | label |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


**List Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**List Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | list |
| `[data-empty]` | Present when the content is empty |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseComboboxReturn<T>` | Yes |  |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `focusable` | `boolean` | No | Whether the trigger is focusable |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-invalid]` | Present when invalid |
| `[data-focusable]` |  |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |


#### Vue

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoFocus` | `boolean` | No | Whether to autofocus the input on mount |
| `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. |
| `collection` | `ListCollection<T>` | No | The collection of items |
| `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs |
| `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered.
Use when you don't need to control the highlighted value of the combobox. |
| `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered.
Use when you don't need to control the value of the combobox's input. |
| `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered.
Use when you don't need to control the open state of the combobox. |
| `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered.
Use when you don't need to control the value of the combobox's selected items. |
| `disabled` | `boolean` | No | Whether the combobox is disabled |
| `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer |
| `form` | `string` | No | The associate form of the combobox. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the combobox |
| `id` | `string` | No | 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
}>` | No | The ids of the elements in the combobox. Useful for composition. |
| `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | 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` | No | The controlled value of the combobox's input |
| `invalid` | `boolean` | No | Whether the combobox is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items |
| `modelValue` | `string[]` | No | The v-model value of the combobox |
| `multiple` | `boolean` | No | Whether to allow multiple selection.

**Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`.
It is recommended to render the selected items in a separate container. |
| `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item |
| `open` | `boolean` | No | The controlled open state of the combobox |
| `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes |
| `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input |
| `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press |
| `placeholder` | `string` | No | The placeholder text of the combobox's input |
| `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu |
| `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
but the user can still interact with it |
| `required` | `boolean` | No | Whether the combobox is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | 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` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | root |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |


**ClearTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ClearTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | clear-trigger |
| `[data-invalid]` | Present when invalid |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-empty]` | Present when the content is empty |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**Empty Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Input Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Input Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | input |
| `[data-invalid]` | Present when invalid |
| `[data-autofocus]` |  |
| `[data-state]` | "open" | "closed" |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `id` | `string` | No |  |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-group |
| `[data-empty]` | Present when the content is empty |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-indicator |
| `[data-state]` | "checked" | "unchecked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `item` | `any` | No | The item to render |
| `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-value]` | The value of the item |


**ItemText Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-text |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |


**Label Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Label Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | label |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


**List Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**List Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | list |
| `[data-empty]` | Present when the content is empty |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `ComboboxApi<PropTypes, T>` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `focusable` | `boolean` | No | Whether the trigger is focusable |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-invalid]` | Present when invalid |
| `[data-focusable]` |  |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |


#### Svelte

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `collection` | `MaybeFunction<ListCollection<T>>` | Yes | The collection of items |
| `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoFocus` | `boolean` | No | Whether to autofocus the input on mount |
| `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. |
| `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs |
| `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered.
Use when you don't need to control the highlighted value of the combobox. |
| `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered.
Use when you don't need to control the value of the combobox's input. |
| `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered.
Use when you don't need to control the open state of the combobox. |
| `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered.
Use when you don't need to control the value of the combobox's selected items. |
| `disabled` | `boolean` | No | Whether the combobox is disabled |
| `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer |
| `form` | `string` | No | The associate form of the combobox. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the combobox |
| `id` | `string` | No | 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
}>` | No | The ids of the elements in the combobox. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | 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` | No | The controlled value of the combobox's input |
| `invalid` | `boolean` | No | Whether the combobox is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items |
| `multiple` | `boolean` | No | Whether to allow multiple selection.

**Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`.
It is recommended to render the selected items in a separate container. |
| `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onHighlightChange` | `(details: HighlightChangeDetails<T>) => void` | No | Function called when an item is highlighted using the pointer
or keyboard navigation. |
| `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected |
| `onValueChange` | `(details: ValueChangeDetails<T>) => void` | No | Function called when a new item is selected |
| `open` | `boolean` | No | The controlled open state of the combobox |
| `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes |
| `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input |
| `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press |
| `placeholder` | `string` | No | The placeholder text of the combobox's input |
| `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
but the user can still interact with it |
| `ref` | `Element` | No |  |
| `required` | `boolean` | No | Whether the combobox is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | 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 |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string[]` | No | The controlled value of the combobox's selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | root |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |


**ClearTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ClearTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | clear-trigger |
| `[data-invalid]` | Present when invalid |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-empty]` | Present when the content is empty |


**Context Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseComboboxContext<T>]>` | Yes |  |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**Empty Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Input Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Input Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | input |
| `[data-invalid]` | Present when invalid |
| `[data-autofocus]` |  |
| `[data-state]` | "open" | "closed" |


**ItemContext Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseComboboxItemContext]>` | Yes |  |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `id` | `string` | No |  |
| `ref` | `Element` | No |  |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-group |
| `[data-empty]` | Present when the content is empty |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-indicator |
| `[data-state]` | "checked" | "unchecked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `item` | `{}` | No |  |
| `persistFocus` | `boolean` | No |  |
| `ref` | `Element` | No |  |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-value]` | The value of the item |


**ItemText Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | item-text |
| `[data-state]` | "checked" | "unchecked" |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |


**Label Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Label Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | label |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


**List Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**List Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | list |
| `[data-empty]` | Present when the content is empty |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseComboboxReturn<T>` | Yes |  |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `ref` | `Element` | No |  |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | combobox |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-invalid]` | Present when invalid |
| `[data-focusable]` |  |
| `[data-readonly]` | Present when read-only |
| `[data-disabled]` | Present when disabled |


### Context

These are the properties available when using `Combobox.Context`, `useComboboxContext` hook or `useCombobox` hook.

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `focused` | `boolean` | Whether the combobox is focused |
| `open` | `boolean` | Whether the combobox is open |
| `inputValue` | `string` | The value of the combobox input |
| `highlightedValue` | `string` | The value of the highlighted item |
| `highlightedItem` | `V` | The highlighted item |
| `setHighlightValue` | `(value: string) => void` | The value of the combobox input |
| `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value |
| `syncSelectedItems` | `VoidFunction` | Function to sync the selected items with the value.
Useful when `value` is updated from async sources. |
| `selectedItems` | `V[]` | The selected items |
| `hasSelectedItems` | `boolean` | Whether there's a selected item |
| `value` | `string[]` | The selected item keys |
| `valueAsString` | `string` | The string representation of the selected items |
| `selectValue` | `(value: string) => void` | Function to select a value |
| `setValue` | `(value: string[]) => void` | Function to set the value of the combobox |
| `clearValue` | `(value?: string) => void` | Function to clear the value of the combobox |
| `focus` | `VoidFunction` | Function to focus on the combobox input |
| `setInputValue` | `(value: string, reason?: InputValueChangeReason) => void` | Function to set the input value of the combobox |
| `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a combobox item |
| `setOpen` | `(open: boolean, reason?: OpenChangeReason) => void` | Function to open or close the combobox |
| `collection` | `ListCollection<V>` | Function to toggle the combobox |
| `reposition` | `(options?: Partial<PositioningOptions>) => void` | Function to set the positioning options |
| `multiple` | `boolean` | Whether the combobox allows multiple selections |
| `disabled` | `boolean` | Whether the combobox is disabled |


## Accessibility

Complies with the [Combobox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).

### Keyboard Support

<KeyBindingsTable id="combobox" />