use std::sync::LazyLock;
use dioxus::prelude::*;
use regex::Regex;
use crate::components::DocNodeRenderer;
use crate::parser::{DocNode, StepsNode};
static STEP_PREFIX_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^Step\s+\d+[:.]\s*").unwrap());
#[derive(Props, Clone, PartialEq)]
pub struct DocStepsProps {
pub steps: StepsNode,
}
#[component]
pub fn DocSteps(props: DocStepsProps) -> Element {
rsx! {
div { class: "my-8",
div { class: "relative border-l-2 border-primary/20 ml-5 space-y-8",
for (i, step) in props.steps.steps.iter().enumerate() {
div { key: "{i}", class: "relative pl-10",
span {
class: "absolute left-0 top-0 -translate-x-1/2 flex items-center justify-center w-7 h-7 bg-primary text-primary-content rounded-full font-semibold text-sm shadow-sm",
"{i + 1}"
}
div {
h4 { class: "font-semibold text-base text-base-content mb-2",
{clean_step_title(&step.title)}
}
StepContent { content: step.content.clone() }
}
}
}
}
}
}
}
fn clean_step_title(title: &str) -> String {
STEP_PREFIX_RE.replace(title, "").trim().to_string()
}
#[derive(Props, Clone, PartialEq)]
struct StepContentProps {
content: Vec<DocNode>,
}
#[component]
fn StepContent(props: StepContentProps) -> Element {
rsx! {
div { class: "prose prose-sm max-w-none",
for (i, node) in props.content.iter().enumerate() {
DocNodeRenderer { key: "{i}", node: node.clone() }
}
}
}
}