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
import {
Select,
SelectContent,
SelectTrigger,
SelectValue,
} from "@ui-sdk/solid/select"
function Example() {
return (
<Select items={["Apple", "Banana", "Pear"]}>
<SelectTrigger aria-label="Fruit">
<SelectValue placeholder="Choose a fruit" />
</SelectTrigger>
<SelectContent />
</Select>
)
}
export { Example }Each string is both the value and its label. Use objects when those need to differ:
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" }. Type the array with ListData, so each entry is checked where you write it:
import type { ListData } from "@ui-sdk/solid/select"
const fruits: ListData = [
{ value: "apple", label: "Apple", keywords: ["red"] },
{ type: "separator" },
{ type: "group", label: "Citrus", items: ["Lemon", "Lime"] },
]Command, Menu and Trigger Menu take the same entries, plus fields of their own like a command's shortcut. Type them with CommandData, MenuData and TriggerMenuData. Tree takes TreeItemData[].
For object values, provide itemToValue for the submitted string and itemToLabel for the displayed text. Select and Combobox show complete examples.
Style the Items
Items from data render as bare parts, with no classes, check marks or arrows. To style them, render the parts yourself. For an array you have, loop over it with For, with your classes inline:
import {
Select,
SelectContent,
SelectItem,
SelectItemIndicator,
SelectTrigger,
SelectValue,
} from "@ui-sdk/solid/select"
import { For } from "solid-js"
const fruits = [
{ value: "apple", label: "Apple" },
{ value: "banana", label: "Banana" },
]
function Example() {
return (
<Select items={fruits}>
<SelectTrigger aria-label="Fruit">
<SelectValue placeholder="Choose a fruit" />
</SelectTrigger>
<SelectContent class="rounded-2xl bg-white p-1">
<For each={fruits}>
{(fruit) => (
<SelectItem
value={fruit.value}
class="flex rounded-xl px-2 py-1.5 data-highlighted:bg-neutral-100"
>
{fruit.label}
<SelectItemIndicator class="ms-auto">✓</SelectItemIndicator>
</SelectItem>
)}
</For>
</SelectContent>
</Select>
)
}
export { Example }Keeping items on the select lets it show the chosen label before the list first renders. Searchable components still filter the items you render: the ones that don't match are hidden.
Items that only exist in state, like results from a server, render from the list's children function, with state.items:
<ComboboxList>
{(state) => (
<For each={state.items as { value: string; label: string }[]}>
{(item) => (
<ComboboxItem
value={item.value}
class="rounded-xl px-2 py-1.5 data-highlighted:bg-neutral-100"
>
{item.label}
</ComboboxItem>
)}
</For>
)}
</ComboboxList>Search and Load Items
Searchable components accept a filter to change how typing narrows their items. Async Options handles server results, debouncing, and stale requests.
Data lists can virtualize large collections. You don't need to render every item yourself.
Define a Menu
A MenuData array describes actions, separators, groups, and submenus. A plain string is an action whose value and label are the string:
import { Menu, MenuTrigger, type MenuData } from "@ui-sdk/solid/menu"
function Example() {
const actions: MenuData = [
{ value: "open", label: "Open", shortcut: "mod+o" },
{ type: "separator" },
{
type: "submenu",
label: "Share",
items: [{ value: "email", label: "Email" }],
},
]
return (
<Menu items={actions} onAction={(value) => console.log(value)}>
<MenuTrigger>File</MenuTrigger>
</Menu>
)
}
export { Example }To style it, put your own MenuContent in the menu and render its items from the same array, as Menu 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 covers registering your own.