Skip to content

ScrollView

ScrollView hosts one content View and scrolls vertically by default.

[[huxerui::composable]]
View Document() {
auto scroll = UseScrollController();
return ScrollView {
Column {
ForEach(sections, RenderSection),
}.With(
Padding(24.0F),
Spacing(16.0F)
),
}.Controller(scroll)
.With(ScrollBar());
}

Set .ScrollAxis(Axis::Horizontal) for horizontal content. .Controller(ScrollController) connects imperative coordination without moving the scroll offset into component state.

ScrollController reports ScrollMetrics and supports ScrollTo, ScrollBy, and virtual-layout ScrollToItem. Create a scope-stable controller with UseScrollController(initial_offset).

The runtime owns pointer wheel or touch scrolling, momentum, bounds, clipping, scrollbar interaction, and nested scroll arbitration. Focused text input may request visibility, but user scrolling remains authoritative and can move away from the field.

ScrollView exposes scroll-view role, extent, current offset, and semantic scroll actions.

  • Constructor: explicit ScrollView(View content).
  • Fluent methods: .ScrollAxis(Axis), .Controller(ScrollController).
  • Common modifiers: ScrollBar, Frame, Grow, Background.

Use VirtualList or VirtualGrid for large collections.

ScrollView measures ordinary content; every child in that content exists even when offscreen. Give the viewport finite space on the scroll axis, for example a height Frame or Grow in a bounded Column. Otherwise the parent may expand to fit the content and no useful scrolling range remains. The default axis is Vertical; horizontal scrolling requires .ScrollAxis(Axis::Horizontal).

Keep one stable UseScrollController() per independently scrolling viewport. ScrollTo(offset) and ScrollBy(delta) return whether a current connection accepted the request. Offsets use logical pixels and clamp to the available range. ScrollToItem is a virtual-layout operation, not a way to index arbitrary descendants of ScrollView.

Metrics(), Offset(), MaxOffset(), ViewportExtent(), and ContentExtent() expose the current projection; IsConnected() lets a caller distinguish a mounted connection. Request scrolling from an event or committed effect, not while constructing the scrollable declaration before it has connected.

For a refreshable feed, wrap this ScrollView with RefreshBox. Wheel/trackpad input, touch drag, scrollbar drag, momentum, focus reveal, and semantic scrolling remain one shared scroll state rather than competing component-owned offsets.