# Select

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

Displays a list of options for the user to pick from.

---

<ComponentPreview id="Select" />

## Anatomy

<Anatomy id="select" />

```tsx
<Select.Root>
  <Select.Label />
  <Select.Control>
    <Select.Trigger>
      <Select.ValueText />
    </Select.Trigger>
    <Select.ClearTrigger />
    <Select.Indicator />
  </Select.Control>
  <Select.Positioner>
    <Select.Content>
      <Select.ItemGroup>
        <Select.ItemGroupLabel />
        <Select.Item>
          <Select.ItemText />
          <Select.ItemIndicator />
        </Select.Item>
      </Select.ItemGroup>
    </Select.Content>
  </Select.Positioner>
  <Select.HiddenSelect />
</Select.Root>
```

## Examples

**Example: basic**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})

export const Basic = () => {
  return (
    <Select.Root className={styles.Root} collection={frameworks}>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select" />
        </Select.Trigger>
        <div className={styles.Indicators}>
          <Select.ClearTrigger className={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              {frameworks.items.map((item) => (
                <Select.Item className={styles.Item} key={item.value} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item.label}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})

export const Basic = () => {
  return (
    <Select.Root class={styles.Root} collection={frameworks}>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select" />
        </Select.Trigger>
        <div class={styles.Indicators}>
          <Select.ClearTrigger class={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Select.ItemGroup class={styles.ItemGroup}>
              <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              <Index each={frameworks.items}>
                {(item) => (
                  <Select.Item class={styles.Item} item={item()}>
                    <Select.ItemText class={styles.ItemText}>{item().label}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                )}
              </Index>
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})
</script>

<template>
  <Select.Root :class="styles.Root" :collection="frameworks">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select" />
      </Select.Trigger>
      <div :class="styles.Indicators">
        <Select.ClearTrigger :class="styles.ClearTrigger">
          <XIcon />
        </Select.ClearTrigger>
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </div>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
            <Select.Item v-for="item in frameworks.items" :key="item.value" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const frameworks = createListCollection({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
  })
</script>

<Select.Root class={styles.Root} collection={frameworks}>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select" />
    </Select.Trigger>
    <div class={styles.Indicators}>
      <Select.ClearTrigger class={styles.ClearTrigger}>
        <XIcon />
      </Select.ClearTrigger>
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </div>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
          {#each frameworks.items as item}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Controlled

Use the `value` and `onValueChange` props to control the selected items.

**Example: controlled**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/select.module.css'

interface Item {
  label: string
  value: string
  disabled?: boolean | undefined
}

export const Controlled = () => {
  const [value, setValue] = useState<string[]>([])

  const collection = createListCollection<Item>({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte', disabled: true },
    ],
  })

  const handleValueChange = (details: Select.ValueChangeDetails<Item>) => {
    setValue(details.value)
  }

  return (
    <Select.Root className={styles.Root} collection={collection} value={value} onValueChange={handleValueChange}>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
        </Select.Trigger>
        <div className={styles.Indicators}>
          <Select.ClearTrigger className={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              {collection.items.map((item) => (
                <Select.Item className={styles.Item} key={item.value} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item.label}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { createSignal } from 'solid-js'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

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

export const Controlled = () => {
  const [value, setValue] = createSignal<string[]>([])

  const collection = createListCollection<Item>({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte', disabled: true },
    ],
  })

  const handleValueChange = (details: Select.ValueChangeDetails<Item>) => {
    setValue(details.value)
  }

  return (
    <Select.Root class={styles.Root} collection={collection} value={value()} onValueChange={handleValueChange}>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
        </Select.Trigger>
        <div class={styles.Indicators}>
          <Select.ClearTrigger class={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Select.ItemGroup class={styles.ItemGroup}>
              <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              <Index each={collection.items}>
                {(item) => (
                  <Select.Item class={styles.Item} item={item()}>
                    <Select.ItemText class={styles.ItemText}>{item().label}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                )}
              </Index>
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-vue-next'
import { ref } from 'vue'
import styles from 'styles/select.module.css'

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

const collection = createListCollection<Item>({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte', disabled: true },
  ],
})
const value = ref<string[]>(['vue'])
</script>

<template>
  <Select.Root :class="styles.Root" :collection="collection" v-model="value">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
      </Select.Trigger>
      <div :class="styles.Indicators">
        <Select.ClearTrigger :class="styles.ClearTrigger">
          <XIcon />
        </Select.ClearTrigger>
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </div>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
            <Select.Item v-for="item in collection.items" :key="item.value" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

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

  let value = $state<string[]>([])

  const collection = createListCollection<Item>({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte', disabled: true },
    ],
  })
</script>

<Select.Root class={styles.Root} {collection} bind:value>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
    </Select.Trigger>
    <div class={styles.Indicators}>
      <Select.ClearTrigger class={styles.ClearTrigger}>
        <XIcon />
      </Select.ClearTrigger>
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </div>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
          {#each collection.items as item (item.value)}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Root Provider

An alternative way to control the select is to use the `RootProvider` component and the `useSelect` hook. This way you
can access the state and methods from outside the component.

**Example: root-provider**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection, useSelect } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})

export const RootProvider = () => {
  const select = useSelect({ collection: frameworks })

  return (
    <>
      <output>selected: {JSON.stringify(select.value)}</output>

      <Select.RootProvider className={styles.Root} value={select}>
        <Select.Label className={styles.Label}>Framework</Select.Label>
        <Select.Control className={styles.Control}>
          <Select.Trigger className={styles.Trigger}>
            <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
          </Select.Trigger>
          <div className={styles.Indicators}>
            <Select.ClearTrigger className={styles.ClearTrigger}>
              <XIcon />
            </Select.ClearTrigger>
            <Select.Indicator className={styles.Indicator}>
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </div>
        </Select.Control>

        <Portal>
          <Select.Positioner>
            <Select.Content className={styles.Content}>
              <Select.ItemGroup className={styles.ItemGroup}>
                <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
                {frameworks.items.map((item) => (
                  <Select.Item className={styles.Item} key={item.value} item={item}>
                    <Select.ItemText className={styles.ItemText}>{item.label}</Select.ItemText>
                    <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                ))}
              </Select.ItemGroup>
            </Select.Content>
          </Select.Positioner>
        </Portal>
        <Select.HiddenSelect />
      </Select.RootProvider>
    </>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection, useSelect } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})

export const RootProvider = () => {
  const select = useSelect({ collection: frameworks })

  return (
    <>
      <output>selected: {JSON.stringify(select().value)}</output>

      <Select.RootProvider class={styles.Root} value={select}>
        <Select.Label class={styles.Label}>Framework</Select.Label>
        <Select.Control class={styles.Control}>
          <Select.Trigger class={styles.Trigger}>
            <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
          </Select.Trigger>
          <div class={styles.Indicators}>
            <Select.ClearTrigger class={styles.ClearTrigger}>
              <XIcon />
            </Select.ClearTrigger>
            <Select.Indicator class={styles.Indicator}>
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </div>
        </Select.Control>

        <Portal>
          <Select.Positioner>
            <Select.Content class={styles.Content}>
              <Select.ItemGroup class={styles.ItemGroup}>
                <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
                <Index each={frameworks.items}>
                  {(item) => (
                    <Select.Item class={styles.Item} item={item()}>
                      <Select.ItemText class={styles.ItemText}>{item().label}</Select.ItemText>
                      <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                    </Select.Item>
                  )}
                </Index>
              </Select.ItemGroup>
            </Select.Content>
          </Select.Positioner>
        </Portal>
        <Select.HiddenSelect />
      </Select.RootProvider>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection, useSelect } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})

const select = useSelect({ collection: frameworks })
</script>

<template>
  <output>selected: {{ JSON.stringify(select.value) }}</output>

  <Select.RootProvider :class="styles.Root" :value="select">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
      </Select.Trigger>
      <div :class="styles.Indicators">
        <Select.ClearTrigger :class="styles.ClearTrigger">
          <XIcon />
        </Select.ClearTrigger>
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </div>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
            <Select.Item v-for="item in frameworks.items" :key="item.value" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection, useSelect } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import styles from 'styles/select.module.css'

  const frameworks = createListCollection({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
  })

  const id = $props.id()
  const select = useSelect({ collection: frameworks, id })
</script>

<div>
  <button class={button.Root} style="margin-bottom: 1rem;" onclick={() => select().focus()}>Focus</button>

  <Select.RootProvider class={styles.Root} value={select}>
    <Select.Label class={styles.Label}>Framework</Select.Label>
    <Select.Control class={styles.Control}>
      <Select.Trigger class={styles.Trigger}>
        <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
      </Select.Trigger>
      <div class={styles.Indicators}>
        <Select.ClearTrigger class={styles.ClearTrigger}>
          <XIcon />
        </Select.ClearTrigger>
        <Select.Indicator class={styles.Indicator}>
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </div>
    </Select.Control>
    <Portal>
      <Select.Positioner>
        <Select.Content class={styles.Content}>
          <Select.ItemGroup class={styles.ItemGroup}>
            <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
            {#each frameworks.items as item}
              <Select.Item class={styles.Item} {item}>
                <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
                <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
              </Select.Item>
            {/each}
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Portal>
    <Select.HiddenSelect />
  </Select.RootProvider>
</div>

```

### Multiple

To enable `multiple` item selection:

**Example: multiple**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte', disabled: true },
  ],
})

export const Multiple = () => {
  return (
    <Select.Root className={styles.Root} collection={frameworks} multiple>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select" />
        </Select.Trigger>
        <div className={styles.Indicators}>
          <Select.ClearTrigger className={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              {frameworks.items.map((item) => (
                <Select.Item className={styles.Item} key={item.value} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item.label}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte', disabled: true },
  ],
})

export const Multiple = () => {
  return (
    <Select.Root class={styles.Root} collection={frameworks} multiple>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select" />
        </Select.Trigger>
        <div class={styles.Indicators}>
          <Select.ClearTrigger class={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Select.ItemGroup class={styles.ItemGroup}>
              <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              <Index each={frameworks.items}>
                {(item) => (
                  <Select.Item class={styles.Item} item={item()}>
                    <Select.ItemText class={styles.ItemText}>{item().label}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                )}
              </Index>
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte', disabled: true },
  ],
})
</script>

<template>
  <Select.Root :class="styles.Root" :collection="frameworks" multiple>
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select" />
      </Select.Trigger>
      <div :class="styles.Indicators">
        <Select.ClearTrigger :class="styles.ClearTrigger">
          <XIcon />
        </Select.ClearTrigger>
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </div>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
            <Select.Item v-for="item in frameworks.items" :key="item.value" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const frameworks = createListCollection({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte', disabled: true },
    ],
  })
</script>

<Select.Root class={styles.Root} collection={frameworks} multiple>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select" />
    </Select.Trigger>
    <div class={styles.Indicators}>
      <Select.ClearTrigger class={styles.ClearTrigger}>
        <XIcon />
      </Select.ClearTrigger>

      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </div>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
          {#each frameworks.items as item (item.value)}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Grouping

Grouping related options can be useful for organizing options into categories.

- Use the `groupBy` prop to configure the grouping of the items.
- Use the `collection.group()` method to get the grouped items.
- Use the `Select.ItemGroup` and `Select.ItemGroupLabel` components to render the grouped items.

**Example: grouping**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { 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' },
  ],
  groupBy: (item) => item.type,
})

export const Grouping = () => {
  return (
    <Select.Root className={styles.Root} collection={frameworks}>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
        </Select.Trigger>
        <div className={styles.Indicators}>
          <Select.ClearTrigger className={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            {frameworks.group().map(([type, group]) => (
              <Select.ItemGroup className={styles.ItemGroup} key={type}>
                <Select.ItemGroupLabel className={styles.ItemGroupLabel}>{type}</Select.ItemGroupLabel>
                {group.map((item) => (
                  <Select.Item className={styles.Item} key={item.value} item={item}>
                    <Select.ItemText className={styles.ItemText}>{item.label}</Select.ItemText>
                    <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                ))}
              </Select.ItemGroup>
            ))}
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { For, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { 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' },
  ],
  groupBy: (item) => item.type,
})

export const Grouping = () => {
  return (
    <Select.Root class={styles.Root} collection={frameworks}>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
        </Select.Trigger>
        <div class={styles.Indicators}>
          <Select.ClearTrigger class={styles.ClearTrigger}>
            <XIcon />
          </Select.ClearTrigger>
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </div>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <For each={frameworks.group()}>
              {([type, group]) => (
                <Select.ItemGroup class={styles.ItemGroup}>
                  <Select.ItemGroupLabel class={styles.ItemGroupLabel}>{type}</Select.ItemGroupLabel>
                  <For each={group}>
                    {(item) => (
                      <Select.Item class={styles.Item} item={item}>
                        <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
                        <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                      </Select.Item>
                    )}
                  </For>
                </Select.ItemGroup>
              )}
            </For>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

const collection = createListCollection({
  items: [
    { 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' },
  ],
  groupBy: (item) => item.type,
})
</script>

<template>
  <Select.Root :class="styles.Root" :collection="collection">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
      </Select.Trigger>
      <div :class="styles.Indicators">
        <Select.ClearTrigger :class="styles.ClearTrigger">
          <XIcon />
        </Select.ClearTrigger>
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </div>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup v-for="[type, group] in collection.group()" :key="type" :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">{{ type }}</Select.ItemGroupLabel>
            <Select.Item v-for="item in group" :key="item.value" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const frameworks = createListCollection({
    items: [
      { 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' },
    ],
    groupBy: (item) => item.type,
  })
</script>

<Select.Root class={styles.Root} collection={frameworks}>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
    </Select.Trigger>
    <div class={styles.Indicators}>
      <Select.ClearTrigger class={styles.ClearTrigger}>
        <XIcon />
      </Select.ClearTrigger>
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </div>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        {#each frameworks.group() as [type, group]}
          <Select.ItemGroup class={styles.ItemGroup}>
            <Select.ItemGroupLabel class={styles.ItemGroupLabel}>{type}</Select.ItemGroupLabel>
            {#each group as item (item.value)}
              <Select.Item class={styles.Item} {item}>
                <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
                <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
              </Select.Item>
            {/each}
          </Select.ItemGroup>
        {/each}
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Field

Use `Field` to manage form state, ARIA labels, helper text, and error text.

**Example: with-field**

#### React

```tsx
import { Field } from '@ark-ui/react/field'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon } from 'lucide-react'
import field from 'styles/field.module.css'
import styles from 'styles/select.module.css'

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

  return (
    <Field.Root className={field.Root}>
      <Select.Root collection={collection} className={styles.Root}>
        <Select.Label className={styles.Label}>Label</Select.Label>
        <Select.Control className={styles.Control}>
          <Select.Trigger className={styles.Trigger}>
            <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
            <Select.Indicator className={styles.Indicator}>
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </Select.Trigger>
        </Select.Control>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            {collection.items.map((item) => (
              <Select.Item className={styles.Item} key={item} item={item}>
                <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
              </Select.Item>
            ))}
          </Select.Content>
        </Select.Positioner>
        <Select.HiddenSelect />
      </Select.Root>
      <Field.HelperText className={field.HelperText}>Additional Info</Field.HelperText>
      <Field.ErrorText className={field.ErrorText}>Error Info</Field.ErrorText>
    </Field.Root>
  )
}

```

#### Solid

```tsx
import { Field } from '@ark-ui/solid/field'
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon } from 'lucide-solid'
import { Index } from 'solid-js/web'
import field from 'styles/field.module.css'
import styles from 'styles/select.module.css'

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

  return (
    <Field.Root class={field.Root}>
      <Select.Root collection={collection} class={styles.Root}>
        <Select.Label class={styles.Label}>Label</Select.Label>
        <Select.Control class={styles.Control}>
          <Select.Trigger class={styles.Trigger}>
            <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
            <Select.Indicator class={styles.Indicator}>
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </Select.Trigger>
        </Select.Control>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Index each={collection.items}>
              {(item) => (
                <Select.Item class={styles.Item} item={item()}>
                  <Select.ItemText class={styles.ItemText}>{item()}</Select.ItemText>
                  <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              )}
            </Index>
          </Select.Content>
        </Select.Positioner>
        <Select.HiddenSelect />
      </Select.Root>
      <Field.HelperText class={field.HelperText}>Additional Info</Field.HelperText>
      <Field.ErrorText class={field.ErrorText}>Error Info</Field.ErrorText>
    </Field.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Field } from '@ark-ui/vue/field'
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'
import field from 'styles/field.module.css'

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

<template>
  <Field.Root :class="field.Root">
    <Select.Root :collection="collection" :class="styles.Root">
      <Select.Label :class="styles.Label">Label</Select.Label>
      <Select.Control :class="styles.Control">
        <Select.Trigger :class="styles.Trigger">
          <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
          <Select.Indicator :class="styles.Indicator">
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
      </Select.Control>
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.Item v-for="item in collection.items" :key="item" :item="item" :class="styles.Item">
            <Select.ItemText :class="styles.ItemText">{{ item }}</Select.ItemText>
            <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
          </Select.Item>
        </Select.Content>
      </Select.Positioner>
      <Select.HiddenSelect />
    </Select.Root>
    <Field.HelperText :class="field.HelperText">Additional Info</Field.HelperText>
    <Field.ErrorText :class="field.ErrorText">Error Info</Field.ErrorText>
  </Field.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Field } from '@ark-ui/svelte/field'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon } from 'lucide-svelte'
  import field from 'styles/field.module.css'
  import styles from 'styles/select.module.css'

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

