1use dioxus::prelude::*;
2
3#[component]
4pub fn Switch(
5 checked: Signal<bool>,
6 #[props(default)] label: Option<String>,
7 #[props(default)] description: Option<String>,
8 #[props(default)] disabled: bool,
9 #[props(default)] glow: Option<bool>,
10 #[props(default)] class: String,
11) -> Element {
12 let is_checked = *checked.read();
13
14 #[cfg(feature = "theme")]
15 let theme_val = crate::theme::use_theme()();
16 #[cfg(feature = "theme")]
17 let track_checked_modifier = match &theme_val.primary_color {
18 crate::theme::PrimaryColor::Violet => "sd-switch__track--checked".to_string(),
19 crate::theme::PrimaryColor::Obsidian => "sd-switch__track--checked-obsidian".to_string(),
20 crate::theme::PrimaryColor::Crimson => "sd-switch__track--checked-crimson".to_string(),
21 crate::theme::PrimaryColor::Cyan => "sd-switch__track--checked-cyan".to_string(),
22 crate::theme::PrimaryColor::Emerald => "sd-switch__track--checked-emerald".to_string(),
23 crate::theme::PrimaryColor::Custom { .. } => {
24 format!("sd-switch__track--checked-{}", theme_val.primary_color.css_prefix())
25 }
26 };
27 #[cfg(feature = "theme")]
28 let glow_modifier = if is_checked {
29 theme_val.resolve_elevation_class("switch", glow)
30 } else {
31 String::new()
32 };
33 #[cfg(feature = "theme")]
34 let base_override = theme_val.resolve_component_base("switch").unwrap_or("");
35 #[cfg(feature = "theme")]
36 let class_modifiers = theme_val.resolve_class_modifiers("switch", &class);
37
38 #[cfg(not(feature = "theme"))]
39 let base_override = "";
40 #[cfg(not(feature = "theme"))]
41 let class_modifiers = String::new();
42 #[cfg(not(feature = "theme"))]
43 let track_checked_modifier = "sd-switch__track--checked".to_string();
44 #[cfg(not(feature = "theme"))]
45 let glow_modifier = if is_checked && glow.unwrap_or(false) {
46 "sd-switch__track--glow".to_string()
47 } else {
48 String::new()
49 };
50
51 let track_active_class = if is_checked {
52 format!("{track_checked_modifier} {glow_modifier}")
53 } else {
54 String::new()
55 };
56
57 let thumb_active_class = if is_checked {
58 "sd-switch__thumb--checked"
59 } else {
60 ""
61 };
62
63 let disabled_class = if disabled { "sd-switch--disabled" } else { "" };
64
65 rsx! {
66 div {
67 class: "sd-switch {base_override} {disabled_class} {class_modifiers} {class}",
68 onclick: move |_| {
69 if !disabled {
70 let next = !*checked.read();
71 *checked.write() = next;
72 }
73 },
74 div {
75 class: "sd-switch__track {track_active_class}",
76 span {
77 class: "sd-switch__thumb {thumb_active_class}",
78 }
79 }
80 if label.is_some() || description.is_some() {
81 div { class: "sd-switch__label-group",
82 if let Some(lbl) = label {
83 span { class: "sd-switch__label", "{lbl}" }
84 }
85 if let Some(desc) = description {
86 span { class: "sd-switch__description", "{desc}" }
87 }
88 }
89 }
90 }
91 }
92}