1use freya_core::prelude::*;
2use torin::{
3 gaps::Gaps,
4 size::Size,
5};
6
7#[cfg(feature = "router")]
8use crate::link::Link;
9use crate::{
10 accordion::Accordion,
11 button::Button,
12 checkbox::Checkbox,
13 chip::Chip,
14 define_theme,
15 floating_tab::FloatingTab,
16 input::Input,
17 loader::CircularLoader,
18 menu::{
19 MenuContainer,
20 MenuItem,
21 },
22 popup::Popup,
23 progressbar::ProgressBar,
24 radio_item::RadioItem,
25 resizable_container::ResizableHandle,
26 scrollviews::ScrollBar,
27 select::Select,
28 sidebar::{
29 SideBar,
30 SideBarItem,
31 },
32 slider::Slider,
33 switch::Switch,
34 table::Table,
35 theming::themes::LIGHT_THEME,
36 tooltip::Tooltip,
37};
38
39#[derive(Clone, Debug, PartialEq)]
40pub struct Theme {
41 pub name: &'static str,
42 pub colors: ColorsSheet,
43 pub button_layout: ButtonLayoutThemePreference,
44 pub compact_button_layout: ButtonLayoutThemePreference,
45 pub expanded_button_layout: ButtonLayoutThemePreference,
46 pub button: ButtonColorsThemePreference,
47 pub filled_button: ButtonColorsThemePreference,
48 pub outline_button: ButtonColorsThemePreference,
49 pub accordion: AccordionThemePreference,
50 pub switch: SwitchThemePreference,
51 pub scrollbar: ScrollBarThemePreference,
52 pub progressbar: ProgressBarThemePreference,
53 pub sidebar: SideBarThemePreference,
54 pub sidebar_item: SideBarItemThemePreference,
55 #[cfg(feature = "router")]
56 pub link: LinkThemePreference,
57 pub tooltip: TooltipThemePreference,
58 pub circular_loader: CircularLoaderThemePreference,
59 pub input: InputThemePreference,
60 pub radio: RadioItemThemePreference,
61 pub checkbox: CheckboxThemePreference,
62 pub resizable_handle: ResizableHandleThemePreference,
63 pub floating_tab: FloatingTabThemePreference,
64 pub slider: SliderThemePreference,
65 pub select: SelectThemePreference,
66 pub popup: PopupThemePreference,
67 pub table: TableThemePreference,
68 pub chip: ChipThemePreference,
69 pub menu_item: MenuItemThemePreference,
70 pub menu_container: MenuContainerThemePreference,
71}
72
73impl Default for Theme {
74 fn default() -> Self {
75 LIGHT_THEME
76 }
77}
78
79#[derive(Clone, Debug, PartialEq, Eq)]
80pub struct ColorsSheet {
81 pub primary: Color,
83 pub secondary: Color,
84 pub tertiary: Color,
85
86 pub success: Color,
88 pub warning: Color,
89 pub error: Color,
90 pub info: Color,
91
92 pub background: Color,
94 pub surface_primary: Color,
95 pub surface_secondary: Color,
96 pub surface_tertiary: Color,
97 pub surface_inverse: Color,
98 pub surface_inverse_secondary: Color,
99 pub surface_inverse_tertiary: Color,
100
101 pub border: Color,
103 pub border_focus: Color,
104 pub border_disabled: Color,
105
106 pub text_primary: Color,
108 pub text_secondary: Color,
109 pub text_placeholder: Color,
110 pub text_inverse: Color,
111 pub text_highlight: Color,
112
113 pub hover: Color,
115 pub focus: Color,
116 pub active: Color,
117 pub disabled: Color,
118
119 pub overlay: Color,
121 pub shadow: Color,
122}
123
124define_theme! {
125 for = Button;
126 theme_field = theme_layout;
127
128 %[component]
129 pub ButtonLayout {
130 %[fields]
131 margin: Gaps,
132 corner_radius: CornerRadius,
133 width: Size,
134 height: Size,
135 padding: Gaps,
136 }
137}
138
139define_theme! {
140 for = Button;
141 theme_field = theme_colors;
142
143 %[component]
144 pub ButtonColors {
145 %[fields]
146 background: Color,
147 hover_background: Color,
148 border_fill: Color,
149 focus_border_fill: Color,
150 color: Color,
151 }
152}
153
154define_theme! {
155 %[component]
156 pub Accordion {
157 %[fields]
158 color: Color,
159 background: Color,
160 border_fill: Color,
161 }
162}
163
164define_theme! {
165 %[component]
166 pub Switch {
167 %[fields]
168 margin: Gaps,
169 background: Color,
170 thumb_background: Color,
171 toggled_background: Color,
172 toggled_thumb_background: Color,
173 focus_border_fill: Color,
174 }
175}
176
177define_theme! {
178 %[component]
179 pub ScrollBar {
180 %[fields]
181 background: Color,
182 thumb_background: Color,
183 hover_thumb_background: Color,
184 active_thumb_background: Color,
185 size: f32,
186 }
187}
188
189define_theme! {
190 %[component]
191 pub ProgressBar {
192 %[fields]
193 color: Color,
194 background: Color,
195 progress_background: Color,
196 height: f32,
197 }
198}
199
200define_theme! {
201 %[component]
202 pub SideBar {
203 %[fields]
204 color: Color,
205 background: Color,
206 padding: Gaps,
207 spacing: f32,
208 }
209}
210
211define_theme! {
212 %[component]
213 pub SideBarItem {
214 %[fields]
215 color: Color,
216 background: Color,
217 hover_background: Color,
218 active_background: Color,
219 corner_radius: CornerRadius,
220 margin: Gaps,
221 padding: Gaps,
222 }
223}
224
225#[cfg(feature = "router")]
226define_theme! {
227 %[component]
228 pub Link {
229 %[fields]
230 color: Color,
231 }
232}
233
234define_theme! {
235 %[component]
236 pub Tooltip {
237 %[fields]
238 color: Color,
239 background: Color,
240 border_fill: Color,
241 }
242}
243
244define_theme! {
245 %[component]
246 pub CircularLoader {
247 %[fields]
248 primary_color: Color,
249 inversed_color: Color,
250 }
251}
252
253define_theme! {
254 %[component]
255 pub Input {
256 %[fields]
257 background: Color,
258 hover_background: Color,
259 border_fill: Color,
260 focus_border_fill: Color,
261 corner_radius: CornerRadius,
262 inner_margin: Gaps,
263 color: Color,
264 placeholder_color: Color,
265 }
266}
267
268define_theme! {
269 %[component]
270 pub RadioItem {
271 %[fields]
272 unselected_fill: Color,
273 selected_fill: Color,
274 border_fill: Color,
275 }
276}
277
278define_theme! {
279 %[component]
280 pub Checkbox {
281 %[fields]
282 unselected_fill: Color,
283 selected_fill: Color,
284 selected_icon_fill: Color,
285 border_fill: Color,
286 }
287}
288
289define_theme! {
290 %[component]
291 pub ResizableHandle {
292 %[fields]
293 background: Color,
294 hover_background: Color,
295 corner_radius: CornerRadius,
296 }
297}
298
299define_theme! {
300 %[component]
301 pub FloatingTab {
302 %[fields]
303 background: Color,
304 hover_background: Color,
305 width: Size,
306 height: Size,
307 padding: Gaps,
308 color: Color,
309 }
310}
311
312define_theme! {
313 %[component]
314 pub Slider {
315 %[fields]
316 background: Color,
317 thumb_background: Color,
318 thumb_inner_background: Color,
319 border_fill: Color,
320 }
321}
322
323define_theme! {
324 %[component]
325 pub Select {
326 %[fields]
327 width: Size,
328 margin: Gaps,
329 select_background: Color,
330 background_button: Color,
331 hover_background: Color,
332 border_fill: Color,
333 focus_border_fill: Color,
334 arrow_fill: Color,
335 color: Color,
336 }
337}
338
339define_theme! {
340 %[component]
341 pub Popup {
342 %[fields]
343 background: Color,
344 color: Color,
345 }
346}
347
348define_theme! {
349 %[component]
350 pub Table {
351 %[fields]
352 background: Color,
353 arrow_fill: Color,
354 hover_row_background: Color,
355 row_background: Color,
356 divider_fill: Color,
357 corner_radius: CornerRadius,
358 color: Color,
359 }
360}
361
362define_theme! {
363 %[component]
364 pub Chip {
365 %[fields]
366 background: Color,
367 hover_background: Color,
368 selected_background: Color,
369 border_fill: Color,
370 selected_border_fill: Color,
371 hover_border_fill: Color,
372 focus_border_fill: Color,
373 margin: f32,
374 corner_radius: CornerRadius,
375 width: Size,
376 height: Size,
377 padding: Gaps,
378 color: Color,
379 hover_color: Color,
380 selected_color: Color,
381 selected_icon_fill: Color,
382 hover_icon_fill: Color,
383 }
384}
385
386define_theme! {
387 %[component]
388 pub MenuContainer {
389 %[fields]
390 background: Color,
391 padding: Gaps,
392 shadow: Color,
393 border_fill: Color,
394 corner_radius: CornerRadius,
395 }
396}
397
398define_theme! {
399 %[component]
400 pub MenuItem {
401 %[fields]
402 background: Color,
403 hover_background: Color,
404 select_background: Color,
405 border_fill: Color,
406 select_border_fill: Color,
407 corner_radius: CornerRadius,
408 color: Color,
409 }
410}