freya_components/theming/
component_themes.rs

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