tui/components/
stepper.rs1use crate::rendering::line::Line;
2use crate::rendering::render_context::ViewContext;
3use crate::rendering::span::Span;
4use crate::rendering::style::Style;
5
6pub enum StepVisualState {
7 Complete,
8 Current,
9 Upcoming,
10}
11
12pub struct StepperItem<'a> {
13 pub label: &'a str,
14 pub state: StepVisualState,
15}
16
17pub struct Stepper<'a> {
18 pub items: &'a [StepperItem<'a>],
19 pub separator: &'a str,
20 pub leading_padding: usize,
21}
22
23impl Stepper<'_> {
24 pub fn render(&self, ctx: &ViewContext) -> Line {
25 let padding = " ".repeat(self.leading_padding);
26 let mut line = Line::new(padding);
27 for (i, item) in self.items.iter().enumerate() {
28 let (glyph, style) = match item.state {
29 StepVisualState::Complete => ("\u{25cf} ", Style::fg(ctx.theme.text_secondary())),
30 StepVisualState::Current => ("\u{25c9} ", Style::fg(ctx.theme.primary())),
31 StepVisualState::Upcoming => ("\u{25cb} ", Style::fg(ctx.theme.muted())),
32 };
33 line.push_span(Span::with_style(glyph.to_string(), style));
34 line.push_span(Span::with_style(item.label.to_string(), style));
35 if i + 1 < self.items.len() {
36 line.push_span(Span::with_style(self.separator.to_string(), Style::fg(ctx.theme.muted())));
37 }
38 }
39 line
40 }
41}