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