dioxus_element_plug/components/
button.rs1use dioxus::prelude::*;
2
3pub const BUTTON: &str = "el-button";
5pub const BUTTON_PRIMARY: &str = "el-button--primary";
6pub const BUTTON_SUCCESS: &str = "el-button--success";
7pub const BUTTON_WARNING: &str = "el-button--warning";
8pub const BUTTON_DANGER: &str = "el-button--danger";
9pub const BUTTON_INFO: &str = "el-button--info";
10pub const BUTTON_LARGE: &str = "el-button--large";
11pub const BUTTON_SMALL: &str = "el-button--small";
12pub const BUTTON_DISABLED: &str = "is-disabled";
13
14#[derive(Clone, PartialEq)]
16pub enum ButtonVariant {
17 Default,
18 Primary,
19 Success,
20 Warning,
21 Danger,
22 Info,
23}
24
25impl ButtonVariant {
26 pub fn as_class(&self) -> &'static str {
27 match self {
28 ButtonVariant::Default => BUTTON,
29 ButtonVariant::Primary => BUTTON_PRIMARY,
30 ButtonVariant::Success => BUTTON_SUCCESS,
31 ButtonVariant::Warning => BUTTON_WARNING,
32 ButtonVariant::Danger => BUTTON_DANGER,
33 ButtonVariant::Info => BUTTON_INFO,
34 }
35 }
36}
37
38#[derive(Clone, PartialEq)]
40pub enum ButtonSize {
41 Large,
42 Medium,
43 Small,
44 Mini,
45}
46
47impl ButtonSize {
48 pub fn as_class(&self) -> &'static str {
49 match self {
50 ButtonSize::Large => "el-button--large",
51 ButtonSize::Medium => "el-button--medium",
52 ButtonSize::Small => "el-button--small",
53 ButtonSize::Mini => "el-button--mini",
54 }
55 }
56}
57
58#[derive(Props, Clone, PartialEq)]
60pub struct ButtonProps {
61 #[props(!optional)]
63 pub children: Element,
64
65 #[props(default = ButtonVariant::Default)]
67 pub variant: ButtonVariant,
68
69 #[props(default)]
71 pub size: Option<ButtonSize>,
72
73 #[props(default = false)]
75 pub disabled: bool,
76
77 #[props(default = false)]
79 pub round: bool,
80
81 #[props(default = false)]
83 pub circle: bool,
84
85 #[props(default = false)]
87 pub loading: bool,
88
89 #[props(default)]
91 pub icon: Option<String>,
92
93 #[props(default = "button".to_string())]
95 pub button_type: String,
96
97 #[props(default)]
99 pub on_click: Option<EventHandler<MouseEvent>>,
100
101 #[props(default)]
103 pub class: Option<String>,
104
105 #[props(default)]
107 pub style: Option<String>,
108}
109
110#[component]
130pub fn Button(props: ButtonProps) -> Element {
131 let base_class = BUTTON;
132 let variant_class = props.variant.as_class();
133
134 let mut classes = vec![base_class, variant_class];
135
136 if let Some(size) = &props.size {
137 classes.push(size.as_class());
138 }
139
140 if props.disabled {
141 classes.push("is-disabled");
142 }
143
144 if props.round {
145 classes.push("is-round");
146 }
147
148 if props.circle {
149 classes.push("is-circle");
150 }
151
152 if props.loading {
153 classes.push("is-loading");
154 }
155
156 if let Some(ref custom_class) = props.class {
157 classes.push(custom_class);
158 }
159
160 let class_string = classes.join(" ");
161
162 let mut icon_element = None;
163 if let Some(ref icon) = props.icon {
164 icon_element = Some(rsx! {
165 i {
166 class: "{icon}"
167 }
168 });
169 }
170
171 let mut loading_element = None;
172 if props.loading {
173 loading_element = Some(rsx! {
174 i {
175 class: "el-icon-loading"
176 }
177 });
178 }
179
180 rsx! {
181 button {
182 class: "{class_string}",
183 r#type: props.button_type,
184 disabled: props.disabled,
185 style: props.style.unwrap_or_default(),
186 onclick: move |event| {
187 if let Some(handler) = props.on_click {
188 handler.call(event);
189 }
190 },
191
192 {loading_element},
193 {icon_element},
194 {props.children}
195 }
196 }
197}
198
199#[component]
201pub fn OutlineButton(props: ButtonProps) -> Element {
202 let mut props = props;
203 let mut class = props.class.unwrap_or_default();
204 class.push_str(" is-plain");
205 props.class = Some(class);
206
207 Button(props)
208}
209
210#[component]
212pub fn TextButton(props: ButtonProps) -> Element {
213 let mut props = props;
214 props.variant = ButtonVariant::Default;
215 let mut class = props.class.unwrap_or_default();
216 class.push_str(" el-button--text");
217 props.class = Some(class);
218
219 Button(props)
220}
221
222#[component]
224pub fn LinkButton(props: ButtonProps) -> Element {
225 rsx! {
226 a {
227 class: "el-button el-button--text",
228 href: "javascript:void(0)",
229 onclick: move |event| {
230 if let Some(handler) = props.on_click {
231 handler.call(event);
232 }
233 },
234 {props.children}
235 }
236 }
237}