gpui_component/theme/theme_color.rs
1use std::{ops::Deref, sync::Arc};
2
3use crate::{ThemeMode, theme::DEFAULT_THEME_COLORS};
4
5use gpui::{Background, Fill, Hsla};
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9/// A theme token that keeps a solid representative color and its renderable background.
10#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
11pub struct ThemeToken {
12 pub color: Hsla,
13 pub background: Background,
14}
15
16impl ThemeToken {
17 pub fn new(color: Hsla, background: Background) -> Self {
18 Self { color, background }
19 }
20}
21
22impl Deref for ThemeToken {
23 type Target = Hsla;
24
25 fn deref(&self) -> &Self::Target {
26 &self.color
27 }
28}
29
30impl From<Hsla> for ThemeToken {
31 fn from(color: Hsla) -> Self {
32 Self {
33 color,
34 background: color.into(),
35 }
36 }
37}
38
39impl From<ThemeToken> for Hsla {
40 fn from(token: ThemeToken) -> Self {
41 token.color
42 }
43}
44
45impl From<ThemeToken> for Background {
46 fn from(token: ThemeToken) -> Self {
47 token.background
48 }
49}
50
51impl From<ThemeToken> for Fill {
52 fn from(token: ThemeToken) -> Self {
53 Fill::Color(token.background)
54 }
55}
56
57/// Theme colors used throughout the UI components.
58#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
59pub struct ThemeColor {
60 /// Used for accents such as hover background on MenuItem, ListItem, etc.
61 pub accent: Hsla,
62 /// Used for accent text color.
63 pub accent_foreground: Hsla,
64 /// Accordion background color.
65 pub accordion: Hsla,
66 /// Default background color.
67 pub background: Hsla,
68 /// Default border color
69 pub border: Hsla,
70 /// Default Button background color.
71 pub button: Hsla,
72 /// Default Button active background color.
73 pub button_active: Hsla,
74 /// Default Button text color.
75 pub button_foreground: Hsla,
76 /// Default Button hover background color.
77 pub button_hover: Hsla,
78 /// Button danger background color, fallback to `danger`.
79 pub button_danger: Hsla,
80 /// Button danger active background color, fallback to `danger_active`.
81 pub button_danger_active: Hsla,
82 /// Button danger text color, fallback to `danger_foreground`.
83 pub button_danger_foreground: Hsla,
84 /// Button danger hover background color, fallback to `danger_hover`.
85 pub button_danger_hover: Hsla,
86 /// Button info background color, fallback to `info`.
87 pub button_info: Hsla,
88 /// Button info active background color, fallback to `info_active`.
89 pub button_info_active: Hsla,
90 /// Button info text color, fallback to `info_foreground`.
91 pub button_info_foreground: Hsla,
92 /// Button info hover background color, fallback to `info_hover`.
93 pub button_info_hover: Hsla,
94 /// Button primary background color, fallback to `primary`.
95 pub button_primary: Hsla,
96 /// Button primary active background color, fallback to `primary_active`.
97 pub button_primary_active: Hsla,
98 /// Button primary text color, fallback to `primary_foreground`.
99 pub button_primary_foreground: Hsla,
100 /// Button primary hover background color, fallback to `primary_hover`.
101 pub button_primary_hover: Hsla,
102 /// Button secondary background color, fallback to `secondary`.
103 pub button_secondary: Hsla,
104 /// Button secondary active background color, fallback to `secondary_active`.
105 pub button_secondary_active: Hsla,
106 /// Button secondary text color, fallback to `secondary_foreground`.
107 pub button_secondary_foreground: Hsla,
108 /// Button secondary hover background color, fallback to `secondary_hover`.
109 pub button_secondary_hover: Hsla,
110 /// Button success background color, fallback to `success`.
111 pub button_success: Hsla,
112 /// Button success active background color, fallback to `success_active`.
113 pub button_success_active: Hsla,
114 /// Button success text color, fallback to `success_foreground`.
115 pub button_success_foreground: Hsla,
116 /// Button success hover background color, fallback to `success_hover`.
117 pub button_success_hover: Hsla,
118 /// Button warning background color, fallback to `warning`.
119 pub button_warning: Hsla,
120 /// Button warning active background color, fallback to `warning_active`.
121 pub button_warning_active: Hsla,
122 /// Button warning text color, fallback to `warning_foreground`.
123 pub button_warning_foreground: Hsla,
124 /// Button warning hover background color, fallback to `warning_hover`.
125 pub button_warning_hover: Hsla,
126 /// Background color for GroupBox.
127 pub group_box: Hsla,
128 /// Text color for GroupBox.
129 pub group_box_foreground: Hsla,
130 /// Input caret color (Blinking cursor).
131 pub caret: Hsla,
132 /// Chart 1 color (`chart.1` in the theme file).
133 pub chart_1: Hsla,
134 /// Chart 2 color (`chart.2` in the theme file).
135 pub chart_2: Hsla,
136 /// Chart 3 color (`chart.3` in the theme file).
137 pub chart_3: Hsla,
138 /// Chart 4 color (`chart.4` in the theme file).
139 pub chart_4: Hsla,
140 /// Chart 5 color (`chart.5` in the theme file).
141 pub chart_5: Hsla,
142 /// Bullish color for candlestick charts (upward price movement).
143 pub chart_bullish: Hsla,
144 /// Bearish color for candlestick charts (downward price movement).
145 pub chart_bearish: Hsla,
146 /// Chart grid line color.
147 pub chart_grid: Hsla,
148 /// Danger background color.
149 pub danger: Hsla,
150 /// Danger active background color.
151 pub danger_active: Hsla,
152 /// Danger text color.
153 pub danger_foreground: Hsla,
154 /// Danger hover background color.
155 pub danger_hover: Hsla,
156 /// Description List label background color.
157 pub description_list_label: Hsla,
158 /// Description List label foreground color.
159 pub description_list_label_foreground: Hsla,
160 /// Drag border color.
161 pub drag_border: Hsla,
162 /// Drop target background color.
163 pub drop_target: Hsla,
164 /// Default text color.
165 pub foreground: Hsla,
166 /// Info background color.
167 pub info: Hsla,
168 /// Info active background color.
169 pub info_active: Hsla,
170 /// Info text color.
171 pub info_foreground: Hsla,
172 /// Info hover background color.
173 pub info_hover: Hsla,
174 /// Border color for inputs such as Input, Select, etc.
175 pub input: Hsla,
176 /// Link text color.
177 pub link: Hsla,
178 /// Active link text color.
179 pub link_active: Hsla,
180 /// Hover link text color.
181 pub link_hover: Hsla,
182 /// Background color for List and ListItem.
183 pub list: Hsla,
184 /// Background color for active ListItem.
185 pub list_active: Hsla,
186 /// Border color for active ListItem.
187 pub list_active_border: Hsla,
188 /// Stripe background color for even ListItem.
189 pub list_even: Hsla,
190 /// Background color for List header.
191 pub list_head: Hsla,
192 /// Hover background color for ListItem.
193 pub list_hover: Hsla,
194 /// Muted backgrounds such as Skeleton and Switch.
195 pub muted: Hsla,
196 /// Muted text color, as used in disabled text.
197 pub muted_foreground: Hsla,
198 /// Background color for Popover.
199 pub popover: Hsla,
200 /// Text color for Popover.
201 pub popover_foreground: Hsla,
202 /// Primary background color.
203 pub primary: Hsla,
204 /// Active primary background color.
205 pub primary_active: Hsla,
206 /// Primary text color.
207 pub primary_foreground: Hsla,
208 /// Hover primary background color.
209 pub primary_hover: Hsla,
210 /// Progress bar background color.
211 pub progress_bar: Hsla,
212 /// Used for focus ring.
213 pub ring: Hsla,
214 /// Scrollbar background color.
215 pub scrollbar: Hsla,
216 /// Scrollbar thumb background color.
217 pub scrollbar_thumb: Hsla,
218 /// Scrollbar thumb hover background color.
219 pub scrollbar_thumb_hover: Hsla,
220 /// Secondary background color.
221 pub secondary: Hsla,
222 /// Active secondary background color.
223 pub secondary_active: Hsla,
224 /// Secondary text color, used for secondary Button text color or secondary text.
225 pub secondary_foreground: Hsla,
226 /// Hover secondary background color.
227 pub secondary_hover: Hsla,
228 /// Input selection background color.
229 pub selection: Hsla,
230 /// Sidebar background color.
231 pub sidebar: Hsla,
232 /// Sidebar accent background color.
233 pub sidebar_accent: Hsla,
234 /// Sidebar accent text color.
235 pub sidebar_accent_foreground: Hsla,
236 /// Sidebar border color.
237 pub sidebar_border: Hsla,
238 /// Sidebar text color.
239 pub sidebar_foreground: Hsla,
240 /// Sidebar primary background color.
241 pub sidebar_primary: Hsla,
242 /// Sidebar primary text color.
243 pub sidebar_primary_foreground: Hsla,
244 /// Skeleton background color.
245 pub skeleton: Hsla,
246 /// Slider bar background color.
247 pub slider_bar: Hsla,
248 /// Slider thumb background color.
249 pub slider_thumb: Hsla,
250 /// Success background color.
251 pub success: Hsla,
252 /// Success text color.
253 pub success_foreground: Hsla,
254 /// Success hover background color.
255 pub success_hover: Hsla,
256 /// Success active background color.
257 pub success_active: Hsla,
258 /// Switch background color.
259 pub switch: Hsla,
260 /// Switch thumb background color.
261 pub switch_thumb: Hsla,
262 /// Tab background color.
263 pub tab: Hsla,
264 /// Tab active background color.
265 pub tab_active: Hsla,
266 /// Tab active text color.
267 pub tab_active_foreground: Hsla,
268 /// TabBar background color.
269 pub tab_bar: Hsla,
270 /// TabBar segmented background color.
271 pub tab_bar_segmented: Hsla,
272 /// Tab text color.
273 pub tab_foreground: Hsla,
274 /// Table background color.
275 pub table: Hsla,
276 /// Table active item background color.
277 pub table_active: Hsla,
278 /// Table active item border color.
279 pub table_active_border: Hsla,
280 /// Stripe background color for even TableRow.
281 pub table_even: Hsla,
282 /// Table head background color.
283 pub table_head: Hsla,
284 /// Table head text color.
285 pub table_head_foreground: Hsla,
286 /// Table footer background color.
287 pub table_foot: Hsla,
288 /// Table footer text color.
289 pub table_foot_foreground: Hsla,
290 /// Table item hover background color.
291 pub table_hover: Hsla,
292 /// Table row border color.
293 pub table_row_border: Hsla,
294 /// TitleBar background color, use for Window title bar.
295 pub title_bar: Hsla,
296 /// TitleBar border color.
297 pub title_bar_border: Hsla,
298 /// StatusBar background color, use for the bottom status bar.
299 pub status_bar: Hsla,
300 /// StatusBar border color.
301 pub status_bar_border: Hsla,
302 /// Warning background color.
303 pub warning: Hsla,
304 /// Warning active background color.
305 pub warning_active: Hsla,
306 /// Warning hover background color.
307 pub warning_hover: Hsla,
308 /// Warning foreground color.
309 pub warning_foreground: Hsla,
310 /// Overlay background color.
311 pub overlay: Hsla,
312 /// Window border color.
313 ///
314 /// # Platform specific:
315 ///
316 /// This is only works on Linux, other platforms we can't change the window border color.
317 pub window_border: Hsla,
318
319 /// The base red color.
320 pub red: Hsla,
321 /// The base red light color.
322 pub red_light: Hsla,
323 /// The base green color.
324 pub green: Hsla,
325 /// The base green light color.
326 pub green_light: Hsla,
327 /// The base blue color.
328 pub blue: Hsla,
329 /// The base blue light color.
330 pub blue_light: Hsla,
331 /// The base yellow color.
332 pub yellow: Hsla,
333 /// The base yellow light color.
334 pub yellow_light: Hsla,
335 /// The base magenta color.
336 pub magenta: Hsla,
337 /// The base magenta light color.
338 pub magenta_light: Hsla,
339 /// The base cyan color.
340 pub cyan: Hsla,
341 /// The base cyan light color.
342 pub cyan_light: Hsla,
343}
344
345macro_rules! define_theme_tokens {
346 ($($field:ident),+ $(,)?) => {
347 /// Legacy resolved tokens retained for compatibility with existing
348 /// `gpui-component` themes and components.
349 ///
350 /// This type intentionally includes component-specific fields such as
351 /// `button_primary`, `tab_active`, and `table_hover`. New application-owned
352 /// components should use [`gpui_base::SemanticThemeTokens`] instead. The
353 /// legacy fields remain public so existing theme files and direct field
354 /// access continue to work unchanged.
355 #[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
356 pub struct ThemeTokens {
357 $(pub $field: ThemeToken,)+
358 }
359
360 impl ThemeTokens {
361 /// Brings the tokens and `colors` back to one value per field after
362 /// an edit, given the two as they were before it.
363 ///
364 /// A field edited on `colors` wins: when its token no longer names
365 /// that color, the token becomes that solid color, dropping any
366 /// gradient it carried — the caller asked for the solid color. A
367 /// field edited only on the tokens writes its solid color back to
368 /// `colors`. A field the edit set on both sides to one color, as
369 /// applying a theme config does, keeps its token, so a gradient
370 /// from a theme file survives; so does an untouched field.
371 pub(crate) fn reconcile(
372 &mut self,
373 colors: &mut ThemeColor,
374 colors_before: &ThemeColor,
375 tokens_before: &ThemeTokens,
376 ) {
377 $(
378 if colors.$field != colors_before.$field {
379 if self.$field.color != colors.$field {
380 self.$field = colors.$field.into();
381 }
382 } else if self.$field != tokens_before.$field {
383 colors.$field = self.$field.color;
384 }
385 )+
386 }
387 }
388
389 impl From<ThemeColor> for ThemeTokens {
390 fn from(colors: ThemeColor) -> Self {
391 Self {
392 $($field: colors.$field.into(),)+
393 }
394 }
395 }
396
397 impl From<&ThemeColor> for ThemeTokens {
398 fn from(colors: &ThemeColor) -> Self {
399 Self::from(*colors)
400 }
401 }
402 };
403}
404
405define_theme_tokens! {
406 accent,
407 accent_foreground,
408 accordion,
409 background,
410 border,
411 button,
412 button_active,
413 button_foreground,
414 button_hover,
415 button_danger,
416 button_danger_active,
417 button_danger_foreground,
418 button_danger_hover,
419 button_info,
420 button_info_active,
421 button_info_foreground,
422 button_info_hover,
423 button_primary,
424 button_primary_active,
425 button_primary_foreground,
426 button_primary_hover,
427 button_secondary,
428 button_secondary_active,
429 button_secondary_foreground,
430 button_secondary_hover,
431 button_success,
432 button_success_active,
433 button_success_foreground,
434 button_success_hover,
435 button_warning,
436 button_warning_active,
437 button_warning_foreground,
438 button_warning_hover,
439 group_box,
440 group_box_foreground,
441 caret,
442 chart_1,
443 chart_2,
444 chart_3,
445 chart_4,
446 chart_5,
447 chart_bullish,
448 chart_bearish,
449 chart_grid,
450 danger,
451 danger_active,
452 danger_foreground,
453 danger_hover,
454 description_list_label,
455 description_list_label_foreground,
456 drag_border,
457 drop_target,
458 foreground,
459 info,
460 info_active,
461 info_foreground,
462 info_hover,
463 input,
464 link,
465 link_active,
466 link_hover,
467 list,
468 list_active,
469 list_active_border,
470 list_even,
471 list_head,
472 list_hover,
473 muted,
474 muted_foreground,
475 popover,
476 popover_foreground,
477 primary,
478 primary_active,
479 primary_foreground,
480 primary_hover,
481 progress_bar,
482 ring,
483 scrollbar,
484 scrollbar_thumb,
485 scrollbar_thumb_hover,
486 secondary,
487 secondary_active,
488 secondary_foreground,
489 secondary_hover,
490 selection,
491 sidebar,
492 sidebar_accent,
493 sidebar_accent_foreground,
494 sidebar_border,
495 sidebar_foreground,
496 sidebar_primary,
497 sidebar_primary_foreground,
498 skeleton,
499 slider_bar,
500 slider_thumb,
501 success,
502 success_foreground,
503 success_hover,
504 success_active,
505 switch,
506 switch_thumb,
507 tab,
508 tab_active,
509 tab_active_foreground,
510 tab_bar,
511 tab_bar_segmented,
512 tab_foreground,
513 table,
514 table_active,
515 table_active_border,
516 table_even,
517 table_head,
518 table_head_foreground,
519 table_foot,
520 table_foot_foreground,
521 table_hover,
522 table_row_border,
523 title_bar,
524 title_bar_border,
525 status_bar,
526 status_bar_border,
527 warning,
528 warning_active,
529 warning_hover,
530 warning_foreground,
531 overlay,
532 window_border,
533 red,
534 red_light,
535 green,
536 green_light,
537 blue,
538 blue_light,
539 yellow,
540 yellow_light,
541 magenta,
542 magenta_light,
543 cyan,
544 cyan_light,
545}
546
547impl ThemeColor {
548 /// Get the default light theme colors.
549 pub fn light() -> Arc<Self> {
550 DEFAULT_THEME_COLORS[&ThemeMode::Light].0.clone()
551 }
552
553 /// Get the default dark theme colors.
554 pub fn dark() -> Arc<Self> {
555 DEFAULT_THEME_COLORS[&ThemeMode::Dark].0.clone()
556 }
557}