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