To pick a value in a form, take CdsSelect; for a tree with checkboxes, async loading and drag and drop — CdsTree; for tabular data with columns — CdsTable. Inside CdsMenu, CdsSelect and CdsAutocomplete the list is already in use — there is no need to assemble it by hand.
Anatomy
The first diagram is the skeleton of a list: subheaders split it into sections, dividers separate blocks, groups reveal nested items. The second one is the structure of an item: the prepend and append areas on the sides and three text blocks between them. Every area is available both as a prop (prepend-icon, title) and as a slot of the same name.
Variations
List data
The items prop takes an array of objects and builds the whole list out of it. The title field gives the heading, value — the value of the item (this is how the list knows what is selected), props — any props of CdsListItem.
When the data arrives from the server in its own format, do not reshape it: item-title, item-value and item-children tell the list which fields to take. Each of them accepts both a field name and a function — that way, for example, item-props assembles the props of an item from several fields of the object.
The props field configures a single item: adds icons, turns on the active state or disables the row.
Item content
An item has three text blocks: title names the record, subtitle refines it, description adds an explanation. On the sides stand an icon (prepend-icon, append-icon) or an avatar (prepend-avatar, append-avatar).
The lines prop limits the subtitle and the description to one, two or three lines — the rest of the text is truncated with an ellipsis, and records with text of different length keep a common rhythm. With three, the icons in the prepend and append areas align to the top of the record instead of its center. :lines="false" removes the limit — the text takes as many lines as it needs.
Structure
Items with type: 'subheader' and type: 'divider' split the list into sections: a subheader names a group of records, a divider separates blocks without a heading.
A children array inside an item turns it into an expandable group — the list manages its state on its own, and v-model:opened lets you manage it from the outside. Nesting is not limited to a single level.
Selection and activation
The activatable prop highlights one item as the current one — this is about navigation: "you are here". selectable turns on picking records — this is about data: "send these ones". Both states are read through v-model:activated and v-model:selected, and select-strategy sets how many items can be picked at once: single-leaf (the default) — one, independent — as many as you like.
Appearance
nav rounds the corners of active items — the look of a side menu. slim removes the inner paddings when the list sits in a narrow panel or a dropdown. color sets the color of active items, bg-color — the background of the list.
Assembling from components
When a row is more than a title with an icon, assemble it from CdsListItem by hand — the slots accept any components: tags, badges, avatars, buttons.
| Slot name | Description |
|---|---|
prepend | Content of the area before the text |
title | Content of the heading (replaces title) |
subtitle | Content of the subtitle (replaces subtitle) |
description | Content of the description (replaces description) |
append | Content of the area after the text |
default | Arbitrary markup inside the item, below the text |
Nesting in this mode is assembled with CdsListGroup: the activator slot gives the heading of the group, the default content — the nested items. The subgroup prop marks a group of the third level and deeper — the expand arrow moves to the start of the row.
The group passes the arrow to the activator as the default value for append-icon, and the append slot replaces that area entirely — so with your own content the arrow disappears. Bring it back with an empty <CdsIcon /> next to it: the icon picks up the direction of the arrow from the defaults of the group and keeps toggling on expand.
Guidelines
Scenarios
Section menu
A side menu is activatable plus nav: exactly one entry is active, mandatory forbids clearing the selection, and v-model:activated keeps the current section in the application state. Subheaders split the entries into meaningful blocks.
Document list with actions
The whole row stays clickable, and the action in the append area works on top of it — that is why the button has @click.stop, otherwise the click would reach the item and select it. The status next to the button is a regular CdsTag.
Picking recipients
The prepend slot receives isSelected and select — the selection state and the function that changes it. This lets you show a checkbox while keeping the click on the whole row: CdsListItemAction aligns it to the grid of the item, and CdsAvatar stands next to it.
Searching through a list
The list is rebuilt from the filtered array — it needs no logic of its own. When there are no matches, a CdsEmptyState is shown instead of an empty list: the user understands that the reason is the query, not the loading.
API
CdsList
Props
| Name | Type | Default | Description |
|---|---|---|---|
activatable | boolean | undefined | — | Allows items to be activated (highlighting the current item without selection mode) |
activated | any | — | Identifiers of the active items (supports v-model through update:activated) |
activeClass | string | undefined | — | Class applied to list items when they are in the active state |
activeColor | string | undefined | — | Color of the component in its active state |
activeStrategy | ActiveStrategyProp | undefined | — | Activation strategy for items (single, multiple, and so on) |
baseColor | string | undefined | — | Color of the component in its inactive state |
bgColor | string | undefined | — | Background color of the component |
collapseIcon | IconValue | undefined | — | Icon shown on a collapsed group |
color | string | undefined | — | Component color |
disabled | boolean | null | undefined | null | Disabled state |
expandIcon | IconValue | undefined | — | Icon shown on an expanded group |
filterable | boolean | undefined | — | FOR INTERNAL USE ONLY Turns on filtering mode: the space key does not select an item but is used for typing. Applies to the CdsCombobox and CdsAutocomplete components |
height | string | number | undefined | — | Component height |
indent | string | number | undefined | — | Indent size for nested item groups |
itemChildren | SelectItemKey | 'children' | Object field that holds the child items, or a function that returns them |
itemProps | SelectItemKey | 'props' | Object field that holds the props of the item, or a function that returns them |
items | any[] | undefined | [] | Array of items to display |
itemsRegistration | ItemsRegistrationType | undefined | 'render' | Item registration strategy: render — as they are rendered, otherwise all at once |
itemTitle | SelectItemKey | 'title' | Object field used as the item title, or a function that returns it |
itemType | SelectItemKey | 'type' | Object field that defines the item type (item, divider, subheader), or a function that returns it |
itemValue | SelectItemKey | 'value' | Object field used as the item value, or a function that returns it |
lines | false | "one" | "two" | "three" | undefined | 'one' | Number of lines in the list items; affects their height. false turns off the fixed height |
mandatory | boolean | undefined | — | Makes the selection mandatory: forbids clearing the selection of the last item |
maxHeight | string | number | undefined | — | Maximum component height |
maxWidth | string | number | undefined | — | Maximum component width |
minHeight | string | number | undefined | — | Minimum component height |
minWidth | string | number | undefined | — | Minimum component width |
nav | boolean | undefined | — | Applies navigation list styles (rounded active items) |
navigationIndex | number | undefined | — | Index of the current item during keyboard navigation (supports v-model) |
navigationStrategy | "focus" | "track" | undefined | 'focus' | Keyboard navigation strategy: focus — moves the focus, track — a virtual cursor |
opened | any | — | Identifiers of the expanded groups (supports v-model through update:opened) |
openStrategy | OpenStrategyProp | undefined | 'list' | Expansion strategy for groups (list, single, multiple) |
prependGap | string | number | undefined | — | Indent before the item content (reserves space for the prepend icon or avatar) |
required | boolean | undefined | — | Makes the selection mandatory: forbids clearing the selection of the last item |
returnObject | boolean | undefined | — | Return an object in the model value instead of an array |
selectable | boolean | undefined | — | Allows items to be selected |
selected | any | — | Identifiers of the selected items (supports v-model through update:selected) |
selectStrategy | SelectStrategyProp | undefined | 'single-leaf' | Selection strategy for items (single-leaf, leaf, independent, classic, and so on) |
slim | boolean | undefined | — | Removes the inner paddings of the list and of the menu container: the list fills the available area completely |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
textColor | string | undefined | — | Text color of the component |
theme | string | undefined | — | Component theme |
valueComparator | ValueComparator | undefined | — | Function that compares item values to determine the selected state |
width | string | number | undefined | — | Component width |
Events
| Name | Type | Description |
|---|---|---|
click:activate | [value: { id: unknown; value: boolean; path: unknown[]; }] | Fires when an item is activated. value — the id of the item, its new state and its path |
click:open | [value: { id: unknown; value: boolean; path: unknown[]; }] | Fires on a click on the group activator. value — the id of the group, its new state and its path |
click:select | [value: { id: unknown; value: boolean; path: unknown[]; }] | Fires when an item is selected. value — the id of the item, its new state and its path |
update:activated | [value: unknown] | Fires when the set of active items changes. value — identifiers of the active items |
update:navigationIndex | [value: unknown] | Fires when the keyboard navigation index changes. value — the new index |
update:opened | [value: unknown] | Fires when the set of expanded groups changes. value — identifiers of the expanded groups |
update:selected | [value: unknown] | Fires when the set of selected items changes. value — identifiers of the selected items |
Slots
| Name | Type | Description |
|---|---|---|
append | ListItemSlot & { item: unknown; } | Content after the item text (in place of the append icon or avatar) |
default | ListItemSlot & { item: unknown; } | Default content. Overrides the automatic rendering of items from items |
description | ListItemDescriptionSlot & { item: unknown; } | Content of the item description (shown below the title and the subtitle) |
divider | { props: { [key: string]: any; title: string; value: any; }; } | Custom rendering of a divider when items is used |
header | { props: { [key: string]: any; title: string; value: any; }; } | Custom rendering of the group activator (its heading) when items is used |
item | { props: { [key: string]: any; title: string; value: any; } & { index: number; }; } | Custom rendering of a list item when items is used |
prepend | ListItemSlot & { item: unknown; } | Content before the item text (in place of the prepend icon or avatar) |
subheader | { props: { [key: string]: any; title: string; value: any; }; } | Custom rendering of a subheader when items is used |
subtitle | ListItemSubtitleSlot & { item: unknown; } | Content of the item subtitle |
title | ListItemTitleSlot & { item: unknown; } | Content of the item title |
Exposed
| Name | Type | Description |
|---|---|---|
children | Map<unknown, unknown[]> | Map of child items keyed by the identifiers of their parents |
focus | (location?: number | "next" | "prev" | "first" | "last" | undefined) => void | Moves the focus to a list item (by index or by a keyword: next, prev, first, last) |
getPath | (id: unknown) => unknown[] | Returns the path (an array of identifiers) to an item by its id |
open | (id: unknown, value: boolean, event?: Event | undefined) => void | Expands or collapses a group by its identifier |
parents | Map<unknown, unknown> | Map of parent items keyed by the identifiers of their children |
select | (id: unknown, value: boolean, event?: Event | undefined) => void | Selects or deselects an item by its identifier |
CdsListGroup
Props
| Name | Type | Default | Description |
|---|---|---|---|
activeColor | string | undefined | — | Color of the component in its active state |
appendIcon | IconValue | undefined | — | Icon shown after the group title |
baseColor | string | undefined | — | Color of the component in its inactive state |
bgColor | string | undefined | — | Background color of the component |
collapseIcon | IconValue | undefined | 'chevron-up' | Icon shown when the group is collapsed |
color | string | undefined | — | Component color |
disabled | boolean | null | undefined | null | Disabled state |
expandIcon | IconValue | undefined | 'chevron-down' | Icon shown when the group is expanded |
fluid | boolean | undefined | — | Removes the indent of the group activator, aligning it to the edge of the list |
prependIcon | IconValue | undefined | — | Icon shown before the group title |
rawId | string | number | undefined | — | Original identifier of the group; used to build the id of the DOM element |
subgroup | boolean | undefined | — | Marks the component as a group of nested lists (a subgroup) |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
textColor | string | undefined | — | Text color of the component |
title | string | undefined | — | Title of the group shown in the default activator |
value | any | — | Value of the group used in the expansion and selection logic |
Slots
| Name | Type | Description |
|---|---|---|
activator | CdsListGroupActivatorSlot | Activator of the group — the heading that expands and collapses the group on click |
default | any | Content of the group (the nested list items) |
Exposed
| Name | Type | Description |
|---|---|---|
isOpen | boolean | Whether the group is expanded |
CdsListItem
Props
| Name | Type | Default | Description |
|---|---|---|---|
active | boolean | undefined | — | Forces the active state of the item |
activeClass | string | undefined | — | Class applied to list items when they are in the active state |
activeColor | string | undefined | — | Color of the component in its active state |
appendAvatar | string | undefined | — | Avatar (image URL) shown after the item content |
appendIcon | IconValue | undefined | — | Icon shown after the item content |
baseColor | string | undefined | — | Color of the component in its inactive state |
bgColor | string | undefined | — | Background color of the component |
color | string | undefined | — | Component color |
description | string | number | boolean | undefined | — | Description of the list item shown below the title and the subtitle |
disabled | boolean | null | undefined | null | Disabled state |
exact | boolean | undefined | — | If true, the active state applies only on an exact route match |
height | string | number | undefined | — | Component height |
href | string | undefined | — | The href attribute of the link. When set, the component behaves as a regular link |
index | number | undefined | — | Index of the item; used for keyboard navigation |
lines | false | "one" | "two" | "three" | undefined | 'one' | Number of lines in the list items; affects their height. false turns off the fixed height |
link | boolean | undefined | — | Turns the item into a clickable link. Detected automatically when href or to is set |
maxHeight | string | number | undefined | — | Maximum component height |
maxWidth | string | number | undefined | — | Maximum component width |
minHeight | string | number | undefined | — | Minimum component height |
minWidth | string | number | undefined | — | Minimum component width |
nav | boolean | undefined | — | Applies navigation list styles (rounded active items) |
prependAvatar | string | undefined | — | Avatar (image URL) shown before the item content |
prependGap | string | number | undefined | — | Indent before the item content (reserves space for the prepend icon or avatar) |
prependIcon | IconValue | undefined | — | Icon shown before the item content |
replace | boolean | undefined | — | If true, navigation replaces the current history entry instead of pushing a new one |
slim | boolean | undefined | — | Removes the inner paddings of the list and of the menu container: the list fills the available area completely |
subtitle | string | number | boolean | undefined | — | Subtitle of the item shown below the title |
tabindex | string | number | undefined | — | Value of the element tabindex attribute |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
textColor | string | undefined | — | Text color of the component |
theme | string | undefined | — | Component theme |
title | string | number | boolean | undefined | — | Title of the item shown in the component |
to | LinkTo | undefined | — | Target route or route location object for RouterLink. When set, the component behaves as a RouterLink |
value | any | — | Value of the item used for selection and activation in the list |
width | string | number | undefined | — | Component width |
Events
| Name | Type | Description |
|---|---|---|
click | [value: MouseEvent | KeyboardEvent] | Fires on a click on the list item |
Slots
| Name | Type | Description |
|---|---|---|
append | ListItemSlot | Content after the item text (in place of the append icon or avatar) |
default | ListItemSlot | Default content inside the item |
description | ListItemDescriptionSlot | Content of the item description (shown below the title and the subtitle) |
prepend | ListItemSlot | Content before the item text (in place of the prepend icon or avatar) |
subtitle | ListItemSubtitleSlot | Content of the item subtitle |
title | ListItemTitleSlot | Content of the item title |
Exposed
| Name | Type | Description |
|---|---|---|
activate | (activated: boolean, e?: Event | undefined) => void | Activates or deactivates the item |
isActivated | boolean | Whether the item is in the active state |
isGroupActivator | boolean | undefined | Whether the item is a group activator |
isSelected | boolean | Whether the item is selected |
list | { filterable: MaybeRefOrGetter<boolean>; hasPrepend: Ref<boolean, boolean>; updateHasPrepend: (value: boolean) => void; trackingIndex: Ref<number, number>; navigationStrategy: Ref<"focus" | "track", "focus" | "track">; uid: string; } | null | Context of the parent list (CdsList) |
root | NestedRoot | Root nesting context of the parent list |
select | (selected: boolean, e?: Event | undefined) => void | Selects or deselects the item |
CdsListItemAction
Props
| Name | Type | Default | Description |
|---|---|---|---|
end | boolean | undefined | — | Places the action at the end of the list item (after the content) |
start | boolean | undefined | — | Places the action at the start of the list item (before the content) |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
Slots
| Name | Type | Description |
|---|---|---|
default | any | Default content of the action |
CdsListItemDescription
Props
| Name | Type | Default | Description |
|---|---|---|---|
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
CdsListItemDivider
Props
| Name | Type | Default | Description |
|---|---|---|---|
color | string | undefined | — | Color of the divider. |
contentOffset | string | number | (string | number)[] | undefined | — | Increases the spacing between the content and the lines. When passed as an array, the second value shifts the slot content down (or right when vertical = true). |
gradient | boolean | undefined | — | Adds a fade-out effect on both ends. |
inset | boolean | undefined | — | Adds an indent to horizontal dividers and reduces the maximum height of vertical ones. |
length | string | number | undefined | — | Length of the divider. Defaults to pixels. |
opacity | string | number | undefined | — | Opacity of the divider. |
theme | string | undefined | — | Component theme |
thickness | string | number | undefined | — | Thickness of the divider. Defaults to pixels. |
variant | "solid" | "dotted" | "dashed" | "double" | undefined | 'solid' | Visual variant of the divider |
vertical | boolean | undefined | — | Renders the divider vertically |
Slots
| Name | Type | Description |
|---|---|---|
default | any | Text or content placed in the gap of the divider |
CdsListItemImage
Props
| Name | Type | Default | Description |
|---|---|---|---|
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
CdsListItemMedia
Props
| Name | Type | Default | Description |
|---|---|---|---|
end | boolean | undefined | — | Places the media at the end of the list item (after the content) |
start | boolean | undefined | — | Places the media at the start of the list item (before the content) |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
Slots
| Name | Type | Description |
|---|---|---|
default | any | Default content of the media |
CdsListItemSubtitle
Props
| Name | Type | Default | Description |
|---|---|---|---|
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
CdsListItemTitle
Props
| Name | Type | Default | Description |
|---|---|---|---|
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
CdsListSubheader
Props
| Name | Type | Default | Description |
|---|---|---|---|
color | string | undefined | — | Color of the subheader text |
inset | boolean | undefined | — | Adds a left indent, aligning the text with the content of the list items |
sticky | boolean | undefined | — | Pins the subheader to the top while the list scrolls |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
title | string | undefined | — | Text of the subheader |
Slots
| Name | Type | Description |
|---|---|---|
default | any | Default content of the subheader (overrides the title prop) |