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 pub primary: Color,
87 pub secondary: Color,
88 pub tertiary: Color,
89
90 pub success: Color,
92 pub warning: Color,
93 pub error: Color,
94 pub info: Color,
95
96 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 pub border: Color,
107 pub border_focus: Color,
108 pub border_disabled: Color,
109
110 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 pub hover: Color,
119 pub focus: Color,
120 pub active: Color,
121 pub disabled: Color,
122
123 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 corner_radius: CornerRadius,
223 margin: Gaps,
224 padding: Gaps,
225 }
226}
227
228#[cfg(feature = "router")]
229define_theme! {
230 %[component]
231 pub Link {
232 %[fields]
233 color: Color,
234 }
235}
236
237define_theme! {
238 %[component]
239 pub Tooltip {
240 %[fields]
241 color: Color,
242 background: Color,
243 border_fill: Color,
244 }
245}
246
247define_theme! {
248 %[component]
249 pub CircularLoader {
250 %[fields]
251 primary_color: Color,
252 inversed_color: Color,
253 }
254}
255
256define_theme! {
257 %[component]
258 pub Input {
259 %[fields]
260 background: Color,
261 hover_background: Color,
262 border_fill: Color,
263 focus_border_fill: Color,
264 corner_radius: CornerRadius,
265 inner_margin: Gaps,
266 color: Color,
267 placeholder_color: Color,
268 }
269}
270
271define_theme! {
272 %[component]
273 pub RadioItem {
274 %[fields]
275 unselected_fill: Color,
276 selected_fill: Color,
277 border_fill: Color,
278 }
279}
280
281define_theme! {
282 %[component]
283 pub Checkbox {
284 %[fields]
285 unselected_fill: Color,
286 selected_fill: Color,
287 selected_icon_fill: Color,
288 border_fill: Color,
289 }
290}
291
292define_theme! {
293 %[component]
294 pub ResizableHandle {
295 %[fields]
296 background: Color,
297 hover_background: Color,
298 }
299}
300
301define_theme! {
302 %[component]
303 pub FloatingTab {
304 %[fields]
305 background: Color,
306 hover_background: Color,
307 width: Size,
308 height: Size,
309 padding: Gaps,
310 color: Color,
311 }
312}
313
314define_theme! {
315 %[component]
316 pub Slider {
317 %[fields]
318 background: Color,
319 thumb_background: Color,
320 thumb_inner_background: Color,
321 border_fill: Color,
322 }
323}
324
325define_theme! {
326 %[component]
327 pub Dropdown {
328 %[fields]
329 width: Size,
330 margin: Gaps,
331 dropdown_background: Color,
332 background_button: Color,
333 hover_background: Color,
334 border_fill: Color,
335 focus_border_fill: Color,
336 arrow_fill: Color,
337 color: Color,
338 }
339}
340
341define_theme! {
342 %[component]
343 pub DropdownItem {
344 %[fields]
345 background: Color,
346 select_background: Color,
347 hover_background: Color,
348 border_fill: Color,
349 select_border_fill: Color,
350 color: Color,
351 }
352}
353
354define_theme! {
355 %[component]
356 pub Popup {
357 %[fields]
358 background: Color,
359 color: Color,
360 }
361}
362
363define_theme! {
364 %[component]
365 pub Table {
366 %[fields]
367 background: Color,
368 arrow_fill: Color,
369 hover_row_background: Color,
370 row_background: Color,
371 divider_fill: Color,
372 corner_radius: CornerRadius,
373 color: Color,
374 }
375}
376
377define_theme! {
378 %[component]
379 pub Chip {
380 %[fields]
381 background: Color,
382 hover_background: Color,
383 selected_background: Color,
384 border_fill: Color,
385 selected_border_fill: Color,
386 hover_border_fill: Color,
387 focus_border_fill: Color,
388 margin: f32,
389 corner_radius: CornerRadius,
390 width: Size,
391 height: Size,
392 padding: Gaps,
393 color: Color,
394 hover_color: Color,
395 selected_color: Color,
396 selected_icon_fill: Color,
397 hover_icon_fill: Color,
398 }
399}
400
401define_theme! {
402 %[component]
403 pub MenuContainer {
404 %[fields]
405 background: Color,
406 padding: Gaps,
407 shadow: Color,
408 border_fill: Color,
409 corner_radius: CornerRadius,
410 }
411}
412
413define_theme! {
414 %[component]
415 pub MenuItem {
416 %[fields]
417 hover_background: Color,
418 corner_radius: CornerRadius,
419 color: Color,
420 }
421}