| title | Motion components | ||||
|---|---|---|---|---|---|
| description | Progress, activity, loading, and host-driven animation. | ||||
| sidebar |
|
Animated from a host-supplied frame counter (see the anim module).
A frame-cycled activity glyph — Braille (smooth default), Line (ASCII
fallback), or Dots. API
use tuika::prelude::*;
view! {
row(gap = 1) {
node(Spinner::new(frame).style(SpinnerStyle::Braille))
text("working…")
}
}A single-row bar: determinate (sub-cell eighth-block fill, optional NN%) or an
indeterminate marquee driven by the frame counter. .label("…") overlays a
centered caption and clips it on narrow terminals.
API
use tuika::prelude::*;
view! {
col(gap = 1) {
node(ProgressBar::determinate(0.6).label("0:42/3:07").percent(true))
node(ProgressBar::indeterminate(frame))
}
}A vertical lifecycle view for multi-step work: queued, running, succeeded,
failed, or skipped. An item may compose a determinate progress bar beneath its
status row. Use ActivityList to answer which step is in which state; use a
standalone ProgressBar to answer how much of one measurable operation is
complete. The host still owns the task model and scheduling.
API
use tuika::prelude::*;
let tasks = vec![
ActivityItem::new("Resolve dependencies", ActivityStatus::Succeeded),
ActivityItem::new("Compile", ActivityStatus::Running).progress(0.42),
ActivityItem::new("Test", ActivityStatus::Queued),
];
view! { node(ActivityList::new(tasks).frame(frame).gap(1)) }A spinner, a message, and an optional trailing hint on one row. API
use tuika::prelude::*;
view! {
node(Loader::new(frame, "compiling crate…").hint("esc to cancel"))
}A scheduler-free keyframe track: values eased over frame offsets, with
Once/Loop/PingPong repeat, sampled purely from the host frame counter — the
minimal analog of OpenTUI's Timeline. Compose several (one per animated property)
rather than reconciling a tween tree. The demo drives three ProgressBars from
three timelines.
API
use tuika::anim::ease_out;
use tuika::prelude::*;
let slide = Timeline::new().keyframe(0, 0.0).ease(30, 1.0, ease_out);
let pulse = Timeline::new()
.keyframe(0, 0.0).keyframe(10, 1.0).keyframe(20, 0.0)
.repeat(Repeat::Loop);
let x = slide.sample(frame); // 0.0 → 1.0 over 30 frames, then holds