<Field.Root class={field.Root}>
  <Select.Root {collection} class={styles.Root}>
    <Select.Label class={styles.Label}>Label</Select.Label>
    <Select.Control class={styles.Control}>
      <Select.Trigger class={styles.Trigger}>
        <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
        <Select.Indicator class={styles.Indicator}>
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
    </Select.Control>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        {#each collection.items as item}
          <Select.Item class={styles.Item} {item}>
            <Select.ItemText class={styles.ItemText}>{item}</Select.ItemText>
            <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
          </Select.Item>
        {/each}
      </Select.Content>
    </Select.Positioner>
    <Select.HiddenSelect />
  </Select.Root>
  <Field.HelperText class={field.HelperText}>Additional Info</Field.HelperText>
  <Field.ErrorText class={field.ErrorText}>Error Info</Field.ErrorText>
</Field.Root>

```

### Form Usage

Here's an example of integrating the `Select` component with a form library.

**Example: form-library**

#### React

```tsx
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import { Controller, type SubmitHandler, useForm } from 'react-hook-form'
import button from 'styles/button.module.css'
import styles from 'styles/select.module.css'

interface Inputs {
  framework: string
}

export const FormLibrary = () => {
  const { control, handleSubmit } = useForm<Inputs>({
    defaultValues: { framework: 'React' },
  })

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

  const onSubmit: SubmitHandler<Inputs> = (data) => {
    window.alert(JSON.stringify(data))
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="framework"
        control={control}
        render={({ field }) => (
          <Select.Root
            className={styles.Root}
            collection={collection}
            value={field.value ? [field.value] : []}
            onValueChange={(e) => field.onChange(e.value[0])}
            name={field.name}
            onInteractOutside={() => field.onBlur()}
          >
            <Select.Label className={styles.Label}>Framework</Select.Label>
            <Select.HiddenSelect />
            <Select.Control className={styles.Control}>
              <Select.Trigger className={styles.Trigger}>
                <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
              </Select.Trigger>
              <div className={styles.Indicators}>
                <Select.ClearTrigger className={styles.ClearTrigger}>
                  <XIcon />
                </Select.ClearTrigger>
                <Select.Indicator className={styles.Indicator}>
                  <ChevronsUpDownIcon />
                </Select.Indicator>
              </div>
            </Select.Control>
            <Select.Positioner>
              <Select.Content className={styles.Content}>
                <Select.ItemGroup className={styles.ItemGroup}>
                  <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
                  {collection.items.map((item) => (
                    <Select.Item className={styles.Item} key={item} item={item}>
                      <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                      <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                    </Select.Item>
                  ))}
                </Select.ItemGroup>
              </Select.Content>
            </Select.Positioner>
          </Select.Root>
        )}
      />

      <button className={button.Root} style={{ marginTop: '1rem' }} type="submit">
        Submit
      </button>
    </form>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { createForm, getValue, setValue } from '@modular-forms/solid'
import { createMemo } from 'solid-js'
import { Index, Portal } from 'solid-js/web'
import button from 'styles/button.module.css'
import styles from 'styles/select.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
  ],
})

