Skip to main content

material_ui_rs/design/style/
toggler.rs

1use iced_widget::core::{Background, Color};
2use iced_widget::toggler::{Catalog, Status, Style, StyleFn};
3
4use crate::Theme;
5use crate::tokens;
6use crate::utils::state_layer;
7
8impl Catalog for Theme {
9    type Class<'a> = StyleFn<'a, Self>;
10
11    fn default<'a>() -> Self::Class<'a> {
12        Box::new(default)
13    }
14
15    fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
16        class(self, status)
17    }
18}
19
20pub fn styled(
21    background: Background,
22    foreground: Background,
23    text_color: Color,
24    border: Option<Color>,
25) -> Style {
26    Style {
27        background,
28        background_border_width: if border.is_some() {
29            tokens::component::switch::TRACK_OUTLINE_WIDTH
30        } else {
31            0.0
32        },
33        background_border_color: border.unwrap_or(Color::TRANSPARENT),
34        foreground,
35        foreground_border_width: 0.0,
36        foreground_border_color: Color::TRANSPARENT,
37        text_color: Some(text_color),
38        border_radius: None,
39        padding_ratio: 0.2,
40    }
41}
42
43pub fn default(theme: &Theme, status: Status) -> Style {
44    let surface = theme.colors().surface;
45    let primary = theme.colors().primary;
46
47    match status {
48        Status::Active { is_toggled } => {
49            if is_toggled {
50                styled(
51                    primary.color.into(),
52                    primary.text.into(),
53                    surface.text,
54                    None,
55                )
56            } else {
57                styled(
58                    surface.container.highest.into(),
59                    theme.colors().outline.color.into(),
60                    surface.text,
61                    Some(theme.colors().outline.color),
62                )
63            }
64        }
65        Status::Hovered { is_toggled } => {
66            if is_toggled {
67                styled(
68                    primary.color.into(),
69                    primary.container.into(),
70                    surface.text,
71                    None,
72                )
73            } else {
74                styled(
75                    surface.container.highest.into(),
76                    surface.text_variant.into(),
77                    surface.text,
78                    Some(theme.colors().outline.color),
79                )
80            }
81        }
82        Status::Disabled { is_toggled } => {
83            if is_toggled {
84                styled(
85                    state_layer(
86                        surface.text,
87                        tokens::component::switch::DISABLED_TRACK_OPACITY,
88                    )
89                    .into(),
90                    state_layer(
91                        surface.color,
92                        tokens::component::switch::DISABLED_SELECTED_HANDLE_OPACITY,
93                    )
94                    .into(),
95                    surface.text,
96                    None,
97                )
98            } else {
99                styled(
100                    state_layer(
101                        surface.container.highest,
102                        tokens::component::switch::DISABLED_TRACK_OPACITY,
103                    )
104                    .into(),
105                    state_layer(
106                        surface.text,
107                        tokens::component::switch::DISABLED_UNSELECTED_HANDLE_OPACITY,
108                    )
109                    .into(),
110                    surface.text,
111                    Some(state_layer(
112                        surface.text,
113                        tokens::component::switch::DISABLED_TRACK_OPACITY,
114                    )),
115                )
116            }
117        }
118    }
119}
120
121#[cfg(test)]
122#[path = "../../../tests/design/style/toggler.rs"]
123mod tests;