Listbox
Searchable, keyboard-navigable list. Built on reka-ui's Listbox with aurora's automatic filtering on top.
Unlike Combobox, this is not a form element — it's a standalone filterable list you compose into popovers, sidebars, or any container. Use it when you want filtering + keyboard nav without the form-input chrome.
The four pieces:
Listbox— root, manages selection and provides filter contextListboxInput— search field, auto-filters items by their text contentListboxContent— scrollable container for itemsListboxItem— selectable item; self-registers its text for filteringListboxEmpty— renders when the search matches nothing
Basic
Apple
Banana
Cherry
Durian
Elderberry
Fig
Grape
Honeydew
Kiwi
Lemon
Mango
html
<Listbox v-model="selected">
<ListboxInput placeholder="Search…" />
<ListboxContent>
<ListboxItem v-for="f in fruits" :key="f" :value="f.toLowerCase()">
{{ f }}
</ListboxItem>
<ListboxEmpty>No matches</ListboxEmpty>
</ListboxContent>
</Listbox>Custom item content
ListboxItem accepts arbitrary slot content. Filtering uses each item's rendered text — composite items still match against everything inside.
United StatesUS
United KingdomGB
GermanyDE
FranceFR
JapanJP
BrazilBR
AustraliaAU
html
<Listbox v-model="country">
<ListboxInput placeholder="Search countries…" />
<ListboxContent>
<ListboxItem v-for="c in countries" :key="c.value" :value="c.value">
<span class="truncate">{{ c.label }}</span>
<span class="ml-auto text-secondary paragraph-2xs">{{ c.value.toUpperCase() }}</span>
</ListboxItem>
<ListboxEmpty>No countries found</ListboxEmpty>
</ListboxContent>
</Listbox>Inside a Popper (dropdown pattern)
Listbox + Popper is the canonical way to build a click-to-open searchable picker without using Combobox (which is a form input).
html
<Popper v-model:is-open="isOpen" placement="bottom-start">
<PopperTrigger>
<Tag clickable outline>{{ selected || 'Pick one' }}</Tag>
</PopperTrigger>
<PopperContent>
<div class="w-72 rounded-2 border border-primary bg-white shadow-300 overflow-hidden">
<Listbox v-model="selected">
<ListboxInput placeholder="Search…" />
<ListboxContent>
<ListboxItem v-for="item in items" :key="item" :value="item">
{{ item }}
</ListboxItem>
<ListboxEmpty>No results</ListboxEmpty>
</ListboxContent>
</Listbox>
</div>
</PopperContent>
</Popper>Listbox — Props
Listbox extends reka-ui's ListboxRoot — every prop documented there is accepted. Most-used:
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | string[] | '' | Selected value(s). Use v-model. |
multiple | boolean | false | Allow multi-selection (modelValue becomes an array). |
disabled | boolean | false | Disable the entire listbox. |
class | string | — | Additional classes for the root. |
ListboxInput
Search input with auto-focus on mount. Text typed here filters the items in real time (case-insensitive substring match against each item's rendered text).
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | — | Additional classes. |
Also forwards reka-ui's ListboxFilterProps.
ListboxContent
Scrollable container for the items. Add max-h-* and overflow-auto (or use the default styling) to constrain long lists.
ListboxItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | AcceptableValue | required | Item value used by v-model. |
disabled | boolean | false | Disable selection. |
class | string | — | Additional classes. |
Items hide automatically when their rendered text doesn't match the current search term.
ListboxEmpty
Renders only when the user has typed something and zero items match. Slot content is whatever you want to display.
html
<ListboxEmpty>No results</ListboxEmpty>