theme: Improve theme color fallbacks based on base colors. (#1069)

- Added a lot of default fallbacks for theme colors based on `base`
colors.
- Added `hue`, `saturation`, `lightness` method to change Hsla color.
- Update stories to use theme colors, not a direct color.
- Improve `Badge`, `Avatar` to use theme colors.
- Added a new theme: `Fahrenheit`.
This commit is contained in:
Jason Lee 2025-07-17 11:43:40 +08:00 committed by GitHub
parent 977ce5df29
commit 9c782796c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 562 additions and 3205 deletions

File diff suppressed because it is too large Load diff

9
Cargo.lock generated
View file

@ -2882,15 +2882,6 @@ dependencies = [
"x11",
]
[[package]]
name = "generate-theme-schema"
version = "0.1.0"
dependencies = [
"gpui-component",
"schemars",
"serde_json",
]
[[package]]
name = "generic-array"
version = "0.14.7"

View file

@ -8,7 +8,6 @@ members = [
"crates/wef/examples/wef-winit",
"crates/webview",
"crates/webview/examples/wef-example",
"script/generate-theme-schema"
]
default-members = ["crates/story"]

View file

@ -3,8 +3,8 @@ use gpui::{
Styled, Window,
};
use gpui_component::{
avatar::Avatar, badge::Badge, blue_500, dock::PanelControl, green_500, red_500, sky_500,
v_flex, yellow_500, Icon, IconName, Sizable as _,
avatar::Avatar, badge::Badge, dock::PanelControl, v_flex, ActiveTheme as _, Icon, IconName,
Sizable as _,
};
use crate::section;
@ -50,7 +50,7 @@ impl Focusable for BadgeStory {
}
impl Render for BadgeStory {
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
v_flex()
.gap_4()
.child(
@ -80,12 +80,24 @@ impl Render for BadgeStory {
.child(
section("Badge with icon")
.max_w_md()
.child(Badge::new().icon(IconName::Check).color(sky_500()).child(
Avatar::new().src("https://avatars.githubusercontent.com/u/5518?v=4"),
))
.child(Badge::new().icon(IconName::Star).color(yellow_500()).child(
Avatar::new().src("https://avatars.githubusercontent.com/u/20092316?v=4"),
)),
.child(
Badge::new()
.icon(IconName::Check)
.color(cx.theme().cyan)
.child(
Avatar::new()
.src("https://avatars.githubusercontent.com/u/5518?v=4"),
),
)
.child(
Badge::new()
.icon(IconName::Star)
.color(cx.theme().yellow)
.child(
Avatar::new()
.src("https://avatars.githubusercontent.com/u/20092316?v=4"),
),
),
)
.child(
section("Badge with dot").max_w_md().child(
@ -97,10 +109,10 @@ impl Render for BadgeStory {
.child(
section("Badge with color")
.max_w_md()
.child(Badge::new().count(3).color(blue_500()).child(
.child(Badge::new().count(3).color(cx.theme().blue).child(
Avatar::new().src("https://avatars.githubusercontent.com/u/5518?v=4"),
))
.child(Badge::new().dot().color(green_500()).count(1).child(
.child(Badge::new().dot().color(cx.theme().green).count(1).child(
Avatar::new().src("https://avatars.githubusercontent.com/u/5518?v=4"),
)),
)
@ -112,7 +124,7 @@ impl Render for BadgeStory {
Badge::new()
.icon(IconName::Check)
.large()
.color(sky_500())
.color(cx.theme().cyan)
.child(
Avatar::new()
.large()
@ -121,11 +133,11 @@ impl Render for BadgeStory {
),
)
.child(
Badge::new().count(2).color(green_500()).large().child(
Badge::new().count(2).color(cx.theme().green).large().child(
Badge::new()
.icon(IconName::Star)
.large()
.color(yellow_500())
.color(cx.theme().yellow)
.child(
Avatar::new().large().src(
"https://avatars.githubusercontent.com/u/20092316?v=4",
@ -134,10 +146,10 @@ impl Render for BadgeStory {
),
)
.child(
Badge::new().count(3).color(green_500()).child(
Badge::new().count(3).color(cx.theme().green).child(
Badge::new()
.icon(IconName::Asterisk)
.color(green_500())
.color(cx.theme().green)
.child(
Avatar::new().src(
"https://avatars.githubusercontent.com/u/22312482?v=4",
@ -150,7 +162,7 @@ impl Render for BadgeStory {
Badge::new()
.icon(IconName::Sun)
.small()
.color(red_500())
.color(cx.theme().red)
.child(
Avatar::new().small().src(
"https://avatars.githubusercontent.com/u/150917089?v=4",

View file

@ -6,8 +6,8 @@ use gpui::{
use gpui_component::{
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
checkbox::Checkbox,
h_flex, indigo, v_flex, white, ActiveTheme, Disableable as _, Icon, IconName, Selectable as _,
Sizable as _, Theme,
h_flex, v_flex, ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _,
Theme,
};
use serde::Deserialize;
@ -81,31 +81,11 @@ impl Render for ButtonStory {
let toggle_multiple = self.toggle_multiple;
let custom_variant = ButtonCustomVariant::new(cx)
.color(if cx.theme().mode.is_dark() {
indigo(800)
} else {
indigo(600)
})
.foreground(if cx.theme().mode.is_dark() {
white()
} else {
white()
})
.border(if cx.theme().mode.is_dark() {
indigo(800)
} else {
indigo(600)
})
.hover(if cx.theme().mode.is_dark() {
indigo(900)
} else {
indigo(700)
})
.active(if cx.theme().mode.is_dark() {
indigo(950)
} else {
indigo(700)
});
.color(cx.theme().magenta)
.foreground(cx.theme().primary_foreground)
.border(cx.theme().magenta)
.hover(cx.theme().magenta.opacity(0.1))
.active(cx.theme().magenta);
v_flex()
.on_action(

View file

@ -3,9 +3,8 @@ use gpui::{
ParentElement as _, Render, Styled as _, Subscription, Window,
};
use gpui_component::{
blue_500,
color_picker::{ColorPicker, ColorPickerEvent, ColorPickerState},
green_500, red_500, v_flex, yellow_500, Colorize, Sizable,
v_flex, ActiveTheme as _, Colorize, Sizable,
};
use crate::section;
@ -36,7 +35,8 @@ impl ColorPickerStory {
}
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let color = cx.new(|cx| ColorPickerState::new(window, cx).default_value(red_500()));
let color =
cx.new(|cx| ColorPickerState::new(window, cx).default_value(cx.theme().primary));
let _subscriptions = vec![cx.subscribe(&color, |this, _, ev, _| match ev {
ColorPickerEvent::Change(color) => {
@ -47,7 +47,7 @@ impl ColorPickerStory {
Self {
color,
selected_color: Some(red_500()),
selected_color: Some(cx.theme().primary),
_subscriptions,
}
}
@ -64,12 +64,7 @@ impl Render for ColorPickerStory {
v_flex().gap_3().child(
section("Normal")
.max_w_md()
.child(ColorPicker::new(&self.color).small().featured_colors(vec![
red_500(),
blue_500(),
green_500(),
yellow_500(),
]))
.child(ColorPicker::new(&self.color).small())
.when_some(self.selected_color, |this, color| {
this.child(color.to_hex())
}),

View file

@ -10,7 +10,7 @@ use gpui::{
use gpui_component::{
button::Button,
checkbox::Checkbox,
h_flex, hsl,
h_flex,
label::Label,
list::{List, ListDelegate, ListEvent, ListItem},
v_flex, ActiveTheme, Sizable,
@ -74,8 +74,8 @@ impl RenderOnce for CompanyListItem {
};
let trend_color = match self.company.change_percent {
change if change > 0.0 => hsl(0.0, 79.0, 53.0),
change if change < 0.0 => hsl(100.0, 79.0, 53.0),
change if change > 0.0 => cx.theme().green,
change if change < 0.0 => cx.theme().red,
_ => cx.theme().foreground,
};

View file

@ -7,7 +7,6 @@ use gpui::{
use gpui_component::{
badge::Badge,
blue_500,
breadcrumb::{Breadcrumb, BreadcrumbItem},
divider::Divider,
h_flex,
@ -17,7 +16,7 @@ use gpui_component::{
SidebarToggleButton,
},
switch::Switch,
v_flex, white, ActiveTheme, Icon, IconName, Side, Sizable,
v_flex, ActiveTheme, Icon, IconName, Side, Sizable,
};
use serde::Deserialize;
@ -261,8 +260,8 @@ impl Render for SidebarStory {
.items_center()
.justify_center()
.rounded(cx.theme().radius)
.bg(blue_500())
.text_color(white())
.bg(cx.theme().success)
.text_color(cx.theme().success_foreground)
.size_8()
.flex_shrink_0()
.when(!self.collapsed, |this| {

View file

@ -1,7 +1,9 @@
use std::{collections::HashMap, sync::LazyLock};
use anyhow::Context;
use gpui::{div, Action, App, InteractiveElement as _, ParentElement as _, Render, SharedString};
use gpui::{
div, px, Action, App, InteractiveElement as _, ParentElement as _, Render, SharedString,
};
use gpui_component::{
button::{Button, ButtonVariants},
popup_menu::PopupMenuExt,
@ -44,6 +46,7 @@ static THEMES: LazyLock<HashMap<SharedString, ThemeConfig>> = LazyLock::new(|| {
include_str!("../../../themes/ayu.json"),
include_str!("../../../themes/catppuccin.json"),
include_str!("../../../themes/everforest.json"),
include_str!("../../../themes/fahrenheit.json"),
include_str!("../../../themes/gruvbox.json"),
include_str!("../../../themes/harper.json"),
include_str!("../../../themes/hybrid.json"),
@ -128,6 +131,8 @@ impl Render for ThemeSwitcher {
let current_theme_id = self.current_theme_name.clone();
move |menu, _, _| {
let mut menu = menu
.scrollable()
.max_h(px(600.))
.menu_with_check(
"Default Light",
current_theme_id == "default-light",

View file

@ -1,5 +1,3 @@
use std::sync::LazyLock;
use gpui::{
div, img, prelude::FluentBuilder, App, Div, Hsla, ImageSource, InteractiveElement,
Interactivity, IntoElement, ParentElement as _, RenderOnce, SharedString, StyleRefinement,
@ -8,31 +6,9 @@ use gpui::{
use crate::{
avatar::{avatar_size, AvatarSized as _},
ActiveTheme, Icon, IconName, Sizable, Size, StyledExt,
ActiveTheme, Colorize, Icon, IconName, Sizable, Size, StyledExt,
};
static AVATAR_COLORS: LazyLock<[Hsla; 17]> = LazyLock::new(|| {
[
crate::red_500(),
crate::orange_500(),
crate::amber_500(),
crate::yellow_500(),
crate::lime_500(),
crate::green_500(),
crate::emerald_500(),
crate::teal_500(),
crate::cyan_500(),
crate::sky_500(),
crate::blue_500(),
crate::indigo_500(),
crate::violet_500(),
crate::fuchsia_500(),
crate::purple_500(),
crate::pink_500(),
crate::rose_500(),
]
});
/// User avatar element.
///
/// We can use [`Sizable`] trait to set the size of the avatar (see also: [`avatar_size`] about the size in pixels).
@ -106,6 +82,12 @@ impl RenderOnce for Avatar {
let mut inner_style = StyleRefinement::default();
inner_style.corner_radii = corner_radii;
const COLOR_COUNT: u64 = 360 / 15;
fn default_color(ix: u64, cx: &mut App) -> Hsla {
let h = (ix * 15).clamp(0, 360) as f32;
cx.theme().blue.hue(h / 360.0)
}
const BG_OPACITY: f32 = 0.2;
self.base
@ -126,8 +108,8 @@ impl RenderOnce for Avatar {
})
.map(|this| match self.src {
None => this.when(self.name.is_some(), |this| {
let color_ix = gpui::hash(&self.short_name) % AVATAR_COLORS.len() as u64;
let color = AVATAR_COLORS[color_ix as usize];
let color_ix = gpui::hash(&self.short_name) % COLOR_COUNT;
let color = default_color(color_ix, cx);
this.bg(color.opacity(BG_OPACITY))
.text_color(color)

View file

@ -3,7 +3,7 @@ use gpui::{
RenderOnce, StyleRefinement, Styled, Window,
};
use crate::{h_flex, red_500, white, ActiveTheme, Icon, Sizable, Size, StyledExt};
use crate::{h_flex, white, ActiveTheme, Icon, Sizable, Size, StyledExt};
#[derive(Default, Clone)]
enum BadgeVariant {
@ -34,7 +34,7 @@ pub struct Badge {
max: usize,
variant: BadgeVariant,
children: Vec<AnyElement>,
color: Hsla,
color: Option<Hsla>,
size: Size,
}
@ -46,7 +46,7 @@ impl Badge {
count: 0,
max: 99,
variant: Default::default(),
color: red_500(),
color: None,
children: Vec::new(),
size: Size::default(),
}
@ -80,7 +80,7 @@ impl Badge {
/// Set the color (background) of the badge.
pub fn color(mut self, color: impl Into<Hsla>) -> Self {
self.color = color.into();
self.color = Some(color.into());
self
}
}
@ -122,7 +122,7 @@ impl RenderOnce for Badge {
.justify_center()
.items_center()
.rounded_full()
.bg(self.color)
.bg(self.color.unwrap_or(cx.theme().red))
.text_color(white())
.text_size(text_size)
.map(|this| match self.variant {

View file

@ -172,7 +172,7 @@ pub struct ColorPicker {
id: ElementId,
style: StyleRefinement,
state: Entity<ColorPickerState>,
featured_colors: Vec<Hsla>,
featured_colors: Option<Vec<Hsla>>,
label: Option<SharedString>,
icon: Option<Icon>,
size: Size,
@ -185,20 +185,7 @@ impl ColorPicker {
id: ("color-picker", state.entity_id()).into(),
style: StyleRefinement::default(),
state: state.clone(),
featured_colors: vec![
crate::black(),
crate::neutral_600(),
crate::neutral_400(),
crate::white(),
crate::red_600(),
crate::orange_600(),
crate::yellow_600(),
crate::green_600(),
crate::blue_600(),
crate::indigo_600(),
crate::purple_600(),
],
featured_colors: None,
size: Size::Medium,
label: None,
icon: None,
@ -211,7 +198,7 @@ impl ColorPicker {
/// This is used to display a set of colors that the user can quickly select from,
/// for example provided user's last used colors.
pub fn featured_colors(mut self, colors: Vec<Hsla>) -> Self {
self.featured_colors = colors;
self.featured_colors = Some(colors);
self
}
@ -284,12 +271,27 @@ impl ColorPicker {
}
fn render_colors(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let featured_colors = self.featured_colors.clone().unwrap_or(vec![
cx.theme().red,
cx.theme().red_light,
cx.theme().blue,
cx.theme().blue_light,
cx.theme().green,
cx.theme().green_light,
cx.theme().yellow,
cx.theme().yellow_light,
cx.theme().cyan,
cx.theme().cyan_light,
cx.theme().magenta,
cx.theme().magenta_light,
]);
let state = self.state.clone();
v_flex()
.gap_3()
.child(
h_flex().gap_1().children(
self.featured_colors
featured_colors
.iter()
.map(|color| self.render_item(*color, true, window, cx)),
),

View file

@ -7,7 +7,7 @@ use std::{collections::HashMap, ops::Deref, sync::LazyLock};
use super::LanguageConfig;
use crate::{
highlighter::{languages, Language},
ThemeMode,
ActiveTheme, Colorize, ThemeMode,
};
pub(super) fn init(cx: &mut App) {
@ -306,78 +306,88 @@ pub struct StatusColors {
impl StatusColors {
#[inline]
pub fn error(&self) -> Hsla {
self.error.unwrap_or(crate::red_500())
pub fn error(&self, cx: &App) -> Hsla {
self.error.unwrap_or(cx.theme().red)
}
#[inline]
pub fn error_background(&self) -> Hsla {
self.error_background.unwrap_or(crate::red_200())
pub fn error_background(&self, cx: &App) -> Hsla {
let bg = cx.theme().background;
self.error_background
.unwrap_or(self.error(cx).lightness(bg.l).saturation(bg.s))
}
#[inline]
pub fn error_border(&self) -> Hsla {
self.error_border.unwrap_or(crate::red_500())
pub fn error_border(&self, cx: &App) -> Hsla {
self.error_border.unwrap_or(self.error(cx))
}
#[inline]
pub fn warning(&self) -> Hsla {
self.warning.unwrap_or(crate::yellow_500())
pub fn warning(&self, cx: &App) -> Hsla {
self.warning.unwrap_or(cx.theme().yellow)
}
#[inline]
pub fn warning_background(&self) -> Hsla {
self.warning_background.unwrap_or(crate::yellow_200())
pub fn warning_background(&self, cx: &App) -> Hsla {
let bg = cx.theme().background;
self.warning_background
.unwrap_or(self.warning(cx).lightness(bg.l).saturation(bg.s))
}
#[inline]
pub fn warning_border(&self) -> Hsla {
self.warning_border.unwrap_or(crate::yellow_500())
pub fn warning_border(&self, cx: &App) -> Hsla {
self.warning_border.unwrap_or(self.warning(cx))
}
#[inline]
pub fn info(&self) -> Hsla {
self.info.unwrap_or(crate::blue_500())
pub fn info(&self, cx: &App) -> Hsla {
self.info.unwrap_or(cx.theme().blue)
}
#[inline]
pub fn info_background(&self) -> Hsla {
self.info_background.unwrap_or(crate::blue_200())
pub fn info_background(&self, cx: &App) -> Hsla {
let bg = cx.theme().background;
self.info_background
.unwrap_or(self.info(cx).lightness(bg.l).saturation(bg.s))
}
#[inline]
pub fn info_border(&self) -> Hsla {
self.info_border.unwrap_or(crate::blue_500())
pub fn info_border(&self, cx: &App) -> Hsla {
self.info_border.unwrap_or(self.info(cx))
}
#[inline]
pub fn success(&self) -> Hsla {
self.success.unwrap_or(crate::green_500())
pub fn success(&self, cx: &App) -> Hsla {
self.success.unwrap_or(cx.theme().green)
}
#[inline]
pub fn success_background(&self) -> Hsla {
self.success_background.unwrap_or(crate::green_200())
pub fn success_background(&self, cx: &App) -> Hsla {
let bg = cx.theme().background;
self.success_background
.unwrap_or(self.success(cx).lightness(bg.l).saturation(bg.s))
}
#[inline]
pub fn success_border(&self) -> Hsla {
self.success_border.unwrap_or(crate::green_500())
pub fn success_border(&self, cx: &App) -> Hsla {
self.success_border.unwrap_or(self.success(cx))
}
#[inline]
pub fn hint(&self) -> Hsla {
self.hint.unwrap_or(crate::neutral_500())
pub fn hint(&self, cx: &App) -> Hsla {
self.hint.unwrap_or(cx.theme().cyan)
}
#[inline]
pub fn hint_background(&self) -> Hsla {
self.hint_background.unwrap_or(crate::neutral_200())
pub fn hint_background(&self, cx: &App) -> Hsla {
let bg = cx.theme().background;
self.hint_background
.unwrap_or(self.hint(cx).lightness(bg.l).saturation(bg.s))
}
#[inline]
pub fn hint_border(&self) -> Hsla {
self.hint_border.unwrap_or(crate::neutral_500())
pub fn hint_border(&self, cx: &App) -> Hsla {
self.hint_border.unwrap_or(self.hint(cx))
}
}

View file

@ -416,7 +416,7 @@ impl TextElement {
|| node_range.end <= visible_range.end
{
marker_styles
.push((node_range, marker.severity.highlight_style(&theme)));
.push((node_range, marker.severity.highlight_style(&theme, cx)));
}
}
}

View file

@ -85,9 +85,9 @@ impl Render for DiagnosticPopover {
return Empty.into_any_element();
};
let (border, bg, fg) = (
self.marker.severity.border(theme),
self.marker.severity.bg(theme),
self.marker.severity.fg(theme),
self.marker.severity.border(theme, cx),
self.marker.severity.bg(theme, cx),
self.marker.severity.fg(theme, cx),
);
let scroll_origin = self.state.read(cx).scroll_handle.offset();

View file

@ -2,7 +2,7 @@ use crate::{
highlighter::HighlightTheme,
input::{InputState, LineColumn},
};
use gpui::{px, HighlightStyle, Hsla, SharedString, UnderlineStyle};
use gpui::{px, App, HighlightStyle, Hsla, SharedString, UnderlineStyle};
use itertools::Itertools;
use std::ops::Range;
@ -102,39 +102,39 @@ impl From<&str> for MarkerSeverity {
}
impl MarkerSeverity {
pub(super) fn bg(&self, theme: &HighlightTheme) -> Hsla {
pub(super) fn bg(&self, theme: &HighlightTheme, cx: &App) -> Hsla {
match self {
Self::Error => theme.style.status.error_background(),
Self::Warning => theme.style.status.warning_background(),
Self::Info => theme.style.status.info_background(),
Self::Hint => theme.style.status.hint_background(),
Self::Error => theme.style.status.error_background(cx),
Self::Warning => theme.style.status.warning_background(cx),
Self::Info => theme.style.status.info_background(cx),
Self::Hint => theme.style.status.hint_background(cx),
}
}
pub(super) fn fg(&self, theme: &HighlightTheme) -> Hsla {
pub(super) fn fg(&self, theme: &HighlightTheme, cx: &App) -> Hsla {
match self {
Self::Error => theme.style.status.error(),
Self::Warning => theme.style.status.warning(),
Self::Info => theme.style.status.info(),
Self::Hint => theme.style.status.hint(),
Self::Error => theme.style.status.error(cx),
Self::Warning => theme.style.status.warning(cx),
Self::Info => theme.style.status.info(cx),
Self::Hint => theme.style.status.hint(cx),
}
}
pub(super) fn border(&self, theme: &HighlightTheme) -> Hsla {
pub(super) fn border(&self, theme: &HighlightTheme, cx: &App) -> Hsla {
match self {
Self::Error => theme.style.status.error_border(),
Self::Warning => theme.style.status.warning_border(),
Self::Info => theme.style.status.info_border(),
Self::Hint => theme.style.status.hint_border(),
Self::Error => theme.style.status.error_border(cx),
Self::Warning => theme.style.status.warning_border(cx),
Self::Info => theme.style.status.info_border(cx),
Self::Hint => theme.style.status.hint_border(cx),
}
}
pub(super) fn highlight_style(&self, theme: &HighlightTheme) -> HighlightStyle {
pub(super) fn highlight_style(&self, theme: &HighlightTheme, cx: &App) -> HighlightStyle {
let color = match self {
Self::Error => Some(theme.style.status.error()),
Self::Warning => Some(theme.style.status.warning()),
Self::Info => Some(theme.style.status.info()),
Self::Hint => Some(theme.style.status.hint()),
Self::Error => Some(theme.style.status.error(cx)),
Self::Warning => Some(theme.style.status.warning(cx)),
Self::Info => Some(theme.style.status.info(cx)),
Self::Hint => Some(theme.style.status.hint(cx)),
};
let mut style = HighlightStyle::default();

View file

@ -41,6 +41,12 @@ pub trait Colorize: Sized {
/// Mix two colors together, the `factor` is a value between 0.0 and 1.0 for first color.
fn mix(&self, other: Self, factor: f32) -> Self;
/// Change the `Hue` of the color by the given in range: 0.0 .. 1.0
fn hue(&self, hue: f32) -> Self;
/// Change the `Saturation` of the color by the given value in range: 0.0 .. 1.0
fn saturation(&self, saturation: f32) -> Self;
/// Change the `Lightness` of the color by the given value in range: 0.0 .. 1.0
fn lightness(&self, lightness: f32) -> Self;
/// Convert the color to a hex string. For example, "#F8FAFC".
fn to_hex(&self) -> String;
@ -161,6 +167,24 @@ impl Colorize for Hsla {
let color: Hsla = v.into();
Ok(color)
}
fn hue(&self, hue: f32) -> Self {
let mut color = *self;
color.h = hue.clamp(0., 1.);
color
}
fn saturation(&self, saturation: f32) -> Self {
let mut color = *self;
color.s = saturation.clamp(0., 1.);
color
}
fn lightness(&self, lightness: f32) -> Self {
let mut color = *self;
color.l = lightness.clamp(0., 1.);
color
}
}
pub(crate) static DEFAULT_COLORS: once_cell::sync::Lazy<ShadcnColors> =
@ -571,4 +595,12 @@ mod tests {
assert_eq!(name1, *name);
}
}
#[test]
fn test_h_s_l() {
let color = hsl(260., 94., 80.);
assert_eq!(color.hue(200. / 360.), hsl(200., 94., 80.));
assert_eq!(color.saturation(74. / 100.), hsl(260., 74., 80.));
assert_eq!(color.lightness(74. / 100.), hsl(260., 94., 74.));
}
}

View file

@ -199,8 +199,8 @@ impl From<ThemeColor> for Theme {
)]
#[serde(rename_all = "snake_case")]
pub enum ThemeMode {
Light,
#[default]
Light,
Dark,
}

View file

@ -31,6 +31,7 @@ pub struct ThemeSet {
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
pub struct ThemeConfig {
/// The name of the theme.
pub name: SharedString,
@ -431,6 +432,8 @@ impl Theme {
apply_color!(blue_light, fallback = self.blue.opacity(0.8));
apply_color!(magenta);
apply_color!(magenta_light, fallback = self.magenta.opacity(0.8));
apply_color!(yellow);
apply_color!(yellow_light, fallback = self.yellow.opacity(0.8));
apply_color!(cyan);
apply_color!(cyan_light, fallback = self.cyan.opacity(0.8));

View file

@ -1 +0,0 @@
cargo run -p generate-theme-schema > .theme-schema.json

View file

@ -1,12 +0,0 @@
[package]
name = "generate-theme-schema"
version = "0.1.0"
edition = "2024"
[dependencies]
serde_json.workspace = true
gpui-component.workspace = true
schemars.workspace = true
[lints]
workspace = true

View file

@ -1,9 +0,0 @@
use gpui_component::ThemeSet;
use schemars::generate::SchemaSettings;
fn main() {
let settings = SchemaSettings::draft07().for_serialize();
let generator = settings.into_generator();
let schema = generator.into_root_schema_for::<ThemeSet>();
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
}

File diff suppressed because it is too large Load diff

View file

@ -232,22 +232,10 @@
"editor.active_line_number": "#DDDDDD",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"

View file

@ -5,7 +5,7 @@
"url": "https://github.com/AlessandroYorba/Alduin",
"themes": [
{
"name": "Alduin Light",
"name": "Alduin",
"mode": "dark",
"colors": {
"accent.background": "#322F2D",
@ -68,22 +68,13 @@
"editor.active_line_number": "#DDDDDD",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"

View file

@ -66,47 +66,19 @@
"editor.line_number": "#ABB0B6",
"editor.active_line_number": "#5C6773",
"conflict": "#FF9940",
"conflict.background": "#FFF4E5",
"conflict.border": "#FF9940",
"created": "#86B300",
"created.background": "#F4FCE5",
"created.border": "#86B300",
"deleted": "#F07171",
"deleted.background": "#FDECEA",
"deleted.border": "#F07171",
"error": "#F07171",
"error.background": "#FDECEA",
"error.border": "#F07171",
"hidden": "#ABB0B6",
"hidden.background": "#ECECED",
"hidden.border": "#D9DCE3",
"hint": "#55B4D4",
"hint.background": "#E5F7FB",
"hint.border": "#55B4D4",
"ignored": "#D9DCE3",
"ignored.background": "#FAFAFA",
"ignored.border": "#E6E8EA",
"info": "#55B4D4",
"info.background": "#E5F7FB",
"info.border": "#55B4D4",
"modified": "#FF9940",
"modified.background": "#FFF4E5",
"modified.border": "#FF9940",
"predictive": "#5C6773",
"predictive.background": "#ECECED",
"predictive.border": "#D9DCE3",
"renamed": "#86B300",
"renamed.background": "#F4FCE5",
"renamed.border": "#86B300",
"success": "#86B300",
"success.background": "#F4FCE5",
"success.border": "#86B300",
"unreachable": "#ABB0B6",
"unreachable.background": "#ECECED",
"unreachable.border": "#D9DCE3",
"warning": "#FF9940",
"warning.background": "#FFF4E5",
"warning.border": "#FF9940",
"syntax": {
"attribute": {
"color": "#86B300"
@ -245,22 +217,10 @@
"editor.active_line_number": "#DDDDDD",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"

View file

@ -63,47 +63,19 @@
"editor.line_number": "#9a9db2",
"editor.active_line_number": "#4c4f69",
"conflict": "#d20f39",
"conflict.background": "#f2d5cf",
"conflict.border": "#d20f39",
"created": "#85dc78",
"created.background": "#dce0e8",
"created.border": "#85dc78",
"deleted": "#dc8a78",
"deleted.background": "#f2d5cf",
"deleted.border": "#dc8a78",
"error": "#d20f39",
"error.background": "#f2d5cf",
"error.border": "#d20f39",
"hidden": "#9a9db2",
"hidden.background": "#EFF1F5",
"hidden.border": "#CCD0DA",
"hint": "#7287fd",
"hint.background": "#dce0e8",
"hint.border": "#7287fd",
"ignored": "#acb0be",
"ignored.background": "#EFF1F5",
"ignored.border": "#CCD0DA",
"info": "#1e66f5",
"info.background": "#dce0e8",
"info.border": "#1e66f5",
"modified": "#df8e1d",
"modified.background": "#dce0e8",
"modified.border": "#df8e1d",
"predictive": "#9a9db2",
"predictive.background": "#EFF1F5",
"predictive.border": "#CCD0DA",
"renamed": "#9978dc",
"renamed.background": "#dce0e8",
"renamed.border": "#9978dc",
"success": "#85dc78",
"success.background": "#dce0e8",
"success.border": "#85dc78",
"unreachable": "#acb0be",
"unreachable.background": "#EFF1F5",
"unreachable.border": "#CCD0DA",
"warning": "#df8e1d",
"warning.background": "#f2d5cf",
"warning.border": "#df8e1d",
"syntax": {
"variable": {
"color": "#4c4f69"
@ -486,22 +458,13 @@
"editor.active_line_number": "#c6d0f5",
"conflict": "#e78284",
"created": "#a6d189",
"created.background": "#2e3b2e",
"deleted.background": "#3b2e2e",
"error.background": "#3b2e2e",
"error.border": "#7b2e2e",
"deleted": "#3b2e2e",
"error": "#3b2e2e",
"hidden": "#51576d",
"hint": "#8caaee",
"hint.background": "#1e2030",
"hint.border": "#3b4b91",
"info.background": "#1e2b4d",
"info.border": "#2e3b91",
"info": "#1e2b4d",
"modified": "#e7d682",
"modified.background": "#3a2f1e",
"predictive": "#51576d",
"success.background": "#2e3b2e",
"warning.background": "#3a2f1e",
"warning.border": "#7b6b2e",
"syntax": {
"attribute": {
"color": "#e7d682"
@ -637,48 +600,21 @@
"editor.active_line.background": "#363a4f",
"editor.line_number": "#b8c0e0",
"editor.active_line_number": "#cad3f5",
"conflict": "#ed8796",
"conflict.background": "#362a2e",
"conflict.border": "#ed8796",
"created": "#a6da95",
"created.background": "#2a3b2e",
"created.border": "#a6da95",
"deleted": "#ed8796",
"deleted.background": "#3b2a2e",
"deleted.border": "#ed8796",
"error": "#ed8796",
"error.background": "#3b2a2e",
"error.border": "#ed8796",
"hidden": "#b8c0e0",
"hidden.background": "#24273a",
"hidden.border": "#494d64",
"hint": "#8aadf4",
"hint.background": "#1e2030",
"hint.border": "#8aadf4",
"ignored": "#494d64",
"ignored.background": "#24273a",
"ignored.border": "#494d64",
"info": "#8aadf4",
"info.background": "#1e2030",
"info.border": "#8aadf4",
"modified": "#eed49f",
"modified.background": "#3a2f1e",
"modified.border": "#eed49f",
"predictive": "#b8c0e0",
"predictive.background": "#24273a",
"predictive.border": "#494d64",
"renamed": "#f5bde6",
"renamed.background": "#3a2f3e",
"renamed.border": "#f5bde6",
"success": "#a6da95",
"success.background": "#2a3b2e",
"success.border": "#a6da95",
"unreachable": "#b8c0e0",
"unreachable.background": "#24273a",
"unreachable.border": "#494d64",
"warning": "#eed49f",
"warning.background": "#3a2f1e",
"warning.border": "#eed49f",
"syntax": {
"attribute": {
"color": "#eed49f"
@ -818,47 +754,19 @@
"editor.line_number": "#6c7086",
"editor.active_line_number": "#cdd6f4",
"conflict": "#f38ba8",
"conflict.background": "#3b2a2e",
"conflict.border": "#f38ba8",
"created": "#a6e3a1",
"created.background": "#2a3b2e",
"created.border": "#a6e3a1",
"deleted": "#f38ba8",
"deleted.background": "#3b2a2e",
"deleted.border": "#f38ba8",
"error": "#f38ba8",
"error.background": "#3b2a2e",
"error.border": "#f38ba8",
"hidden": "#6c7086",
"hidden.background": "#181825",
"hidden.border": "#313244",
"hint": "#89b4fa",
"hint.background": "#181825",
"hint.border": "#89b4fa",
"ignored": "#6c7086",
"ignored.background": "#181825",
"ignored.border": "#313244",
"info": "#89b4fa",
"info.background": "#181825",
"info.border": "#89b4fa",
"modified": "#f9e2af",
"modified.background": "#3a2f1e",
"modified.border": "#f9e2af",
"predictive": "#6c7086",
"predictive.background": "#181825",
"predictive.border": "#313244",
"renamed": "#f5c2e7",
"renamed.background": "#3a2f3e",
"renamed.border": "#f5c2e7",
"success": "#a6e3a1",
"success.background": "#2a3b2e",
"success.border": "#a6e3a1",
"unreachable": "#6c7086",
"unreachable.background": "#181825",
"unreachable.border": "#313244",
"warning": "#f9e2af",
"warning.background": "#3a2f1e",
"warning.border": "#f9e2af",
"syntax": {
"attribute": {
"color": "#f9e2af"

View file

@ -67,39 +67,19 @@
"editor.line_number": "#959a9d",
"editor.active_line_number": "#5F6D75",
"conflict": "#e67e80",
"conflict.background": "#f4e4e4",
"conflict.border": "#e67e80",
"created": "#a7c080",
"created.background": "#eaf4e4",
"created.border": "#a7c080",
"deleted": "#e67e80",
"deleted.background": "#f4e4e4",
"deleted.border": "#e67e80",
"error": "#e67e80",
"error.background": "#f4e4e4",
"error.border": "#e67e80",
"hidden": "#959a9d",
"hint": "#7fbbb3",
"hint.background": "#e0f4f4",
"hint.border": "#7fbbb3",
"ignored": "#959a9d",
"info": "#7fbbb3",
"info.background": "#e0f4f4",
"info.border": "#7fbbb3",
"modified": "#dbbc7f",
"modified.background": "#f9f4e4",
"modified.border": "#dbbc7f",
"predictive": "#5F6D75",
"renamed": "#a7c080",
"renamed.background": "#eaf4e4",
"renamed.border": "#a7c080",
"success": "#a7c080",
"success.background": "#eaf4e4",
"success.border": "#a7c080",
"unreachable": "#959a9d",
"warning": "#dbbc7f",
"warning.background": "#f9f4e4",
"warning.border": "#dbbc7f",
"syntax": {
"attribute": {
"color": "#dbbc7f"
@ -240,22 +220,10 @@
"editor.active_line_number": "#DDDDDD",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"

142
themes/fahrenheit.json Normal file
View file

@ -0,0 +1,142 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Fahrenheit",
"author": "iTerm2-Color-Schemes",
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes",
"themes": [
{
"name": "Fahrenheit",
"mode": "dark",
"colors": {
"accent.background": "#171717",
"accent.foreground": "#dcdcdc",
"accordion.active.background": "#1e1e1e",
"accordion.background": "#2e2e2e",
"accordion.hover.background": "#3e3e3e",
"background": "#000000",
"border": "#444444",
"card.background": "#090909",
"card.foreground": "#dcdcdc",
"danger.background": "#593002",
"danger.active.background": "#4b2901",
"danger.hover.background": "#593002AA",
"foreground": "#FFFFCE",
"input.border": "#3e3e3e",
"list.active.background": "#21010122",
"list.active.border": "#720202",
"list.hover.background": "#111111",
"muted.background": "#2e2e2e",
"muted.foreground": "#828282",
"panel.background": "#1e1e1e",
"popover.background": "#090909",
"popover.foreground": "#dcdcdc",
"primary.active.background": "#570101",
"primary.background": "#720202",
"primary.foreground": "#FFFFCE",
"primary.hover.background": "#720202AA",
"scrollbar.background": "#1e1e1e00",
"scrollbar.thumb.background": "#3e3e3e",
"secondary.background": "#202020",
"secondary.active.background": "#20202099",
"secondary.foreground": "#979797",
"secondary.hover.background": "#202020EE",
"tab.foreground": "#808080",
"table.background": "#1e1e1e00",
"table.hover.background": "#1E1E1E",
"base.red": "#720202",
"base.red.light": "#c93636",
"base.green": "#047202",
"base.green.light": "#39c936",
"base.yellow": "#726302",
"base.yellow.light": "#c9b536",
"base.blue": "#022d72",
"base.blue.light": "#0551cb",
"base.magenta": "#5d0272",
"base.magenta.light": "#ae36c9",
"base.cyan": "#027272",
"base.cyan.light": "#36c9c9"
},
"highlight": {
"editor.foreground": "#FFFFCE",
"editor.background": "#000000",
"editor.active_line.background": "#1e1e1e",
"editor.line_number": "#828282",
"warning.border": "#720202",
"syntax": {
"attribute": {
"color": "#fecf75"
},
"boolean": {
"color": "#fd9f4d"
},
"comment": {
"color": "#828282"
},
"comment.doc": {
"color": "#828282"
},
"constant": {
"color": "#fd9f4d"
},
"constructor": {
"color": "#cb4a05"
},
"embedded": {
"color": "#dcdcdc"
},
"function": {
"color": "#fd9f4d"
},
"keyword": {
"color": "#cb4a05"
},
"link_text": {
"color": "#cda074",
"font_style": "normal"
},
"link_uri": {
"color": "#9e744d",
"font_style": "italic"
},
"number": {
"color": "#cb4a05"
},
"string": {
"color": "#cc734d"
},
"string.escape": {
"color": "#cc734d"
},
"string.regex": {
"color": "#cc734d"
},
"string.special": {
"color": "#fd9f4d"
},
"string.special.symbol": {
"color": "#fd9f4d"
},
"tag": {
"color": "#cb4a05"
},
"text.literal": {
"color": "#fd9f4d"
},
"title": {
"color": "#cda074",
"font_weight": 600
},
"type": {
"color": "#cda074"
},
"property": {
"color": "#dcdcdc"
},
"variable.special": {
"color": "#cb4a05"
}
}
}
}
]
}

View file

@ -66,47 +66,19 @@
"editor.line_number": "#928374",
"editor.active_line_number": "#3c3836",
"conflict": "#cc241d",
"conflict.background": "#fdeeee",
"conflict.border": "#9d0006",
"created": "#79740e",
"created.background": "#f2e5bc",
"created.border": "#b57614",
"deleted": "#9d0006",
"deleted.background": "#ffe9e9",
"deleted.border": "#cc241d",
"error": "#cc241d",
"error.background": "#fdeeee",
"error.border": "#9d0006",
"hidden": "#928374",
"hidden.background": "#ebdbb2",
"hidden.border": "#d5c4a1",
"hint": "#458588",
"hint.background": "#ebdbb2",
"hint.border": "#076678",
"ignored": "#928374",
"ignored.background": "#ebdbb2",
"ignored.border": "#d5c4a1",
"info": "#458588",
"info.background": "#cdf4fc",
"info.border": "#076678",
"modified": "#b57614",
"modified.background": "#f2e5bc",
"modified.border": "#d79921",
"predictive": "#928374",
"predictive.background": "#ebdbb2",
"predictive.border": "#d5c4a1",
"renamed": "#b57614",
"renamed.background": "#f2e5bc",
"renamed.border": "#d79921",
"success": "#79740e",
"success.background": "#f2e5bc",
"success.border": "#b57614",
"unreachable": "#928374",
"unreachable.background": "#ebdbb2",
"unreachable.border": "#d5c4a1",
"warning": "#d79921",
"warning.background": "#f2e5bc",
"warning.border": "#b57614",
"syntax": {
"attribute": {
"color": "#b57614"
@ -245,47 +217,19 @@
"editor.line_number": "#8F8F8F",
"editor.active_line_number": "#DDDDDD",
"conflict": "#f06555",
"conflict.background": "#3a1010",
"conflict.border": "#9d0006",
"created": "#3f72e2",
"created.background": "#3a2a15",
"created.border": "#b57614",
"deleted": "#9d0006",
"deleted.background": "#3a1010",
"deleted.border": "#cc241d",
"error": "#cc241d",
"error.background": "#3a1010",
"error.border": "#9d0006",
"hidden": "#9E9E9E",
"hidden.background": "#3a3229",
"hidden.border": "#d5c4a1",
"hint": "#b283f8",
"hint.background": "#150820",
"hint.border": "#3f0891",
"ignored": "#928374",
"ignored.background": "#3a3229",
"ignored.border": "#d5c4a1",
"info": "#458588",
"info.background": "#0b0f1a",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3a2f15",
"modified.border": "#d79921",
"predictive": "#5D5945",
"predictive.background": "#3a3229",
"predictive.border": "#d5c4a1",
"renamed": "#b57614",
"renamed.background": "#3a2f15",
"renamed.border": "#d79921",
"success": "#79740e",
"success.background": "#2a1a15",
"success.border": "#b57614",
"unreachable": "#928374",
"unreachable.background": "#3a3229",
"unreachable.border": "#d5c4a1",
"warning": "#d79921",
"warning.background": "#2a1a15",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"

View file

@ -60,47 +60,19 @@
"editor.line_number": "#726E69",
"editor.active_line_number": "#a8a49d",
"conflict": "#ff5874",
"conflict.background": "#18151B",
"conflict.border": "#ff5874",
"created": "#489e48",
"created.background": "#18151B",
"created.border": "#489e48",
"deleted": "#ff5874",
"deleted.background": "#18151B",
"deleted.border": "#ff5874",
"error": "#ff5874",
"error.background": "#18151B",
"error.border": "#ff5874",
"hidden": "#726E69",
"hidden.background": "#18151B",
"hidden.border": "#333333",
"hint": "#7fb5e1",
"hint.background": "#18151B",
"hint.border": "#7fb5e1",
"ignored": "#726E69",
"ignored.background": "#18151B",
"ignored.border": "#333333",
"info": "#7fb5e1",
"info.background": "#18151B",
"info.border": "#7fb5e1",
"modified": "#b296c6",
"modified.background": "#18151B",
"modified.border": "#b296c6",
"predictive": "#726E69",
"predictive.background": "#18151B",
"predictive.border": "#333333",
"renamed": "#b296c6",
"renamed.background": "#18151B",
"renamed.border": "#b296c6",
"success": "#489e48",
"success.background": "#18151B",
"success.border": "#489e48",
"unreachable": "#726E69",
"unreachable.background": "#18151B",
"unreachable.border": "#333333",
"warning": "#f8b63f",
"warning.background": "#18151B",
"warning.border": "#f8b63f",
"syntax": {
"attribute": {
"color": "#b296c6"

View file

@ -66,47 +66,19 @@
"editor.line_number": "#5F5F5F",
"editor.active_line_number": "#1C1C1C",
"conflict": "#D2602D",
"conflict.background": "#FFE4E1",
"conflict.border": "#FF7F7F",
"created": "#3F72E2",
"created.background": "#E0F7E4",
"created.border": "#A0D7A0",
"deleted": "#FF5F5F",
"deleted.background": "#FFE4E1",
"deleted.border": "#FF7F7F",
"error": "#FF5F5F",
"error.background": "#FFE4E1",
"error.border": "#FF7F7F",
"hidden": "#9E9E9E",
"hidden.background": "#E8E8E8",
"hidden.border": "#CACACA",
"hint": "#5F87AF",
"hint.background": "#D4E2E2",
"hint.border": "#A0C4C4",
"ignored": "#B3B3B3",
"ignored.background": "#F7F7F7",
"ignored.border": "#D0D0D0",
"info": "#005F87",
"info.background": "#D4E2E2",
"info.border": "#A0C4C4",
"modified": "#B0A878",
"modified.background": "#F7F3E0",
"modified.border": "#D0C4A0",
"predictive": "#5D5945",
"predictive.background": "#F7F7F7",
"predictive.border": "#D0D0D0",
"renamed": "#5F87AF",
"renamed.background": "#D4E2E2",
"renamed.border": "#A0C4C4",
"success": "#005F00",
"success.background": "#E4F7E4",
"success.border": "#A0D7A0",
"unreachable": "#9E9E9E",
"unreachable.background": "#F7F7F7",
"unreachable.border": "#D0D0D0",
"warning": "#948000",
"warning.background": "#FFF7E0",
"warning.border": "#D7C490",
"syntax": {
"attribute": {
"color": "#948000"

View file

@ -72,22 +72,10 @@
"editor.active_line_number": "#DDDDDD",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Kibble",
"author": "iTerm2-Color-Schemes",
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes",
@ -62,47 +63,19 @@
"editor.line_number": "#726E69",
"editor.active_line_number": "#f7f7f7",
"conflict": "#c70031",
"conflict.background": "#0e100a",
"conflict.border": "#e00038",
"created": "#2BCF13",
"created.background": "#0e100a",
"created.border": "#6ce05c",
"deleted": "#c70031",
"deleted.background": "#0e100a",
"deleted.border": "#e00038",
"error": "#c70031",
"error.background": "#0e100a",
"error.border": "#e00038",
"hidden": "#726E69",
"hidden.background": "#242223",
"hidden.border": "#333333",
"hint": "#0798ab",
"hint.background": "#242223",
"hint.border": "#68f2e0",
"ignored": "#726E69",
"ignored.background": "#242223",
"ignored.border": "#333333",
"info": "#0798ab",
"info.background": "#242223",
"info.border": "#68f2e0",
"modified": "#3449d1",
"modified.background": "#0e100a",
"modified.border": "#4457d5",
"predictive": "#726E69",
"predictive.background": "#242223",
"predictive.border": "#333333",
"renamed": "#3449d1",
"renamed.background": "#0e100a",
"renamed.border": "#4457d5",
"success": "#2BCF13",
"success.background": "#0e100a",
"success.border": "#6ce05c",
"unreachable": "#726E69",
"unreachable.background": "#242223",
"unreachable.border": "#333333",
"warning": "#c7a302",
"warning.background": "#0e100a",
"warning.border": "#f3f79e",
"syntax": {
"attribute": {
"color": "#3449d1"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "macOS Classic",
"author": "huacnlee",
"url": "https://github.com/huacnlee/zed-theme-macos-classic",
@ -70,23 +71,11 @@
"editor.active_line_number": "#000000",
"conflict": "#C5060B",
"created": "#1642FF",
"created.background": "#e5ffe9",
"deleted.background": "#FBEAE5",
"error.background": "#FBEAE5",
"error.border": "#EC9F89",
"hidden": "#6D6D6D",
"hint": "#9e5dff",
"hint.background": "#ece6ff",
"hint.border": "#bc8fff",
"info.background": "#E5EAFF",
"info.border": "#8DA1FF",
"modified": "#9e7008",
"modified.background": "#fff2e5",
"predictive": "#A4ABB6",
"success.background": "#E5FFE5",
"warning": "#C99401",
"warning.background": "#FFFBE5",
"warning.border": "#D9CC89",
"syntax": {
"attribute": {
"color": "#957931"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Mandarin Square",
"author": "huacnlee",
"url": "https://en.wikipedia.org/wiki/Mandarin_square",
@ -65,47 +66,19 @@
"editor.line_number": "#928374",
"editor.active_line_number": "#ebdbb2",
"conflict": "#cc241d",
"conflict.background": "#3c3836",
"conflict.border": "#9d0006",
"created": "#7c6f64",
"created.background": "#504945",
"created.border": "#b57614",
"deleted": "#9d0006",
"deleted.background": "#3c3836",
"deleted.border": "#cc241d",
"error": "#cc241d",
"error.background": "#3c3836",
"error.border": "#9d0006",
"hidden": "#928374",
"hidden.background": "#504945",
"hidden.border": "#665c54",
"hint": "#83a598",
"hint.background": "#504945",
"hint.border": "#076678",
"ignored": "#928374",
"ignored.background": "#504945",
"ignored.border": "#665c54",
"info": "#83a598",
"info.background": "#504945",
"info.border": "#076678",
"modified": "#b57614",
"modified.background": "#504945",
"modified.border": "#d79921",
"predictive": "#928374",
"predictive.background": "#504945",
"predictive.border": "#665c54",
"renamed": "#b57614",
"renamed.background": "#504945",
"renamed.border": "#d79921",
"success": "#7c6f64",
"success.background": "#504945",
"success.border": "#b57614",
"unreachable": "#928374",
"unreachable.background": "#504945",
"unreachable.border": "#665c54",
"warning": "#d79921",
"warning.background": "#504945",
"warning.border": "#b57614",
"syntax": {
"attribute": {
"color": "#d79921"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Matrix",
"author": "iruzo",
"url": "https://github.com/iruzo/matrix-nvim",
@ -67,47 +68,19 @@
"editor.line_number": "#007700",
"editor.active_line_number": "#00FF00",
"conflict": "#FF0000",
"conflict.background": "#0D0208",
"conflict.border": "#12410E",
"created": "#82d967",
"created.background": "#001900",
"created.border": "#156B12",
"deleted": "#FF0000",
"deleted.background": "#0D0208",
"deleted.border": "#12410E",
"error": "#FF0000",
"error.background": "#0D0208",
"error.border": "#12410E",
"hidden": "#007700",
"hidden.background": "#001900",
"hidden.border": "#12410E",
"hint": "#3fd43a",
"hint.background": "#001900",
"hint.border": "#156B12",
"ignored": "#007700",
"ignored.background": "#001900",
"ignored.border": "#12410E",
"info": "#3fd43a",
"info.background": "#001900",
"info.border": "#156B12",
"modified": "#82d967",
"modified.background": "#001900",
"modified.border": "#156B12",
"predictive": "#007700",
"predictive.background": "#001900",
"predictive.border": "#12410E",
"renamed": "#82d967",
"renamed.background": "#001900",
"renamed.border": "#156B12",
"success": "#82d967",
"success.background": "#001900",
"success.border": "#156B12",
"unreachable": "#007700",
"unreachable.background": "#001900",
"unreachable.border": "#12410E",
"warning": "#ffd700",
"warning.background": "#001900",
"warning.border": "#156B12",
"syntax": {
"attribute": {
"color": "#82d967"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Mellifluous",
"author": "Ramojus Lapinskas",
"url": "https://github.com/ramojus/mellifluous.nvim",
@ -66,47 +67,19 @@
"editor.line_number": "#727272",
"editor.active_line_number": "#383a42",
"conflict": "#e06c75",
"conflict.background": "#E7E7E7",
"conflict.border": "#be5046",
"created": "#828040",
"created.background": "#F0F0F0",
"created.border": "#929292",
"deleted": "#be5046",
"deleted.background": "#E7E7E7",
"deleted.border": "#e06c75",
"error": "#e06c75",
"error.background": "#E7E7E7",
"error.border": "#be5046",
"hidden": "#727272",
"hidden.background": "#d5d5d5",
"hidden.border": "#cacaca",
"hint": "#5A6599",
"hint.background": "#d5d5d5",
"hint.border": "#626ca2",
"ignored": "#727272",
"ignored.background": "#d5d5d5",
"ignored.border": "#cacaca",
"info": "#5A6599",
"info.background": "#d5d5d5",
"info.border": "#626ca2",
"modified": "#727272",
"modified.background": "#F0F0F0",
"modified.border": "#cacaca",
"predictive": "#727272",
"predictive.background": "#d5d5d5",
"predictive.border": "#cacaca",
"renamed": "#727272",
"renamed.background": "#F0F0F0",
"renamed.border": "#cacaca",
"success": "#828040",
"success.background": "#F0F0F0",
"success.border": "#727272",
"unreachable": "#727272",
"unreachable.background": "#d5d5d5",
"unreachable.border": "#cacaca",
"warning": "#cbaa89",
"warning.background": "#F0F0F0",
"warning.border": "#727272",
"syntax": {
"attribute": {
"color": "#727272"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Molokai",
"author": "Tomas Restrepo",
"url": "https://github.com/tomasr/molokai",
@ -59,47 +60,19 @@
"editor.line_number": "#767676",
"editor.active_line_number": "#0a0a0a",
"conflict": "#e14775",
"conflict.background": "#FEFAF9",
"conflict.border": "#E4DEDA",
"created": "#269D69",
"created.background": "#E4DEDA",
"created.border": "#ADADB0",
"deleted": "#e14775",
"deleted.background": "#FEFAF9",
"deleted.border": "#E4DEDA",
"error": "#e14775",
"error.background": "#FEFAF9",
"error.border": "#E4DEDA",
"hidden": "#767676",
"hidden.background": "#FEFAF9",
"hidden.border": "#E4DEDA",
"hint": "#7058be",
"hint.background": "#E4DEDA",
"hint.border": "#ADADB0",
"ignored": "#767676",
"ignored.background": "#FEFAF9",
"ignored.border": "#E4DEDA",
"info": "#1c8ca8",
"info.background": "#E4DEDA",
"info.border": "#ADADB0",
"modified": "#cc7a0a",
"modified.background": "#E4DEDA",
"modified.border": "#ADADB0",
"predictive": "#ADADB0",
"predictive.background": "#FEFAF9",
"predictive.border": "#E4DEDA",
"renamed": "#E14774",
"renamed.background": "#FEFAF9",
"renamed.border": "#E4DEDA",
"success": "#269D69",
"success.background": "#E4DEDA",
"success.border": "#ADADB0",
"unreachable": "#767676",
"unreachable.background": "#FEFAF9",
"unreachable.border": "#E4DEDA",
"warning": "#cc7a0a",
"warning.background": "#E4DEDA",
"warning.border": "#ADADB0",
"syntax": {
"attribute": {
"color": "#e14775"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Solarized",
"author": "Ethan Schoonover",
"url": "https://ethanschoonover.com/solarized",
@ -74,47 +75,19 @@
"editor.line_number": "#93A1A1",
"editor.active_line_number": "#073642",
"conflict": "#DC322F",
"conflict.background": "#FDF6E3",
"conflict.border": "#CB4B16",
"created": "#859900",
"created.background": "#FDF6E3",
"created.border": "#586E75",
"deleted": "#DC322F",
"deleted.background": "#FDF6E3",
"deleted.border": "#CB4B16",
"error": "#DC322F",
"error.background": "#FDF6E3",
"error.border": "#CB4B16",
"hidden": "#93A1A1",
"hidden.background": "#FDF6E3",
"hidden.border": "#DCD4BC",
"hint": "#2AA198",
"hint.background": "#EEE8D5",
"hint.border": "#586E75",
"ignored": "#93A1A1",
"ignored.background": "#FDF6E3",
"ignored.border": "#DCD4BC",
"info": "#268BD2",
"info.background": "#FDF6E3",
"info.border": "#586E75",
"modified": "#B58900",
"modified.background": "#FDF6E3",
"modified.border": "#657B83",
"predictive": "#586E75",
"predictive.background": "#FDF6E3",
"predictive.border": "#DCD4BC",
"renamed": "#2AA198",
"renamed.background": "#FDF6E3",
"renamed.border": "#586E75",
"success": "#859900",
"success.background": "#FDF6E3",
"success.border": "#586E75",
"unreachable": "#DC322F",
"unreachable.background": "#FDF6E3",
"unreachable.border": "#CB4B16",
"warning": "#B58900",
"warning.background": "#FDF6E3",
"warning.border": "#657B83",
"syntax": {
"attribute": {
"color": "#B58900"

View file

@ -2,6 +2,7 @@
"name": "Spaceduck",
"author": "Guillermo Rodriguez",
"url": "https://github.com/pineapplegiant/spaceduck",
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"themes": [
{
"name": "Spaceduck",
@ -59,47 +60,19 @@
"editor.line_number": "#4b6479",
"editor.active_line_number": "#ecf0c1",
"conflict": "#e33400",
"conflict.background": "#46190C",
"conflict.border": "#e33400",
"created": "#5ccc96",
"created.background": "#0C4619",
"created.border": "#5ccc96",
"deleted": "#e33400",
"deleted.background": "#46190C",
"deleted.border": "#e33400",
"error": "#e33400",
"error.background": "#46190C",
"error.border": "#e33400",
"hidden": "#4b6479",
"hidden.background": "#0F111B",
"hidden.border": "#272C42",
"hint": "#C86D8C",
"hint.background": "#250c4b",
"hint.border": "#C86D8C",
"ignored": "#4b6479",
"ignored.background": "#0F111B",
"ignored.border": "#272C42",
"info": "#089CC5",
"info.background": "#0C194D",
"info.border": "#089CC5",
"modified": "#f2ce00",
"modified.background": "#3A310E",
"modified.border": "#f2ce00",
"predictive": "#5D5945",
"predictive.background": "#1a1b33",
"predictive.border": "#5D5945",
"renamed": "#089CC5",
"renamed.background": "#003a5b",
"renamed.border": "#089CC5",
"success": "#5ccc96",
"success.background": "#0C4619",
"success.border": "#5ccc96",
"unreachable": "#4b6479",
"unreachable.background": "#0F111B",
"unreachable.border": "#272C42",
"warning": "#f2ce00",
"warning.background": "#3A310E",
"warning.border": "#f2ce00",
"syntax": {
"attribute": {
"color": "#f2ce00"

View file

@ -2,6 +2,7 @@
"name": "Tokyo",
"author": "Folke Lemaitre",
"url": "https://github.com/folke/tokyonight.nvim",
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"themes": [
{
"name": "Tokyo Night",
@ -63,47 +64,19 @@
"editor.line_number": "#565f89",
"editor.active_line_number": "#c0caf5",
"conflict": "#f7768e",
"conflict.background": "#2C3045",
"conflict.border": "#7aa2f7",
"created": "#9ece6a",
"created.background": "#1a1b26",
"created.border": "#414868",
"deleted": "#f7768e",
"deleted.background": "#292e42",
"deleted.border": "#7aa2f7",
"error": "#f7768e",
"error.background": "#292e42",
"error.border": "#7aa2f7",
"hidden": "#565f89",
"hidden.background": "#1a1b26",
"hidden.border": "#292e42",
"hint": "#7dcfff",
"hint.background": "#1a1b26",
"hint.border": "#414868",
"ignored": "#565f89",
"ignored.background": "#1a1b26",
"ignored.border": "#292e42",
"info": "#7aa2f7",
"info.background": "#1a1b26",
"info.border": "#414868",
"modified": "#e0af68",
"modified.background": "#292e42",
"modified.border": "#7aa2f7",
"predictive": "#565f89",
"predictive.background": "#1a1b26",
"predictive.border": "#292e42",
"renamed": "#7aa2f7",
"renamed.background": "#1a1b26",
"renamed.border": "#414868",
"success": "#9ece6a",
"success.background": "#1a1b26",
"success.border": "#414868",
"unreachable": "#565f89",
"unreachable.background": "#1a1b26",
"unreachable.border": "#292e42",
"warning": "#e0af68",
"warning.background": "#292e42",
"warning.border": "#7aa2f7",
"syntax": {
"attribute": {
"color": "#e0af68"
@ -242,22 +215,14 @@
"editor.active_line_number": "#B0B9E2",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"deleted": "#f7768e",
"error": "#f7768e",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"success": "#9ece6a",
"warning": "#e0af68",
"syntax": {
"attribute": {
"color": "#be9a52"
@ -395,47 +360,19 @@
"editor.line_number": "#6e738d",
"editor.active_line_number": "#c0caf5",
"conflict": "#ed8796",
"conflict.background": "#2d3149",
"conflict.border": "#82aaff",
"created": "#c3e88d",
"created.background": "#222436",
"created.border": "#444b6a",
"deleted": "#ed8796",
"deleted.background": "#2d3149",
"deleted.border": "#82aaff",
"error": "#ed8796",
"error.background": "#2d3149",
"error.border": "#82aaff",
"hidden": "#6e738d",
"hidden.background": "#222436",
"hidden.border": "#2d3149",
"hint": "#86e1fc",
"hint.background": "#222436",
"hint.border": "#444b6a",
"ignored": "#6e738d",
"ignored.background": "#222436",
"ignored.border": "#2d3149",
"info": "#82aaff",
"info.background": "#222436",
"info.border": "#444b6a",
"modified": "#ffc777",
"modified.background": "#2d3149",
"modified.border": "#82aaff",
"predictive": "#6e738d",
"predictive.background": "#222436",
"predictive.border": "#2d3149",
"renamed": "#82aaff",
"renamed.background": "#222436",
"renamed.border": "#444b6a",
"success": "#c3e88d",
"success.background": "#222436",
"success.border": "#444b6a",
"unreachable": "#6e738d",
"unreachable.background": "#222436",
"unreachable.border": "#2d3149",
"warning": "#ffc777",
"warning.background": "#2d3149",
"warning.border": "#82aaff",
"syntax": {
"attribute": {
"color": "#ffc777"

View file

@ -1,4 +1,5 @@
{
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
"name": "Twilight",
"author": "MacroMates",
"url": "https://macromates.com",
@ -67,22 +68,10 @@
"editor.active_line_number": "#DDDDDD",
"conflict": "#D2602D",
"created": "#3f72e2",
"created.background": "#0C4619",
"deleted.background": "#46190C",
"error.background": "#46190C",
"error.border": "#802207",
"hidden": "#9E9E9E",
"hint": "#b283f8",
"hint.background": "#250c4b",
"hint.border": "#3f0891",
"info.background": "#0C194D",
"info.border": "#082190",
"modified": "#B0A878",
"modified.background": "#3A310E",
"predictive": "#5D5945",
"success.background": "#0C4619",
"warning.background": "#3A310E",
"warning.border": "#7B6508",
"syntax": {
"attribute": {
"color": "#be9a52"