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