Skip to main content

dioxus_element_plug/styles/
theme.rs

1//! # Theme System
2//!
3//! Theme definitions and builders for Element Plus style customization.
4
5use crate::styles::prelude::*;
6
7/// Complete Element Plus theme with all customizable properties
8#[derive(Debug, Clone)]
9pub struct Theme {
10    // Colors
11    pub color_primary: &'static str,
12    pub color_success: &'static str,
13    pub color_warning: &'static str,
14    pub color_danger: &'static str,
15    pub color_info: &'static str,
16    pub color_white: &'static str,
17    pub color_black: &'static str,
18    pub color_text_primary: &'static str,
19    pub color_text_regular: &'static str,
20    pub color_text_secondary: &'static str,
21    pub color_text_placeholder: &'static str,
22    pub border_color_base: &'static str,
23    pub border_color_light: &'static str,
24    pub border_color_lighter: &'static str,
25    pub border_color_extra_light: &'static str,
26    pub background_color_base: &'static str,
27
28    // Font sizes
29    pub font_size_extra_large: &'static str,
30    pub font_size_large: &'static str,
31    pub font_size_medium: &'static str,
32    pub font_size_base: &'static str,
33    pub font_size_small: &'static str,
34    pub font_size_extra_small: &'static str,
35
36    // Font family
37    pub font_family: &'static str,
38    pub font_weight_primary: &'static str,
39    pub line_height_primary: &'static str,
40
41    // Borders
42    pub border_radius_base: &'static str,
43    pub border_radius_small: &'static str,
44    pub border_radius_circle: &'static str,
45    pub border_radius_large: &'static str,
46
47    // Component sizes
48    pub component_size_large: &'static str,
49    pub component_size_default: &'static str,
50    pub component_size_small: &'static str,
51
52    // Spacing
53    pub padding_base: &'static str,
54    pub padding_small: &'static str,
55    pub padding_large: &'static str,
56    pub margin_base: &'static str,
57    pub margin_small: &'static str,
58    pub margin_large: &'static str,
59
60    // Transitions
61    pub transition_duration_slow: &'static str,
62    pub transition_duration_base: &'static str,
63    pub transition_duration_fast: &'static str,
64    pub all_transition: &'static str,
65    pub fade_transition: &'static str,
66    pub border_transition_base: &'static str,
67    pub color_transition_base: &'static str,
68    pub cubic_bezier_primary: &'static str,
69    pub cubic_bezier_secondary: &'static str,
70
71    // Shadows
72    pub box_shadow_base: &'static str,
73    pub box_shadow_light: &'static str,
74    pub box_shadow_lighter: &'static str,
75    pub box_shadow_dark: &'static str,
76
77    // Z-index
78    pub z_index_base: i32,
79    pub z_index_popper: i32,
80    pub z_index_overlay: i32,
81    pub z_index_dialog: i32,
82    pub z_index_message: i32,
83    pub z_index_notification: i32,
84    pub z_index_tooltip: i32,
85}
86
87impl Default for Theme {
88    fn default() -> Self {
89        Self {
90            // Colors
91            color_primary: COLOR_PRIMARY,
92            color_success: COLOR_SUCCESS,
93            color_warning: COLOR_WARNING,
94            color_danger: COLOR_DANGER,
95            color_info: COLOR_INFO,
96            color_white: COLOR_WHITE,
97            color_black: COLOR_BLACK,
98            color_text_primary: COLOR_TEXT_PRIMARY,
99            color_text_regular: COLOR_TEXT_REGULAR,
100            color_text_secondary: COLOR_TEXT_SECONDARY,
101            color_text_placeholder: COLOR_TEXT_PLACEHOLDER,
102            border_color_base: BORDER_COLOR_BASE,
103            border_color_light: BORDER_COLOR_LIGHT,
104            border_color_lighter: BORDER_COLOR_LIGHTER,
105            border_color_extra_light: BORDER_COLOR_EXTRA_LIGHT,
106            background_color_base: BACKGROUND_COLOR_BASE,
107
108            // Font sizes
109            font_size_extra_large: FONT_SIZE_EXTRA_LARGE,
110            font_size_large: FONT_SIZE_LARGE,
111            font_size_medium: FONT_SIZE_MEDIUM,
112            font_size_base: FONT_SIZE_BASE,
113            font_size_small: FONT_SIZE_SMALL,
114            font_size_extra_small: FONT_SIZE_EXTRA_SMALL,
115
116            // Font family
117            font_family: FONT_FAMILY,
118            font_weight_primary: FONT_WEIGHT_PRIMARY,
119            line_height_primary: FONT_LINE_HEIGHT_PRIMARY,
120
121            // Borders
122            border_radius_base: BORDER_RADIUS_BASE,
123            border_radius_small: BORDER_RADIUS_SMALL,
124            border_radius_circle: BORDER_RADIUS_CIRCLE,
125            border_radius_large: BORDER_RADIUS_LARGE,
126
127            // Component sizes
128            component_size_large: COMPONENT_SIZE_LARGE,
129            component_size_default: COMPONENT_SIZE_DEFAULT,
130            component_size_small: COMPONENT_SIZE_SMALL,
131
132            // Spacing
133            padding_base: SPACING_MD,
134            padding_small: SPACING_SM,
135            padding_large: SPACING_LG,
136            margin_base: SPACING_MD,
137            margin_small: SPACING_SM,
138            margin_large: SPACING_LG,
139
140            // Transitions
141            transition_duration_slow: TRANSITION_DURATION_SLOW,
142            transition_duration_base: TRANSITION_DURATION_BASE,
143            transition_duration_fast: TRANSITION_DURATION_FAST,
144            all_transition: "all .3s cubic-bezier(.645,.045,.355,1)",
145            fade_transition: "opacity .3s cubic-bezier(.55,0,.1,1)",
146            border_transition_base: "border-color .2s cubic-bezier(.645,.045,.355,1)",
147            color_transition_base: "color .2s cubic-bezier(.645,.045,.355,1)",
148            cubic_bezier_primary: "cubic-bezier(.645,.045,.355,1)",
149            cubic_bezier_secondary: "cubic-bezier(.23,1,.32,1)",
150
151            // Shadows
152            box_shadow_base: BOX_SHADOW_BASE,
153            box_shadow_light: BOX_SHADOW_LIGHT,
154            box_shadow_lighter: BOX_SHADOW_LIGHTER,
155            box_shadow_dark: BOX_SHADOW_DARK,
156
157            // Z-index
158            z_index_base: 100,
159            z_index_popper: 2000,
160            z_index_overlay: 2000,
161            z_index_dialog: 2001,
162            z_index_message: 2002,
163            z_index_notification: 2003,
164            z_index_tooltip: 2004,
165        }
166    }
167}
168
169/// Theme builder for custom theme creation
170#[derive(Debug, Default)]
171pub struct ThemeBuilder {
172    theme: Theme,
173}
174
175impl ThemeBuilder {
176    pub fn new() -> Self {
177        Self::default()
178    }
179
180    pub fn primary_color(mut self, color: &'static str) -> Self {
181        self.theme.color_primary = color;
182        self
183    }
184
185    pub fn success_color(mut self, color: &'static str) -> Self {
186        self.theme.color_success = color;
187        self
188    }
189
190    pub fn warning_color(mut self, color: &'static str) -> Self {
191        self.theme.color_warning = color;
192        self
193    }
194
195    pub fn danger_color(mut self, color: &'static str) -> Self {
196        self.theme.color_danger = color;
197        self
198    }
199
200    pub fn info_color(mut self, color: &'static str) -> Self {
201        self.theme.color_info = color;
202        self
203    }
204
205    pub fn font_size_base(mut self, size: &'static str) -> Self {
206        self.theme.font_size_base = size;
207        self
208    }
209
210    pub fn border_radius_base(mut self, radius: &'static str) -> Self {
211        self.theme.border_radius_base = radius;
212        self
213    }
214
215    pub fn build(self) -> Theme {
216        self.theme
217    }
218}
219
220/// Generate CSS variables string for theme
221pub fn generate_css_variables(theme: &Theme) -> String {
222    format!(
223        ":root {{\n  
224  /* Colors */\n  
225  --el-color-primary: {};\n  
226  --el-color-success: {};\n  
227  --el-color-warning: {};\n  
228  --el-color-danger: {};\n  
229  --el-color-info: {};\n  
230  --el-color-white: {};\n  
231  --el-color-black: {};\n
232  /* Text colors */\n  
233  --el-color-text-primary: {};\n  
234  --el-color-text-regular: {};\n  
235  --el-color-text-secondary: {};\n  
236  --el-color-text-placeholder: {};\n
237  /* Border colors */\n  
238  --el-border-color-base: {};\n  
239  --el-border-color-light: {};\n  
240  --el-border-color-lighter: {};\n  
241  --el-border-color-extra-light: {};\n
242  /* Background */\n  
243  --el-background-color-base: {};\n
244  /* Font sizes */\n  
245  --el-font-size-extra-large: {};\n  
246  --el-font-size-large: {};\n  
247  --el-font-size-medium: {};\n  
248  --el-font-size-base: {};\n  
249  --el-font-size-small: {};\n  
250  --el-font-size-extra-small: {};\n
251  /* Font */\n  
252  --el-font-family: {};\n  
253  --el-font-weight-primary: {};\n  
254  --el-line-height-primary: {};\n
255  /* Border radius */\n  
256  --el-border-radius-base: {};\n  
257  --el-border-radius-small: {};\n  
258  --el-border-radius-circle: {};\n  
259  --el-border-radius-large: {};\n
260  /* Box shadows */\n  
261  --el-box-shadow-base: {};\n  
262  --el-box-shadow-light: {};\n  
263  --el-box-shadow-lighter: {};\n  
264  --el-box-shadow-dark: {};\n
265  /* Transition */\n  
266  --el-transition-duration-slow: {};\n  
267  --el-transition-duration-base: {};\n  
268  --el-transition-duration-fast: {};\n\n}}",
269        theme.color_primary,
270        theme.color_success,
271        theme.color_warning,
272        theme.color_danger,
273        theme.color_info,
274        theme.color_white,
275        theme.color_black,
276        theme.color_text_primary,
277        theme.color_text_regular,
278        theme.color_text_secondary,
279        theme.color_text_placeholder,
280        theme.border_color_base,
281        theme.border_color_light,
282        theme.border_color_lighter,
283        theme.border_color_extra_light,
284        theme.background_color_base,
285        theme.font_size_extra_large,
286        theme.font_size_large,
287        theme.font_size_medium,
288        theme.font_size_base,
289        theme.font_size_small,
290        theme.font_size_extra_small,
291        theme.font_family,
292        theme.font_weight_primary,
293        theme.line_height_primary,
294        theme.border_radius_base,
295        theme.border_radius_small,
296        theme.border_radius_circle,
297        theme.border_radius_large,
298        theme.box_shadow_base,
299        theme.box_shadow_light,
300        theme.box_shadow_lighter,
301        theme.box_shadow_dark,
302        theme.transition_duration_slow,
303        theme.transition_duration_base,
304        theme.transition_duration_fast
305    )
306}