# Listbox

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

A component for selecting a single or multiple items from a list.

---

<ComponentPreview id="Listbox" />

## Anatomy

{/* <Anatomy id="listbox" /> */}

```tsx
<Listbox.Root>
  <Listbox.Label />
  <Listbox.Content>
    <Listbox.ItemGroup>
      <Listbox.ItemGroupLabel />
      <Listbox.Item>
        <Listbox.ItemText />
        <Listbox.ItemIndicator />
      </Listbox.Item>
    </Listbox.ItemGroup>
  </Listbox.Content>
  <Listbox.ValueText />
</Listbox.Root>
```

## Examples

### Basic

Here's a basic example of the Listbox component.

**Example: basic**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component Basic() {
  const collection = createListCollection(
    {
      items: [
        { label: 'United States', value: 'us' },
        { label: 'United Kingdom', value: 'uk' },
        { label: 'Canada', value: 'ca' },
        { label: 'Australia', value: 'au' },
        { label: 'Germany', value: 'de' },
        { label: 'France', value: 'fr' },
        { label: 'Japan', value: 'jp' },
      ],
    },
  );

  <Listbox.Root class={styles.Root} {collection}>
    <Listbox.Label class={styles.Label}>{'Select Country'}</Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Controlled

The Listbox component can be controlled by using the `value` and `onValueChange` props. This allows you to manage the
selected value externally.

**Example: controlled**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import { track } from 'ripple';
import styles from 'styles/listbox.module.css';

export component Controlled() {
  const collection = createListCollection(
    {
      items: [
        { label: 'Small', value: 'sm' },
        { label: 'Medium', value: 'md' },
        { label: 'Large', value: 'lg' },
        { label: 'Extra Large', value: 'xl' },
      ],
    },
  );

  let value = track(['md']);

  <Listbox.Root
    class={styles.Root}
    {collection}
    {value}
    onValueChange={(e) => {
      @value = e.value;
    }}
  >
    <Listbox.Label class={styles.Label}>{'Select Size'}</Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Root Provider

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

**Example: root-provider**

```ripple
import { Listbox, createListCollection, useListbox } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import button from 'styles/button.module.css';
import styles from 'styles/listbox.module.css';

export component RootProvider() {
  const collection = createListCollection(
    {
      items: [
        { label: 'Low', value: 'low' },
        { label: 'Medium', value: 'medium' },
        { label: 'High', value: 'high' },
        { label: 'Critical', value: 'critical' },
      ],
    },
  );

  const listbox = useListbox({ collection });

  <div class="stack">
    <button
      type="button"
      class={button.Root}
      onClick={() => {
        @listbox.setValue(['high']);
      }}
    >
      {'Set to High'}
    </button>
    <Listbox.RootProvider class={styles.Root} value={listbox}>
      <Listbox.Label class={styles.Label}>{'Select Priority'}</Listbox.Label>
      <Listbox.Content class={styles.Content}>
        for (const item of collection.items; key item.value) {
          <Listbox.Item class={styles.Item} {item}>
            <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
            <Listbox.ItemIndicator class={styles.ItemIndicator}>
              <Check />
            </Listbox.ItemIndicator>
          </Listbox.Item>
        }
      </Listbox.Content>
    </Listbox.RootProvider>
  </div>
}

```

### Disabled Item

Listbox items can be disabled using the `disabled` prop on the collection item.

**Example: disabled-item**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component DisabledItem() {
  const collection = createListCollection(
    {
      items: [
        { label: 'Free', value: 'free' },
        { label: 'Pro', value: 'pro' },
        { label: 'Enterprise', value: 'enterprise', disabled: true },
        { label: 'Custom', value: 'custom' },
      ],
    },
  );

  <Listbox.Root class={styles.Root} {collection}>
    <Listbox.Label class={styles.Label}>{'Select Plan'}</Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

> You can also use the `isItemDisabled` within the `createListCollection` to disable items based on a condition.

### Multiple

You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time.

**Example: multiple**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component Multiple() {
  const collection = createListCollection(
    {
      items: [
        { label: 'Monday', value: 'mon' },
        { label: 'Tuesday', value: 'tue' },
        { label: 'Wednesday', value: 'wed' },
        { label: 'Thursday', value: 'thu' },
        { label: 'Friday', value: 'fri' },
        { label: 'Saturday', value: 'sat' },
        { label: 'Sunday', value: 'sun' },
      ],
    },
  );

  <Listbox.Root class={styles.Root} {collection} selectionMode="multiple">
    <Listbox.Label class={styles.Label}>{'Select Days'}</Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Grouping

The Listbox component supports grouping items. You can use the `groupBy` function to group items based on a specific
property.

**Example: group**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component Group() {
  const collection = createListCollection(
    {
      items: [
        { label: 'New York', value: 'nyc', region: 'North America' },
        { label: 'Los Angeles', value: 'lax', region: 'North America' },
        { label: 'Toronto', value: 'yyz', region: 'North America' },
        { label: 'London', value: 'lhr', region: 'Europe' },
        { label: 'Paris', value: 'cdg', region: 'Europe' },
        { label: 'Berlin', value: 'ber', region: 'Europe' },
        { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' },
        { label: 'Singapore', value: 'sin', region: 'Asia Pacific' },
        { label: 'Sydney', value: 'syd', region: 'Asia Pacific' },
      ],
      groupBy: (item) => item.region,
    },
  );

  <Listbox.Root class={styles.Root} {collection}>
    <Listbox.Label class={styles.Label}>{'Select Region'}</Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const [region, items] of collection.group(); key region) {
        <Listbox.ItemGroup class={styles.ItemGroup}>
          <Listbox.ItemGroupLabel class={styles.ItemGroupLabel}>{region}</Listbox.ItemGroupLabel>
          for (const item of items; key item.value) {
            <Listbox.Item class={styles.Item} {item}>
              <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
              <Listbox.ItemIndicator class={styles.ItemIndicator}>
                <Check />
              </Listbox.ItemIndicator>
            </Listbox.Item>
          }
        </Listbox.ItemGroup>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Extended Selection

The extended selection mode allows users to select multiple items using keyboard modifiers like `Cmd` (Mac) or `Ctrl`
(Windows/Linux).

**Example: extended-select**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component ExtendedSelect() {
  const collection = createListCollection(
    {
      items: [
        { label: 'React', value: 'react' },
        { label: 'Vue', value: 'vue' },
        { label: 'Angular', value: 'angular' },
        { label: 'Svelte', value: 'svelte' },
        { label: 'Solid', value: 'solid' },
        { label: 'Preact', value: 'preact' },
      ],
    },
  );

  <Listbox.Root class={styles.Root} {collection} selectionMode="extended">
    <Listbox.Label class={styles.Label}>
      {'Hold '}
      <kbd>{'⌘'}</kbd>
      {' or '}
      <kbd>{'Ctrl'}</kbd>
      {' to select multiple'}
    </Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Horizontal

Use the `orientation` prop to display the listbox items horizontally.

**Example: horizontal**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component Horizontal() {
  const collection = createListCollection(
    {
      items: [
        {
          title: 'Midnight Dreams',
          artist: 'Luna Ray',
          image: 'https://picsum.photos/seed/album1/300/300',
        },
        {
          title: 'Neon Skyline',
          artist: 'The Electric',
          image: 'https://picsum.photos/seed/album2/300/300',
        },
        {
          title: 'Acoustic Sessions',
          artist: 'Sarah Woods',
          image: 'https://picsum.photos/seed/album3/300/300',
        },
        {
          title: 'Urban Echoes',
          artist: 'Metro Collective',
          image: 'https://picsum.photos/seed/album4/300/300',
        },
        {
          title: 'Summer Vibes',
          artist: 'Coastal Waves',
          image: 'https://picsum.photos/seed/album5/300/300',
        },
      ],
      itemToValue: (item) => item.title,
      itemToString: (item) => item.title,
    },
  );

  <Listbox.Root class={styles.Root} {collection} orientation="horizontal">
    <Listbox.Label class={styles.Label}>{'Select Album'}</Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.title) {
        <Listbox.Item class={styles.ItemCard} {item}>
          <Listbox.ItemIndicator class={styles.ItemCardIndicator}>
            <Check />
          </Listbox.ItemIndicator>
          <img class={styles.ItemCardImage} src={item.image} alt={item.title} />
          <span class={styles.ItemCardTitle}>{item.title}</span>
          <span class={styles.ItemCardArtist}>{item.artist}</span>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Grid Layout

Use `createGridCollection` to display items in a grid layout with keyboard navigation support.

**Example: grid**

```ripple
import { createGridCollection } from 'ark-ripple/collection';
import { Listbox } from 'ark-ripple/listbox';
import styles from 'styles/listbox.module.css';

export component Grid() {
  const collection = createGridCollection(
    {
      items: [
        { label: '😀', value: 'grinning' },
        { label: '😍', value: 'heart-eyes' },
        { label: '🥳', value: 'partying' },
        { label: '😎', value: 'sunglasses' },
        { label: '🤩', value: 'star-struck' },
        { label: '😂', value: 'joy' },
        { label: '🥰', value: 'smiling-hearts' },
        { label: '😊', value: 'blush' },
        { label: '🤗', value: 'hugging' },
        { label: '😇', value: 'innocent' },
        { label: '🔥', value: 'fire' },
        { label: '✨', value: 'sparkles' },
        { label: '💯', value: 'hundred' },
        { label: '🎉', value: 'tada' },
        { label: '❤️', value: 'heart' },
        { label: '👍', value: 'thumbs-up' },
        { label: '👏', value: 'clap' },
        { label: '🚀', value: 'rocket' },
        { label: '⭐', value: 'star' },
        { label: '🌈', value: 'rainbow' },
      ],
      columnCount: 5,
    },
  );

  <Listbox.Root class={styles.Root} {collection}>
    <Listbox.Label class={styles.Label}>{'Pick a reaction'}</Listbox.Label>
    <Listbox.Content class={styles.GridContent}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.GridItem} {item}>
          <Listbox.ItemText>{item.label}</Listbox.ItemText>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Filtering

Use `useListCollection` with the `filter` function to enable filtering of items.

**Example: filtering**

```ripple
import { useListCollection } from 'ark-ripple/collection';
import { Listbox } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import field from 'styles/field.module.css';
import styles from 'styles/listbox.module.css';

export component Filtering() {
  const { collection, filter } = useListCollection(
    {
      initialItems: [
        { label: 'React', value: 'react' },
        { label: 'Vue', value: 'vue' },
        { label: 'Angular', value: 'angular' },
        { label: 'Svelte', value: 'svelte' },
        { label: 'Solid', value: 'solid' },
        { label: 'Next.js', value: 'nextjs' },
        { label: 'Nuxt.js', value: 'nuxtjs' },
        { label: 'Remix', value: 'remix' },
        { label: 'Gatsby', value: 'gatsby' },
        { label: 'Preact', value: 'preact' },
      ],
      filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()),
    },
  );

  <Listbox.Root class={styles.Root} {collection}>
    <Listbox.Label class={styles.Label}>{'Select Framework'}</Listbox.Label>
    <Listbox.Input
      class={field.Input}
      placeholder="Search frameworks..."
      onInput={(e: Event) => filter((e.target as HTMLInputElement).value)}
    />
    <Listbox.Content class={styles.Content}>
      for (const item of @collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
      <Listbox.Empty class={styles.Empty}>{'No frameworks found'}</Listbox.Empty>
    </Listbox.Content>
  </Listbox.Root>
}

```

### Select All

Use `useListboxContext` to implement a "Select All" functionality that allows users to select or deselect all items at
once.

**Example: select-all**

```ripple
import { Listbox, createListCollection, useListboxContext } from 'ark-ripple/listbox';
import { Check, Minus } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

const frameworks = createListCollection(
  {
    items: [
      { label: 'React', value: 'react' },
      { label: 'Vue', value: 'vue' },
      { label: 'Angular', value: 'angular' },
      { label: 'Svelte', value: 'svelte' },
      { label: 'Next.js', value: 'nextjs' },
      { label: 'Nuxt.js', value: 'nuxtjs' },
      { label: 'Remix', value: 'remix' },
      { label: 'Gatsby', value: 'gatsby' },
    ],
  },
);

component SelectAllHeader() {
  const listbox = useListboxContext();
  const isAllSelected = @listbox.value.length === frameworks.items.length;
  const isSomeSelected =
    @listbox.value.length > 0 && @listbox.value.length < frameworks.items.length;

  const handleSelectAll = () => {
    if (isAllSelected) {
      @listbox.setValue([]);
    } else {
      @listbox.setValue(frameworks.items.map((item) => item.value));
    }
  };

  <button class={styles.SelectAllHeader} type="button" onClick={handleSelectAll}>
    <span class={styles.SelectAllHeaderIndicator}>
      if (isAllSelected) {
        <Check />
      } else if (isSomeSelected) {
        <Minus />
      }
    </span>
    <span class={styles.Label}>{'Select All'}</span>
  </button>
}

export component SelectAll() {
  <Listbox.Root class={styles.Root} collection={frameworks} selectionMode="multiple">
    <SelectAllHeader />
    <Listbox.Content class={styles.Content}>
      for (const item of frameworks.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

### Value Text

Use `Listbox.ValueText` to display the selected values as a comma-separated string.

**Example: value-text**

```ripple
import { Listbox, createListCollection } from 'ark-ripple/listbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/listbox.module.css';

export component ValueText() {
  const collection = createListCollection(
    {
      items: [
        { label: 'Red', value: 'red' },
        { label: 'Blue', value: 'blue' },
        { label: 'Green', value: 'green' },
        { label: 'Yellow', value: 'yellow' },
        { label: 'Purple', value: 'purple' },
      ],
    },
  );

  <Listbox.Root
    class={styles.Root}
    {collection}
    selectionMode="multiple"
    defaultValue={['red', 'blue']}
  >
    <Listbox.Label class={styles.Label}>
      {'Colors: '}
      <Listbox.ValueText class={styles.ValueText} />
    </Listbox.Label>
    <Listbox.Content class={styles.Content}>
      for (const item of collection.items; key item.value) {
        <Listbox.Item class={styles.Item} {item}>
          <Listbox.ItemText class={styles.ItemText}>{item.label}</Listbox.ItemText>
          <Listbox.ItemIndicator class={styles.ItemIndicator}>
            <Check />
          </Listbox.ItemIndicator>
        </Listbox.Item>
      }
    </Listbox.Content>
  </Listbox.Root>
}

```

## API Reference

### Props

**Component API Reference**

**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. |
| `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 listbox. |
| `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered.
Use when you don't need to control the value of the listbox. |
| `deselectable` | `boolean` | No | Whether to disallow empty selection |
| `disabled` | `boolean` | No | Whether the listbox is disabled |
| `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed |
| `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
  label: string
  item: (id: string | number) => string
  itemGroup: (id: string | number) => string
  itemGroupLabel: (id: string | number) => string
}>` | No | The ids of the elements in the listbox. Useful for composition. |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options |
| `onHighlightChange` | `(details: HighlightChangeDetails<T>) => void` | No | The callback fired when the highlighted item changes. |
| `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. |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. |
| `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index |
| `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox.

- `single`: The user can select a single item.
- `multiple`: The user can select multiple items without using modifier keys.
- `extended`: The user can select multiple items by using modifier keys. |
| `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted |
| `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox |
| `value` | `string[]` | No | The controlled keys of the selected items |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | listbox |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the listbox |
| `[data-disabled]` | Present when disabled |


**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]` | listbox |
| `[data-part]` | content |
| `[data-activedescendant]` | The id the active descendant of the content |
| `[data-orientation]` | The orientation of the content |
| `[data-layout]` |  |
| `[data-empty]` | Present when the content is empty |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--column-count` | The column count value for the Content |


**Empty Props:**

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


**Input Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing |


**Input Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | listbox |
| `[data-part]` | input |
| `[data-disabled]` | Present when disabled |


**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]` | listbox |
| `[data-part]` | item-group |
| `[data-disabled]` | Present when disabled |
| `[data-orientation]` | The orientation of the item |
| `[data-empty]` | Present when the content is empty |


**ItemIndicator Props:**

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


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | listbox |
| `[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. |
| `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover |
| `item` | `any` | No | The item to render |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | listbox |
| `[data-part]` | item |
| `[data-value]` | The value of the item |
| `[data-selected]` | Present when selected |
| `[data-layout]` |  |
| `[data-state]` | "checked" | "unchecked" |
| `[data-orientation]` | The orientation of the item |
| `[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]` | listbox |
| `[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]` | listbox |
| `[data-part]` | label |
| `[data-disabled]` | Present when disabled |


**RootProvider Props:**

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


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


**ValueText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | listbox |
| `[data-part]` | value-text |
| `[data-disabled]` | Present when disabled |


### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `empty` | `boolean` | Whether the select value is empty |
| `highlightedValue` | `string` | The value of the highlighted item |
| `highlightedItem` | `V` | The highlighted item |
| `highlightValue` | `(value: string) => void` | Function to highlight a value |
| `clearHighlightedValue` | `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.

**Note**: This should only be called when the selectionMode is `multiple` or `extended`.
Otherwise, an exception will be thrown. |
| `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. |
| `getItemState` | `(props: ItemProps<any>) => ItemState` | Returns the state of a select item |
| `collection` | `ListCollection<V>` | Function to toggle the select |
| `disabled` | `boolean` | Whether the select is disabled |
