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 corner_radius: CornerRadius,
366 }
367}
368
369define_theme! {
370 %[component]
371 pub Slider {
372 %[fields]
373 background: Color,
374 thumb_background: Color,
375 thumb_inner_background: Color,
376 border_fill: Color,
377 }
378}
379
380define_theme! {
381 %[component]
382 pub ColorPicker {
383 %[fields]
384 background: Color,
385 color: Color,
386 border_fill: Color,
387 }
388}
389
390define_theme! {
391 %[component]
392 pub Select {
393 %[fields]
394 width: Size,
395 margin: Gaps,
396 select_background: Color,
397 background_button: Color,
398 hover_background: Color,
399 border_fill: Color,
400 focus_border_fill: Color,
401 arrow_fill: Color,
402 color: Color,
403 }
404}
405
406define_theme! {
407 %[component]
408 pub Popup {
409 %[fields]
410 background: Color,
411 color: Color,
412 }
413}
414
415define_theme! {
416 %[component]
417 pub Table {
418 %[fields]
419 background: Color,
420 arrow_fill: Color,
421 hover_row_background: Color,
422 row_background: Color,
423 divider_fill: Color,
424 corner_radius: CornerRadius,
425 color: Color,
426 }
427}
428
429#[cfg(feature = "markdown")]
430define_theme! {
431 %[component]
432 pub MarkdownViewer {
433 %[fields]
434 color: Color,
435 background_code: Color,
436 color_code: Color,
437 background_blockquote: Color,
438 border_blockquote: Color,
439 background_divider: Color,
440 heading_h1: f32,
441 heading_h2: f32,
442 heading_h3: f32,
443 heading_h4: f32,
444 heading_h5: f32,
445 heading_h6: f32,
446 paragraph_size: f32,
447 code_font_size: f32,
448 table_font_size: f32,
449 }
450}
451
452define_theme! {
453 %[component]
454 pub Chip {
455 %[fields]
456 background: Color,
457 hover_background: Color,
458 selected_background: Color,
459 border_fill: Color,
460 selected_border_fill: Color,
461 hover_border_fill: Color,
462 focus_border_fill: Color,
463 margin: f32,
464 corner_radius: CornerRadius,
465 width: Size,
466 height: Size,
467 padding: Gaps,
468 color: Color,
469 hover_color: Color,
470 selected_color: Color,
471 selected_icon_fill: Color,
472 hover_icon_fill: Color,
473 }
474}
475
476define_theme! {
477 %[component]
478 pub MenuContainer {
479 %[fields]
480 background: Color,
481 padding: Gaps,
482 shadow: Color,
483 border_fill: Color,
484 corner_radius: CornerRadius,
485 }
486}
487
488define_theme! {
489 %[component]
490 pub MenuItem {
491 %[fields]
492 background: Color,
493 hover_background: Color,
494 select_background: Color,
495 border_fill: Color,
496 select_border_fill: Color,
497 corner_radius: CornerRadius,
498 color: Color,
499 }
500}
501
502define_theme! {
503 %[component]
504 pub ButtonSegment {
505 %[fields]
506 background: Color,
507 hover_background: Color,
508 disabled_background: Color,
509 selected_background: Color,
510 focus_background: Color,
511 padding: Gaps,
512 selected_padding: Gaps,
513 width: Size,
514 height: Size,
515 color: Color,
516 selected_icon_fill: Color,
517 }
518}
519
520define_theme! {
521 %[component]
522 pub SegmentedButton {
523 %[fields]
524 background: Color,
525 border_fill: Color,
526 corner_radius: CornerRadius,
527 }
528}
529
530#[cfg(feature = "calendar")]
531define_theme! {
532 %[component]
533 pub Calendar {
534 %[fields]
535 background: Color,
536 day_background: Color,
537 day_hover_background: Color,
538 day_selected_background: Color,
539 color: Color,
540 day_other_month_color: Color,
541 header_color: Color,
542 corner_radius: CornerRadius,
543 padding: Gaps,
544 day_corner_radius: CornerRadius,
545 nav_button_hover_background: Color,
546 }
547}
548
549#[cfg(feature = "titlebar")]
550define_theme! {
551 %[component]
552 pub TitlebarButton {
553 %[fields]
554 background: Color,
555 hover_background: Color,
556 corner_radius: CornerRadius,
557 width: Size,
558 height: Size,
559 }
560}