Skip to main content

freya_components/theming/
themes.rs

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