add button

This commit is contained in:
2026-10-28 17:02:02 +07:00
parent 12d4120bfd
commit 0b8b619342
13 changed files with 708 additions and 54 deletions
+1
View File
@@ -10,6 +10,7 @@ use crate::ThemeVariant;
#[derive(Clone, Debug, Default, PartialEq, Deserialize)]
pub struct ThemeDefinition {
pub mode: Option<ThemeVariant>,
pub control_radius: Option<f32>,
pub accent: Option<String>,
pub accent_foreground: Option<String>,
pub background: Option<String>,
+26 -1
View File
@@ -20,7 +20,7 @@ pub use ramps::{AccentShades, Oklch};
pub use resolve::{Ramps, ResolvedTheme};
pub use system::{AccessibilityPreferences, PartialPalette, SourceKind, SystemTheme};
use gpui::{App, Global, WindowAppearance};
use gpui::{App, Global, Pixels, WindowAppearance, px};
/// Light or dark, resolved from the system appearance.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, serde::Deserialize)]
@@ -46,11 +46,35 @@ pub struct Theme {
pub variant: ThemeVariant,
pub colors: ColorTokens,
pub ramps: Ramps,
pub radius: Radius,
pub accessibility: AccessibilityPreferences,
}
impl Global for Theme {}
/// Corner radii components paint from; grows one class at a time.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Radius {
pub control: Pixels,
}
impl Default for Radius {
fn default() -> Self {
Self { control: px(6.) }
}
}
/// Reads the resolved theme global from any app context.
pub trait ActiveTheme {
fn theme(&self) -> &Theme;
}
impl ActiveTheme for App {
fn theme(&self) -> &Theme {
Theme::global(self)
}
}
impl Theme {
/// Reads the theme global. Panics before `init`.
pub fn global(cx: &App) -> &Self {
@@ -62,6 +86,7 @@ impl Theme {
variant: resolved.variant,
colors: resolved.colors,
ramps: resolved.ramps,
radius: resolved.radius,
accessibility: resolved.accessibility,
}
}
+20 -2
View File
@@ -6,12 +6,14 @@
use crate::definition::ThemeDefinition;
use crate::ramps::{AccentShades, Oklch, contrast_foreground, derive_shades, mix};
use crate::system::SystemTheme;
use crate::{ColorTokens, ThemeVariant};
use crate::{ColorTokens, Radius, ThemeVariant};
use gpui::px;
/// Derived state shades for the colors that get pressed and hovered.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Ramps {
pub primary: AccentShades,
pub secondary: AccentShades,
pub destructive: AccentShades,
}
@@ -21,6 +23,7 @@ pub struct ResolvedTheme {
pub variant: ThemeVariant,
pub colors: ColorTokens,
pub ramps: Ramps,
pub radius: Radius,
pub accessibility: crate::system::AccessibilityPreferences,
}
@@ -134,10 +137,20 @@ pub(crate) fn resolve(
.to_hsla();
}
let mut radius = Radius::default();
if let Some(control) = preset.and_then(|def| def.control_radius) {
radius.control = px(control);
}
ResolvedTheme {
variant,
ramps: Ramps {
primary: derive_shades(primary, colors.background, variant == ThemeVariant::Dark),
secondary: derive_shades(
colors.secondary,
colors.background,
variant == ThemeVariant::Dark,
),
destructive: derive_shades(
destructive,
colors.background,
@@ -145,6 +158,7 @@ pub(crate) fn resolve(
),
},
colors,
radius,
accessibility,
}
}
@@ -188,6 +202,8 @@ mod tests {
assert_eq!(resolved.colors.background, base.background);
assert_eq!(resolved.colors.accent, base.accent);
assert_eq!(resolved.ramps.primary.base, base.primary);
assert_eq!(resolved.ramps.secondary.base, base.secondary);
assert_eq!(resolved.radius.control, px(6.));
}
}
@@ -240,7 +256,7 @@ mod tests {
#[test]
fn preset_beats_system_and_the_mode_override_beats_everything() {
let def = ThemeDefinition::parse_toml(
"mode = \"dark\"\nbackground = \"#1a1b26\"\naccent = \"#7aa2f7\"\n",
"mode = \"dark\"\nbackground = \"#1a1b26\"\naccent = \"#7aa2f7\"\ncontrol_radius = 12.0\n",
)
.unwrap();
let palette = PartialPalette {
@@ -259,6 +275,8 @@ mod tests {
assert!((bg.b - 0x26 as f32 / 255.0).abs() < 0.001);
let accent = Rgba::from(resolved.colors.accent);
assert!((accent.r - 0x7a as f32 / 255.0).abs() < 0.001);
// And the metric override beats the radius default.
assert_eq!(resolved.radius.control, px(12.));
let forced = resolve(
&system(ThemeVariant::Light, palette, None),