Skip to main content

material_ui_rs/design/style/
container.rs

1use iced_widget::container::{Catalog, Style, StyleFn};
2use iced_widget::core::{Background, Border, border};
3
4use crate::Theme;
5use crate::tokens;
6use crate::utils::shadow_from_level;
7
8impl Catalog for Theme {
9    type Class<'a> = StyleFn<'a, Self>;
10
11    fn default<'a>() -> Self::Class<'a> {
12        Box::new(transparent)
13    }
14
15    fn style(&self, class: &Self::Class<'_>) -> Style {
16        class(self)
17    }
18}
19
20pub fn transparent(_theme: &Theme) -> Style {
21    Style {
22        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
23        ..Style::default()
24    }
25}
26
27pub fn primary(theme: &Theme) -> Style {
28    let primary = theme.colors().primary;
29
30    Style {
31        background: Some(Background::Color(primary.color)),
32        text_color: Some(primary.text),
33        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
34        ..Style::default()
35    }
36}
37
38pub fn primary_container(theme: &Theme) -> Style {
39    let primary = theme.colors().primary;
40
41    Style {
42        background: Some(Background::Color(primary.container)),
43        text_color: Some(primary.container_text),
44        border: border::rounded(tokens::shape::CORNER_SMALL),
45        ..Style::default()
46    }
47}
48
49pub fn secondary(theme: &Theme) -> Style {
50    let secondary = theme.colors().secondary;
51
52    Style {
53        background: Some(Background::Color(secondary.color)),
54        text_color: Some(secondary.text),
55        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
56        ..Style::default()
57    }
58}
59
60pub fn secondary_container(theme: &Theme) -> Style {
61    let secondary = theme.colors().secondary;
62
63    Style {
64        background: Some(Background::Color(secondary.container)),
65        text_color: Some(secondary.container_text),
66        border: border::rounded(tokens::shape::CORNER_SMALL),
67        ..Style::default()
68    }
69}
70
71pub fn tertiary(theme: &Theme) -> Style {
72    let tertiary = theme.colors().tertiary;
73
74    Style {
75        background: Some(Background::Color(tertiary.color)),
76        text_color: Some(tertiary.text),
77        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
78        ..Style::default()
79    }
80}
81
82pub fn tertiary_container(theme: &Theme) -> Style {
83    let tertiary = theme.colors().tertiary;
84
85    Style {
86        background: Some(Background::Color(tertiary.container)),
87        text_color: Some(tertiary.container_text),
88        border: border::rounded(tokens::shape::CORNER_SMALL),
89        ..Style::default()
90    }
91}
92
93pub fn error(theme: &Theme) -> Style {
94    let error = theme.colors().error;
95
96    Style {
97        background: Some(Background::Color(error.color)),
98        text_color: Some(error.text),
99        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
100        ..Style::default()
101    }
102}
103
104pub fn error_container(theme: &Theme) -> Style {
105    let error = theme.colors().error;
106
107    Style {
108        background: Some(Background::Color(error.container)),
109        text_color: Some(error.container_text),
110        border: border::rounded(tokens::shape::CORNER_SMALL),
111        ..Style::default()
112    }
113}
114
115pub fn surface(theme: &Theme) -> Style {
116    let surface = theme.colors().surface;
117
118    Style {
119        background: Some(Background::Color(surface.color)),
120        text_color: Some(surface.text),
121        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
122        ..Style::default()
123    }
124}
125
126pub fn surface_container_lowest(theme: &Theme) -> Style {
127    let surface = theme.colors().surface;
128
129    Style {
130        background: Some(Background::Color(surface.container.lowest)),
131        text_color: Some(surface.text),
132        border: border::rounded(tokens::shape::CORNER_SMALL),
133        ..Style::default()
134    }
135}
136
137pub fn surface_container_low(theme: &Theme) -> Style {
138    let surface = theme.colors().surface;
139
140    Style {
141        background: Some(Background::Color(surface.container.low)),
142        text_color: Some(surface.text),
143        border: border::rounded(tokens::shape::CORNER_SMALL),
144        ..Style::default()
145    }
146}
147
148pub fn surface_container(theme: &Theme) -> Style {
149    let surface = theme.colors().surface;
150
151    Style {
152        background: Some(Background::Color(surface.container.base)),
153        text_color: Some(surface.text),
154        border: border::rounded(tokens::shape::CORNER_SMALL),
155        ..Style::default()
156    }
157}
158
159pub fn surface_container_high(theme: &Theme) -> Style {
160    let surface = theme.colors().surface;
161
162    Style {
163        background: Some(Background::Color(surface.container.high)),
164        text_color: Some(surface.text),
165        border: border::rounded(tokens::shape::CORNER_SMALL),
166        ..Style::default()
167    }
168}
169
170pub fn surface_container_highest(theme: &Theme) -> Style {
171    let surface = theme.colors().surface;
172
173    Style {
174        background: Some(Background::Color(surface.container.highest)),
175        text_color: Some(surface.text),
176        border: border::rounded(tokens::shape::CORNER_SMALL),
177        ..Style::default()
178    }
179}
180
181pub fn inverse_surface(theme: &Theme) -> Style {
182    let inverse = theme.colors().inverse;
183
184    Style {
185        background: Some(Background::Color(inverse.inverse_surface)),
186        text_color: Some(inverse.inverse_surface_text),
187        border: border::rounded(tokens::shape::CORNER_EXTRA_SMALL),
188        ..Style::default()
189    }
190}
191
192pub fn outlined(theme: &Theme) -> Style {
193    let base = transparent(theme);
194
195    Style {
196        border: Border {
197            color: theme.colors().outline.color,
198            width: tokens::component::button::OUTLINED_OUTLINE_WIDTH,
199            ..base.border
200        },
201        ..base
202    }
203}
204
205pub fn elevated_card(theme: &Theme) -> Style {
206    let colors = theme.colors();
207
208    Style {
209        background: Some(Background::Color(colors.surface.container.low)),
210        text_color: Some(colors.surface.text),
211        border: border::rounded(tokens::component::card::CONTAINER_SHAPE),
212        shadow: shadow_from_level(
213            tokens::component::card::ELEVATED_ELEVATION.active,
214            colors.shadow,
215        ),
216        ..Style::default()
217    }
218}
219
220pub fn filled_card(theme: &Theme) -> Style {
221    let colors = theme.colors();
222
223    Style {
224        background: Some(Background::Color(colors.surface.container.highest)),
225        text_color: Some(colors.surface.text),
226        border: border::rounded(tokens::component::card::CONTAINER_SHAPE),
227        shadow: shadow_from_level(
228            tokens::component::card::FILLED_ELEVATION.active,
229            colors.shadow,
230        ),
231        ..Style::default()
232    }
233}
234
235pub fn outlined_card(theme: &Theme) -> Style {
236    let colors = theme.colors();
237
238    Style {
239        background: Some(Background::Color(colors.surface.color)),
240        text_color: Some(colors.surface.text),
241        border: Border {
242            color: colors.outline.variant,
243            width: tokens::component::card::OUTLINED_OUTLINE_WIDTH,
244            radius: tokens::component::card::CONTAINER_SHAPE.into(),
245        },
246        shadow: shadow_from_level(
247            tokens::component::card::OUTLINED_ELEVATION.active,
248            colors.shadow,
249        ),
250        ..Style::default()
251    }
252}
253
254#[cfg(test)]
255#[path = "../../../tests/design/style/container.rs"]
256mod tests;