Skip to content

VirtualList ​

Renders large data lists into the viewport window: only visible items (plus a top/bottom buffer) are rendered, with head/tail padding placeholders to support the scroll height, and scroll events throttled via rAF. It is a generic rendering primitive reused by table / tree.

Basic Usage ​

Fixed-height virtual list

Provide data via the items property (or the items attribute as a JSON string); height sets the viewport height and item-height the height of each item. Without a template, each item renders String(item) by default.

Custom Item Content ​

oas-item event-bound content

Each visible item emits oas-item after rendering with detail containing { index, item, element }, which the host can use to fill in the item content; alternatively, a <template slot="item"> inside the component can serve as a static per-item template.

Scroll Events ​

oas-scroll window display

Visible window: 0–0 · scrollTop: 0

Scroll events are emitted as oas-scroll, throttled by rAF, with detail being { scrollTop, start, end }.

Scroll to a Specific Item ​

The scrollToIndex(index, options?) method scrolls to the item at the given index: options.align supports start (item top aligned to the viewport top) / center (vertically centered) / end (item bottom aligned to the viewport bottom) / auto (default: no scroll if the item is already fully visible, otherwise the minimal scroll to bring it into view); options.smooth enables smooth scrolling. Row positioning of embedded consumers (list / tree) also goes through this public contract without reaching into internal DOM.

scrollToIndex scroll positioning

JumpCurrent scrollTop: 0

Dynamic Row Height ​

With dynamic-height, rows may have different heights: unmeasured rows are laid out using estimated-item-height (defaults to item-height), and rendered rows are measured by ResizeObserver, which progressively corrects total height and offsets. When rows above the viewport change height, scrollTop is compensated automatically to keep the visual anchor stable (no jump when scrolling up). scrollToIndex also works in dynamic mode (positioned by the height table). Picking an estimate close to the real average row height minimizes corrections.

Dynamic height (mixed row heights)

scrollToIndex(40)Total height corrects progressively with measurement; scrolling stays smooth

Render Buffer ​

buffer controls how many extra items are pre-rendered above and below the visible area (default 4): a larger buffer means fewer blank areas (white screens) while scrolling, at the cost of more rendered DOM nodes.

Render buffer buffer

buffer="0": rendered items —; only items within the visible window are rendered.

buffer="8": rendered items —; 8 extra items pre-rendered above and below.

Custom Scroll Container ​

scroll-target external container

When scroll-target (a CSS selector) is set, the component does not provide its own scrollbar; instead an external container scrolls the whole content (e.g. page-level scrolling), and the window is computed from the external container's scrollTop.

API ​

oas-virtual-list ​

Attributes ​

AttributeDescriptionTypeDefault
bufferNumber of items pre-rendered above/below (rendered early beyond the visible area to reduce scrolling blanks)string4
dynamic-heightDynamic row height: rows may vary in height (unmeasured rows use the estimate; rendered rows are measured and progressively corrected; scrollTop is auto-compensated when rows above the viewport change)boolean—
estimated-item-heightEstimated row height for dynamic mode (px; defaults to item-height; closest to the real average minimizes corrections)string—
heightViewport height (px)string320
item-heightFixed height of each item (px)string36
itemsData array (property channel, takes precedence over the items attribute); data JSON string (attribute channel)unknown[][]
scroll-targetCSS selector of the external scroll container; when set, the component has no scrollbar of its own and listens to the external scrollstring—

Events ​

EventDescription
oas-itemEmitted after each visible item renders, detail: { index, item, element }
oas-scrollScroll event (rAF throttled), detail: { scrollTop, start, end }

Slots ​

NameDescription
template[slot="item"]Static per-item template, cloned into each visible item container (optional)

Parts: ::part(viewport) scroll viewport, ::part(inner) content, ::part(padding-top) / ::part(padding-bottom) placeholders, ::part(items) window item container, ::part(item) a single item.

viewportFocusable (JS property, default true) controls whether the viewport is Tab-focusable; embedded consumers (whose rows carry their own roving tabindex) set it to false to disable viewport focusing.

Released under the MIT OR Apache-2.0 License.