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 pub primary: Color,
100 pub secondary: Color,
101 pub tertiary: Color,
102
103 pub success: Color,
105 pub warning: Color,
106 pub error: Color,
107 pub info: Color,
108
109 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 pub border: Color,
120 pub border_focus: Color,
121 pub border_disabled: Color,
122
123 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 pub hover: Color,
132 pub focus: Color,
133 pub active: Color,
134 pub disabled: Color,
135
136 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}