<script setup>
import {
SelectionList,
createSelectionListCollection,
} from "@dicehub/kappa/components/selection-list";
const profiles = createSelectionListCollection({
items: [
{ value: "balanced", label: "Balanced", detail: "8 CPU · 32 GB" },
{ value: "fast", label: "Fast turnaround", detail: "32 CPU · 64 GB" },
],
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
</script>
<template>
<SelectionList.Root :collection="profiles" :default-value="['balanced']">
<SelectionList.Label>Compute profile</SelectionList.Label>
<SelectionList.Content>
<SelectionList.Item v-for="item in profiles.items" :key="item.value" :item="item">
<SelectionList.ItemContent>
<SelectionList.ItemText>{{ item.label }}</SelectionList.ItemText>
<SelectionList.ItemDescription>{{ item.detail }}</SelectionList.ItemDescription>
</SelectionList.ItemContent>
<SelectionList.ItemIndicator />
</SelectionList.Item>
</SelectionList.Content>
</SelectionList.Root>
</template>Installation
Selection List is part of the main Kappa package. It uses Ark UI Listbox for focus, selection, and accessibility. Kappa adds compact styling and parts for rich item content.
Barrel
import {
SelectionList,
createSelectionListCollection,
type SelectionListProps,
} from "@dicehub/kappa";Granular
import {
SelectionList,
createSelectionListCollection,
type SelectionListProps,
} from "@dicehub/kappa/components/selection-list";Usage
Create one collection and pass each item from that collection to Item. The selected value is always a string array, including single selection.
<script setup>
import {
SelectionList,
createSelectionListCollection,
} from "@dicehub/kappa/components/selection-list";
const profiles = createSelectionListCollection({
items: [
{ value: "balanced", label: "Balanced", detail: "8 CPU · 32 GB" },
{ value: "fast", label: "Fast turnaround", detail: "32 CPU · 64 GB" },
],
itemToString: (item) => item.label,
itemToValue: (item) => item.value,
});
</script>
<template>
<SelectionList.Root :collection="profiles" :default-value="['balanced']">
<SelectionList.Label>Compute profile</SelectionList.Label>
<SelectionList.Content>
<SelectionList.Item v-for="item in profiles.items" :key="item.value" :item="item">
<SelectionList.ItemContent>
<SelectionList.ItemText>{{ item.label }}</SelectionList.ItemText>
<SelectionList.ItemDescription>{{ item.detail }}</SelectionList.ItemDescription>
</SelectionList.ItemContent>
<SelectionList.ItemIndicator />
</SelectionList.Item>
</SelectionList.Content>
</SelectionList.Root>
</template>Composition
SelectionList.Root
├── SelectionList.Label
├── SelectionList.Input (optional filter control)
├── SelectionList.ValueText (optional selected summary)
└── SelectionList.Content
├── SelectionList.Empty
├── SelectionList.ItemGroup (optional)
│ ├── SelectionList.ItemGroupLabel
│ └── SelectionList.Item
└── SelectionList.Item
├── SelectionList.ItemMedia (optional)
├── SelectionList.ItemContent
│ ├── SelectionList.ItemText
│ └── SelectionList.ItemDescription (optional)
├── SelectionList.ItemMeta (optional)
└── SelectionList.ItemIndicatorArk UI owns option roles, typeahead, focus movement, disabled items, range selection, and controlled state. Kappa does not copy this behavior.
Contentis the focusable and scrollable listbox surface.ItemTextsupplies the searchable text. Rich layout parts remain optional.Inputprovides connected keyboard behavior. The application filters the collection.RootProvideraccepts a machine fromuseSelectionList.
<script setup>
import {
SelectionList,
createSelectionListCollection,
useSelectionList,
} from "@dicehub/kappa/components/selection-list";
const collection = createSelectionListCollection({ items: ["CPU", "GPU"] });
const list = useSelectionList({ collection, defaultValue: ["CPU"] });
</script>
<template>
<SelectionList.RootProvider :value="list">
<SelectionList.Content>…</SelectionList.Content>
</SelectionList.RootProvider>
</template>Examples
Multiple Selection
Select independent result fields without modifier keys.
<script setup>
import { ref } from "vue";
import { SelectionList, createSelectionListCollection } from "@dicehub/kappa";
const selected = ref(["pressure", "velocity"]);
const fields = createSelectionListCollection({ items: ["pressure", "velocity", "temperature"] });
</script>
<template>
<SelectionList.Root v-model="selected" :collection="fields" selection-mode="multiple">
<SelectionList.Label>Result fields</SelectionList.Label>
<SelectionList.Content>
<SelectionList.Item v-for="field in fields.items" :key="field" :item="field">
<SelectionList.ItemText>{{ field }}</SelectionList.ItemText>
<SelectionList.ItemIndicator />
</SelectionList.Item>
</SelectionList.Content>
</SelectionList.Root>
</template>Filtering
Filter the collection while the input and list share keyboard navigation.
<script setup>
import { computed, ref } from "vue";
import { SelectionList, createSelectionListCollection } from "@dicehub/kappa";
const query = ref("");
const files = createSelectionListCollection({ items: ["controlDict", "fvSchemes", "fvSolution"] });
const results = computed(() => files.filter((text) => text.toLowerCase().includes(query.value.toLowerCase())));
</script>
<template>
<SelectionList.Root :collection="results">
<SelectionList.Label>Case file</SelectionList.Label>
<SelectionList.Input
:value="query"
auto-highlight
keyboard-priority="navigate"
placeholder="Filter files…"
@input="query = $event.target.value"
/>
<SelectionList.Content>
<SelectionList.Empty>No matching files</SelectionList.Empty>
<SelectionList.Item v-for="file in results.items" :key="file" :item="file">
<SelectionList.ItemText>{{ file }}</SelectionList.ItemText>
<SelectionList.ItemIndicator />
</SelectionList.Item>
</SelectionList.Content>
</SelectionList.Root>
</template>Groups and Disabled Items
Organize related targets and keep unavailable options visible.
<SelectionList.Root :collection="targets" :default-value="['local']">
<SelectionList.Label>Execution target</SelectionList.Label>
<SelectionList.Content>
<SelectionList.ItemGroup v-for="([group, items], index) in targets.group()" :id="`target-group-${index}`">
<SelectionList.ItemGroupLabel>{{ group }}</SelectionList.ItemGroupLabel>
<SelectionList.Item v-for="item in items" :key="item.value" :item="item">
<SelectionList.ItemText>{{ item.label }}</SelectionList.ItemText>
<SelectionList.ItemMeta>{{ item.status }}</SelectionList.ItemMeta>
<SelectionList.ItemIndicator />
</SelectionList.Item>
</SelectionList.ItemGroup>
</SelectionList.Content>
</SelectionList.Root>Sizes
Use the base density for rich choices or the small density for compact tools.
<SelectionList.Root :collection="profiles" size="base">…</SelectionList.Root>
<SelectionList.Root :collection="profiles" size="sm">…</SelectionList.Root>Accessibility
- Use a visible
Labelor add an accessible name to the root. - Arrow keys move focus. Enter or Space selects the focused item.
- In multiple mode, Control or Command + A selects all enabled items.
- Extended mode supports modifier-key and range selection.
- Disabled, selected, hover, and keyboard-focus states remain distinct in both themes.
- Use
scrollToIndexFnwhen a virtual scroller owns item movement.
See the official Ark UI Listbox documentationfor the complete behavior and accessibility contract.
API Reference
SelectionList.Root
The root accepts Ark UI Listbox props plus Kappa's visual size.
| Prop | Type | Default | Description |
|---|---|---|---|
collection | ListCollection<T> | required | Items plus value, text, disabled, and optional grouping mappers. |
modelValue / v-model | string[] | — | Controlled selected values. |
defaultValue | string[] | [] | Initial values for uncontrolled use. |
selectionMode | "single" | "multiple" | "extended" | "single" | Selects one item, independent multiple items, or modifier-key ranges. |
size | "sm" | "base" | "base" | Sets the item density. |
disabled | boolean | false | Disables selection and navigation. |
deselectable | boolean | false | Allows a single selected item to be cleared. |
disallowSelectAll | boolean | false | Disables the Control or Command+A select-all action. |
highlightedValue / v-model:highlightedValue | string | null | — | Controls the focused item value. |
orientation | "horizontal" | "vertical" | "vertical" | Sets arrow-key navigation direction. |
loopFocus | boolean | false | Wraps keyboard focus at the first and last items. |
selectOnHighlight | boolean | false | Selects items when keyboard focus moves. |
typeahead | boolean | true | Finds items from typed text while content has focus. |
scrollToIndexFn | (details) => void | — | Connects keyboard navigation to a custom scroller or virtual list. |
Parts
| Part | Element | Description |
|---|---|---|
SelectionList.Root | div | Owns collection, focus, and selected values. |
SelectionList.RootProvider | div | Uses an external useSelectionList machine. |
SelectionList.Label | label | Provides the accessible list name. |
SelectionList.Input | input | Connects filtering input and list keyboard navigation. |
SelectionList.Content | div | Scrollable listbox container. |
SelectionList.Empty | div | Renders only when the collection is empty. |
SelectionList.ItemGroup / ItemGroupLabel | div | Groups related options and names the group. |
SelectionList.Item | div | One selectable option from the collection. |
SelectionList.ItemMedia / ItemContent | span / div | Optional Kappa layout for media and stacked copy. |
SelectionList.ItemText / ItemDescription / ItemMeta | div / span | Primary label, supporting copy, and compact metadata. |
SelectionList.ItemIndicator | div | Shows the selected state with a default check. |
SelectionList.ValueText | span | Formats selected item text from the collection. |
SelectionList.Context / ItemContext | slot | Exposes root actions or current item state. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | string[] | Emitted when controlled selection changes. |
valueChange | { value, items } | Emitted with selected values and resolved items. |
select | { value, valueAsString } | Emitted for each selection action. |
update:highlightedValue | string | null | Emitted when controlled focus changes. |
highlightChange | { highlightedValue, highlightedItem } | Emitted with the focused value and item. |
Data Attributes
| Attribute | Value | Description |
|---|---|---|
data-slot | "selection-list" / "selection-list-item" / … | Stable Kappa selectors for each named part. |
data-selected | "" | Present on selected items and their indicators. |
data-focus / data-focus-visible | "" | Keyboard focus state owned by Ark UI. |
data-disabled | "" | Present on disabled roots or items. |
data-size | "sm" | "base" | Resolved Kappa density on the root. |
Exports
| Export | Description |
|---|---|
SelectionList | Compound namespace and root component. |
SelectionList.Root / RootProvider | Machine-owned and provider-owned roots. |
SelectionList.Label / Input / Content / Empty | List labeling, filtering, and collection parts. |
SelectionList.Item* / ItemGroup* | Selectable option behavior and rich Kappa item layout. |
createSelectionListCollection | Kappa alias for Ark createListCollection. |
useSelectionList / useSelectionListContext / useSelectionListItemContext | Kappa aliases for Ark listbox composables. |
SelectionListProps / SelectionListEmits / SelectionListCollection | Root, event, and collection contracts. |