Skip to content

Component VirtualRow

MeowLynxSea edited this page Jun 13, 2026 · 6 revisions

VirtualRow

A virtualised list: only the rows visible in the scroll viewport (plus a small overdraw) are mounted, no matter how many items the underlying controller reports. Two variants:

  • virtual_list — variable row heights.
  • uniform_virtual_list — fixed row height (cheaper, but every row must be the same height).

Import

use yororen_ui::headless::virtual_list::virtual_list;
use yororen_ui::headless::virtual_list::VirtualListController;
use yororen_ui::headless::virtual_list::uniform_virtual_list;
use yororen_ui::headless::virtual_list::UniformVirtualListController;

Minimal example

use yororen_ui::headless::virtual_list::{virtual_list, VirtualListController};
use yororen_ui::headless::label::label;
use gpui::Entity;

let controller: Entity<VirtualListController> =
    cx.new(|_| VirtualListController::with_default(10_000));

// In render:
virtual_list("rows", &controller, cx)
    .row(|ix, _window, _cx| label(format!("item-{ix}"), format!("Item {ix}"), _cx).render(_cx))
    .render(cx)

// Later, to update the count:
controller.update(cx, |c, _cx| c.reset(20_000));

For the fixed-height variant:

use yororen_ui::headless::virtual_list::{uniform_virtual_list, UniformVirtualListController};

let controller = cx.new(|_| UniformVirtualListController::with_default(1_000));

uniform_virtual_list("rows", controller.read(cx).item_count(), &controller, cx)
    .row(|ix, _window, _cx| label(format!("row-{ix}"), format!("Row {ix}"), _cx).render(_cx))
    .render(cx)

Props (virtual_list)

Method Purpose
item_count(n) Override the count (otherwise read from the controller on each frame).
alignment(a) ListAlignment::Top (default) or Center / Bottom.
overdraw(px) Extra pixels above/below the viewport kept mounted. Default 16px.
sizing(b) ListSizingBehavior (auto / fixed).
row(closure) Required. Row builder: Fn(usize, &mut Window, &mut App) -> AnyElement.
on_visible_range_change(closure) Fn(Range<usize>, &mut Window, &mut App) + 'static + Send + Sync.

uniform_virtual_list is the same except it has no alignment / overdraw (every row is the same height).

Notes

  • Factories take (id, controller_ref, _cx). The controller reference is held by the renderer.
  • The controller is owned by the caller — keep it as a field on the parent view.
  • .render(cx) returns Stateful<Div>. The render is a no-op if no .row(...) is set, so set the row closure before calling .render.
  • For a "load more on scroll" pattern, append items in on_visible_range_change when the visible range approaches the end (call controller.append(n)).

See also

Tree, ListItem, Spinner (removed in v0.3)

Clone this wiki locally