# Lists and Menus

Supply options as data, load them from a server, and define menu actions.

Select, Combobox, Autocomplete, Listbox, and Trigger Menu accept items as data. Use this when your choices already come from an array. You can also compose their item parts yourself.

## Start with Strings

```vue
<script setup lang="ts">
import {
  Select,
  SelectContent,
  SelectTrigger,
  SelectValue,
} from "@ui-sdk/vue/select"
</script>

<template>
  <Select :items="['Apple', 'Banana', 'Pear']">
    <SelectTrigger aria-label="Fruit"
      ><SelectValue placeholder="Choose a fruit"
    /></SelectTrigger>
    <SelectContent />
  </Select>
</template>
```

Each string is both the value and its label. Use objects when those need to differ:

```ts
const items = [
  { value: "apple", label: "Apple" },
  { value: "banana", label: "Banana", disabled: true },
]
```

Items can have `keywords` for searching. Group them with `{ type: "group", label, items }`, or separate them with `{ type: "separator" }`.

For object values, provide `item-to-value` for the submitted string and `item-to-label` for the displayed text. [Select](/docs/vue/components/select) and [Combobox](/docs/vue/components/combobox) show complete examples.

## Style the Items

Items as data render bare parts, each with just its label. To style them, render the parts yourself from your array, with your classes right on them. Type the array with `ListData`, so a mistake in it shows up where you write it:

```vue
<script setup lang="ts">
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  type ListData,
} from "@ui-sdk/vue/select"

const fruits = [
  { value: "apple", label: "Apple" },
  { value: "banana", label: "Banana" },
] satisfies ListData
</script>

<template>
  <Select :items="fruits">
    <SelectTrigger aria-label="Fruit" class="…"
      ><SelectValue placeholder="Choose a fruit"
    /></SelectTrigger>
    <SelectContent class="…">
      <SelectItem
        v-for="fruit in fruits"
        :key="fruit.value"
        :value="fruit.value"
        class="…"
      >
        {{ fruit.label }}
      </SelectItem>
    </SelectContent>
  </Select>
</template>
```

A list that searches still filters the items you render, and hides the ones that don't match. When the items come from state, like results from a server, the list part's slot gives you the ones to show. Write `<SelectList v-slot="{ state }">` and render `state.items`.

## Search and Load Items

Searchable components accept a `filter` to change how typing narrows their items. [Async Options](/docs/vue/utilities/async-options) handles server results, debouncing, and stale requests.

Data lists can virtualize large collections. You don't need to render every item yourself.

## Describe a Menu

A `MenuData` array describes actions, separators, groups, and submenus. A plain string is an action whose value and label are the string:

```vue
<script setup lang="ts">
import { Menu, MenuTrigger, type MenuData } from "@ui-sdk/vue/menu"

const actions: MenuData = [
  { value: "open", label: "Open", shortcut: "mod+o" },
  { type: "separator" },
  {
    type: "submenu",
    label: "Share",
    items: [{ value: "email", label: "Email" }],
  },
]
</script>

<template>
  <Menu :items="actions" @action="(value: string) => console.log(value)">
    <MenuTrigger>File</MenuTrigger>
  </Menu>
</template>
```

A data menu renders bare parts too. To style it, place a `MenuContent` of your own and render the items in it, as [Menu](/docs/vue/components/menu#menus-as-data) shows. That page also covers checkbox items, radio groups, and nested menus.

## Keys and Shortcuts

`loop` controls whether arrow keys wrap around a list. Components that support `orientation` use it to choose the navigation axis.

A trigger's `shortcut="mod+k"` opens it from elsewhere on the page. A data menu runs item shortcuts while closed; a manually rendered MenuItem's shortcut only displays the keys. [Shortcuts](/docs/vue/utilities/shortcuts) covers registering your own.
