diff --git a/.theme-schema.json b/.theme-schema.json index 1d33be0e..ed4fc22f 100644 --- a/.theme-schema.json +++ b/.theme-schema.json @@ -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": { diff --git a/crates/story/src/lib.rs b/crates/story/src/lib.rs index 4b430e3e..c7c9969a 100644 --- a/crates/story/src/lib.rs +++ b/crates/story/src/lib.rs @@ -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(), diff --git a/crates/story/src/main.rs b/crates/story/src/main.rs index 081b4417..c35cf985 100644 --- a/crates/story/src/main.rs +++ b/crates/story/src/main.rs @@ -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( diff --git a/crates/ui/src/scroll/scrollbar.rs b/crates/ui/src/scroll/scrollbar.rs index e234dfd5..54f495a7 100644 --- a/crates/ui/src/scroll/scrollbar.rs +++ b/crates/ui/src/scroll/scrollbar.rs @@ -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; diff --git a/crates/ui/src/theme/mod.rs b/crates/ui/src/theme/mod.rs index 974f44dd..f359e3af 100644 --- a/crates/ui/src/theme/mod.rs +++ b/crates/ui/src/theme/mod.rs @@ -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 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 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(), diff --git a/crates/ui/src/theme/schema.rs b/crates/ui/src/theme/schema.rs index 076d0829..df668a98 100644 --- a/crates/ui/src/theme/schema.rs +++ b/crates/ui/src/theme/schema.rs @@ -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, - /// The base font size, default is 16. - #[serde(rename = "font.size")] - pub font_size: Option, - #[serde(rename = "themes")] pub themes: Vec, } @@ -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, + /// The base font family, default is system font: `.SystemUIFont`. + #[serde(rename = "font.family")] + pub font_family: Option, + + /// The border radius for general elements, default is 6. + #[serde(rename = "radius")] + pub radius: Option, + /// The border radius for large elements like Modals and Notifications, default is 8. + #[serde(rename = "radius.lg")] + pub radius_lg: Option, + /// Set shadows in the theme, for example the Input and Button, default is true. + #[serde(rename = "shadow")] + pub shadow: Option, + /// 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; } } diff --git a/themes/matrix.json b/themes/matrix.json index f376a0ce..c0f866be 100644 --- a/themes/matrix.json +++ b/themes/matrix.json @@ -7,6 +7,8 @@ { "name": "Matrix", "mode": "dark", + "radius": 0, + "radius.lg": 0, "colors": { "accent.background": "#002d00", "accent.foreground": "#00FF00",