repose-ui 0.12.2

UI widgets and libs for Repose
Documentation

Views, Modifiers, and Layout

Repose UI is built around three core ideas:

  • View: an immutable description of a UI node.
  • Modifier: layout, styling, and interaction hints attached to a View.
  • Layout + paint: a separate pass (layout_and_paint) that turns the View tree into a Scene + hit regions using the Taffy layout engine.

Views

A View is a lightweight value that describes what to show, not how it is rendered. It is cheap to create and you are expected to rebuild the entire view tree on each frame:

use repose_core::*;
use repose_ui::*;

fn Counter(count: i32, on_inc: impl Fn() + 'static) -> View {
    Column(Modifier::new().padding(16.0)).child((
        Text(format!("Count = {count}")),
        Button("Increment".into_children(), on_inc),
    ))
}

Internally, a View has:

  • id: ViewId — assigned during composition/layout.
  • kind: ViewKind — which widget it is (Text, Button, ScrollV, etc.).
  • modifier: Modifier — layout/styling/interaction metadata.
  • children: Vec<View> — owned child views.

Views are pure data: they do not hold state or references into platform APIs. State lives in signals / remember_* and platform integration happens in the runner (repose-platform).

Modifiers

Modifier describes how a view participates in layout and hit‑testing:

  • Size hints: size, width, height, min_size, max_size, fill_max_size, fill_max_width, fill_max_height.
  • Box model: padding, padding_values.
  • Visuals: background, background_brush, border, clip_rounded, alpha, transform.
  • Flex / grid: flex_grow, flex_shrink, flex_basis, align_self, justify_content, align_items, grid, grid_span.
  • Positioning: absolute(), offset(..) for overlay / Stack / FABs.
  • Interaction: clickable(), pointer callbacks, on_scroll, semantics.
  • Custom paint: painter (used by repose-canvas).

Example:

use repose_core::*;
use repose_ui::*;

fn CardExample() -> View {
    Surface(
        Modifier::new()
            .padding(16.0)
            .background(theme().surface)
            .border(1.0, theme().outline, 8.0)
            .clip_rounded(8.0),
        Text("Hello, Repose!"),
    )
}

Modifiers are merged into a Taffy Style inside layout_and_paint. Most values are specified in density‑independent pixels (dp) and converted to physical pixels (px) using the current Density local.

Layout

Layout is a pure function:

pub fn layout_and_paint(
    root: &View,
    size_px: (u32, u32),
    textfield_states: &HashMap<u64, Rc<RefCell<TextFieldState>>>,
    interactions: &Interactions,
    focused: Option<u64>,
) -> (Scene, Vec<HitRegion>, Vec<SemNode>);

It:

  1. Clones the root View and assigns stable ViewIds.
  2. Builds a parallel Taffy tree and computes layout for the given window size.
  3. Walks the tree to:
    • Emit SceneNodes for visuals (rects, text, images, scrollbars, etc.).
    • Build HitRegions for input routing (clicks, pointer events, scroll).
    • Build SemNodes for accessibility / semantics.

Row, Column, Stack, Grid, ScrollV and ScrollXY are all special ViewKinds that map into Taffy styles and additional paint/hit logic.

Because layout + paint are separate from the platform runner, you can reuse the same UI code on desktop, Android, and other platforms.