1use freya_core::prelude::*;
2use torin::{
3 gaps::Gaps,
4 size::Size,
5};
6
7#[cfg(feature = "calendar")]
8use crate::calendar::Calendar;
9#[cfg(feature = "router")]
10use crate::link::Link;
11#[cfg(feature = "markdown")]
12use crate::markdown::MarkdownViewer;
13#[cfg(feature = "titlebar")]
14use crate::titlebar::TitlebarButton;
15use crate::{
16 accordion::Accordion,
17 button::Button,
18 card::Card,
19 checkbox::Checkbox,
20 chip::Chip,
21 color_picker::ColorPicker,
22 define_theme,
23 floating_tab::FloatingTab,
24 input::Input,
25 loader::CircularLoader,
26 menu::{
27 MenuContainer,
28 MenuItem,
29 },
30 popup::Popup,
31 progressbar::ProgressBar,
32 radio_item::RadioItem,
33 resizable_container::ResizableHandle,
34 scrollviews::ScrollBar,
35 segmented_button::{
36 ButtonSegment,
37 SegmentedButton,
38 },
39 select::Select,
40 sidebar::SideBarItem,
41 slider::Slider,
42 switch::Switch,
43 table::Table,
44 theming::themes::LIGHT_THEME,
45 tooltip::Tooltip,
46};
47
48#[derive(Clone, Debug, PartialEq)]
49pub struct Theme {
50 pub name: &'static str,
51 pub colors: ColorsSheet,
52 pub button_layout: ButtonLayoutThemePreference,
53 pub compact_button_layout: ButtonLayoutThemePreference,
54 pub expanded_button_layout: ButtonLayoutThemePreference,
55 pub button: ButtonColorsThemePreference,
56 pub filled_button: ButtonColorsThemePreference,
57 pub outline_button: ButtonColorsThemePreference,
58 pub flat_button: ButtonColorsThemePreference,
59 pub card_layout: CardLayoutThemePreference,
60 pub compact_card_layout: CardLayoutThemePreference,
61 pub filled_card: CardColorsThemePreference,
62 pub outline_card: CardColorsThemePreference,
63 pub accordion: AccordionThemePreference,
64 pub switch: SwitchColorsThemePreference,
65 pub switch_layout: SwitchLayoutThemePreference,
66 pub expanded_switch_layout: SwitchLayoutThemePreference,
67 pub scrollbar: ScrollBarThemePreference,
68 pub progressbar: ProgressBarThemePreference,
69 pub sidebar_item: SideBarItemThemePreference,
70 #[cfg(feature = "router")]
71 pub link: LinkThemePreference,
72 pub tooltip: TooltipThemePreference,
73 pub circular_loader: CircularLoaderThemePreference,
74 pub input_layout: InputLayoutThemePreference,
75 pub compact_input_layout: InputLayoutThemePreference,
76 pub expanded_input_layout: InputLayoutThemePreference,
77 pub input: InputColorsThemePreference,
78 pub filled_input: InputColorsThemePreference,
79 pub flat_input: InputColorsThemePreference,
80 pub radio: RadioItemThemePreference,
81 pub checkbox: CheckboxThemePreference,
82 pub resizable_handle: ResizableHandleThemePreference,
83 pub floating_tab: FloatingTabThemePreference,
84 pub slider: SliderThemePreference,
85 pub color_picker: ColorPickerThemePreference,
86 pub select: SelectThemePreference,
87 pub popup: PopupThemePreference,
88 pub table: TableThemePreference,
89 #[cfg(feature = "markdown")]
90 pub markdown_viewer: MarkdownViewerThemePreference,
91 pub chip: ChipThemePreference,
92 pub menu_item: MenuItemThemePreference,
93 pub menu_container: MenuContainerThemePreference,
94 pub button_segment: ButtonSegmentThemePreference,
95 pub segmented_button: SegmentedButtonThemePreference,
96 #[cfg(feature = "calendar")]
97 pub calendar: CalendarThemePreference,
98 #[cfg(feature = "titlebar")]
99 pub titlebar_button: TitlebarButtonThemePreference,
100}
101
102impl Default for Theme {
103 fn default() -> Self {
104 LIGHT_THEME
105 }
106}
107
108#[derive(Clone, Debug, PartialEq, Eq)]
109pub struct ColorsSheet {
110 pub primary: Color,
112 pub secondary: Color,
113 pub tertiary: Color,
114
115 pub success: Color,
117 pub warning: Color,
118 pub error: Color,
119 pub info: Color,
120
121 pub background: Color,
123 pub surface_primary: Color,
124 pub surface_secondary: Color,
125 pub surface_tertiary: Color,
126 pub surface_inverse: Color,
127 pub surface_inverse_secondary: Color,
128 pub surface_inverse_tertiary: Color,
129
130 pub border: Color,
132 pub border_focus: Color,
133 pub border_disabled: Color,
134
135 pub text_primary: Color,
137 pub text_secondary: Color,
138 pub text_placeholder: Color,
139 pub text_inverse: Color,
140 pub text_highlight: Color,
141
142 pub hover: Color,
144 pub focus: Color,
145 pub active: Color,
146 pub disabled: Color,
147
148 pub overlay: Color,
150 pub shadow: Color,
151}
152
153define_theme! {
154 for = Button;
155 theme_field = theme_layout;
156
157 %[component]
158 pub ButtonLayout {
159 %[fields]
160 margin: Gaps,
161 corner_radius: CornerRadius,
162 width: Size,
163 height: Size,
164 padding: Gaps,
165 }
166}
167
168define_theme! {
169 for = Button;
170 theme_field = theme_colors;
171
172 %[component]
173 pub ButtonColors {
174 %[fields]
175 background: Color,
176 hover_background: Color,
177 border_fill: Color,
178 focus_border_fill: Color,
179 color: Color,
180 }
181}
182
183define_theme! {
184 for = Card;
185 theme_field = theme_layout;
186
187 %[component]
188 pub CardLayout {
189 %[fields]
190 corner_radius: CornerRadius,
191 padding: Gaps,
192 }
193}
194
195define_theme! {
196 for = Card;
197 theme_field = theme_colors;
198
199 %[component]
200 pub CardColors {
201 %[fields]
202 background: Color,
203 hover_background: Color,
204 border_fill: Color,
205 color: Color,
206 shadow: Color,
207 }
208}
209
210define_theme! {
211 %[component]
212 pub Accordion {
213 %[fields]
214 color: Color,
215 background: Color,
216 border_fill: Color,
217 }
218}
219
220define_theme! {
221 for = Switch;
222 theme_field = theme_colors;
223
224 %[component]
225 pub SwitchColors {
226 %[fields]
227 background: Color,
228 thumb_background: Color,
229 toggled_background: Color,
230 toggled_thumb_background: Color,
231 focus_border_fill: Color,
232 }
233}
234
235define_theme! {
236 for = Switch;
237 theme_field = theme_layout;
238
239 %[component]
240 pub SwitchLayout {
241 %[fields]
242 margin: Gaps,
243 width: f32,
244 height: f32,
245 padding: f32,
246 thumb_size: f32,
247 toggled_thumb_size: f32,
248 thumb_offset: f32,
249 toggled_thumb_offset: f32,
250 }
251}
252
253define_theme! {
254 %[component]
255 pub ScrollBar {
256 %[fields]
257 background: Color,
258 thumb_background: Color,
259 hover_thumb_background: Color,
260 active_thumb_background: Color,
261 size: f32,
262 }
263}
264
265define_theme! {
266 %[component]
267 pub ProgressBar {
268 %[fields]
269 color: Color,
270 background: Color,
271 progress_background: Color,
272 height: f32,
273 }
274}
275
276define_theme! {
277 %[component]
278 pub SideBarItem {
279 %[fields]
280 color: Color,
281 background: Color,
282 hover_background: Color,
283 active_background: Color,
284 corner_radius: CornerRadius,
285 margin: Gaps,
286 padding: Gaps,
287 }
288}
289
290#[cfg(feature = "router")]
291define_theme! {
292 %[component]
293 pub Link {
294 %[fields]
295 color: Color,
296 }
297}
298
299define_theme! {
300 %[component]
301 pub Tooltip {
302 %[fields]
303 color: Color,
304 background: Color,
305 border_fill: Color,
306 font_size: f32,
307 }
308}
309
310define_theme! {
311 %[component]
312 pub CircularLoader {
313 %[fields]
314 primary_color: Color,
315 inversed_color: Color,
316 }
317}
318
319define_theme! {
320 for = Input;
321 theme_field = theme_layout;
322
323 %[component]
324 pub InputLayout {
325 %[fields]
326 corner_radius: CornerRadius,
327 inner_margin: Gaps,
328 }
329}
330
331define_theme! {
332 for = Input;
333 theme_field = theme_colors;
334
335 %[component]
336 pub InputColors {
337 %[fields]
338 background: Color,
339 hover_background: Color,
340 border_fill: Color,
341 focus_border_fill: Color,
342 color: Color,
343 placeholder_color: Color,
344 }
345}
346
347define_theme! {
348 %[component]
349 pub RadioItem {
350 %[fields]
351 unselected_fill: Color,
352 selected_fill: Color,
353 border_fill: Color,
354 }
355}
356
357define_theme! {
358 %[component]
359 pub Checkbox {
360 %[fields]
361 unselected_fill: Color,
362 selected_fill: Color,
363 selected_icon_fill: Color,
364 border_fill: Color,
365 }
366}
367
368define_theme! {
369 %[component]
370 pub ResizableHandle {
371 %[fields]
372 background: Color,
373 hover_background: Color,
374 corner_radius: CornerRadius,
375 }
376}
377
378define_theme! {
379 %[component]
380 pub FloatingTab {
381 %[fields]
382 background: Color,
383 hover_background: Color,
384 width: Size,
385 height: Size,
386 padding: Gaps,
387 color: Color,
388 corner_radius: CornerRadius,
389 }
390}
391
392define_theme! {
393 %[component]
394 pub Slider {
395 %[fields]
396 background: Color,
397 thumb_background: Color,
398 thumb_inner_background: Color,
399 border_fill: Color,
400 }
401}
402
403define_theme! {
404 %[component]
405 pub ColorPicker {
406 %[fields]
407 background: Color,
408 color: Color,
409 border_fill: Color,
410 }
411}
412
413define_theme! {
414 %[component]
415 pub Select {
416 %[fields]
417 width: Size,
418 margin: Gaps,
419 select_background: Color,
420 background_button: Color,
421 hover_background: Color,
422 border_fill: Color,
423 focus_border_fill: Color,
424 arrow_fill: Color,
425 color: Color,
426 }
427}
428
429define_theme! {
430 %[component]
431 pub Popup {
432 %[fields]
433 background: Color,
434 color: Color,
435 }
436}
437
438define_theme! {
439 %[component]
440 pub Table {
441 %[fields]
442 background: Color,
443 arrow_fill: Color,
444 hover_row_background: Color,
445 row_background: Color,
446 divider_fill: Color,
447 corner_radius: CornerRadius,
448 color: Color,
449 }
450}
451
452#[cfg(feature = "markdown")]
453define_theme! {
454 %[component]
455 pub MarkdownViewer {
456 %[fields]
457 color: Color,
458 background_code: Color,
459 color_code: Color,
460 background_blockquote: Color,
461 border_blockquote: Color,
462 background_divider: Color,
463 heading_h1: f32,
464 heading_h2: f32,
465 heading_h3: f32,
466 heading_h4: f32,
467 heading_h5: f32,
468 heading_h6: f32,
469 paragraph_size: f32,
470 code_font_size: f32,
471 table_font_size: f32,
472 }
473}
474
475define_theme! {
476 %[component]
477 pub Chip {
478 %[fields]
479 background: Color,
480 hover_background: Color,
481 selected_background: Color,
482 border_fill: Color,
483 selected_border_fill: Color,
484 hover_border_fill: Color,
485 focus_border_fill: Color,
486 margin: f32,
487 corner_radius: CornerRadius,
488 width: Size,
489 height: Size,
490 padding: Gaps,
491 color: Color,
492 hover_color: Color,
493 selected_color: Color,
494 selected_icon_fill: Color,
495 hover_icon_fill: Color,
496 }
497}
498
499define_theme! {
500 %[component]
501 pub MenuContainer {
502 %[fields]
503 background: Color,
504 padding: Gaps,
505 shadow: Color,
506 border_fill: Color,
507 corner_radius: CornerRadius,
508 }
509}
510
511define_theme! {
512 %[component]
513 pub MenuItem {
514 %[fields]
515 background: Color,
516 hover_background: Color,
517 select_background: Color,
518 border_fill: Color,
519 select_border_fill: Color,
520 corner_radius: CornerRadius,
521 color: Color,
522 }
523}
524
525define_theme! {
526 %[component]
527 pub ButtonSegment {
528 %[fields]
529 background: Color,
530 hover_background: Color,
531 disabled_background: Color,
532 selected_background: Color,
533 focus_background: Color,
534 padding: Gaps,
535 selected_padding: Gaps,
536 width: Size,
537 height: Size,
538 color: Color,
539 selected_icon_fill: Color,
540 }
541}
542
543define_theme! {
544 %[component]
545 pub SegmentedButton {
546 %[fields]
547 background: Color,
548 border_fill: Color,
549 corner_radius: CornerRadius,
550 }
551}
552
553#[cfg(feature = "calendar")]
554define_theme! {
555 %[component]
556 pub Calendar {
557 %[fields]
558 background: Color,
559 day_background: Color,
560 day_hover_background: Color,
561 day_selected_background: Color,
562 color: Color,
563 day_other_month_color: Color,
564 header_color: Color,
565 corner_radius: CornerRadius,
566 padding: Gaps,
567 day_corner_radius: CornerRadius,
568 nav_button_hover_background: Color,
569 }
570}
571
572#[cfg(feature = "titlebar")]
573define_theme! {
574 %[component]
575 pub TitlebarButton {
576 %[fields]
577 background: Color,
578 hover_background: Color,
579 corner_radius: CornerRadius,
580 width: Size,
581 height: Size,
582 }
583}