4.3k

Timeline

A timeline/ledger list container: a vertical column of timeline-item children (for and if work inside it). Each item pairs a leading indicator badge — indicator text or a small dot, colored by variant — with a title/description/meta content column, joined by a connector rail; set connector="false" on the last item to end the rail. Binding on-press makes the whole item pressable with a trailing chevron. For a horizontal stage indicator, see stepper.

timeline
A timeline rendered by the engine (light theme)
indicator badges, titles with descriptions and meta lines, and the connector rail

Markup

<timeline gap="0">
  <timeline-item indicator="1" variant="primary" title="Build" description="Compiled 214 files in 1.8s." meta="zig build · 1.8s"></timeline-item>
  <timeline-item indicator="2" title="Test" description="Canvas and runtime suites passing." meta="zig build test · 42s" on-press="open_test_log"></timeline-item>
  <timeline-item indicator="3" title="Package" connector="false"></timeline-item>
</timeline>

Zig builder

The builder additionally takes an icon option that draws a registry icon inside the indicator badge (a vector check for finished steps).

ui.timeline(.{}, .{
    ui.timelineItem(.{ .icon = "check", .variant = .primary, .title = "Build", .description = "Compiled 214 files in 1.8s.", .meta = "zig build · 1.8s" }),
    ui.timelineItem(.{ .indicator = "2", .title = "Test", .description = "Canvas and runtime suites passing.", .meta = "zig build test · 42s", .on_press = .open_test_log }),
    ui.timelineItem(.{ .indicator = "3", .title = "Package", .connector = false }),
})

Eject

When theming is not enough and you need to own the timeline’s shape, eject it: the canonical source lands in your project as your code — SDK updates never touch it, and ejecting twice errors instead of overwriting your edits. timeline ejects as a markup template (src/components/timeline.native); timeline-item ejects as a Zig view function (src/components/timeline_item.zig).

native eject component timeline
native eject component timeline-item

The ownership model and what to do after ejecting are in Use, eject, or build.

Attributes

AttributeDescription
gapSpacing between items (plain number).
growFlex grow factor.
keySibling-scoped identity key.
global-keyParent-independent identity: ids survive reparenting between containers.
labelAccessible name; when set it REPLACES the element's text as the announced name - screen readers and automation snapshots see the label, never the text it shadows.

Items

title is required on every item.

AttributeDescription
titletimeline-item: bold first line (a literal or one {binding}). Required.
descriptiontimeline-item: wrapped muted preview under the title (a literal or one {binding}).
metatimeline-item: muted trailing meta line, e.g. "claude · sonnet · 1m 12s" (a literal or one {binding}).
indicatortimeline-item: leading badge text ("✓", a number); empty renders a small dot.
varianttimeline-item: indicator color variant (default|primary|secondary|outline|ghost|destructive) - map run outcomes here.
connectortimeline-item: false ends the connector rail (set on the last item).
selectedtimeline-item: selected state (true/false or a {binding}).
on-presstimeline-item: Msg dispatched from anywhere on the item (tag or tag:{payload}); adds a trailing chevron.