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:
observe— scroll/resize on the spacer element itself (the consumer gives it a fixed height +overflow-y).observe_window— scroll/resize onwindow; the spacer is just a tall element in document flow.
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
ResizeObserveron the scroll container — dispatcheson_resize - a
ResizeObserveron each row tagged withdata-index— dispatcheson_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 observersvirtualizer— the current state from the consumer’s modelrender—fn(VirtualItem) -> Element(msg)for each visible rowon_scroll— fired on every scroll event with the new offsetattributes— extra attributes on the scroll container (e.g. CSS height)