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