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 }
285}
286
287define_theme! {
288 %[component]
289 pub CircularLoader {
290 %[fields]
291 primary_color: Color,
292 inversed_color: Color,
293 }
294}
295
296define_theme! {
297 for = Input;
298 theme_field = theme_layout;
299
300 %[component]
301 pub InputLayout {
302 %[fields]
303 corner_radius: CornerRadius,
304 inner_margin: Gaps,
305 }
306}
307
308define_theme! {
309 for = Input;
310 theme_field = theme_colors;
311
312 %[component]
313 pub InputColors {
314 %[fields]
315 background: Color,
316 hover_background: Color,
317 border_fill: Color,
318 focus_border_fill: Color,
319 color: Color,
320 placeholder_color: Color,
321 }
322}
323
324define_theme! {
325 %[component]
326 pub RadioItem {
327 %[fields]
328 unselected_fill: Color,
329 selected_fill: Color,
330 border_fill: Color,
331 }
332}
333
334define_theme! {
335 %[component]
336 pub Checkbox {
337 %[fields]
338 unselected_fill: Color,
339 selected_fill: Color,
340 selected_icon_fill: Color,
341 border_fill: Color,
342 }
343}
344
345define_theme! {
346 %[component]
347 pub ResizableHandle {
348 %[fields]
349 background: Color,
350 hover_background: Color,
351 corner_radius: CornerRadius,
352 }
353}
354
355define_theme! {
356 %[component]
357 pub FloatingTab {
358 %[fields]
359 background: Color,
360 hover_background: Color,
361 width: Size,
362 height: Size,
363 padding: Gaps,
364 color: Color,
365 }
366}
367
368define_theme! {
369 %[component]
370 pub Slider {
371 %[fields]
372 background: Color,
373 thumb_background: Color,
374 thumb_inner_background: Color,
375 border_fill: Color,
376 }
377}
378
379define_theme! {
380 %[component]
381 pub ColorPicker {
382 %[fields]
383 background: Color,
384 color: Color,
385 border_fill: Color,
386 }
387}
388
389define_theme! {
390 %[component]
391 pub Select {
392 %[fields]
393 width: Size,
394 margin: Gaps,
395 select_background: Color,
396 background_button: Color,
397 hover_background: Color,
398 border_fill: Color,
399 focus_border_fill: Color,
400 arrow_fill: Color,
401 color: Color,
402 }
403}
404
405define_theme! {
406 %[component]
407 pub Popup {
408 %[fields]
409 background: Color,
410 color: Color,
411 }
412}
413
414define_theme! {
415 %[component]
416 pub Table {
417 %[fields]
418 background: Color,
419 arrow_fill: Color,
420 hover_row_background: Color,
421 row_background: Color,
422 divider_fill: Color,
423 corner_radius: CornerRadius,
424 color: Color,
425 }
426}
427
428#[cfg(feature = "markdown")]
429define_theme! {
430 %[component]
431 pub MarkdownViewer {
432 %[fields]
433 color: Color,
434 background_code: Color,
435 color_code: Color,
436 background_blockquote: Color,
437 border_blockquote: Color,
438 background_divider: Color,
439 heading_h1: f32,
440 heading_h2: f32,
441 heading_h3: f32,
442 heading_h4: f32,
443 heading_h5: f32,
444 heading_h6: f32,
445 paragraph_size: f32,
446 code_font_size: f32,
447 table_font_size: f32,
448 }
449}
450
451define_theme! {
452 %[component]
453 pub Chip {
454 %[fields]
455 background: Color,
456 hover_background: Color,
457 selected_background: Color,
458 border_fill: Color,
459 selected_border_fill: Color,
460 hover_border_fill: Color,
461 focus_border_fill: Color,
462 margin: f32,
463 corner_radius: CornerRadius,
464 width: Size,
465 height: Size,
466 padding: Gaps,
467 color: Color,
468 hover_color: Color,
469 selected_color: Color,
470 selected_icon_fill: Color,
471 hover_icon_fill: Color,
472 }
473}
474
475define_theme! {
476 %[component]
477 pub MenuContainer {
478 %[fields]
479 background: Color,
480 padding: Gaps,
481 shadow: Color,
482 border_fill: Color,
483 corner_radius: CornerRadius,
484 }
485}
486
487define_theme! {
488 %[component]
489 pub MenuItem {
490 %[fields]
491 background: Color,
492 hover_background: Color,
493 select_background: Color,
494 border_fill: Color,
495 select_border_fill: Color,
496 corner_radius: CornerRadius,
497 color: Color,
498 }
499}
500
501define_theme! {
502 %[component]
503 pub ButtonSegment {
504 %[fields]
505 background: Color,
506 hover_background: Color,
507 disabled_background: Color,
508 selected_background: Color,
509 focus_background: Color,
510 padding: Gaps,
511 selected_padding: Gaps,
512 width: Size,
513 height: Size,
514 color: Color,
515 selected_icon_fill: Color,
516 }
517}
518
519define_theme! {
520 %[component]
521 pub SegmentedButton {
522 %[fields]
523 background: Color,
524 border_fill: Color,
525 corner_radius: CornerRadius,
526 }
527}
528
529#[cfg(feature = "calendar")]
530define_theme! {
531 %[component]
532 pub Calendar {
533 %[fields]
534 background: Color,
535 day_background: Color,
536 day_hover_background: Color,
537 day_selected_background: Color,
538 color: Color,
539 day_other_month_color: Color,
540 header_color: Color,
541 corner_radius: CornerRadius,
542 padding: Gaps,
543 day_corner_radius: CornerRadius,
544 nav_button_hover_background: Color,
545 }
546}
547
548#[cfg(feature = "titlebar")]
549define_theme! {
550 %[component]
551 pub TitlebarButton {
552 %[fields]
553 background: Color,
554 hover_background: Color,
555 corner_radius: CornerRadius,
556 width: Size,
557 height: Size,
558 }
559}