The dropdowns of CdsSelect and CdsAutocomplete, as well as the CdsTree tree, already virtualize their items — there is no need to wrap them. Render a short list — up to a couple of hundred rows — with the regular CdsList: virtualization will not pay off there.
Variations
Fixed height
The height prop sets the height of the viewport — the scrolling happens inside it. If all the rows have the same height, set item-height: the component will not measure every row, and the positions and the scrollbar will be exact from the very first render.
Dynamic height
Without item-height the component measures the rows automatically — this fits content of variable length: comments, messages, descriptions. The heights get refined as you scroll, so the scrollbar may shift slightly.
Renderless mode
The renderless prop removes the own scroll container: the component listens to the scrolling of the nearest scrollable parent and renders the rows without wrappers. The slot additionally receives itemRef — bind it to the root node of the row so that the component knows its height. This is how the list fits into an existing scroll — of a panel or of the whole page. Give the scrollable parent position: relative — the component counts the row positions from it.
Guidelines
Scenarios
Catalog search
Pass an already filtered array to items: a computed recalculates the records on input, and the component picks the new list up on its own. item-key="id" binds the rows to the records rather than to the positions in the array — so the rows do not get mixed up while filtering.
Jumping through a journal
The component exposes the scrollToIndex method — get it through a ref and scroll the list programmatically. The month buttons calculate the index of the first operation of the month; with a fixed item-height the jump lands exactly on the right row.
Selection in a long list
The rows outside the screen do not exist in the DOM, so keep the selection state in the data, not in the rows themselves. In the demo the checked ids live in a Set: the checkbox of a row reads it and changes it on click — the selection survives any scrolling.
API
CdsVirtualScroll
Props
| Name | Type | Default | Description |
|---|---|---|---|
height | string | number | undefined | — | Component height |
itemHeight | string | number | undefined | null | Height of a single item in pixels. When omitted, the height is measured automatically. |
itemKey | SelectItemKey | null | Key that identifies an item (a field name, a path or a function). The index is used by default. |
items | readonly unknown[] | undefined | [] | Array of the items rendered by the virtual scroll. |
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 |
renderless | boolean | undefined | — | Renderless mode: the component does not create its own scroll container and uses the nearest scrollable parent instead. |
width | string | number | undefined | — | Component width |
Slots
| Name | Type | Description |
|---|---|---|
default | CdsVirtualScrollSlot<any> & { itemRef?: TemplateRef | undefined; } | Content of a single list item. In renderless mode it additionally receives itemRef. |
Exposed
| Name | Type | Description |
|---|---|---|
calculateVisibleItems | () => void | Recalculates the window of visible items — needed after their height changes outside the update cycle. |
scrollToIndex | (index: number) => void | Scrolls the list to the item with the given index. |
CdsVirtualScrollItem
Props
| Name | Type | Default | Description |
|---|---|---|---|
renderless | boolean | undefined | — | Renderless mode: the item renders only the slot content, without a wrapper. |
Events
| Name | Type | Description |
|---|---|---|
update:height | [height: number] | Tells the virtual list that the height of the item has changed. |
Slots
| Name | Type | Description |
|---|---|---|
default | { itemRef: TemplateRef; } | Content of the item. In renderless mode it receives itemRef to measure the height. |