dioxus_element_plug/components/
radio.rs1use dioxus::prelude::*;
2
3#[derive(Clone, PartialEq)]
5pub enum RadioSize {
6 Large,
7 Default,
8 Small,
9}
10
11impl RadioSize {
12 pub fn as_class(&self) -> &'static str {
13 match self {
14 RadioSize::Large => "el-radio--large",
15 RadioSize::Default => "",
16 RadioSize::Small => "el-radio--small",
17 }
18 }
19}
20
21#[derive(Props, Clone, PartialEq)]
23pub struct RadioProps {
24 #[props(default)]
26 pub children: Option<Element>,
27
28 #[props(default)]
30 pub label: Option<String>,
31
32 pub value: String,
34
35 #[props(default = false)]
37 pub model_value: bool,
38
39 #[props(default = false)]
41 pub disabled: bool,
42
43 #[props(default = false)]
45 pub border: bool,
46
47 #[props(default = RadioSize::Default)]
49 pub size: RadioSize,
50
51 #[props(default)]
53 pub name: Option<String>,
54
55 #[props(default)]
57 pub on_change: Option<EventHandler<String>>,
58
59 #[props(default)]
61 pub class: Option<String>,
62
63 #[props(default)]
65 pub style: Option<String>,
66}
67
68#[component]
78pub fn Radio(props: RadioProps) -> Element {
79 let mut class_names = vec!["el-radio".to_string()];
80
81 let size_class = props.size.as_class();
82 if !size_class.is_empty() {
83 class_names.push(size_class.to_string());
84 }
85
86 if props.model_value {
87 class_names.push("is-checked".to_string());
88 }
89
90 if props.disabled {
91 class_names.push("is-disabled".to_string());
92 }
93
94 if props.border {
95 class_names.push("is-bordered".to_string());
96 }
97
98 if let Some(ref custom_class) = props.class {
99 class_names.push(custom_class.clone());
100 }
101
102 let class_string = class_names.join(" ");
103 let style_string = props.style.clone().unwrap_or_default();
104 let value_clone1 = props.value.clone();
105 let value_clone2 = props.value.clone();
106
107 rsx! {
108 label {
109 class: "{class_string}",
110 style: "{style_string}",
111 role: "radio",
112 aria_checked: "{props.model_value}",
113 span {
114 class: "el-radio__input",
115 span {
116 class: "el-radio__inner",
117 }
118 input {
119 r#type: "radio",
120 class: "el-radio__original",
121 name: props.name.clone().unwrap_or_default(),
122 value: "{props.value}",
123 checked: props.model_value,
124 onchange: move |_| {
125 if !props.disabled {
126 if let Some(handler) = props.on_change {
127 handler.call(value_clone1.clone());
128 }
129 }
130 },
131 }
132 }
133 span {
134 class: "el-radio__label",
135 onclick: move |_| {
136 if !props.disabled {
137 if let Some(handler) = props.on_change {
138 handler.call(value_clone2.clone());
139 }
140 }
141 },
142 if let Some(ref label) = props.label {
143 "{label}"
144 }
145 {props.children}
146 }
147 }
148 }
149}
150
151#[derive(Props, Clone, PartialEq)]
153pub struct RadioGroupProps {
154 #[props(default)]
156 pub children: Element,
157
158 #[props(default = false)]
160 pub disabled: bool,
161
162 #[props(default = RadioSize::Default)]
164 pub size: RadioSize,
165
166 #[props(default)]
168 pub text_color: Option<String>,
169
170 #[props(default)]
172 pub fill: Option<String>,
173
174 #[props(default)]
176 pub name: Option<String>,
177
178 #[props(default)]
180 pub on_change: Option<EventHandler<String>>,
181
182 #[props(default)]
184 pub class: Option<String>,
185
186 #[props(default)]
188 pub style: Option<String>,
189}
190
191#[component]
193pub fn RadioGroup(props: RadioGroupProps) -> Element {
194 let mut class_names = vec!["el-radio-group".to_string()];
195
196 if props.disabled {
197 class_names.push("is-disabled".to_string());
198 }
199
200 if let Some(ref custom_class) = props.class {
201 class_names.push(custom_class.clone());
202 }
203
204 let class_string = class_names.join(" ");
205 let style_string = props.style.clone().unwrap_or_default();
206
207 rsx! {
208 div {
209 class: "{class_string}",
210 style: "{style_string}",
211 role: "radiogroup",
212 {props.children}
213 }
214 }
215}
216
217#[derive(Props, Clone, PartialEq)]
219pub struct RadioButtonProps {
220 #[props(default)]
222 pub children: Option<Element>,
223
224 #[props(default)]
226 pub label: Option<String>,
227
228 pub value: String,
230
231 #[props(default = false)]
233 pub model_value: bool,
234
235 #[props(default = false)]
237 pub disabled: bool,
238
239 #[props(default)]
241 pub on_change: Option<EventHandler<String>>,
242
243 #[props(default)]
245 pub class: Option<String>,
246
247 #[props(default)]
249 pub style: Option<String>,
250}
251
252#[component]
254pub fn RadioButton(props: RadioButtonProps) -> Element {
255 let mut class_names = vec!["el-radio-button".to_string()];
256
257 if props.model_value {
258 class_names.push("is-checked".to_string());
259 }
260
261 if props.disabled {
262 class_names.push("is-disabled".to_string());
263 }
264
265 if let Some(ref custom_class) = props.class {
266 class_names.push(custom_class.clone());
267 }
268
269 let class_string = class_names.join(" ");
270 let style_string = props.style.clone().unwrap_or_default();
271 let value_clone = props.value.clone();
272
273 rsx! {
274 label {
275 class: "{class_string}",
276 style: "{style_string}",
277 span {
278 class: "el-radio-button__inner",
279 role: "radio",
280 aria_checked: "{props.model_value}",
281 onclick: move |_| {
282 if !props.disabled {
283 if let Some(handler) = props.on_change {
284 handler.call(value_clone.clone());
285 }
286 }
287 },
288 if let Some(ref label) = props.label {
289 "{label}"
290 }
291 {props.children}
292 }
293 }
294 }
295}