Skip to main content

material_ui_rs/design/style/
checkbox.rs

1use iced_widget::checkbox::{Catalog, Status, Style, StyleFn};
2use iced_widget::core::{Background, Border, Color, border};
3
4use crate::Theme;
5use crate::tokens;
6use crate::utils::{HOVERED_LAYER_OPACITY, 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_color: Color,
22    background_unchecked: Option<Color>,
23    icon_color: Color,
24    border_color: Color,
25    text_color: Option<Color>,
26    is_checked: bool,
27) -> Style {
28    Style {
29        background: Background::Color(if is_checked {
30            background_color
31        } else {
32            background_unchecked.unwrap_or(Color::TRANSPARENT)
33        }),
34        icon_color,
35        border: if is_checked {
36            border::rounded(tokens::component::checkbox::CONTAINER_SHAPE)
37        } else {
38            Border {
39                color: border_color,
40                width: tokens::component::checkbox::UNSELECTED_OUTLINE_WIDTH,
41                radius: tokens::component::checkbox::CONTAINER_SHAPE.into(),
42            }
43        },
44        text_color,
45    }
46}
47
48pub fn default(theme: &Theme, status: Status) -> Style {
49    let surface = theme.colors().surface;
50    let primary = theme.colors().primary;
51
52    match status {
53        Status::Active { is_checked } => styled(
54            primary.color,
55            None,
56            primary.text,
57            surface.text_variant,
58            Some(surface.text),
59            is_checked,
60        ),
61        Status::Hovered { is_checked } => styled(
62            primary.color,
63            Some(state_layer(surface.text, HOVERED_LAYER_OPACITY)),
64            primary.text,
65            surface.text,
66            Some(surface.text),
67            is_checked,
68        ),
69        Status::Disabled { is_checked } => styled(
70            state_layer(
71                surface.text,
72                tokens::component::checkbox::SELECTED_DISABLED_CONTAINER_OPACITY,
73            ),
74            None,
75            surface.color,
76            state_layer(
77                surface.text,
78                tokens::component::checkbox::UNSELECTED_DISABLED_CONTAINER_OPACITY,
79            ),
80            Some(state_layer(
81                surface.text,
82                tokens::state::DISABLED_LABEL_TEXT_OPACITY,
83            )),
84            is_checked,
85        ),
86    }
87}
88
89pub fn error(theme: &Theme, status: Status) -> Style {
90    let surface = theme.colors().surface;
91    let error = theme.colors().error;
92
93    match status {
94        Status::Active { is_checked } => styled(
95            error.color,
96            None,
97            error.text,
98            error.color,
99            Some(error.color),
100            is_checked,
101        ),
102        Status::Hovered { is_checked } => styled(
103            error.color,
104            Some(state_layer(error.color, HOVERED_LAYER_OPACITY)),
105            error.text,
106            error.color,
107            Some(error.color),
108            is_checked,
109        ),
110        Status::Disabled { is_checked } => styled(
111            state_layer(
112                surface.text,
113                tokens::component::checkbox::SELECTED_DISABLED_CONTAINER_OPACITY,
114            ),
115            None,
116            surface.color,
117            state_layer(
118                surface.text,
119                tokens::component::checkbox::UNSELECTED_DISABLED_CONTAINER_OPACITY,
120            ),
121            Some(state_layer(
122                surface.text,
123                tokens::state::DISABLED_LABEL_TEXT_OPACITY,
124            )),
125            is_checked,
126        ),
127    }
128}
129
130#[cfg(test)]
131#[path = "../../../tests/design/style/checkbox.rs"]
132mod tests;