HelixOverviewComponentsMapsGraphIntroductionInstallationDeriving a themeSandboxTheme builderVisual testingCortexDocsEngramBuildingTraceBuildingRecallDeclaredServicesInsightsGet in touchSource on GitHub
Loading the reference
Virtual ListView SourceEdit in SandboxView MarkdownCopy MarkdownOpen in ClaudeOpen in CursorA list that renders only the rows of a long set that are on screen.StableSince 0.1.0LayoutUsageimport'@fusion.dev/helix/virtual-list'import'@fusion.dev/helix-headless/virtual-list'Preview
API ReferenceRoothelix-virtual-listA list that renders only the rows of a long set that are on screen.
PropTypeDescriptioncolumnsnumberDefault1How many items a line holds. One, the default, is a list; more lays the
items out as a grid of that many equal columns, windowed a line at a
time, with Left and Right moving along a line.disabledKeysstringDefault""The keys of the items a reader cannot choose or move to, separated by
commas, as value writes keys. Their rows carry aria-disabled.emptyLabelstringDefault""The text of the row shown when there are no items and none are loading,
where the empty slot is empty. Empty, the default, shows no row.estimatenumberDefault32The height of one row, in pixels, used to find the row at a scroll offset.forstringDefault""The id of the script element that holds the items as JSON. items wins
where both are set.gapnumberDefault0The space between two rows, and between two columns in a grid, in
pixels. The list counts it in each row's place, so a gap does not walk
the rows away from the scroll position the way a margin on each row
would.itemsreadonlyunknown[]The items, as an array. Set it as a property.keyFieldstringDefault""The field of each item that is its key in value, as a key or a path of
keys. Empty reads a string or a number item as its own key, and any
other item by its place in the set.labelstringDefault""The list's name, read by screen readers, because only some of its rows
are rendered at a time.layout"grid"|"waterfall"Default"grid"How items of more than one column are laid out. grid, the default, puts
them in lines of equal columns. waterfall puts each item, in the order
of the set, under the column that ends highest, as a wall of photos of
different heights is: columns, or min-column-width, says how many
columns. Rows of a waterfall are measured, and Up and Down move along a
column.loadingbooleanDefaultfalseMarks the list as busy fetching more items, and draws a row after the last
item that says so.loadingLabelstringDefault"Loading more"The text of the row drawn while loading is set, where the loading slot is empty.measuredbooleanDefaultfalsePlaces each row by its own measured height. Without it, rows are placed
by one height: estimate until rows are drawn, then the drawn rows' height,
read once. Rows that come out different heights are placed by their own
heights either way.minColumnWidthnumberDefault0The narrowest a column of a grid may be, in pixels. Set, the list lays
out as many columns as fit the box at that width, at least one, and
follows the box as it resizes, which columns then does not decide.orientation"horizontal"|"vertical"Default"vertical"Which way the list runs. horizontal lays the items out along a line
and scrolls it sideways: Left and Right move between items, the other
way round on a right-to-left page, and estimate is an item's width. A
grid and a waterfall always run down.renderItemVirtualListRenderer<any>Draws one item into its row, given the item and its index. Set it as a
property.renderSectionVirtualListSectionRendererDraws each section's header, given its name and its place among the
sections, for a list given section-field. Set it as a property. Where
it is unset, the header is the name as text.reorderablebooleanDefaultfalseLets a reader move items, once @fusion.dev/helix/virtual-list/reorder
(or @fusion.dev/helix-headless/virtual-list/reorder) is imported: Alt
with an arrow moves the row the keys are on, and a pointer drags a row.
The list moves no item itself: you move your items on helix-reorder.
Without that import it does nothing, so a list that never moves items
carries none of the code. A list of one column, without sections or a
waterfall.sectionFieldstringDefault""The field of each item that names its section, as a key or a path of
keys. Set, the items are drawn in sections: a header, then the items, in
an element with the group role that the header names. A section starts
wherever the field changes, so give the items in order. A list of one
column only.selectionBehavior"replace"|"toggle"Default"toggle"What a press does to the items already chosen: toggle adds or takes out
the item, and replace selects it alone and lets the arrow keys carry the
selection, with Control or Command adding or taking out one item.selectionMode"multiple"|"single"Makes the list a list box a reader chooses from: single selects one
item, and multiple any number. Unset is a list a reader reads.textFieldstringDefault""The field of each item that typing matches, as a key or a path of keys
(author.name).valuestringDefault""The keys of the chosen items, separated by commas, in a list with
selection-mode. Set it to start with items chosen.
ReadTypeDescriptionrangeVirtualListRangeThe items on screen, as items.slice(first, last) reads them.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The <template> that defines one row. The list writes the rows it renders beside it, and this slot shows them between the two spacers.emptyContent for the row shown when there are no items and none are loading. Falls back to empty-label.loadingContent for the row after the last item while loading is set. Falls back to loading-label.
EventTypeDescriptionchangeEventFired once a press or a key has changed which items are selected, in a list with selection-mode.helix-before-changeHelixBeforeChangeEventFired before a press or a key changes which items are selected, with the value it would leave. Cancelable.helix-before-reorderHelixBeforeReorderEventFired when an item is dropped at a new place, in a reorderable list with @fusion.dev/helix/virtual-list/reorder imported, with every key in the new order. Cancelable: cancel it to keep the item where it is.helix-load-moreHelixLoadMoreEventFired when a reader comes within one screen of the last item, once for each length of the set.helix-range-changeHelixRangeChangeEventFired when the items on screen change, with the new first and last, which range also holds.helix-reorderHelixReorderEventFired after helix-before-reorder when nobody canceled it. Set items to the order in keys. Cancelable: cancel it to say the move did not happen.
MethodTypeDescriptionscrollToIndex(index: number, options: VirtualListScrollOptions) => voidScrolls the list to show the item at index.
PartDescriptionafterThe space that stands in for the rows below the rendered ones.beforeThe space that stands in for the rows above the rendered ones.emptyThe row shown when there are no items and none are loading, where empty-label or the empty slot gives it content.loadingThe row after the last item while loading is set.viewportThe scrolling box.
CSS PropertyDescription--virtual-list-block-sizeHow tall the scrolling box is. A list that runs across is as tall as its rows unless you set it.--virtual-list-disabled-opacityHow faint a row disabled-keys names is drawn.--virtual-list-drag-preview-background-colorThe fill behind the copy of a row a pointer drags, in a reorderable list with @fusion.dev/helix/virtual-list/reorder imported.--virtual-list-drag-preview-border-colorThe color of the edge around the copy of a row a pointer drags.--virtual-list-drag-preview-border-widthThe width of the edge around the copy of a row a pointer drags. None by default, where the shadow lifts it.--virtual-list-drag-preview-opacityThe opacity of the copy of a row a pointer drags.--virtual-list-drag-preview-radiusThe corner radius of the copy of a row a pointer drags.--virtual-list-drag-preview-shadowThe shadow that raises the copy of a row a pointer drags over the page.--virtual-list-dragging-opacityThe opacity of a row being dragged, in a reorderable list with @fusion.dev/helix/virtual-list/reorder imported.--virtual-list-drop-indicator-colorThe color of the line where a dragged row would land.--virtual-list-drop-indicator-sizeThe thickness of the line where a dragged row would land.--virtual-list-empty-colorThe color of the text in the row shown when there are no items.--virtual-list-empty-paddingThe space around the text in the row shown when there are no items.--virtual-list-loading-colorThe color of the text in the row drawn while loading is set.--virtual-list-loading-paddingThe space around the text in the row drawn while loading is set.--virtual-list-scrollbar-thumb-colorThe thumb of the list's scrollbar. Defaults to --helix-scrollbar-thumb-color.--virtual-list-scrollbar-thumb-hover-colorThe thumb while the pointer is over the list. Defaults to --helix-scrollbar-thumb-hover-color.--virtual-list-scrollbar-track-colorThe track of the list's scrollbar. Defaults to --helix-scrollbar-track-color.--virtual-list-selected-background-colorThe fill behind a chosen row, in a list with selection-mode.--virtual-list-selected-colorThe color of the text in a chosen row, in a list with selection-mode. Inherited by default.
Custom stateDescriptionemptyWhile the list has read its items and holds none.horizontalWhile the list runs across, with orientation="horizontal".loadingWhile loading is set.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Roothelix-headless-virtual-listA list that renders only the rows of a long set that are on screen.
PropTypeDescriptioncolumnsnumberDefault1How many items a line holds. One, the default, is a list; more lays the
items out as a grid of that many equal columns, windowed a line at a
time, with Left and Right moving along a line.disabledKeysstringDefault""The keys of the items a reader cannot choose or move to, separated by
commas, as value writes keys. Their rows carry aria-disabled.emptyLabelstringDefault""The text of the row shown when there are no items and none are loading,
where the empty slot is empty. Empty, the default, shows no row.estimatenumberDefault32The height of one row, in pixels, used to find the row at a scroll offset.forstringDefault""The id of the script element that holds the items as JSON. items wins
where both are set.gapnumberDefault0The space between two rows, and between two columns in a grid, in
pixels. The list counts it in each row's place, so a gap does not walk
the rows away from the scroll position the way a margin on each row
would.itemsreadonlyunknown[]The items, as an array. Set it as a property.keyFieldstringDefault""The field of each item that is its key in value, as a key or a path of
keys. Empty reads a string or a number item as its own key, and any
other item by its place in the set.labelstringDefault""The list's name, read by screen readers, because only some of its rows
are rendered at a time.layout"grid"|"waterfall"Default"grid"How items of more than one column are laid out. grid, the default, puts
them in lines of equal columns. waterfall puts each item, in the order
of the set, under the column that ends highest, as a wall of photos of
different heights is: columns, or min-column-width, says how many
columns. Rows of a waterfall are measured, and Up and Down move along a
column.loadingbooleanDefaultfalseMarks the list as busy fetching more items, and draws a row after the last
item that says so.loadingLabelstringDefault"Loading more"The text of the row drawn while loading is set, where the loading slot is empty.measuredbooleanDefaultfalsePlaces each row by its own measured height. Without it, rows are placed
by one height: estimate until rows are drawn, then the drawn rows' height,
read once. Rows that come out different heights are placed by their own
heights either way.minColumnWidthnumberDefault0The narrowest a column of a grid may be, in pixels. Set, the list lays
out as many columns as fit the box at that width, at least one, and
follows the box as it resizes, which columns then does not decide.orientation"horizontal"|"vertical"Default"vertical"Which way the list runs. horizontal lays the items out along a line
and scrolls it sideways: Left and Right move between items, the other
way round on a right-to-left page, and estimate is an item's width. A
grid and a waterfall always run down.renderItemVirtualListRenderer<any>Draws one item into its row, given the item and its index. Set it as a
property.renderSectionVirtualListSectionRendererDraws each section's header, given its name and its place among the
sections, for a list given section-field. Set it as a property. Where
it is unset, the header is the name as text.reorderablebooleanDefaultfalseLets a reader move items, once @fusion.dev/helix/virtual-list/reorder
(or @fusion.dev/helix-headless/virtual-list/reorder) is imported: Alt
with an arrow moves the row the keys are on, and a pointer drags a row.
The list moves no item itself: you move your items on helix-reorder.
Without that import it does nothing, so a list that never moves items
carries none of the code. A list of one column, without sections or a
waterfall.sectionFieldstringDefault""The field of each item that names its section, as a key or a path of
keys. Set, the items are drawn in sections: a header, then the items, in
an element with the group role that the header names. A section starts
wherever the field changes, so give the items in order. A list of one
column only.selectionBehavior"replace"|"toggle"Default"toggle"What a press does to the items already chosen: toggle adds or takes out
the item, and replace selects it alone and lets the arrow keys carry the
selection, with Control or Command adding or taking out one item.selectionMode"multiple"|"single"Makes the list a list box a reader chooses from: single selects one
item, and multiple any number. Unset is a list a reader reads.textFieldstringDefault""The field of each item that typing matches, as a key or a path of keys
(author.name).valuestringDefault""The keys of the chosen items, separated by commas, in a list with
selection-mode. Set it to start with items chosen.
ReadTypeDescriptionrangeVirtualListRangeThe items on screen, as items.slice(first, last) reads them.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The <template> that defines one row. The list writes the rows it renders beside it, and this slot shows them between the two spacers.emptyContent for the row shown when there are no items and none are loading. Falls back to empty-label.loadingContent for the row after the last item while loading is set. Falls back to loading-label.
EventTypeDescriptionchangeEventFired once a press or a key has changed which items are selected, in a list with selection-mode.helix-before-changeHelixBeforeChangeEventFired before a press or a key changes which items are selected, with the value it would leave. Cancelable.helix-before-reorderHelixBeforeReorderEventFired when an item is dropped at a new place, in a reorderable list with @fusion.dev/helix/virtual-list/reorder imported, with every key in the new order. Cancelable: cancel it to keep the item where it is.helix-load-moreHelixLoadMoreEventFired when a reader comes within one screen of the last item, once for each length of the set.helix-range-changeHelixRangeChangeEventFired when the items on screen change, with the new first and last, which range also holds.helix-reorderHelixReorderEventFired after helix-before-reorder when nobody canceled it. Set items to the order in keys. Cancelable: cancel it to say the move did not happen.
MethodTypeDescriptionscrollToIndex(index: number, options: VirtualListScrollOptions) => voidScrolls the list to show the item at index.
PartDescriptionafterThe space that stands in for the rows below the rendered ones.beforeThe space that stands in for the rows above the rendered ones.emptyThe row shown when there are no items and none are loading, where empty-label or the empty slot gives it content.loadingThe row after the last item while loading is set.viewportThe scrolling box. On this tier, it needs only a block size.
Custom stateDescriptionemptyWhile the list has read its items and holds none.horizontalWhile the list runs across, with orientation="horizontal".loadingWhile loading is set.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Examples
NameDescriptionChoosingFive hundred people to choose from, with Shift for a range and Control or Command with A for all of them.GridThree thousand swatches four to a line, windowed a line at a time, with the arrow keys moving along a line and down a column.Loading MoreFiles given as an array and drawn from a row template with links, with more added as you near the end.PreviewTwo thousand rows set as JSON, with only the visible rows rendered.PreviewTwo thousand rows set as JSON, with only the visible rows rendered.WaterfallTwo thousand cards of different heights in three columns, each placed under the column that ends highest, with Down and Up moving along a column and Left and Right across.