Skip to content

CdsList

A list shows a set of records of the same kind — menu sections, documents, employees, settings — so that the one you need is easy to find and pick. Build it from an items array in a single line, or from CdsListItem components when a row is more than a title with an icon.

Storybook GitLab Figma
Test coverage: 98% — good coverage
API in specs
164 / 164 props, events, slots and exposed members with a test
Test cases
190 unit · 5 browser
Known bugs
15 pinned by an it.fails test
Code coverage
98.3% lines · 93% branches measured in v4.0.0-alpha.13
A11y (axe)
35 recommendations in 17 stories measured in v4.0.0-alpha.11

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 nameDescription
prependContent of the area before the text
titleContent of the heading (replaces title)
subtitleContent of the subtitle (replaces subtitle)
descriptionContent of the description (replaces description)
appendContent of the area after the text
defaultArbitrary 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

NameTypeDefaultDescription
activatableboolean | undefined—Allows items to be activated (highlighting the current item without selection mode)
activatedany—Identifiers of the active items (supports v-model through update:activated)
activeClassstring | undefined—Class applied to list items when they are in the active state
activeColorstring | undefined—Color of the component in its active state
activeStrategyActiveStrategyProp | undefined—Activation strategy for items (single, multiple, and so on)
baseColorstring | undefined—Color of the component in its inactive state
bgColorstring | undefined—Background color of the component
collapseIconIconValue | undefined—Icon shown on a collapsed group
colorstring | undefined—Component color
disabledboolean | null | undefinednullDisabled state
expandIconIconValue | undefined—Icon shown on an expanded group
filterableboolean | 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
heightstring | number | undefined—Component height
indentstring | number | undefined—Indent size for nested item groups
itemChildrenSelectItemKey'children'Object field that holds the child items, or a function that returns them
itemPropsSelectItemKey'props'Object field that holds the props of the item, or a function that returns them
itemsany[] | undefined[]Array of items to display
itemsRegistrationItemsRegistrationType | undefined'render'Item registration strategy: render — as they are rendered, otherwise all at once
itemTitleSelectItemKey'title'Object field used as the item title, or a function that returns it
itemTypeSelectItemKey'type'Object field that defines the item type (item, divider, subheader), or a function that returns it
itemValueSelectItemKey'value'Object field used as the item value, or a function that returns it
linesfalse | "one" | "two" | "three" | undefined'one'Number of lines in the list items; affects their height. false turns off the fixed height
mandatoryboolean | undefined—Makes the selection mandatory: forbids clearing the selection of the last item
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
navboolean | undefined—Applies navigation list styles (rounded active items)
navigationIndexnumber | 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
openedany—Identifiers of the expanded groups (supports v-model through update:opened)
openStrategyOpenStrategyProp | undefined'list'Expansion strategy for groups (list, single, multiple)
prependGapstring | number | undefined—Indent before the item content (reserves space for the prepend icon or avatar)
requiredboolean | undefined—Makes the selection mandatory: forbids clearing the selection of the last item
returnObjectboolean | undefined—Return an object in the model value instead of an array
selectableboolean | undefined—Allows items to be selected
selectedany—Identifiers of the selected items (supports v-model through update:selected)
selectStrategySelectStrategyProp | undefined'single-leaf'Selection strategy for items (single-leaf, leaf, independent, classic, and so on)
slimboolean | undefined—Removes the inner paddings of the list and of the menu container: the list fills the available area completely
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
textColorstring | undefined—Text color of the component
themestring | undefined—Component theme
valueComparatorValueComparator | undefined—Function that compares item values to determine the selected state
widthstring | number | undefined—Component width

Events

NameTypeDescription
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

