Listbox
Move through a visible option list and select one or several values.
Usage
Single
Keep one active value while moving and selecting with keyboard or pointer input.
Keep one active value while moving and selecting with keyboard or pointer input.
<!-- Listbox / Single -->
<script setup lang="ts">
import { ListboxItem, ListboxItemIndicator, ListboxItemText, ListboxRoot } from '@sectile/vue/listbox'
const items = ['production', 'staging', 'development']
</script>
<template>
<ListboxRoot
:items="items"
selection-mode="single"
:default-value="'production'"
>
<ListboxItem v-for="item in items" :key="item" :value="item">
<ListboxItemText>{{ item }}</ListboxItemText>
<ListboxItemIndicator>Selected</ListboxItemIndicator>
</ListboxItem>
</ListboxRoot>
</template>Multiple
Select several values independently without collapsing the existing selection.
Select several values independently without collapsing the existing selection.
<!-- Listbox / Multiple -->
<script setup lang="ts">
import { ListboxItem, ListboxItemIndicator, ListboxItemText, ListboxRoot } from '@sectile/vue/listbox'
const items = ['production', 'staging', 'development']
</script>
<template>
<ListboxRoot
:items="items"
selection-mode="multiple"
:default-value="['production', 'development']"
>
<ListboxItem v-for="item in items" :key="item" :value="item">
<ListboxItemText>{{ item }}</ListboxItemText>
<ListboxItemIndicator>Selected</ListboxItemIndicator>
</ListboxItem>
</ListboxRoot>
</template>Follow focus
Move selection together with the active listbox item.
Move selection together with the active listbox item.
<!-- Listbox / Follow Focus -->
<script setup lang="ts">
import { ListboxItem, ListboxItemIndicator, ListboxItemText, ListboxRoot } from '@sectile/vue/listbox'
const items = ['production', 'staging', 'development']
</script>
<template>
<ListboxRoot
:items="items"
selection-mode="single"
:default-value="'production'"
>
<ListboxItem v-for="item in items" :key="item" :value="item">
<ListboxItemText>{{ item }}</ListboxItemText>
<ListboxItemIndicator>Selected</ListboxItemIndicator>
</ListboxItem>
</ListboxRoot>
</template>Controlled
Let the parent own the current value and apply accepted changes back to the component.
Let the parent own the current value and apply accepted changes back to the component.
<!-- Listbox / Controlled -->
<script setup lang="ts">
import { ListboxItem, ListboxItemIndicator, ListboxItemText, ListboxRoot } from '@sectile/vue/listbox'
const items = ['production', 'staging', 'development']
</script>
<template>
<ListboxRoot
:items="items"
selection-mode="single"
:default-value="'production'"
>
<ListboxItem v-for="item in items" :key="item" :value="item">
<ListboxItemText>{{ item }}</ListboxItemText>
<ListboxItemIndicator>Selected</ListboxItemIndicator>
</ListboxItem>
</ListboxRoot>
</template>API
Vue package: @sectile/vue/listbox
ListboxRootListboxItemListboxItemTextListboxItemIndicator
Props
ListboxRootProps
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
defaultValueInitial value used when the component owns its state.
disabledWhether interaction is unavailable.
disabledItemsItem values excluded from focus and selection.
formID of the native form associated with the control.
itemsOrdered item values managed by the component.
modelValueCurrent value when state is controlled by the parent.
nameName used for native form submission.
orientationAxis used for layout and keyboard movement.
readonlyWhether the value can be inspected but not changed.
requiredWhether the control must contain a valid value before submission.
selectionModeWhether selection contains one value or multiple values.
textValueReturns searchable or presentational text for an item value.
ListboxItemProps
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
disabledWhether interaction is unavailable.
valueCurrent value exposed by this contract.
ListboxPartProps
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
Slots
ListboxRootSlotProps
disabledWhether interaction is unavailable.
highlightedValueValue currently highlighted for interaction.
readonlyWhether the value can be inspected but not changed.
valueCurrent value exposed by this contract.
ListboxItemSlotProps
disabledWhether interaction is unavailable.
highlightedWhether this item is highlighted for interaction.
selectedWhether this item is selected.
valueCurrent value exposed by this contract.
Events
ListboxRoot
activateEmitted when an item becomes active.
highlightEmitted when the highlighted item changes.
update:modelValueEmitted when the component requests a new controlled value.
Other types
ListboxSelectionMode
type ListboxSelectionMode = 'single' | 'multiple'ListboxValue
type ListboxValue = string | readonly string[]ListboxTextValueResolver
type ListboxTextValueResolver = NonNullable<ListboxRootProps['textValue']>ListboxValueChangeHandler
type ListboxValueChangeHandler = (value: ListboxValue) => voidListboxHighlightHandler
type ListboxHighlightHandler = (value: string | null) => voidListboxActivateHandler
type ListboxActivateHandler = (value: string) => voidParts
Shared scope: [data-scope="listbox"]. Combine it with a part selector to keep styles local to this component.
| Part | Selector | Role | Extra attributes |
|---|---|---|---|
root | [data-part="root"] | Defines the component boundary and owns its composed parts. | — |
item | [data-part="item"] | Represents one selectable or actionable item. | — |
item-text | [data-part="item-text"] | Renders the item label independently from its controls. | — |
item-indicator | [data-part="item-indicator"] | Shows the item selection state. | — |
Keyboard interaction
| Key | Behavior |
|---|---|
| Arrow keys | Move the active option in the visible orientation. |
| Home / End | Move to the first or last eligible option. |
| Enter / Space | Select or activate the current option. |
| Printable text | Move to the next matching option when typeahead is available. |
Accessibility
The labeled listbox exposes active, selected, and disabled option state without moving DOM focus to every item.
See the corresponding WAI-ARIA pattern for the host accessibility contract.
