virtual_list/lustre

Lustre adapter for virtual_list.

The pure core lives in virtual_list. This module owns the runtime side: rendering the spacer + visible items, and wiring up the DOM observers (scroll, container resize, item resize) via FFI. Each observer dispatches a message back into the consumer’s update loop, which then mutates the virtualizer state with the corresponding pure setter.

Two observation modes are exposed:

The observation primitives are ported from TanStack Virtual’s observeElementOffset / observeWindowOffset / observeElementRect callbacks. Credit to the TanStack team — see README.md.

Values

pub fn observe(
  id container_id: String,
  on_scroll on_scroll: fn(Int) -> msg,
  on_resize on_resize: fn(Int) -> msg,
  on_measure_item on_measure_item: fn(Int, Int) -> msg,
) -> effect.Effect(msg)

Set up the DOM observers that drive the virtualizer’s measurements.

Call this once after the scroll container has been mounted (e.g. from the initial route load). The returned effect installs:

  • a ResizeObserver on the scroll container — dispatches on_resize
  • a ResizeObserver on each row tagged with data-index — dispatches on_measure_item
  • the initial scroll offset — dispatched via on_scroll

These observers persist for the lifetime of the page; Lustre will tear them down with the element when the route changes.

pub fn observe_window(
  id container_id: String,
  on_scroll on_scroll: fn(Int) -> msg,
  on_resize on_resize: fn(Int) -> msg,
  on_measure_item on_measure_item: fn(Int, Int) -> msg,
) -> effect.Effect(msg)

Window-scroll variant of observe. The page itself is the scroll surface; the vlist element is just a tall spacer in flow. Scroll offset is reported relative to the spacer’s top, so the same virtualizer math works without changes — only the source of scroll/resize events differs.

Use this when you want the page to scroll instead of an inner container. In that case do NOT set overflow-y or a fixed height on the vlist element via attributes.

pub fn view(
  id container_id: String,
  virtualizer virtualizer: virtual_list.Virtualizer,
  render render: fn(virtual_list.VirtualItem) -> element.Element(
    msg,
  ),
  on_scroll on_scroll: fn(Int) -> msg,
  attributes attributes: List(attribute.Attribute(msg)),
) -> element.Element(msg)

Render the virtual list inside a scrollable container.

  • id — DOM id used by the FFI observers
  • virtualizer— the current state from the consumer’s model
  • renderfn(VirtualItem) -> Element(msg) for each visible row
  • on_scroll — fired on every scroll event with the new offset
  • attributes — extra attributes on the scroll container (e.g. CSS height)
Search Document