windjammer_ui/components/generated/
theme.rs

1#![allow(clippy::all)]
2#![allow(noop_method_call)]
3use super::traits::Renderable;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
6pub struct ColorPalette {
7    pub bg_primary: String,
8    pub bg_secondary: String,
9    pub bg_tertiary: String,
10    pub bg_elevated: String,
11    pub text_primary: String,
12    pub text_secondary: String,
13    pub text_muted: String,
14    pub accent_primary: String,
15    pub accent_secondary: String,
16    pub accent_success: String,
17    pub accent_warning: String,
18    pub accent_error: String,
19    pub border_subtle: String,
20    pub border_default: String,
21    pub axis_x: String,
22    pub axis_y: String,
23    pub axis_z: String,
24}
25
26impl ColorPalette {
27    #[inline]
28    pub fn dark() -> ColorPalette {
29        ColorPalette {
30            bg_primary: "#0a0a1a".to_string(),
31            bg_secondary: "#16213e".to_string(),
32            bg_tertiary: "#1a2744".to_string(),
33            bg_elevated: "#1e2d4d".to_string(),
34            text_primary: "#e0e0e0".to_string(),
35            text_secondary: "#a0a0a0".to_string(),
36            text_muted: "#666666".to_string(),
37            accent_primary: "#e94560".to_string(),
38            accent_secondary: "#0f3460".to_string(),
39            accent_success: "#4ade80".to_string(),
40            accent_warning: "#facc15".to_string(),
41            accent_error: "#ef4444".to_string(),
42            border_subtle: "rgba(255,255,255,0.05)".to_string(),
43            border_default: "rgba(255,255,255,0.1)".to_string(),
44            axis_x: "#e94560".to_string(),
45            axis_y: "#4ade80".to_string(),
46            axis_z: "#60a5fa".to_string(),
47        }
48    }
49    #[inline]
50    pub fn light() -> ColorPalette {
51        ColorPalette {
52            bg_primary: "#f5f5f5".to_string(),
53            bg_secondary: "#ffffff".to_string(),
54            bg_tertiary: "#fafafa".to_string(),
55            bg_elevated: "#ffffff".to_string(),
56            text_primary: "#1a1a2e".to_string(),
57            text_secondary: "#666666".to_string(),
58            text_muted: "#999999".to_string(),
59            accent_primary: "#e94560".to_string(),
60            accent_secondary: "#3b82f6".to_string(),
61            accent_success: "#22c55e".to_string(),
62            accent_warning: "#eab308".to_string(),
63            accent_error: "#dc2626".to_string(),
64            border_subtle: "rgba(0,0,0,0.05)".to_string(),
65            border_default: "rgba(0,0,0,0.1)".to_string(),
66            axis_x: "#dc2626".to_string(),
67            axis_y: "#16a34a".to_string(),
68            axis_z: "#2563eb".to_string(),
69        }
70    }
71    #[inline]
72    pub fn high_contrast() -> ColorPalette {
73        ColorPalette {
74            bg_primary: "#000000".to_string(),
75            bg_secondary: "#1a1a1a".to_string(),
76            bg_tertiary: "#2a2a2a".to_string(),
77            bg_elevated: "#333333".to_string(),
78            text_primary: "#ffffff".to_string(),
79            text_secondary: "#cccccc".to_string(),
80            text_muted: "#888888".to_string(),
81            accent_primary: "#ffcc00".to_string(),
82            accent_secondary: "#00ffcc".to_string(),
83            accent_success: "#00ff00".to_string(),
84            accent_warning: "#ffff00".to_string(),
85            accent_error: "#ff0000".to_string(),
86            border_subtle: "rgba(255,255,255,0.2)".to_string(),
87            border_default: "rgba(255,255,255,0.4)".to_string(),
88            axis_x: "#ff6666".to_string(),
89            axis_y: "#66ff66".to_string(),
90            axis_z: "#6666ff".to_string(),
91        }
92    }
93    #[inline]
94    pub fn monokai() -> ColorPalette {
95        ColorPalette {
96            bg_primary: "#272822".to_string(),
97            bg_secondary: "#3e3d32".to_string(),
98            bg_tertiary: "#49483e".to_string(),
99            bg_elevated: "#75715e".to_string(),
100            text_primary: "#f8f8f2".to_string(),
101            text_secondary: "#a6a997".to_string(),
102            text_muted: "#75715e".to_string(),
103            accent_primary: "#f92672".to_string(),
104            accent_secondary: "#66d9ef".to_string(),
105            accent_success: "#a6e22e".to_string(),
106            accent_warning: "#fd971f".to_string(),
107            accent_error: "#f92672".to_string(),
108            border_subtle: "rgba(255,255,255,0.05)".to_string(),
109            border_default: "rgba(255,255,255,0.1)".to_string(),
110            axis_x: "#f92672".to_string(),
111            axis_y: "#a6e22e".to_string(),
112            axis_z: "#66d9ef".to_string(),
113        }
114    }
115    #[inline]
116    pub fn nord() -> ColorPalette {
117        ColorPalette {
118            bg_primary: "#2e3440".to_string(),
119            bg_secondary: "#3b4252".to_string(),
120            bg_tertiary: "#434c5e".to_string(),
121            bg_elevated: "#4c566a".to_string(),
122            text_primary: "#eceff4".to_string(),
123            text_secondary: "#d8dee9".to_string(),
124            text_muted: "#81a1c1".to_string(),
125            accent_primary: "#88c0d0".to_string(),
126            accent_secondary: "#81a1c1".to_string(),
127            accent_success: "#a3be8c".to_string(),
128            accent_warning: "#ebcb8b".to_string(),
129            accent_error: "#bf616a".to_string(),
130            border_subtle: "rgba(255,255,255,0.05)".to_string(),
131            border_default: "rgba(255,255,255,0.1)".to_string(),
132            axis_x: "#bf616a".to_string(),
133            axis_y: "#a3be8c".to_string(),
134            axis_z: "#5e81ac".to_string(),
135        }
136    }
137}
138
139#[derive(Debug, Clone)]
140pub struct EditorTheme {
141    pub name: String,
142    pub palette: ColorPalette,
143    pub font_family: String,
144    pub font_size_base: i32,
145    pub border_radius: i32,
146    pub spacing_unit: i32,
147    pub animation_duration: i32,
148}
149
150impl EditorTheme {
151    #[inline]
152    pub fn default() -> EditorTheme {
153        EditorTheme {
154            name: "Windjammer Dark".to_string(),
155            palette: ColorPalette::dark(),
156            font_family: "'Inter', 'SF Pro', -apple-system, sans-serif".to_string(),
157            font_size_base: 13,
158            border_radius: 6,
159            spacing_unit: 8,
160            animation_duration: 150,
161        }
162    }
163    #[inline]
164    pub fn light() -> EditorTheme {
165        EditorTheme {
166            name: "Windjammer Light".to_string(),
167            palette: ColorPalette::light(),
168            font_family: "'Inter', 'SF Pro', -apple-system, sans-serif".to_string(),
169            font_size_base: 13,
170            border_radius: 6,
171            spacing_unit: 8,
172            animation_duration: 150,
173        }
174    }
175    #[inline]
176    pub fn monokai() -> EditorTheme {
177        EditorTheme {
178            name: "Monokai Pro".to_string(),
179            palette: ColorPalette::monokai(),
180            font_family: "'Fira Code', 'JetBrains Mono', monospace".to_string(),
181            font_size_base: 13,
182            border_radius: 4,
183            spacing_unit: 8,
184            animation_duration: 100,
185        }
186    }
187    #[inline]
188    pub fn nord() -> EditorTheme {
189        EditorTheme {
190            name: "Nord".to_string(),
191            palette: ColorPalette::nord(),
192            font_family: "'Source Sans Pro', 'Nunito', sans-serif".to_string(),
193            font_size_base: 14,
194            border_radius: 8,
195            spacing_unit: 10,
196            animation_duration: 200,
197        }
198    }
199}
200
201impl Renderable for EditorTheme {
202    #[inline]
203    fn render(self) -> String {
204        let css = format!(
205            "{}{}{}{}{}{}{}{}{}{}{}",
206            ":root { 
207            --bg-primary: ",
208            self.palette.bg_primary.as_str(),
209            ";
210            --bg-secondary: ",
211            self.palette.bg_secondary.as_str(),
212            ";
213            --accent-primary: ",
214            self.palette.accent_primary.as_str(),
215            ";
216            --text-primary: ",
217            self.palette.text_primary.as_str(),
218            ";
219        }
220        body {
221            font-family: ",
222            self.font_family.as_str(),
223            ";
224            color: var(--text-primary);
225            background: var(--bg-primary);
226        }"
227        );
228        css
229    }
230}
231
232#[derive(Debug, Clone, PartialEq, Eq, Default)]
233pub struct ThemeSwitcher {
234    pub current_theme: String,
235    pub themes: Vec<String>,
236    pub on_change: String,
237}
238
239impl ThemeSwitcher {
240    #[inline]
241    pub fn new() -> ThemeSwitcher {
242        let mut themes = Vec::new();
243        themes.push("dark".to_string());
244        themes.push("light".to_string());
245        themes.push("monokai".to_string());
246        themes.push("nord".to_string());
247        themes.push("high-contrast".to_string());
248        ThemeSwitcher {
249            current_theme: "dark".to_string(),
250            themes,
251            on_change: "".to_string(),
252        }
253    }
254    #[inline]
255    pub fn on_change(mut self, handler: String) -> ThemeSwitcher {
256        self.on_change = handler;
257        self
258    }
259}
260
261impl Renderable for ThemeSwitcher {
262    #[inline]
263    fn render(self) -> String {
264        let mut options = "".to_string();
265        for t in &self.themes {
266            let selected = {
267                if t.as_str() == self.current_theme.as_str() {
268                    "selected".to_string()
269                } else {
270                    "".to_string()
271                }
272            };
273            options += format!("<option value='{}' {}>{}</option>", t, selected, t).as_str();
274        }
275        format!(
276            "
277            <div class='theme-switcher'>
278                <label>🎨 Theme</label>
279                <select onchange='{}(this.value)'>
280                    {}
281                </select>
282            </div>
283        ",
284            self.on_change, options
285        )
286    }
287}