export const FormLibrary = () => {
  const [formStore, { Form, Field }] = createForm({
    initialValues: { value: 'solid' },
  })

  const value = createMemo(() => getValue(formStore, 'value'))

  return (
    <>
      <div style={{ 'margin-bottom': '1rem' }}>Value is {value()}</div>
      <Form
        onSubmit={(data) => {
          window.alert(JSON.stringify(data))
        }}
      >
        <Field name="value">
          {(field, props) => (
            <Select.Root
              class={styles.Root}
              collection={frameworks}
              value={field.value ? [field.value] : []}
              invalid={!!field.error}
              name={field.name}
              onValueChange={(e) => setValue(formStore, field.name, e.value[0])}
            >
              <Select.Label class={styles.Label}>Framework</Select.Label>
              <Select.Control class={styles.Control}>
                <Select.Trigger class={styles.Trigger}>
                  <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
                </Select.Trigger>
                <div class={styles.Indicators}>
                  <Select.ClearTrigger class={styles.ClearTrigger}>
                    <XIcon />
                  </Select.ClearTrigger>
                  <Select.Indicator class={styles.Indicator}>
                    <ChevronsUpDownIcon />
                  </Select.Indicator>
                </div>
              </Select.Control>
              <Portal>
                <Select.Positioner>
                  <Select.Content class={styles.Content}>
                    <Select.ItemGroup class={styles.ItemGroup}>
                      <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
                      <Index each={frameworks.items}>
                        {(item) => (
                          <Select.Item class={styles.Item} item={item()}>
                            <Select.ItemText class={styles.ItemText}>{item().label}</Select.ItemText>
                            <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                          </Select.Item>
                        )}
                      </Index>
                    </Select.ItemGroup>
                  </Select.Content>
                </Select.Positioner>
              </Portal>
              <Select.HiddenSelect {...props} />
            </Select.Root>
          )}
        </Field>

        <button class={button.Root} style={{ 'margin-top': '1rem' }} type="submit">
          Submit
        </button>
      </Form>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { useForm, useField } from 'vee-validate'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'
import button from 'styles/button.module.css'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Solid', value: 'solid' },
    { label: 'Vue', value: 'vue' },
    { label: 'Svelte', value: 'svelte' },
  ],
})

const { handleSubmit, values } = useForm({
  initialValues: {
    framework: 'vue',
  },
})

const { value: framework, setValue } = useField<string>('framework')

const onSubmit = handleSubmit((values) => {
  window.alert(JSON.stringify(values))
})
</script>

