dioxus_element_plug/components/
switch.rs1use dioxus::prelude::*;
2
3#[derive(Clone, PartialEq)]
5pub enum SwitchSize {
6 Large,
7 Default,
8 Small,
9}
10
11impl SwitchSize {
12 pub fn as_class(&self) -> &'static str {
13 match self {
14 SwitchSize::Large => "el-switch--large",
15 SwitchSize::Default => "",
16 SwitchSize::Small => "el-switch--small",
17 }
18 }
19}
20
21#[derive(Props, Clone, PartialEq)]
23pub struct SwitchProps {
24 #[props(default = false)]
26 pub model_value: bool,
27
28 #[props(default = false)]
30 pub disabled: bool,
31
32 #[props(default = false)]
34 pub loading: bool,
35
36 #[props(default = SwitchSize::Default)]
38 pub size: SwitchSize,
39
40 #[props(default)]
42 pub width: Option<String>,
43
44 #[props(default = false)]
46 pub inline_prompt: bool,
47
48 #[props(default)]
50 pub active_text: Option<String>,
51
52 #[props(default)]
54 pub inactive_text: Option<String>,
55
56 #[props(default)]
58 pub active_icon: Option<String>,
59
60 #[props(default)]
62 pub inactive_icon: Option<String>,
63
64 #[props(default)]
66 pub name: Option<String>,
67
68 #[props(default)]
70 pub on_change: Option<EventHandler<bool>>,
71
72 #[props(default)]
74 pub class: Option<String>,
75
76 #[props(default)]
78 pub style: Option<String>,
79}
80
81#[component]
96pub fn Switch(props: SwitchProps) -> Element {
97 let mut class_names = vec!["el-switch".to_string()];
98
99 let size_class = props.size.as_class();
100 if !size_class.is_empty() {
101 class_names.push(size_class.to_string());
102 }
103
104 if props.model_value {
105 class_names.push("is-checked".to_string());
106 }
107
108 if props.disabled {
109 class_names.push("is-disabled".to_string());
110 }
111
112 if props.loading {
113 class_names.push("is-loading".to_string());
114 }
115
116 if let Some(ref custom_class) = props.class {
117 class_names.push(custom_class.clone());
118 }
119
120 let class_string = class_names.join(" ");
121
122 let mut style_parts = vec![props.style.clone().unwrap_or_default()];
123 if let Some(ref width) = props.width {
124 style_parts.push(format!("width: {};", width));
125 }
126 let style_string = style_parts.join("");
127
128 rsx! {
129 div {
130 class: "{class_string}",
131 style: "{style_string}",
132 role: "switch",
133 aria_checked: "{props.model_value}",
134 onclick: move |_| {
135 if !props.disabled && !props.loading {
136 if let Some(handler) = props.on_change {
137 handler.call(!props.model_value);
138 }
139 }
140 },
141 div {
142 class: "el-switch__core",
143 if props.inline_prompt {
144 div {
145 class: "el-switch__inner",
146 if props.model_value {
147 if let Some(ref text) = props.active_text {
148 span { class: "el-switch__text", "{text}" }
149 } else if let Some(ref icon) = props.active_icon {
150 i { class: "{icon}" }
151 }
152 } else {
153 if let Some(ref text) = props.inactive_text {
154 span { class: "el-switch__text", "{text}" }
155 } else if let Some(ref icon) = props.inactive_icon {
156 i { class: "{icon}" }
157 }
158 }
159 }
160 }
161 div {
162 class: "el-switch__action",
163 if props.loading {
164 i { class: "el-icon-loading" }
165 }
166 }
167 }
168 if !props.inline_prompt {
169 if props.model_value {
170 if let Some(ref text) = props.active_text {
171 span {
172 class: "el-switch__label el-switch__label--left is-active",
173 "{text}"
174 }
175 }
176 } else {
177 if let Some(ref text) = props.inactive_text {
178 span {
179 class: "el-switch__label el-switch__label--right is-active",
180 "{text}"
181 }
182 }
183 }
184 }
185 if let Some(ref name) = props.name {
186 input {
187 r#type: "hidden",
188 name: "{name}",
189 value: "{props.model_value}",
190 }
191 }
192 }
193 }
194}