freya_components/theming/
component_themes.rs

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