windjammer-ui 0.3.6

Cross-platform UI framework for Windjammer (Web, Desktop, Mobile)
Documentation
// Stepper Component - Multi-step progress indicator

use super::traits::Renderable

pub struct StepperStep {
    label: string,
    description: string,
    completed: bool,
}

impl StepperStep {
    pub fn new(label: string) -> StepperStep {
        StepperStep {
            label: label,
            description: String::new(),
            completed: false,
        }
    }

    pub fn description(self, desc: string) -> StepperStep {
        self.description = desc;
        self
    }

    pub fn completed(self, completed: bool) -> StepperStep {
        self.completed = completed;
        self
    }
}

pub struct Stepper {
    steps: Vec<StepperStep>,
    current_step: i32,
}

impl Stepper {
    pub fn new() -> Stepper {
        Stepper {
            steps: Vec::new(),
            current_step: 0,
        }
    }

    pub fn step(self, step: StepperStep) -> Stepper {
        self.steps.push(step);
        self
    }

    pub fn current_step(self, index: i32) -> Stepper {
        self.current_step = index;
        self
    }

}

impl Renderable for Stepper {
fn render(self) -> string {
        let mut html = String::new();

        html.push_str("<div style='display: flex; align-items: center; justify-content: space-between; padding: 24px 0;'>");

        let total_steps = self.steps.len() as i32;

        for (step_index, step) in self.steps.iter().enumerate() {
            let step_index = step_index as i32;
            let is_current = step_index == self.current_step;
            let is_completed = step.completed || step_index < self.current_step;

            // Step circle
            html.push_str("<div style='display: flex; flex-direction: column; align-items: center; flex: 1;'>");

            // Circle
            let bg_color = if is_completed {
                "#10b981"
            } else if is_current {
                "#3b82f6"
            } else {
                "#e2e8f0"
            };

            let text_color = if is_completed || is_current {
                "white"
            } else {
                "#718096"
            };

            html.push_str("<div style='width: 40px; height: 40px; border-radius: 50%; background: ");
            html.push_str(bg_color);
            html.push_str("; color: ");
            html.push_str(text_color);
            html.push_str("; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 16px; margin-bottom: 8px;'>");

            if is_completed {
                html.push('✓');
            } else {
                html.push_str(&format!("{}", step_index + 1));
            }

            html.push_str("</div>");

            // Label
            html.push_str("<div style='text-align: center;'>");
            html.push_str("<div style='font-weight: 600; font-size: 14px; color: ");
            if is_current {
                html.push_str("#1a202c");
            } else {
                html.push_str("#718096");
            }
            html.push_str("; margin-bottom: 4px;'>");
            html.push_str(&step.label);
            html.push_str("</div>");

            if step.description.len() > 0 {
                html.push_str("<div style='font-size: 12px; color: #a0aec0;'>");
                html.push_str(&step.description);
                html.push_str("</div>");
            }

            html.push_str("</div>");

            html.push_str("</div>");

            // Connector line (except for last step)
            if step_index < total_steps - 1 {
                let line_color = if is_completed {
                    "#10b981"
                } else {
                    "#e2e8f0"
                };

                html.push_str("<div style='flex: 1; height: 2px; background: ");
                html.push_str(line_color);
                html.push_str("; margin: 0 8px; margin-bottom: 48px;'></div>");
            }
        }

        html.push_str("</div>");
        html
    }
}