<template>
  <div>
    <div style="margin-bottom: 1rem">Value is {{ values.framework }}</div>
    <form @submit="onSubmit">
      <Select.Root
        :class="styles.Root"
        :collection="frameworks"
        :model-value="framework ? [framework] : []"
        @value-change="(e) => setValue(e.value[0])"
      >
        <Select.Label :class="styles.Label">Framework</Select.Label>
        <Select.Control :class="styles.Control">
          <Select.Trigger :class="styles.Trigger">
            <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
          </Select.Trigger>
          <div :class="styles.Indicators">
            <Select.ClearTrigger :class="styles.ClearTrigger">
              <XIcon />
            </Select.ClearTrigger>
            <Select.Indicator :class="styles.Indicator">
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </div>
        </Select.Control>
        <Teleport to="body">
          <Select.Positioner>
            <Select.Content :class="styles.Content">
              <Select.ItemGroup :class="styles.ItemGroup">
                <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
                <Select.Item v-for="item in frameworks.items" :key="item.value" :item="item" :class="styles.Item">
                  <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
                  <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
                </Select.Item>
              </Select.ItemGroup>
            </Select.Content>
          </Select.Positioner>
        </Teleport>
        <Select.HiddenSelect name="framework" />
      </Select.Root>
      <button :class="button.Root" style="margin-top: 1rem" type="submit">Submit</button>
    </form>
  </div>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import { createForm } from '@tanstack/svelte-form'
  import styles from 'styles/select.module.css'
  import button from 'styles/button.module.css'

  const frameworks = createListCollection({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
    ],
  })

  const form = createForm(() => ({
    defaultValues: {
      framework: 'solid',
    },
    onSubmit: async ({ value }) => {
      console.log(value)
    },
  }))

  const formData = $derived(form.state.values)
</script>

<div style="margin-bottom: 1rem;">Value is {formData.framework}</div>

<form
  onsubmit={(e) => {
    e.preventDefault()
    form.handleSubmit()
  }}
