theme: Export more theme options for schema. (#1442)

- Fix theme switch to support other UI settings (e.g.: radius, shadow,
font_size).
- Update `matrix` theme to use rounded 0px.

<img width="1380" height="1139" alt="image"
src="https://github.com/user-attachments/assets/24832fde-5b5e-4508-9b38-6c3c2890aedb"
/>
This commit is contained in:
Jason Lee 2025-10-28 11:28:18 +08:00 committed by GitHub
parent cc0f936348
commit 904c9f3fa7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 85 additions and 18 deletions

View file

@ -25,6 +25,26 @@
"format": "float",
"default": null
},
"font.family": {
"description": "The base font family, default is system font: `.SystemUIFont`.",
"type": ["string", "null"],
"default": null
},
"radius": {
"description": "The border radius for general elements, default is 6.",
"type": ["number", "null"],
"default": null
},
"radius.lg": {
"description": "The border radius for large elements like Modals and Notifications, default is 8.",
"type": ["number", "null"],
"default": null
},
"shadow": {
"description": "Set shadows in the theme, for example the Input and Button, default is true.",
"type": ["boolean", "null"],
"default": null
},
"themes": {
"type": "array",
"items": {

View file

@ -413,7 +413,7 @@ impl Styled for StorySection {
}
impl RenderOnce for StorySection {
fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
GroupBox::new()
.outline()
.title(
@ -426,7 +426,7 @@ impl RenderOnce for StorySection {
)
.content_style(
StyleRefinement::default()
.rounded_lg()
.rounded(cx.theme().radius_lg)
.overflow_x_hidden()
.items_center()
.justify_center(),

View file

@ -214,8 +214,10 @@ impl Render for Gallery {
.child(
div()
.bg(cx.theme().sidebar_accent)
.px_1()
.rounded_full()
.when(cx.theme().radius.is_zero(), |this| {
this.rounded(px(0.))
})
.flex_1()
.mx_1()
.child(

View file

@ -9,8 +9,8 @@ use crate::{ActiveTheme, AxisExt};
use gpui::{
fill, point, px, relative, size, App, Axis, BorderStyle, Bounds, ContentMask, Corner,
CursorStyle, Edges, Element, GlobalElementId, Hitbox, HitboxBehavior, Hsla, InspectorElementId,
IntoElement, LayoutId, ListState, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
Pixels, Point, Position, ScrollHandle, ScrollWheelEvent, Size, Style, Timer,
IntoElement, IsZero, LayoutId, ListState, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
PaintQuad, Pixels, Point, Position, ScrollHandle, ScrollWheelEvent, Size, Style, Timer,
UniformListScrollHandle, Window,
};
use schemars::JsonSchema;
@ -728,7 +728,10 @@ impl Element for Scrollbar {
|window| {
for state in prepaint.states.iter() {
let axis = state.axis;
let radius = state.radius;
let mut radius = state.radius;
if cx.theme().radius.is_zero() {
radius = px(0.);
}
let bounds = state.bounds;
let thumb_bounds = state.thumb_bounds;
let scroll_area_size = state.scroll_size;

View file

@ -64,7 +64,7 @@ pub struct Theme {
impl Default for Theme {
fn default() -> Self {
Self::from(ThemeColor::default())
Self::from(&ThemeColor::default())
}
}
@ -181,8 +181,8 @@ impl Theme {
}
}
impl From<ThemeColor> for Theme {
fn from(colors: ThemeColor) -> Self {
impl From<&ThemeColor> for Theme {
fn from(colors: &ThemeColor) -> Self {
Theme {
mode: ThemeMode::default(),
transparent: Hsla::transparent_black(),
@ -201,7 +201,7 @@ impl From<ThemeColor> for Theme {
tile_grid_size: px(8.),
tile_shadow: true,
tile_radius: px(0.),
colors,
colors: *colors,
light_theme: Rc::new(ThemeConfig::default()),
dark_theme: Rc::new(ThemeConfig::default()),
highlight_theme: HighlightTheme::default_light(),

View file

@ -1,7 +1,7 @@
use std::{rc::Rc, sync::Arc};
use anyhow::Result;
use gpui::{Hsla, SharedString};
use gpui::{px, Hsla, SharedString};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@ -21,10 +21,6 @@ pub struct ThemeSet {
/// The URL of the theme.
pub url: Option<SharedString>,
/// The base font size, default is 16.
#[serde(rename = "font.size")]
pub font_size: Option<f32>,
#[serde(rename = "themes")]
pub themes: Vec<ThemeConfig>,
}
@ -38,6 +34,24 @@ pub struct ThemeConfig {
pub name: SharedString,
/// The mode of the theme, default is light.
pub mode: ThemeMode,
/// The base font size, default is 16.
#[serde(rename = "font.size")]
pub font_size: Option<f32>,
/// The base font family, default is system font: `.SystemUIFont`.
#[serde(rename = "font.family")]
pub font_family: Option<SharedString>,
/// The border radius for general elements, default is 6.
#[serde(rename = "radius")]
pub radius: Option<usize>,
/// The border radius for large elements like Modals and Notifications, default is 8.
#[serde(rename = "radius.lg")]
pub radius_lg: Option<usize>,
/// Set shadows in the theme, for example the Input and Button, default is true.
#[serde(rename = "shadow")]
pub shadow: Option<bool>,
/// The colors of the theme.
pub colors: ThemeConfigColors,
/// The highlight theme, this part is combilbility with `style` section in Zed theme.
@ -623,12 +637,38 @@ impl Theme {
}
let default_theme = if config.mode.is_dark() {
ThemeColor::dark()
Self::from(ThemeColor::dark().as_ref())
} else {
ThemeColor::light()
Self::from(ThemeColor::light().as_ref())
};
self.colors.apply_config(&config, &default_theme);
if let Some(font_size) = config.font_size {
self.font_size = px(font_size);
} else {
self.font_size = default_theme.font_size;
}
if let Some(font_family) = &config.font_family {
self.font_family = font_family.clone();
} else {
self.font_family = default_theme.font_family.clone();
}
if let Some(radius) = config.radius {
self.radius = px(radius as f32);
} else {
self.radius = default_theme.radius;
}
if let Some(radius_lg) = config.radius_lg {
self.radius_lg = px(radius_lg as f32);
} else {
self.radius_lg = default_theme.radius_lg;
}
if let Some(shadow) = config.shadow {
self.shadow = shadow;
} else {
self.shadow = default_theme.shadow;
}
self.colors.apply_config(&config, &default_theme.colors);
self.mode = config.mode;
}
}

View file

@ -7,6 +7,8 @@
{
"name": "Matrix",
"mode": "dark",
"radius": 0,
"radius.lg": 0,
"colors": {
"accent.background": "#002d00",
"accent.foreground": "#00FF00",