1use freya_core::prelude::*;
2#[cfg(feature = "titlebar")]
3use torin::prelude::Length;
4use torin::{
5 gaps::Gaps,
6 size::Size,
7};
8
9#[cfg(feature = "calendar")]
10use crate::calendar::CalendarThemePreference;
11#[cfg(feature = "router")]
12use crate::link::LinkThemePreference;
13#[cfg(feature = "markdown")]
14use crate::markdown::MarkdownViewerThemePreference;
15#[cfg(feature = "titlebar")]
16use crate::titlebar::TitlebarButtonThemePreference;
17use crate::{
18 accordion::AccordionThemePreference,
19 button::{
20 ButtonColorsThemePreference,
21 ButtonLayoutThemePreference,
22 },
23 card::{
24 CardColorsThemePreference,
25 CardLayoutThemePreference,
26 },
27 checkbox::CheckboxThemePreference,
28 chip::ChipThemePreference,
29 color_picker::ColorPickerThemePreference,
30 floating_tab::FloatingTabThemePreference,
31 input::{
32 InputColorsThemePreference,
33 InputLayoutThemePreference,
34 },
35 loader::CircularLoaderThemePreference,
36 menu::{
37 MenuContainerThemePreference,
38 MenuItemThemePreference,
39 },
40 popup::PopupThemePreference,
41 progressbar::ProgressBarThemePreference,
42 radio_item::RadioItemThemePreference,
43 resizable_container::ResizableHandleThemePreference,
44 scrollviews::ScrollBarThemePreference,
45 segmented_button::{
46 ButtonSegmentThemePreference,
47 SegmentedButtonThemePreference,
48 },
49 select::SelectThemePreference,
50 sidebar::SideBarItemThemePreference,
51 slider::SliderThemePreference,
52 switch::{
53 SwitchColorsThemePreference,
54 SwitchLayoutThemePreference,
55 },
56 table::TableThemePreference,
57 theming::{
58 component_themes::{
59 ColorsSheet,
60 Theme,
61 },
62 macros::Preference,
63 },
64 tooltip::TooltipThemePreference,
65};
66
67pub const LIGHT_COLORS: ColorsSheet = ColorsSheet {
68 primary: Color::from_rgb(103, 80, 164),
70 secondary: Color::from_rgb(202, 193, 227),
71 tertiary: Color::from_rgb(79, 61, 130),
72
73 success: Color::from_rgb(76, 175, 80),
75 warning: Color::from_rgb(255, 193, 7),
76 error: Color::from_rgb(244, 67, 54),
77 info: Color::from_rgb(33, 150, 243),
78
79 background: Color::from_rgb(250, 250, 250),
81 surface_primary: Color::from_rgb(210, 210, 210),
82 surface_secondary: Color::from_rgb(225, 225, 225),
83 surface_tertiary: Color::from_rgb(245, 245, 245),
84 surface_inverse: Color::from_rgb(125, 125, 125),
85 surface_inverse_secondary: Color::from_rgb(110, 110, 110),
86 surface_inverse_tertiary: Color::from_rgb(90, 90, 90),
87
88 border: Color::from_rgb(210, 210, 210),
90 border_focus: Color::from_rgb(180, 180, 180),
91 border_disabled: Color::from_rgb(210, 210, 210),
92
93 text_primary: Color::from_rgb(10, 10, 10),
95 text_secondary: Color::from_rgb(100, 100, 100),
96 text_placeholder: Color::from_rgb(150, 150, 150),
97 text_inverse: Color::WHITE,
98 text_highlight: Color::from_rgb(38, 89, 170),
99
100 hover: Color::from_rgb(235, 235, 235),
102 focus: Color::from_rgb(225, 225, 255),
103 active: Color::from_rgb(200, 200, 200),
104 disabled: Color::from_rgb(210, 210, 210),
105
106 overlay: Color::from_af32rgb(0.5, 0, 0, 0),
108 shadow: Color::from_af32rgb(0.2, 0, 0, 0),
109};
110
111pub const DARK_COLORS: ColorsSheet = ColorsSheet {
112 primary: Color::from_rgb(103, 80, 164),
114 secondary: Color::from_rgb(202, 193, 227),
115 tertiary: Color::from_rgb(79, 61, 130),
116
117 success: Color::from_rgb(129, 199, 132),
119 warning: Color::from_rgb(255, 213, 79),
120 error: Color::from_rgb(229, 115, 115),
121 info: Color::from_rgb(100, 181, 246),
122
123 background: Color::from_rgb(20, 20, 20),
125 surface_primary: Color::from_rgb(60, 60, 60),
126 surface_secondary: Color::from_rgb(45, 45, 45),
127 surface_tertiary: Color::from_rgb(25, 25, 25),
128 surface_inverse: Color::from_rgb(135, 135, 135),
129 surface_inverse_secondary: Color::from_rgb(150, 150, 150),
130 surface_inverse_tertiary: Color::from_rgb(170, 170, 170),
131
132 border: Color::from_rgb(60, 60, 60),
134 border_focus: Color::from_rgb(110, 110, 110),
135 border_disabled: Color::from_rgb(80, 80, 80),
136
137 text_primary: Color::from_rgb(250, 250, 250),
139 text_secondary: Color::from_rgb(210, 210, 210),
140 text_placeholder: Color::from_rgb(150, 150, 150),
141 text_inverse: Color::WHITE,
142 text_highlight: Color::from_rgb(96, 145, 224),
143
144 hover: Color::from_rgb(80, 80, 80),
146 focus: Color::from_rgb(100, 100, 120),
147 active: Color::from_rgb(70, 70, 70),
148 disabled: Color::from_rgb(50, 50, 50),
149
150 overlay: Color::from_af32rgb(0.2, 255, 255, 255),
152 shadow: Color::from_af32rgb(0.6, 0, 0, 0),
153};
154
155fn register_base_component_themes(theme: &mut Theme) {
156 theme.set(
157 "button_layout",
158 ButtonLayoutThemePreference {
159 padding: Preference::Specific(Gaps::new(6., 12., 6., 12.)),
160 margin: Preference::Specific(Gaps::new_all(0.)),
161 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
162 width: Preference::Specific(Size::Inner),
163 height: Preference::Specific(Size::Inner),
164 },
165 );
166 theme.set(
167 "compact_button_layout",
168 ButtonLayoutThemePreference {
169 padding: Preference::Specific(Gaps::new(3., 6., 3., 6.)),
170 margin: Preference::Specific(Gaps::new_all(0.)),
171 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
172 width: Preference::Specific(Size::Inner),
173 height: Preference::Specific(Size::Inner),
174 },
175 );
176 theme.set(
177 "expanded_button_layout",
178 ButtonLayoutThemePreference {
179 padding: Preference::Specific(Gaps::new(10., 16., 10., 16.)),
180 margin: Preference::Specific(Gaps::new_all(0.)),
181 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
182 width: Preference::Specific(Size::Inner),
183 height: Preference::Specific(Size::Inner),
184 },
185 );
186 theme.set(
187 "button",
188 ButtonColorsThemePreference {
189 background: Preference::Reference("surface_tertiary"),
190 hover_background: Preference::Reference("hover"),
191 border_fill: Preference::Reference("border"),
192 focus_border_fill: Preference::Reference("border_focus"),
193 color: Preference::Reference("text_primary"),
194 },
195 );
196 theme.set(
197 "filled_button",
198 ButtonColorsThemePreference {
199 background: Preference::Reference("primary"),
200 hover_background: Preference::Reference("tertiary"),
201 border_fill: Preference::Specific(Color::TRANSPARENT),
202 focus_border_fill: Preference::Reference("secondary"),
203 color: Preference::Reference("text_inverse"),
204 },
205 );
206 theme.set(
207 "outline_button",
208 ButtonColorsThemePreference {
209 background: Preference::Reference("surface_tertiary"),
210 hover_background: Preference::Reference("hover"),
211 border_fill: Preference::Reference("border"),
212 focus_border_fill: Preference::Reference("secondary"),
213 color: Preference::Reference("primary"),
214 },
215 );
216 theme.set(
217 "flat_button",
218 ButtonColorsThemePreference {
219 background: Preference::Specific(Color::TRANSPARENT),
220 hover_background: Preference::Reference("surface_tertiary"),
221 border_fill: Preference::Specific(Color::TRANSPARENT),
222 focus_border_fill: Preference::Reference("border"),
223 color: Preference::Reference("text_primary"),
224 },
225 );
226 theme.set(
227 "card_layout",
228 CardLayoutThemePreference {
229 padding: Preference::Specific(Gaps::new(16., 16., 16., 16.)),
230 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
231 },
232 );
233 theme.set(
234 "compact_card_layout",
235 CardLayoutThemePreference {
236 padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
237 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
238 },
239 );
240 theme.set(
241 "filled_card",
242 CardColorsThemePreference {
243 background: Preference::Reference("primary"),
244 hover_background: Preference::Reference("tertiary"),
245 border_fill: Preference::Specific(Color::TRANSPARENT),
246 color: Preference::Reference("text_inverse"),
247 shadow: Preference::Reference("shadow"),
248 },
249 );
250 theme.set(
251 "outline_card",
252 CardColorsThemePreference {
253 background: Preference::Reference("surface_tertiary"),
254 hover_background: Preference::Reference("hover"),
255 border_fill: Preference::Reference("border"),
256 color: Preference::Reference("text_primary"),
257 shadow: Preference::Reference("shadow"),
258 },
259 );
260 theme.set(
261 "accordion",
262 AccordionThemePreference {
263 color: Preference::Reference("text_primary"),
264 background: Preference::Reference("surface_tertiary"),
265 border_fill: Preference::Reference("border"),
266 },
267 );
268 theme.set(
269 "switch",
270 SwitchColorsThemePreference {
271 background: Preference::Reference("surface_secondary"),
272 thumb_background: Preference::Reference("surface_inverse"),
273 toggled_background: Preference::Reference("secondary"),
274 toggled_thumb_background: Preference::Reference("primary"),
275 focus_border_fill: Preference::Reference("border_focus"),
276 },
277 );
278 theme.set(
279 "switch_layout",
280 SwitchLayoutThemePreference {
281 margin: Preference::Specific(Gaps::new_all(0.)),
282 width: Preference::Specific(48.),
283 height: Preference::Specific(28.),
284 padding: Preference::Specific(4.),
285 thumb_size: Preference::Specific(16.),
286 toggled_thumb_size: Preference::Specific(20.),
287 pressed_thumb_size_offset: Preference::Specific(4.),
288 thumb_offset: Preference::Specific(2.),
289 toggled_thumb_offset: Preference::Specific(20.),
290 },
291 );
292 theme.set(
293 "expanded_switch_layout",
294 SwitchLayoutThemePreference {
295 margin: Preference::Specific(Gaps::new_all(0.)),
296 width: Preference::Specific(56.),
297 height: Preference::Specific(32.),
298 padding: Preference::Specific(4.),
299 thumb_size: Preference::Specific(18.),
300 toggled_thumb_size: Preference::Specific(22.),
301 pressed_thumb_size_offset: Preference::Specific(4.),
302 thumb_offset: Preference::Specific(2.),
303 toggled_thumb_offset: Preference::Specific(26.),
304 },
305 );
306 theme.set(
307 "scrollbar",
308 ScrollBarThemePreference {
309 background: Preference::Reference("surface_primary"),
310 thumb_background: Preference::Reference("surface_inverse"),
311 hover_thumb_background: Preference::Reference("surface_inverse_secondary"),
312 active_thumb_background: Preference::Reference("surface_inverse_tertiary"),
313 size: Preference::Specific(15.),
314 },
315 );
316 theme.set(
317 "progressbar",
318 ProgressBarThemePreference {
319 color: Preference::Reference("text_inverse"),
320 background: Preference::Reference("surface_primary"),
321 progress_background: Preference::Reference("primary"),
322 height: Preference::Specific(20.),
323 },
324 );
325 theme.set(
326 "sidebar_item",
327 SideBarItemThemePreference {
328 color: Preference::Reference("text_primary"),
329 background: Preference::Reference("surface_tertiary"),
330 active_background: Preference::Reference("surface_secondary"),
331 hover_background: Preference::Reference("hover"),
332 corner_radius: Preference::Specific(CornerRadius::new_all(12.)),
333 margin: Preference::Specific(Gaps::new_all(0.)),
334 padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
335 },
336 );
337 #[cfg(feature = "router")]
338 theme.set(
339 "link",
340 LinkThemePreference {
341 color: Preference::Reference("text_highlight"),
342 },
343 );
344 theme.set(
345 "tooltip",
346 TooltipThemePreference {
347 background: Preference::Reference("surface_tertiary"),
348 color: Preference::Reference("text_primary"),
349 border_fill: Preference::Reference("surface_primary"),
350 font_size: Preference::Specific(14.),
351 },
352 );
353 theme.set(
354 "circular_loader",
355 CircularLoaderThemePreference {
356 primary_color: Preference::Reference("surface_primary"),
357 inversed_color: Preference::Reference("surface_inverse"),
358 },
359 );
360 theme.set(
361 "input_layout",
362 InputLayoutThemePreference {
363 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
364 inner_margin: Preference::Specific(Gaps::new(8., 8., 8., 8.)),
365 },
366 );
367 theme.set(
368 "compact_input_layout",
369 InputLayoutThemePreference {
370 corner_radius: Preference::Specific(CornerRadius::new_all(4.)),
371 inner_margin: Preference::Specific(Gaps::new(4., 6., 4., 6.)),
372 },
373 );
374 theme.set(
375 "expanded_input_layout",
376 InputLayoutThemePreference {
377 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
378 inner_margin: Preference::Specific(Gaps::new(12., 12., 12., 12.)),
379 },
380 );
381 theme.set(
382 "input",
383 InputColorsThemePreference {
384 background: Preference::Reference("surface_tertiary"),
385 hover_background: Preference::Reference("background"),
386 color: Preference::Reference("text_primary"),
387 placeholder_color: Preference::Reference("text_secondary"),
388 border_fill: Preference::Reference("border"),
389 focus_border_fill: Preference::Reference("border_focus"),
390 },
391 );
392 theme.set(
393 "filled_input",
394 InputColorsThemePreference {
395 background: Preference::Reference("primary"),
396 hover_background: Preference::Reference("tertiary"),
397 color: Preference::Reference("text_inverse"),
398 placeholder_color: Preference::Reference("text_inverse"),
399 border_fill: Preference::Specific(Color::TRANSPARENT),
400 focus_border_fill: Preference::Reference("secondary"),
401 },
402 );
403 theme.set(
404 "flat_input",
405 InputColorsThemePreference {
406 background: Preference::Specific(Color::TRANSPARENT),
407 hover_background: Preference::Reference("surface_tertiary"),
408 color: Preference::Reference("text_primary"),
409 placeholder_color: Preference::Reference("text_secondary"),
410 border_fill: Preference::Specific(Color::TRANSPARENT),
411 focus_border_fill: Preference::Reference("border"),
412 },
413 );
414 theme.set(
415 "radio",
416 RadioItemThemePreference {
417 unselected_fill: Preference::Reference("surface_inverse_tertiary"),
418 selected_fill: Preference::Reference("primary"),
419 border_fill: Preference::Reference("surface_primary"),
420 },
421 );
422 theme.set(
423 "checkbox",
424 CheckboxThemePreference {
425 unselected_fill: Preference::Reference("surface_inverse_tertiary"),
426 selected_fill: Preference::Reference("primary"),
427 selected_icon_fill: Preference::Reference("secondary"),
428 border_fill: Preference::Reference("surface_primary"),
429 },
430 );
431 theme.set(
432 "resizable_handle",
433 ResizableHandleThemePreference {
434 background: Preference::Reference("surface_secondary"),
435 hover_background: Preference::Reference("surface_primary"),
436 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
437 },
438 );
439 theme.set(
440 "floating_tab",
441 FloatingTabThemePreference {
442 background: Preference::Specific(Color::TRANSPARENT),
443 hover_background: Preference::Reference("surface_secondary"),
444 color: Preference::Reference("text_primary"),
445 padding: Preference::Specific(Gaps::new(6., 12., 6., 12.)),
446 width: Preference::Specific(Size::Inner),
447 height: Preference::Specific(Size::Inner),
448 corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
449 },
450 );
451 theme.set(
452 "slider",
453 SliderThemePreference {
454 background: Preference::Reference("surface_primary"),
455 thumb_background: Preference::Reference("secondary"),
456 thumb_inner_background: Preference::Reference("primary"),
457 border_fill: Preference::Reference("surface_primary"),
458 },
459 );
460 theme.set(
461 "color_picker",
462 ColorPickerThemePreference {
463 background: Preference::Reference("surface_tertiary"),
464 border_fill: Preference::Reference("border"),
465 color: Preference::Reference("text_primary"),
466 },
467 );
468 theme.set(
469 "select",
470 SelectThemePreference {
471 width: Preference::Specific(Size::Inner),
472 margin: Preference::Specific(Gaps::new_all(0.)),
473 select_background: Preference::Reference("background"),
474 background_button: Preference::Reference("surface_tertiary"),
475 hover_background: Preference::Reference("hover"),
476 color: Preference::Reference("text_primary"),
477 border_fill: Preference::Reference("border"),
478 focus_border_fill: Preference::Reference("border_focus"),
479 arrow_fill: Preference::Reference("text_primary"),
480 },
481 );
482 theme.set(
483 "popup",
484 PopupThemePreference {
485 background: Preference::Reference("background"),
486 color: Preference::Reference("text_primary"),
487 },
488 );
489 theme.set(
490 "table",
491 TableThemePreference {
492 background: Preference::Reference("background"),
493 arrow_fill: Preference::Reference("text_primary"),
494 row_background: Preference::Specific(Color::TRANSPARENT),
495 hover_row_background: Preference::Reference("surface_secondary"),
496 divider_fill: Preference::Reference("surface_primary"),
497 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
498 color: Preference::Reference("text_primary"),
499 },
500 );
501 #[cfg(feature = "markdown")]
502 theme.set(
503 "markdown_viewer",
504 MarkdownViewerThemePreference {
505 color: Preference::Reference("text_primary"),
506 background_code: Preference::Reference("surface_tertiary"),
507 color_code: Preference::Reference("text_primary"),
508 background_blockquote: Preference::Reference("surface_tertiary"),
509 border_blockquote: Preference::Reference("surface_primary"),
510 background_divider: Preference::Reference("border"),
511 heading_h1: Preference::Specific(32.0),
512 heading_h2: Preference::Specific(28.0),
513 heading_h3: Preference::Specific(24.0),
514 heading_h4: Preference::Specific(20.0),
515 heading_h5: Preference::Specific(18.0),
516 heading_h6: Preference::Specific(16.0),
517 paragraph_size: Preference::Specific(16.0),
518 code_font_size: Preference::Specific(14.0),
519 table_font_size: Preference::Specific(14.0),
520 },
521 );
522 theme.set(
523 "chip",
524 ChipThemePreference {
525 background: Preference::Reference("background"),
526 hover_background: Preference::Reference("tertiary"),
527 selected_background: Preference::Reference("primary"),
528 border_fill: Preference::Reference("border"),
529 hover_border_fill: Preference::Reference("tertiary"),
530 selected_border_fill: Preference::Reference("primary"),
531 focus_border_fill: Preference::Reference("secondary"),
532 padding: Preference::Specific(Gaps::new(8., 14., 8., 14.)),
533 margin: Preference::Specific(0.),
534 corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
535 width: Preference::Specific(Size::Inner),
536 height: Preference::Specific(Size::Inner),
537 color: Preference::Reference("text_primary"),
538 hover_color: Preference::Reference("text_inverse"),
539 selected_color: Preference::Reference("text_inverse"),
540 selected_icon_fill: Preference::Reference("secondary"),
541 hover_icon_fill: Preference::Reference("secondary"),
542 },
543 );
544 theme.set(
545 "menu_item",
546 MenuItemThemePreference {
547 background: Preference::Specific(Color::TRANSPARENT),
548 hover_background: Preference::Reference("surface_secondary"),
549 select_background: Preference::Reference("surface_secondary"),
550 border_fill: Preference::Specific(Color::TRANSPARENT),
551 select_border_fill: Preference::Reference("border_focus"),
552 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
553 color: Preference::Reference("text_primary"),
554 },
555 );
556 theme.set(
557 "menu_container",
558 MenuContainerThemePreference {
559 background: Preference::Reference("background"),
560 padding: Preference::Specific(Gaps::new_all(4.)),
561 shadow: Preference::Reference("shadow"),
562 border_fill: Preference::Reference("surface_primary"),
563 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
564 },
565 );
566 theme.set(
567 "button_segment",
568 ButtonSegmentThemePreference {
569 background: Preference::Reference("surface_tertiary"),
570 hover_background: Preference::Reference("hover"),
571 disabled_background: Preference::Reference("disabled"),
572 selected_background: Preference::Reference("hover"),
573 focus_background: Preference::Reference("surface_secondary"),
574 padding: Preference::Specific(Gaps::new(8., 16., 8., 16.)),
575 selected_padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
576 width: Preference::Specific(Size::Inner),
577 height: Preference::Specific(Size::Inner),
578 color: Preference::Reference("text_primary"),
579 selected_icon_fill: Preference::Reference("primary"),
580 },
581 );
582 theme.set(
583 "segmented_button",
584 SegmentedButtonThemePreference {
585 background: Preference::Reference("surface_tertiary"),
586 border_fill: Preference::Reference("border"),
587 corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
588 },
589 );
590 #[cfg(feature = "calendar")]
591 theme.set(
592 "calendar",
593 CalendarThemePreference {
594 background: Preference::Reference("surface_tertiary"),
595 day_background: Preference::Specific(Color::TRANSPARENT),
596 day_hover_background: Preference::Reference("hover"),
597 day_selected_background: Preference::Reference("surface_primary"),
598 color: Preference::Reference("text_primary"),
599 day_other_month_color: Preference::Reference("text_placeholder"),
600 header_color: Preference::Reference("text_primary"),
601 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
602 padding: Preference::Specific(Gaps::new_all(12.)),
603 day_corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
604 nav_button_hover_background: Preference::Reference("hover"),
605 },
606 );
607 #[cfg(feature = "titlebar")]
608 theme.set(
609 "titlebar_button",
610 TitlebarButtonThemePreference {
611 background: Preference::Specific(Color::TRANSPARENT),
612 hover_background: Preference::Reference("hover"),
613 corner_radius: Preference::Specific(CornerRadius::new_all(0.0)),
614 width: Preference::Specific(Size::Pixels(Length::new(46.0))),
615 height: Preference::Specific(Size::Fill),
616 },
617 );
618}
619
620pub fn light_theme() -> Theme {
622 let mut theme = Theme::new("light", LIGHT_COLORS);
623 register_base_component_themes(&mut theme);
624 theme
625}
626
627pub fn dark_theme() -> Theme {
629 let mut theme = Theme::new("dark", DARK_COLORS);
630 register_base_component_themes(&mut theme);
631 theme
632}