>
  <form.Field name="framework">
    {#snippet children(field)}
      {@const state = field.state}
      <Select.Root
        class={styles.Root}
        collection={frameworks}
        value={state.value ? [state.value] : []}
        invalid={state.meta.errors.length > 0}
        name={field.name}
        onValueChange={(details) => {
          field.handleChange(details.value[0])
        }}
      >
        <Select.Label class={styles.Label}>Framework</Select.Label>
        <Select.Control class={styles.Control}>
          <Select.Trigger class={styles.Trigger}>
            <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
            <Select.Indicator class={styles.Indicator}>
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </Select.Trigger>
          <div class={styles.Indicators}>
            <Select.ClearTrigger class={styles.ClearTrigger}>
              <XIcon />
            </Select.ClearTrigger>
            <Select.Indicator class={styles.Indicator}>
              <ChevronsUpDownIcon />
            </Select.Indicator>
          </div>
        </Select.Control>
        <Portal>
          <Select.Positioner>
            <Select.Content class={styles.Content}>
              <Select.ItemGroup class={styles.ItemGroup}>
                <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
                {#each frameworks.items as item}
                  <Select.Item class={styles.Item} {item}>
                    <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                {/each}
              </Select.ItemGroup>
            </Select.Content>
          </Select.Positioner>
        </Portal>
        <Select.HiddenSelect />
      </Select.Root>
    {/snippet}
  </form.Field>
  <button class={button.Root} style="margin-top: 1rem;" type="submit">Submit</button>
</form>

```

### Async Loading

Here's an example of how to load the items asynchronously when the select is opened.

**Example: async**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/select.module.css'

function loadData() {
  return new Promise<string[]>((resolve) => {
    setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500)
  })
}

export const Async = () => {
  const [items, setItems] = useState<string[] | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<Error | null>(null)

  const collection = createListCollection<string>({
    items: items || [],
  })

  const handleOpenChange = (details: Select.OpenChangeDetails) => {
    if (details.open && items == null) {
      setLoading(true)
      setError(null)
      loadData()
        .then((data) => setItems(data))
        .catch((err) => setError(err))
        .finally(() => setLoading(false))
    }
  }

  return (
    <Select.Root className={styles.Root} collection={collection} onOpenChange={handleOpenChange}>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select" />
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            {loading ? (
              <div className={styles.Item}>Loading...</div>
            ) : error ? (
              <div className={styles.Item}>Error: {error.message}</div>
            ) : (
              collection.items.map((item) => (
                <Select.Item className={styles.Item} key={item} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))
            )}
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon } from 'lucide-solid'
import { Index, Match, Switch, createMemo, createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

function loadData() {
  return new Promise<string[]>((resolve) => {
    setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500)
  })
}

export const Async = () => {
  const [items, setItems] = createSignal<string[] | null>(null)
  const [loading, setLoading] = createSignal(false)
  const [error, setError] = createSignal<Error | null>(null)

  const collection = createMemo(() =>
    createListCollection<string>({
      items: items() || [],
    }),
  )

  const handleOpenChange = (details: Select.OpenChangeDetails) => {
    if (details.open && items() === null) {
      setLoading(true)
      setError(null)
      loadData()
        .then((data) => setItems(data))
        .catch((err) => setError(err))
        .finally(() => setLoading(false))
    }
  }

  return (
    <Select.Root class={styles.Root} collection={collection()} onOpenChange={handleOpenChange}>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select" />
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Switch>
              <Match when={loading()}>
                <div class={styles.Item}>Loading...</div>
              </Match>
              <Match when={error()}>
                <div class={styles.Item}>Error: {error()?.message}</div>
              </Match>
              <Match when={items() !== null}>
                <Index each={collection().items}>
                  {(item) => (
                    <Select.Item class={styles.Item} item={item()}>
                      <Select.ItemText class={styles.ItemText}>{item()}</Select.ItemText>
                      <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                    </Select.Item>
                  )}
                </Index>
              </Match>
            </Switch>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import { computed, ref } from 'vue'
import styles from 'styles/select.module.css'

function loadData() {
  return new Promise<string[]>((resolve) => {
    setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500)
  })
}

const data = ref<string[] | null>(null)
const loading = ref(false)
const error = ref<Error | null>(null)

const collection = computed(() =>
  createListCollection({
    items: data.value ?? [],
  }),
)

const handleOpenChange = async (details: Select.OpenChangeDetails) => {
  if (details.open && data.value === null) {
    loading.value = true
    error.value = null
    try {
      const result = await loadData()
      data.value = result
    } catch (err) {
      error.value = err as Error
    } finally {
      loading.value = false
    }
  }
}
</script>

<template>
  <Select.Root :class="styles.Root" :collection="collection" @open-change="handleOpenChange">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select" />
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <div v-if="loading" :class="styles.Item">Loading...</div>
          <div v-else-if="error" :class="styles.Item">Error: {{ error.message }}</div>
          <template v-else>
            <Select.Item v-for="item in collection.items" :key="item" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </template>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  // biome-ignore lint/style/useImportType: intentional
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  function loadData() {
    return new Promise<string[]>((resolve) => {
      setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500)
    })
  }

  let data = $state<string[] | null>(null)
  let loading = $state(false)
  let error = $state<Error | null>(null)

  const collection = $derived(
    createListCollection({
      items: data ?? [],
    }),
  )

  const handleOpenChange = (details: Select.OpenChangeDetails) => {
    if (details.open && data === null) {
      loading = true
      error = null
      loadData()
        .then((result) => {
          data = result
        })
        .catch((err) => {
          error = err
        })
        .finally(() => {
          loading = false
        })
    }
  }
</script>

<Select.Root class={styles.Root} {collection} onOpenChange={handleOpenChange}>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select" />
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </Select.Trigger>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        {#if loading}
          <div class={styles.Item}>Loading...</div>
        {:else if error}
          <div class={styles.Item}>Error: {error.message}</div>
        {:else}
          {#each collection.items as item}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        {/if}
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Lazy Mount

Use `lazyMount` and `unmountOnExit` to control when content is mounted, improving performance.

**Example: lazy-mount**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

export const LazyMount = () => {
  const collection = createListCollection({
    items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'],
  })

  return (
    <Select.Root className={styles.Root} collection={collection} lazyMount unmountOnExit>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger className={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              {collection.items.map((item) => (
                <Select.Item className={styles.Item} key={item} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

export const LazyMount = () => {
  const collection = createListCollection({
    items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'],
  })

  return (
    <Select.Root class={styles.Root} collection={collection} lazyMount unmountOnExit>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Select.ItemGroup class={styles.ItemGroup}>
              <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              <Index each={collection.items}>
                {(item) => (
                  <Select.Item class={styles.Item} item={item()}>
                    <Select.ItemText class={styles.ItemText}>{item()}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                )}
              </Index>
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

const collection = createListCollection({
  items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'],
})
</script>

<template>
  <Select.Root :class="styles.Root" :collection="collection" :lazy-mount="true" :unmount-on-exit="true">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
      <Select.ClearTrigger :class="styles.ClearTrigger">Clear</Select.ClearTrigger>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
            <Select.Item v-for="item in collection.items" :key="item" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const collection = createListCollection({
    items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'],
  })
</script>

<Select.Root class={styles.Root} {collection} lazyMount unmountOnExit>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </Select.Trigger>
    <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
          {#each collection.items as item}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Select on Highlight

Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard).

**Example: select-on-highlight**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection, useSelect } from '@ark-ui/react/select'
import { ChevronsUpDownIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

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

  const select = useSelect({
    collection,
    onHighlightChange({ highlightedValue }) {
      if (highlightedValue) {
        select.selectValue(highlightedValue)
      }
    },
  })

  return (
    <Select.RootProvider className={styles.Root} value={select}>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger className={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              {collection.items.map((item) => (
                <Select.Item className={styles.Item} key={item} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.RootProvider>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection, useSelect } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

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

  const select = useSelect({
    collection,
    onHighlightChange({ highlightedValue }) {
      if (highlightedValue) {
        select().selectValue(highlightedValue)
      }
    },
  })

  return (
    <Select.RootProvider class={styles.Root} value={select}>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Select.ItemGroup class={styles.ItemGroup}>
              <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              <Index each={collection.items}>
                {(item) => (
                  <Select.Item class={styles.Item} item={item()}>
                    <Select.ItemText class={styles.ItemText}>{item()}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                )}
              </Index>
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.RootProvider>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection, useSelect } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

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

const select = useSelect({
  collection,
  onHighlightChange({ highlightedValue }) {
    if (highlightedValue) {
      select.value.selectValue(highlightedValue)
    }
  },
})
</script>

<template>
  <Select.RootProvider :class="styles.Root" :value="select">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.Item v-for="item in collection.items" :key="item" :item="item" :class="styles.Item">
            <Select.ItemText :class="styles.ItemText">{{ item }}</Select.ItemText>
            <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
          </Select.Item>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection, useSelect } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const frameworks = createListCollection({
    items: [
      { label: 'React', value: 'react' },
      { label: 'Solid', value: 'solid' },
      { label: 'Vue', value: 'vue' },
      { label: 'Svelte', value: 'svelte' },
    ],
  })

  const select = useSelect({
    collection: frameworks,
    onHighlightChange({ highlightedValue }) {
      if (highlightedValue) {
        select().selectValue(highlightedValue)
      }
    },
  })
</script>

<Select.RootProvider class={styles.Root} value={select}>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </Select.Trigger>
    <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
          {#each frameworks.items as item}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.RootProvider>

```

### Max Selection

Here's an example of limiting the number of items that can be selected in a multiple select.

**Example: max-selected**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/select.module.css'

const items = ['React', 'Solid', 'Vue', 'Svelte']
const MAX_SELECTION = 2
const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION

export const MaxSelected = () => {
  const [value, setValue] = useState<string[]>([])

  const collection = createListCollection({
    items: items.map((item) => ({
      label: item,
      value: item,
      disabled: hasReachedMax(value) && !value.includes(item),
    })),
  })

  const handleValueChange = (details: Select.ValueChangeDetails) => {
    if (hasReachedMax(value) && details.value.length > value.length) return
    setValue(details.value)
  }

  return (
    <Select.Root
      className={styles.Root}
      collection={collection}
      multiple
      value={value}
      onValueChange={handleValueChange}
    >
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select" />
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger className={styles.ClearTrigger}>
          <XIcon />
        </Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              {collection.items.map((item) => (
                <Select.Item className={styles.Item} key={item.value} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item.label}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-solid'
import { Index, createMemo, createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

const items = ['React', 'Solid', 'Vue', 'Svelte']
const MAX_SELECTION = 2
const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION

export const MaxSelected = () => {
  const [value, setValue] = createSignal<string[]>([])

  const collection = createMemo(() =>
    createListCollection({
      items: items.map((item) => ({
        label: item,
        value: item,
        disabled: hasReachedMax(value()) && !value().includes(item),
      })),
    }),
  )

  const handleValueChange = (details: Select.ValueChangeDetails) => {
    if (hasReachedMax(value()) && details.value.length > value().length) return
    setValue(details.value)
  }

  return (
    <Select.Root
      class={styles.Root}
      collection={collection()}
      multiple
      value={value()}
      onValueChange={handleValueChange}
    >
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select" />
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger class={styles.ClearTrigger}>
          <XIcon />
        </Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <Select.ItemGroup class={styles.ItemGroup}>
              <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
              <Index each={collection().items}>
                {(item) => (
                  <Select.Item class={styles.Item} item={item()}>
                    <Select.ItemText class={styles.ItemText}>{item().label}</Select.ItemText>
                    <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                  </Select.Item>
                )}
              </Index>
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
// biome-ignore lint/style/useImportType: intentional
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon, XIcon } from 'lucide-vue-next'
import { computed, ref } from 'vue'
import styles from 'styles/select.module.css'

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

const value = ref<string[]>([])
const MAX_SELECTION = 2

const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION

const collection = computed(() =>
  createListCollection({
    items: items.map((item) => ({
      label: item,
      value: item,
      disabled: hasReachedMax(value.value) && !value.value.includes(item),
    })),
  }),
)

const handleValueChange = (details: Select.ValueChangeDetails) => {
  if (hasReachedMax(value.value) && details.value.length > value.value.length) return
  value.value = details.value
}
</script>

<template>
  <Select.Root :class="styles.Root" :collection="collection" multiple :value="value" @value-change="handleValueChange">
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select" />
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
      <Select.ClearTrigger :class="styles.ClearTrigger">
        <XIcon />
      </Select.ClearTrigger>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Frameworks</Select.ItemGroupLabel>
            <Select.Item v-for="item in collection.items" :key="item.value" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item.label }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  // biome-ignore lint/style/useImportType: intentional
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon, XIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const items = ['React', 'Solid', 'Vue', 'Svelte']
  const MAX_SELECTION = 2
  const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION

  let value = $state<string[]>([])

  const collection = $derived(
    createListCollection({
      items: items.map((item) => ({
        label: item,
        value: item,
        disabled: hasReachedMax(value) && !value.includes(item),
      })),
    }),
  )

  const handleValueChange = (details: Select.ValueChangeDetails) => {
    if (hasReachedMax(value) && details.value.length > value.length) return
    value = details.value
  }
</script>

<Select.Root class={styles.Root} {collection} multiple {value} onValueChange={handleValueChange}>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select" />
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </Select.Trigger>
    <Select.ClearTrigger class={styles.ClearTrigger}>
      <XIcon />
    </Select.ClearTrigger>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Frameworks</Select.ItemGroupLabel>
          {#each collection.items as item (item.value)}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item.label}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Select All

Use `selectAll()` from the select context to select all items at once.

**Example: select-all**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon } from 'lucide-react'
import styles from 'styles/select.module.css'
import button from 'styles/button.module.css'

const SelectAllButton = () => {
  return (
    <Select.Context>
      {(api) => (
        <button
          className={button.Root}
          style={{ width: '100%', marginBottom: '0.25rem' }}
          type="button"
          onClick={() => {
            api.selectAll()
            api.setOpen(false)
          }}
        >
          Select All
        </button>
      )}
    </Select.Context>
  )
}

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

  return (
    <Select.Root className={styles.Root} collection={collection}>
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger className={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content}>
            <SelectAllButton />
            {collection.items.map((item) => (
              <Select.Item className={styles.Item} key={item} item={item}>
                <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
              </Select.Item>
            ))}
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'
import button from 'styles/button.module.css'

const SelectAllButton = () => {
  return (
    <Select.Context>
      {(api) => (
        <button
          class={button.Root}
          style={{ width: '100%', 'margin-bottom': '0.25rem' }}
          type="button"
          onClick={() => {
            api().selectAll()
            api().setOpen(false)
          }}
        >
          Select All
        </button>
      )}
    </Select.Context>
  )
}

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

  return (
    <Select.Root class={styles.Root} collection={collection}>
      <Select.Label class={styles.Label}>Framework</Select.Label>
      <Select.Control class={styles.Control}>
        <Select.Trigger class={styles.Trigger}>
          <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator class={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content class={styles.Content}>
            <SelectAllButton />
            <Index each={collection.items}>
              {(item) => (
                <Select.Item class={styles.Item} item={item()}>
                  <Select.ItemText class={styles.ItemText}>{item()}</Select.ItemText>
                  <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              )}
            </Index>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'
import button from 'styles/button.module.css'

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

<template>
  <Select.Root :class="styles.Root" :collection="collection" multiple>
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content">
          <Select.Context v-slot="api">
            <button
              :class="button.Root"
              type="button"
              style="margin-bottom: 0.5rem"
              @click="
                () => {
                  api.selectAll()
                  api.setOpen(false)
                }
              "
            >
              Select All
            </button>
          </Select.Context>
          <Select.Item v-for="item in collection.items" :key="item" :item="item" :class="styles.Item">
            <Select.ItemText :class="styles.ItemText">{{ item }}</Select.ItemText>
            <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
          </Select.Item>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'
  import button from 'styles/button.module.css'

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

<Select.Root class={styles.Root} {collection}>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </Select.Trigger>
    <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content}>
        <Select.Context>
          {#snippet render(api)}
            <button
              class={button.Root}
              type="button"
              style="width: 100%; margin-bottom: 0.25rem"
              onclick={() => {
                api().selectAll()
                api().setOpen(false)
              }}
            >
              Select All
            </button>
          {/snippet}
        </Select.Context>
        {#each collection.items as item}
          <Select.Item class={styles.Item} {item}>
            <Select.ItemText class={styles.ItemText}>{item}</Select.ItemText>
            <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
          </Select.Item>
        {/each}
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

### Overflow

For selects with many items, use `positioning.fitViewport` to ensure the dropdown fits within the viewport. Combine with
a max-height on the content to enable scrolling.

**Example: overflow**

#### React

```tsx
import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronsUpDownIcon } from 'lucide-react'
import styles from 'styles/select.module.css'

export const Overflow = () => {
  const collection = createListCollection({
    items: [
      'Name 1',
      'Name 2',
      'Name 3',
      'Name 4',
      'Name 5',
      'Name 6',
      'Name 7',
      'Name 8',
      'Name 9',
      'Name 10',
      'Name 11',
      'Name 12',
      'Name 13',
      'Name 14',
    ],
  })

  return (
    <Select.Root
      className={styles.Root}
      collection={collection}
      positioning={{
        fitViewport: true,
        placement: 'bottom-start',
        sameWidth: true,
      }}
    >
      <Select.Label className={styles.Label}>Framework</Select.Label>
      <Select.Control className={styles.Control}>
        <Select.Trigger className={styles.Trigger}>
          <Select.ValueText className={styles.ValueText} placeholder="Select a Framework" />
          <Select.Indicator className={styles.Indicator}>
            <ChevronsUpDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger className={styles.ClearTrigger}>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content className={styles.Content} style={{ maxHeight: '200px' }}>
            <Select.ItemGroup className={styles.ItemGroup}>
              <Select.ItemGroupLabel className={styles.ItemGroupLabel}>Names</Select.ItemGroupLabel>
              {collection.items.map((item) => (
                <Select.Item className={styles.Item} key={item} item={item}>
                  <Select.ItemText className={styles.ItemText}>{item}</Select.ItemText>
                  <Select.ItemIndicator className={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

```

#### Solid

```tsx
import { Select, createListCollection } from '@ark-ui/solid/select'
import { ChevronsUpDownIcon } from 'lucide-solid'
import { Index, Portal } from 'solid-js/web'
import styles from 'styles/select.module.css'

const collection = createListCollection({
  items: [
    'Name 1',
    'Name 2',
    'Name 3',
    'Name 4',
    'Name 5',
    'Name 6',
    'Name 7',
    'Name 8',
    'Name 9',
    'Name 10',
    'Name 11',
    'Name 12',
    'Name 13',
    'Name 14',
  ],
})

export const Overflow = () => (
  <Select.Root
    class={styles.Root}
    collection={collection}
    positioning={{
      fitViewport: true,
      placement: 'bottom-start',
      sameWidth: true,
    }}
  >
    <Select.Label class={styles.Label}>Framework</Select.Label>
    <Select.Control class={styles.Control}>
      <Select.Trigger class={styles.Trigger}>
        <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
        <Select.Indicator class={styles.Indicator}>
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
      <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
    </Select.Control>
    <Portal>
      <Select.Positioner>
        <Select.Content class={styles.Content} style={{ 'max-height': '200px' }}>
          <Select.ItemGroup class={styles.ItemGroup}>
            <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Names</Select.ItemGroupLabel>
            <Index each={collection.items}>
              {(item) => (
                <Select.Item class={styles.Item} item={item()}>
                  <Select.ItemText class={styles.ItemText}>{item()}</Select.ItemText>
                  <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
                </Select.Item>
              )}
            </Index>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Portal>
    <Select.HiddenSelect />
  </Select.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Select, createListCollection } from '@ark-ui/vue/select'
import { ChevronsUpDownIcon } from 'lucide-vue-next'
import styles from 'styles/select.module.css'

const collection = createListCollection({
  items: [
    'Name 1',
    'Name 2',
    'Name 3',
    'Name 4',
    'Name 5',
    'Name 6',
    'Name 7',
    'Name 8',
    'Name 9',
    'Name 10',
    'Name 11',
    'Name 12',
    'Name 13',
    'Name 14',
  ],
})
</script>

<template>
  <Select.Root
    :class="styles.Root"
    :collection="collection"
    :positioning="{
      fitViewport: true,
      placement: 'bottom-start',
      sameWidth: true,
    }"
  >
    <Select.Label :class="styles.Label">Framework</Select.Label>
    <Select.Control :class="styles.Control">
      <Select.Trigger :class="styles.Trigger">
        <Select.ValueText :class="styles.ValueText" placeholder="Select a Framework" />
        <Select.Indicator :class="styles.Indicator">
          <ChevronsUpDownIcon />
        </Select.Indicator>
      </Select.Trigger>
      <Select.ClearTrigger :class="styles.ClearTrigger">Clear</Select.ClearTrigger>
    </Select.Control>
    <Teleport to="body">
      <Select.Positioner>
        <Select.Content :class="styles.Content" :style="{ maxHeight: '200px' }">
          <Select.ItemGroup :class="styles.ItemGroup">
            <Select.ItemGroupLabel :class="styles.ItemGroupLabel">Names</Select.ItemGroupLabel>
            <Select.Item v-for="item in collection.items" :key="item" :item="item" :class="styles.Item">
              <Select.ItemText :class="styles.ItemText">{{ item }}</Select.ItemText>
              <Select.ItemIndicator :class="styles.ItemIndicator">✓</Select.ItemIndicator>
            </Select.Item>
          </Select.ItemGroup>
        </Select.Content>
      </Select.Positioner>
    </Teleport>
    <Select.HiddenSelect />
  </Select.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Portal } from '@ark-ui/svelte/portal'
  import { Select, createListCollection } from '@ark-ui/svelte/select'
  import { ChevronsUpDownIcon } from 'lucide-svelte'
  import styles from 'styles/select.module.css'

  const collection = createListCollection({
    items: [
      'Name 1',
      'Name 2',
      'Name 3',
      'Name 4',
      'Name 5',
      'Name 6',
      'Name 7',
      'Name 8',
      'Name 9',
      'Name 10',
      'Name 11',
      'Name 12',
      'Name 13',
      'Name 14',
    ],
  })
</script>

<Select.Root
  class={styles.Root}
  {collection}
  positioning={{
    fitViewport: true,
    placement: 'bottom-start',
    sameWidth: true,
  }}
>
  <Select.Label class={styles.Label}>Framework</Select.Label>
  <Select.Control class={styles.Control}>
    <Select.Trigger class={styles.Trigger}>
      <Select.ValueText class={styles.ValueText} placeholder="Select a Framework" />
      <Select.Indicator class={styles.Indicator}>
        <ChevronsUpDownIcon />
      </Select.Indicator>
    </Select.Trigger>
    <Select.ClearTrigger class={styles.ClearTrigger}>Clear</Select.ClearTrigger>
  </Select.Control>
  <Portal>
    <Select.Positioner>
      <Select.Content class={styles.Content} style="max-height: 200px">
        <Select.ItemGroup class={styles.ItemGroup}>
          <Select.ItemGroupLabel class={styles.ItemGroupLabel}>Names</Select.ItemGroupLabel>
          {#each collection.items as item}
            <Select.Item class={styles.Item} {item}>
              <Select.ItemText class={styles.ItemText}>{item}</Select.ItemText>
              <Select.ItemIndicator class={styles.ItemIndicator}>✓</Select.ItemIndicator>
            </Select.Item>
          {/each}
        </Select.ItemGroup>
      </Select.Content>
    </Select.Positioner>
  </Portal>
  <Select.HiddenSelect />
</Select.Root>

```

## Guides

### Type Safety

The `Select.RootComponent` type enables you to create typed wrapper components that maintain full type safety for
collection items.

```tsx
const Select: ArkSelect.RootComponent = (props) => {
  return <ArkSelect.Root {...props}>{/* ... */}</ArkSelect.Root>
}
```

Use the wrapper with full type inference on `onValueChange` and other callbacks:

```tsx
const App = () => {
  const collection = createListCollection({
    initialItems: [
      { label: 'React', value: 'react' },
      { label: 'Vue', value: 'vue' },
    ],
  })
  return (
    <Select
      collection={collection}
      onValueChange={(e) => {
        // e.items is typed as Array<{ label: string, value: string }>
        console.log(e.items)
      }}
    >
      {/* ... */}
    </Select>
  )
}
```

### Nested Usage

When using the Select component within a `Popover` or `Dialog`, avoid rendering its content within a `Portal` or
`Teleport`.

This ensures the Select's content stays within the Popover/Dialog's DOM hierarchy rather than being portalled to the
document body, maintaining proper interaction and accessibility behavior.

### Hidden Select

The `Select.HiddenSelect` component renders a native HTML `<select>` element that's visually hidden but remains in the
DOM. This component is essential for:

- **Form submission**: Native form submission and serialization work seamlessly since the actual `<select>` element
  exists in the DOM
- **Browser auto-fill**: Browsers can properly auto-fill the select based on previously submitted form data
- **Progressive enhancement**: Forms remain functional even if JavaScript fails to load

```tsx
<Select.Root>
  <Select.HiddenSelect />
  {/* Other Select components */}
</Select.Root>
```

The hidden select automatically syncs with the Select component's value, ensuring form data is always up-to-date.

### Empty State

You can create an empty state component that displays when there are no items in the collection. Use the
`useSelectContext` hook to check the collection size:

```tsx
const SelectEmpty = (props: React.ComponentProps<'div'>) => {
  const select = useSelectContext()
  if (select.collection.size === 0) {
    return <div {...props} role="presentation" />
  }
  return null
}
```

Then use it within your Select content:

```tsx
<Select.Content>
  <SelectEmpty>No items to display</SelectEmpty>
  {/* Your items */}
</Select.Content>
```

### Available Size

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

```css
/* width of the select trigger */
--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='select'][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 |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoComplete` | `string` | No | The autocomplete attribute for the hidden select. Enables browser autofill (e.g. "address-level1" for state). |
| `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected |
| `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox |
| `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened.
Use when you don't need to control the highlighted value of the select. |
| `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user |
| `defaultValue` | `string[]` | No | The initial default value of the select when rendered.
Use when you don't need to control the value of the select. |
| `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item.

**Note:** this is only applicable for single selection |
| `disabled` | `boolean` | No | Whether the select is disabled |
| `form` | `string` | No | The associate form of the underlying select. |
| `highlightedValue` | `string` | No | The controlled key of the highlighted item |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  content: string
  control: string
  trigger: string
  clearTrigger: string
  label: string
  hiddenSelect: string
  positioner: string
  item: (id: string | number) => string
  itemGroup: (id: string | number) => string
  itemGroupLabel: (id: string | number) => string
}>` | No | The ids of the elements in the select. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `invalid` | `boolean` | No | Whether the select is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options |
| `multiple` | `boolean` | No | Whether to allow multiple selection |
| `name` | `string` | No | The `name` attribute of the underlying select. |
| `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 | The callback fired when the highlighted item 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 | The callback fired when the selected item changes. |
| `open` | `boolean` | No | Whether the select menu is open |
| `positioning` | `PositioningOptions` | No | The positioning options of the menu. |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `readOnly` | `boolean` | No | Whether the select is read-only |
| `required` | `boolean` | No | Whether the select is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string[]` | No | The controlled keys of the selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[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]` | select |
| `[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]` | select |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-activedescendant]` | The id the active descendant of the content |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested selects |


**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]` | select |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**HiddenSelect Props:**

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


**Indicator Props:**

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


**Indicator Data Attributes:**

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


**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]` | select |
| `[data-part]` | item-group |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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]` | select |
| `[data-part]` | item |
| `[data-value]` | The value of the item |
| `[data-state]` | "checked" | "unchecked" |
| `[data-highlighted]` | Present when highlighted |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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]` | select |
| `[data-part]` | label |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-required]` | Present when required |


**List Props:**

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


**Positioner Props:**

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


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseSelectReturn<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. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-placement]` | The placement of the trigger |
| `[data-placeholder-shown]` | Present when placeholder is shown |


**ValueText Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `placeholder` | `string` | No | Text to display when no value is selected. |


**ValueText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | value-text |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


#### Solid

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `collection` | `ListCollection<T>` | Yes | The collection of items |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoComplete` | `string` | No | The autocomplete attribute for the hidden select. Enables browser autofill (e.g. "address-level1" for state). |
| `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected |
| `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox |
| `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened.
Use when you don't need to control the highlighted value of the select. |
| `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user |
| `defaultValue` | `string[]` | No | The initial default value of the select when rendered.
Use when you don't need to control the value of the select. |
| `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item.

**Note:** this is only applicable for single selection |
| `disabled` | `boolean` | No | Whether the select is disabled |
| `form` | `string` | No | The associate form of the underlying select. |
| `highlightedValue` | `string` | No | The controlled key of the highlighted item |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  content: string
  control: string
  trigger: string
  clearTrigger: string
  label: string
  hiddenSelect: string
  positioner: string
  item: (id: string | number) => string
  itemGroup: (id: string | number) => string
  itemGroupLabel: (id: string | number) => string
}>` | No | The ids of the elements in the select. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `invalid` | `boolean` | No | Whether the select is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options |
| `multiple` | `boolean` | No | Whether to allow multiple selection |
| `name` | `string` | No | The `name` attribute of the underlying select. |
| `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 | The callback fired when the highlighted item 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 | The callback fired when the selected item changes. |
| `open` | `boolean` | No | Whether the select menu is open |
| `positioning` | `PositioningOptions` | No | The positioning options of the menu. |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `readOnly` | `boolean` | No | Whether the select is read-only |
| `required` | `boolean` | No | Whether the select is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string[]` | No | The controlled keys of the selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[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]` | select |
| `[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]` | select |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-activedescendant]` | The id the active descendant of the content |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested selects |


**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]` | select |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**HiddenSelect Props:**

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


**Indicator 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. |


**Indicator Data Attributes:**

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


**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]` | select |
| `[data-part]` | item-group |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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]` | select |
| `[data-part]` | item |
| `[data-value]` | The value of the item |
| `[data-state]` | "checked" | "unchecked" |
| `[data-highlighted]` | Present when highlighted |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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]` | select |
| `[data-part]` | label |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-required]` | Present when required |


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


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


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseSelectReturn<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. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-placement]` | The placement of the trigger |
| `[data-placeholder-shown]` | Present when placeholder is shown |


**ValueText 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. |
| `placeholder` | `string` | No | Text to display when no value is selected. |


**ValueText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | value-text |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


#### Vue

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `collection` | `ListCollection<T>` | Yes | The collection of items |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoComplete` | `string` | No | The autocomplete attribute for the hidden select. Enables browser autofill (e.g. "address-level1" for state). |
| `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected |
| `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox |
| `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened.
Use when you don't need to control the highlighted value of the select. |
| `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user |
| `defaultValue` | `string[]` | No | The initial default value of the select when rendered.
Use when you don't need to control the value of the select. |
| `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item.

**Note:** this is only applicable for single selection |
| `disabled` | `boolean` | No | Whether the select is disabled |
| `form` | `string` | No | The associate form of the underlying select. |
| `highlightedValue` | `string` | No | The controlled key of the highlighted item |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  content: string
  control: string
  trigger: string
  clearTrigger: string
  label: string
  hiddenSelect: string
  positioner: string
  item(id: string | number): string
  itemGroup(id: string | number): string
  itemGroupLabel(id: string | number): string
}>` | No | The ids of the elements in the select. Useful for composition. |
| `invalid` | `boolean` | No | Whether the select is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options |
| `modelValue` | `string[]` | No | The model value of the select |
| `multiple` | `boolean` | No | Whether to allow multiple selection |
| `name` | `string` | No | The `name` attribute of the underlying select. |
| `open` | `boolean` | No | Whether the select menu is open |
| `positioning` | `PositioningOptions` | No | The positioning options of the menu. |
| `readOnly` | `boolean` | No | Whether the select is read-only |
| `required` | `boolean` | No | Whether the select is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[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]` | select |
| `[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]` | select |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-activedescendant]` | The id the active descendant of the content |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested selects |


**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]` | select |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**HiddenSelect Props:**

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


**Indicator Props:**

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


**Indicator Data Attributes:**

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


**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]` | select |
| `[data-part]` | item-group |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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]` | select |
| `[data-part]` | item |
| `[data-value]` | The value of the item |
| `[data-state]` | "checked" | "unchecked" |
| `[data-highlighted]` | Present when highlighted |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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]` | select |
| `[data-part]` | label |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-required]` | Present when required |


**List Props:**

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


**Positioner Props:**

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


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `SelectApi<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. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-placement]` | The placement of the trigger |
| `[data-placeholder-shown]` | Present when placeholder is shown |


**ValueText Props:**

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


**ValueText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | value-text |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


#### Svelte

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `collection` | `ListCollection<T>` | Yes | The collection of items |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoComplete` | `string` | No | The autocomplete attribute for the hidden select. Enables browser autofill (e.g. "address-level1" for state). |
| `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected |
| `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox |
| `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened.
Use when you don't need to control the highlighted value of the select. |
| `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user |
| `defaultValue` | `string[]` | No | The initial default value of the select when rendered.
Use when you don't need to control the value of the select. |
| `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item.

**Note:** this is only applicable for single selection |
| `disabled` | `boolean` | No | Whether the select is disabled |
| `form` | `string` | No | The associate form of the underlying select. |
| `highlightedValue` | `string` | No | The controlled key of the highlighted item |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  content: string
  control: string
  trigger: string
  clearTrigger: string
  label: string
  hiddenSelect: string
  positioner: string
  item: (id: string | number) => string
  itemGroup: (id: string | number) => string
  itemGroupLabel: (id: string | number) => string
}>` | No | The ids of the elements in the select. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `invalid` | `boolean` | No | Whether the select is invalid |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options |
| `multiple` | `boolean` | No | Whether to allow multiple selection |
| `name` | `string` | No | The `name` attribute of the underlying select. |
| `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 | The callback fired when the highlighted item 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 | The callback fired when the selected item changes. |
| `open` | `boolean` | No | Whether the select menu is open |
| `positioning` | `PositioningOptions` | No | The positioning options of the menu. |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `readOnly` | `boolean` | No | Whether the select is read-only |
| `ref` | `Element` | No |  |
| `required` | `boolean` | No | Whether the select is required |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
| `value` | `string[]` | No | The controlled keys of the selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[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]` | select |
| `[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]` | select |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | listbox |
| `[data-has-nested]` | listbox |
| `[data-placement]` | The placement of the content |
| `[data-activedescendant]` | The id the active descendant of the content |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested selects |