NameTypeDescription
appendListItemSlot & { item: unknown; }Content after the item text (in place of the append icon or avatar)
defaultListItemSlot & { item: unknown; }Default content. Overrides the automatic rendering of items from items
descriptionListItemDescriptionSlot & { 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
prependListItemSlot & { 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
subtitleListItemSubtitleSlot & { item: unknown; }Content of the item subtitle
titleListItemTitleSlot & { item: unknown; }Content of the item title

Exposed

NameTypeDescription
childrenMap<unknown, unknown[]>Map of child items keyed by the identifiers of their parents
focus(location?: number | "next" | "prev" | "first" | "last" | undefined) => voidMoves 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) => voidExpands or collapses a group by its identifier
parentsMap<unknown, unknown>Map of parent items keyed by the identifiers of their children
select(id: unknown, value: boolean, event?: Event | undefined) => voidSelects or deselects an item by its identifier

CdsListGroup ​

Props

NameTypeDefaultDescription
activeColorstring | undefined—Color of the component in its active state
appendIconIconValue | undefined—Icon shown after the group title
baseColorstring | undefined—Color of the component in its inactive state
bgColorstring | undefined—Background color of the component
collapseIconIconValue | undefined'chevron-up'Icon shown when the group is collapsed
colorstring | undefined—Component color
disabledboolean | null | undefinednullDisabled state
expandIconIconValue | undefined'chevron-down'Icon shown when the group is expanded
fluidboolean | undefined—Removes the indent of the group activator, aligning it to the edge of the list
prependIconIconValue | undefined—Icon shown before the group title
rawIdstring | number | undefined—Original identifier of the group; used to build the id of the DOM element
subgroupboolean | undefined—Marks the component as a group of nested lists (a subgroup)
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
textColorstring | undefined—Text color of the component
titlestring | undefined—Title of the group shown in the default activator
valueany—Value of the group used in the expansion and selection logic

Slots

NameTypeDescription
activatorCdsListGroupActivatorSlotActivator of the group — the heading that expands and collapses the group on click
defaultanyContent of the group (the nested list items)

Exposed

NameTypeDescription
isOpenbooleanWhether the group is expanded

CdsListItem ​

Props

NameTypeDefaultDescription
activeboolean | undefined—Forces the active state of the item
activeClassstring | undefined—Class applied to list items when they are in the active state
activeColorstring | undefined—Color of the component in its active state
appendAvatarstring | undefined—Avatar (image URL) shown after the item content
appendIconIconValue | undefined—Icon shown after the item content
baseColorstring | undefined—Color of the component in its inactive state
bgColorstring | undefined—Background color of the component
colorstring | undefined—Component color
descriptionstring | number | boolean | undefined—Description of the list item shown below the title and the subtitle
disabledboolean | null | undefinednullDisabled state
exactboolean | undefined—If true, the active state applies only on an exact route match
heightstring | number | undefined—Component height
hrefstring | undefined—The href attribute of the link. When set, the component behaves as a regular link
indexnumber | undefined—Index of the item; used for keyboard navigation
linesfalse | "one" | "two" | "three" | undefined'one'Number of lines in the list items; affects their height. false turns off the fixed height
linkboolean | undefined—Turns the item into a clickable link. Detected automatically when href or to is set
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
navboolean | undefined—Applies navigation list styles (rounded active items)
prependAvatarstring | undefined—Avatar (image URL) shown before the item content
prependGapstring | number | undefined—Indent before the item content (reserves space for the prepend icon or avatar)
prependIconIconValue | undefined—Icon shown before the item content
replaceboolean | undefined—If true, navigation replaces the current history entry instead of pushing a new one
slimboolean | undefined—Removes the inner paddings of the list and of the menu container: the list fills the available area completely
subtitlestring | number | boolean | undefined—Subtitle of the item shown below the title
tabindexstring | number | undefined—Value of the element tabindex attribute
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
textColorstring | undefined—Text color of the component
themestring | undefined—Component theme
titlestring | number | boolean | undefined—Title of the item shown in the component
toLinkTo | undefined—Target route or route location object for RouterLink. When set, the component behaves as a RouterLink
valueany—Value of the item used for selection and activation in the list
widthstring | number | undefined—Component width

Events

NameTypeDescription
click[value: MouseEvent | KeyboardEvent]Fires on a click on the list item

Slots

NameTypeDescription
appendListItemSlotContent after the item text (in place of the append icon or avatar)
defaultListItemSlotDefault content inside the item
descriptionListItemDescriptionSlotContent of the item description (shown below the title and the subtitle)
prependListItemSlotContent before the item text (in place of the prepend icon or avatar)
subtitleListItemSubtitleSlotContent of the item subtitle
titleListItemTitleSlotContent of the item title

Exposed

NameTypeDescription
activate(activated: boolean, e?: Event | undefined) => voidActivates or deactivates the item
isActivatedbooleanWhether the item is in the active state
isGroupActivatorboolean | undefinedWhether the item is a group activator
isSelectedbooleanWhether 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; } | nullContext of the parent list (CdsList)
rootNestedRootRoot nesting context of the parent list
select(selected: boolean, e?: Event | undefined) => voidSelects or deselects the item

CdsListItemAction ​

Props

NameTypeDefaultDescription
endboolean | undefined—Places the action at the end of the list item (after the content)
startboolean | undefined—Places the action at the start of the list item (before the content)
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

Slots

NameTypeDescription
defaultanyDefault content of the action

CdsListItemDescription ​

Props

NameTypeDefaultDescription
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

CdsListItemDivider ​

Props

NameTypeDefaultDescription
colorstring | undefined—Color of the divider.
contentOffsetstring | 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).
gradientboolean | undefined—Adds a fade-out effect on both ends.
insetboolean | undefined—Adds an indent to horizontal dividers and reduces the maximum height of vertical ones.
lengthstring | number | undefined—Length of the divider. Defaults to pixels.
opacitystring | number | undefined—Opacity of the divider.
themestring | undefined—Component theme
thicknessstring | number | undefined—Thickness of the divider. Defaults to pixels.
variant"solid" | "dotted" | "dashed" | "double" | undefined'solid'Visual variant of the divider
verticalboolean | undefined—Renders the divider vertically

Slots

NameTypeDescription
defaultanyText or content placed in the gap of the divider

CdsListItemImage ​

Props

NameTypeDefaultDescription
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

CdsListItemMedia ​

Props

NameTypeDefaultDescription
endboolean | undefined—Places the media at the end of the list item (after the content)
startboolean | undefined—Places the media at the start of the list item (before the content)
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

Slots

NameTypeDescription
defaultanyDefault content of the media

CdsListItemSubtitle ​

Props

NameTypeDefaultDescription
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

CdsListItemTitle ​

Props

NameTypeDefaultDescription
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

CdsListSubheader ​

Props

NameTypeDefaultDescription
colorstring | undefined—Color of the subheader text
insetboolean | undefined—Adds a left indent, aligning the text with the content of the list items
stickyboolean | undefined—Pins the subheader to the top while the list scrolls
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
titlestring | undefined—Text of the subheader

Slots

NameTypeDescription
defaultanyDefault content of the subheader (overrides the title prop)