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