Skip to main content

dioxus_element_plug/components/
steps.rs

1use dioxus::prelude::*;
2
3/// Steps direction
4#[derive(Clone, PartialEq)]
5pub enum StepsDirection {
6    Horizontal,
7    Vertical,
8}
9
10/// Steps props
11#[derive(Props, Clone, PartialEq)]
12pub struct StepsProps {
13    #[props(default)]
14    pub children: Element,
15
16    /// Current active step
17    #[props(default = 0)]
18    pub active: u32,
19
20    /// Space between steps
21    #[props(default)]
22    pub space: Option<String>,
23
24    #[props(default = StepsDirection::Horizontal)]
25    pub direction: StepsDirection,
26
27    /// Whether to show the finish status icon
28    #[props(default = false)]
29    pub simple: bool,
30
31    /// Whether to align center
32    #[props(default = false)]
33    pub align_center: bool,
34
35    #[props(default)]
36    pub on_change: Option<EventHandler<u32>>,
37
38    #[props(default)]
39    pub class: Option<String>,
40
41    #[props(default)]
42    pub style: Option<String>,
43}
44
45/// Steps component for step-by-step processes
46#[component]
47pub fn Steps(props: StepsProps) -> Element {
48    let mut class_names = vec!["el-steps".to_string()];
49    match props.direction {
50        StepsDirection::Horizontal => class_names.push("is-horizontal".to_string()),
51        StepsDirection::Vertical => class_names.push("is-vertical".to_string()),
52    }
53    if props.simple { class_names.push("is-simple".to_string()); }
54    if props.align_center { class_names.push("is-center".to_string()); }
55    if let Some(ref c) = props.class { class_names.push(c.clone()); }
56
57    rsx! {
58        div {
59            class: "{class_names.join(\" \")}",
60            style: props.style.clone().unwrap_or_default(),
61            {props.children}
62        }
63    }
64}
65
66/// Step status
67#[derive(Clone, PartialEq)]
68pub enum StepStatus {
69    Wait,
70    Process,
71    Finish,
72    Error,
73    Success,
74}
75
76impl StepStatus {
77    pub fn as_class(&self) -> &'static str {
78        match self {
79            StepStatus::Wait => "is-wait",
80            StepStatus::Process => "is-process",
81            StepStatus::Finish => "is-finish",
82            StepStatus::Error => "is-error",
83            StepStatus::Success => "is-success",
84        }
85    }
86}
87
88/// Step props
89#[derive(Props, Clone, PartialEq)]
90pub struct StepProps {
91    #[props(default)]
92    pub children: Option<Element>,
93
94    /// Step title
95    pub title: String,
96
97    /// Step description
98    #[props(default)]
99    pub description: Option<String>,
100
101    /// Step icon
102    #[props(default)]
103    pub icon: Option<String>,
104
105    /// Step status
106    #[props(default = StepStatus::Wait)]
107    pub status: StepStatus,
108
109    #[props(default)]
110    pub class: Option<String>,
111}
112
113/// Step component for individual steps
114#[component]
115pub fn Step(props: StepProps) -> Element {
116    let mut class_names = vec!["el-step".to_string()];
117    class_names.push(props.status.as_class().to_string());
118    if let Some(ref c) = props.class { class_names.push(c.clone()); }
119
120    rsx! {
121        div {
122            class: "{class_names.join(\" \")}",
123            div {
124                class: "el-step__head",
125                div {
126                    class: "el-step__icon",
127                    if let Some(ref icon) = props.icon {
128                        i { class: "{icon}" }
129                    } else {
130                        span { class: "el-step__icon-inner", "" }
131                    }
132                }
133            }
134            div {
135                class: "el-step__main",
136                div {
137                    class: "el-step__title",
138                    "{props.title}"
139                }
140                if let Some(ref desc) = props.description {
141                    div {
142                        class: "el-step__description",
143                        "{desc}"
144                    }
145                }
146            }
147        }
148    }
149}