**Context Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseSelectReturn<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]` | select |
| `[data-part]` | control |
| `[data-state]` | "open" | "closed" |
| `[data-focus]` | Present when focused |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |


**HiddenSelect Props:**

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


**Indicator 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 |  |


**Indicator Data Attributes:**

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


**ItemContext Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseSelectItemContext]>` | 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]` | select |
| `[data-part]` | item-group |
| `[data-disabled]` | Present when disabled |


**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]` | select |
| `[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. |
| `disabled` | `boolean` | No |  |
| `item` | `NonNullable<T>` | No |  |
| `ref` | `Element` | No |  |


**Item Data Attributes:**

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


**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]` | select |
| `[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]` | select |
| `[data-part]` | label |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-required]` | Present when required |


**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 |  |


**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 |  |


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseSelectReturn<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]` | select |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-readonly]` | Present when read-only |
| `[data-placement]` | The placement of the trigger |
| `[data-placeholder-shown]` | Present when placeholder is shown |


**ValueText 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. |
| `placeholder` | `string` | No |  |
| `ref` | `Element` | No |  |


**ValueText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | select |
| `[data-part]` | value-text |
| `[data-disabled]` | Present when disabled |
| `[data-invalid]` | Present when invalid |
| `[data-focus]` | Present when focused |


### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `focused` | `boolean` | Whether the select is focused |
| `open` | `boolean` | Whether the select is open |
| `empty` | `boolean` | Whether the select value is empty |
| `highlightedValue` | `string` | The value of the highlighted item |
| `highlightedItem` | `V` | The highlighted item |
| `setHighlightValue` | `(value: string) => void` | Function to highlight a value |
| `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value |
| `selectedItems` | `V[]` | The selected items |
| `hasSelectedItems` | `boolean` | Whether there's a selected option |
| `value` | `string[]` | The selected item keys |
| `valueAsString` | `string` | The string representation of the selected items |
| `selectValue` | `(value: string) => void` | Function to select a value |
| `selectAll` | `VoidFunction` | Function to select all values |
| `setValue` | `(value: string[]) => void` | Function to set the value of the select |
| `clearValue` | `(value?: string) => void` | Function to clear the value of the select.
If a value is provided, it will only clear that value, otherwise, it will clear all values. |
| `focus` | `VoidFunction` | Function to focus on the select input |
| `getItemState` | `(props: ItemProps<any>) => ItemState` | Returns the state of a select item |
| `setOpen` | `(open: boolean) => void` | Function to open or close the select |
| `collection` | `ListCollection<V>` | Function to toggle the select |
| `reposition` | `(options?: Partial<PositioningOptions>) => void` | Function to set the positioning options of the select |
| `multiple` | `boolean` | Whether the select allows multiple selections |
| `disabled` | `boolean` | Whether the select is disabled |


## Accessibility

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

### Keyboard Support

<KeyBindingsTable id="select" />