Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Components
  2. Virtualized List
  3. Usage

Virtualized list

Usage

Overview

VirtualizedList from @prepared911/ui/virtualized-list is the list for thousands of rows: roster feeds, log tails, and other single-column collections. Every row stays in the DOM. Rows outside the viewport skip layout and paint through content-visibility: auto, so find-in-page, the accessibility tree, and keyboard focus still cover the whole list. estimatedItemSize reserves space for a row the browser has not laid out yet; after a row renders once, the browser remembers its real height.

The figure above is the docs anatomy (viewport, row, empty state). Import the component from @prepared911/ui/virtualized-list, not @prepared911/ui-core.

When to use

  • Hundreds or thousands of cheap rows where mapping them all into a plain Scrollable drops frames.
  • Append-heavy feeds (live logs, chat) with stable row keys.
  • Lists that must stay searchable and keyboard-reachable, including rows the operator has not scrolled to.

When not to use

  • Short lists (dozens of rows). Map the rows inside Scrollable; it is simpler.
  • A table of records with columns, sorting, or selection. Use DataTable, which windows its rows.
  • A list that must drop off-screen nodes to save memory. This list skips work, not nodes.

Content guidelines

  • Empty states use the EmptyState pattern with a concrete next step, passed as emptyContent.
  • Give each row a stable getItemKey when rows insert or reorder. The default key is the index.
  • Draw hover and focus inside the row. Paint containment clips anything outside the row's border box, with a --space-4 margin for the focus ring.

Behavior and states

  • Row heights. Pass estimatedItemSize close to the typical row height in pixels. A wrong estimate only makes the scrollbar approximate until rows render. Variable heights need no per-index function.
  • Paging. onEndReached fires when the end of the list scrolls into view, and pauses while loadingRow or errorRow is showing.
  • Reverse order. reverseOrder pins the newest row to the visual block end, as in a chat log. Indexes still count from the first item.

Best practices

Do

  • Key rows by id when the list inserts or reorders.
  • Name the scroll region with scrollRegionLabel when the list scrolls and no row holds a focusable control.

Don't

  • Nest the list in a second scroll container without giving this one a bounded height.
  • Reach for className or style. The component does not take them.

Accessibility

Tab reaches a control in any row, including a row the browser has not laid out, and focusing it scrolls that row into view. See Accessibility.

Related components

  • Scrollable for a short list.
  • Data table when the rows are records in columns.

Previous

Video player / API and Development

Next

Virtualized List / API and Development

On this page

Overview
When to use
When not to use
Content guidelines
Behavior and states
Best practices
Accessibility
Related components