dioxus_mdx/components/
steps.rs1use std::sync::LazyLock;
4
5use dioxus::prelude::*;
6use regex::Regex;
7
8use crate::components::DocNodeRenderer;
9use crate::parser::{DocNode, StepsNode};
10
11static STEP_PREFIX_RE: LazyLock<Regex> =
12 LazyLock::new(|| Regex::new(r"^Step\s+\d+[:.]\s*").unwrap());
13
14#[derive(Props, Clone, PartialEq)]
16pub struct DocStepsProps {
17 pub steps: StepsNode,
19}
20
21#[component]
23pub fn DocSteps(props: DocStepsProps) -> Element {
24 rsx! {
25 div { class: "my-8",
26 div { class: "relative border-l-2 border-primary/20 ml-5 space-y-8",
28 for (i, step) in props.steps.steps.iter().enumerate() {
29 div { key: "{i}", class: "relative pl-10",
30 span {
32 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",
33 "{i + 1}"
34 }
35 div {
37 h4 { class: "font-semibold text-base text-base-content mb-2",
39 {clean_step_title(&step.title)}
41 }
42 StepContent { content: step.content.clone() }
44 }
45 }
46 }
47 }
48 }
49 }
50}
51
52fn clean_step_title(title: &str) -> String {
54 STEP_PREFIX_RE.replace(title, "").trim().to_string()
56}
57
58#[derive(Props, Clone, PartialEq)]
60struct StepContentProps {
61 content: Vec<DocNode>,
62}
63
64#[component]
66fn StepContent(props: StepContentProps) -> Element {
67 rsx! {
68 div { class: "prose prose-sm max-w-none",
69 for (i, node) in props.content.iter().enumerate() {
70 DocNodeRenderer { key: "{i}", node: node.clone() }
71 }
72 }
73 }
74}