diff --git a/apps/desktop/src/components/badge.rs b/apps/desktop/src/components/badge.rs index 235f2a6c..fde5c8f1 100644 --- a/apps/desktop/src/components/badge.rs +++ b/apps/desktop/src/components/badge.rs @@ -1,8 +1,9 @@ use gpui::{ - App, FontWeight, IntoElement, RenderOnce, SharedString, Window, div, px, transparent_black, + App, FontWeight, IntoElement, RenderOnce, SharedString, Window, div, prelude::*, px, + transparent_black, }; -use crate::components::prelude::*; +use crate::theme::ActiveTheme; #[allow(dead_code)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -36,8 +37,7 @@ impl Badge { impl RenderOnce for Badge { fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement { - let theme = theme(window); - let colors = theme.colors; + let colors = window.theme().colors; let transparent = transparent_black(); let (background, foreground, border) = match self.variant { BadgeVariant::Default => (colors.primary, colors.primary_foreground, transparent), diff --git a/apps/desktop/src/components/button.rs b/apps/desktop/src/components/button.rs index 03775d7c..b08a3a72 100644 --- a/apps/desktop/src/components/button.rs +++ b/apps/desktop/src/components/button.rs @@ -1,9 +1,9 @@ use gpui::{ App, ClickEvent, ElementId, FontWeight, IntoElement, MouseButton, RenderOnce, SharedString, - Window, div, px, transparent_black, + Window, div, prelude::*, px, transparent_black, }; -use crate::components::prelude::*; +use crate::theme::ActiveTheme; #[allow(dead_code)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -115,7 +115,7 @@ impl Button { impl RenderOnce for Button { fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement { - let theme = theme(window); + let theme = window.theme(); let colors = theme.colors; let transparent = transparent_black(); @@ -177,7 +177,7 @@ impl RenderOnce for Button { this.px(px(self.size.horizontal_padding())) }) .when(self.full_width, |this| this.w_full()) - .rounded_theme(theme) + .rounded(theme.radius) .border_1() .border_color(border) .bg(background) @@ -186,7 +186,7 @@ impl RenderOnce for Button { .font_weight(FontWeight::MEDIUM) .whitespace_nowrap() .tab_index(0) - .focus(|style| style.border_ring(theme)) + .focus(|style| style.border_color(colors.ring)) .child(self.label); if self.disabled { diff --git a/apps/desktop/src/components/context_menu.rs b/apps/desktop/src/components/context_menu.rs index a9448bea..91caadc7 100644 --- a/apps/desktop/src/components/context_menu.rs +++ b/apps/desktop/src/components/context_menu.rs @@ -2,10 +2,10 @@ use std::rc::Rc; use gpui::{ AnyElement, App, ElementId, Entity, IntoElement, MouseButton, Pixels, Point, Render, - SharedString, Window, anchored, deferred, div, px, + SharedString, Window, anchored, deferred, div, prelude::*, px, }; -use crate::components::prelude::*; +use crate::theme::ActiveTheme; type SelectHandler = Rc; @@ -152,7 +152,7 @@ impl Render for ContextMenu { return div().into_any_element(); }; - let theme = theme(window); + let theme = window.theme(); let colors = theme.colors; let items = self .items @@ -168,6 +168,11 @@ impl Render for ContextMenu { variant, .. } => { + let foreground = if *variant == ContextMenuItemVariant::Destructive { + colors.destructive + } else { + colors.popover_foreground + }; let hover = if *variant == ContextMenuItemVariant::Destructive { colors.destructive.opacity(0.1) } else { @@ -184,14 +189,7 @@ impl Render for ContextMenu { .py(px(4.0)) .rounded(px(5.0)) .text_xs() - .when( - *variant == ContextMenuItemVariant::Destructive, - |this| this.text_destructive(theme), - ) - .when( - *variant != ContextMenuItemVariant::Destructive, - |this| this.text_popover_foreground(theme), - ) + .text_color(foreground) .when(*disabled, |this| this.opacity(0.5).cursor_not_allowed()) .when(!*disabled, |this| { this.cursor_default() @@ -212,7 +210,7 @@ impl Render for ContextMenu { this.child( div() .text_size(px(10.0)) - .text_muted_foreground(theme) + .text_color(colors.muted_foreground) .child(shortcut), ) }) @@ -222,14 +220,14 @@ impl Render for ContextMenu { .px(px(8.0)) .py(px(6.0)) .text_xs() - .text_muted_foreground(theme) + .text_color(colors.muted_foreground) .child(label.clone()) .into_any_element(), ContextMenuItem::Separator => div() .h(px(1.0)) .mx(px(-4.0)) .my(px(4.0)) - .bg_border_subtle(theme) + .bg(colors.border.opacity(0.5)) .into_any_element(), } }) @@ -247,11 +245,11 @@ impl Render for ContextMenu { .max_h(window.viewport_size().height - px(16.0)) .overflow_y_scroll() .p(px(4.0)) - .rounded_theme(theme) - .bg_popover(theme) - .text_popover_foreground(theme) + .rounded(theme.radius) + .bg(colors.popover) + .text_color(colors.popover_foreground) .border_1() - .border_foreground_muted(theme) + .border_color(colors.foreground.opacity(0.1)) .shadow_md() .on_mouse_down_out(cx.listener(|this, _, _, cx| this.close(cx))) .children(items), diff --git a/apps/desktop/src/components/label.rs b/apps/desktop/src/components/label.rs index 130dfe56..1150f82e 100644 --- a/apps/desktop/src/components/label.rs +++ b/apps/desktop/src/components/label.rs @@ -1,6 +1,6 @@ -use gpui::{App, FontWeight, IntoElement, RenderOnce, SharedString, Window, div}; +use gpui::{App, FontWeight, IntoElement, RenderOnce, SharedString, Window, div, prelude::*}; -use crate::components::prelude::*; +use crate::theme::ActiveTheme; #[derive(IntoElement)] pub(crate) struct Label { @@ -32,13 +32,16 @@ impl Label { impl RenderOnce for Label { fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement { - let theme = theme(window); + let colors = window.theme().colors; div() .text_xs() .font_weight(FontWeight::MEDIUM) - .when(self.muted, |this| this.text_muted_foreground(theme)) - .when(!self.muted, |this| this.text_foreground(theme)) + .text_color(if self.muted { + colors.muted_foreground + } else { + colors.foreground + }) .when(self.disabled, |this| this.opacity(0.5)) .child(self.text) } diff --git a/apps/desktop/src/components/mod.rs b/apps/desktop/src/components/mod.rs index c63186ae..17a9aa15 100644 --- a/apps/desktop/src/components/mod.rs +++ b/apps/desktop/src/components/mod.rs @@ -2,9 +2,7 @@ mod badge; mod button; mod context_menu; mod label; -pub(crate) mod prelude; mod resizable; -mod semantic; mod separator; pub(crate) use badge::{Badge, BadgeVariant}; diff --git a/apps/desktop/src/components/prelude.rs b/apps/desktop/src/components/prelude.rs deleted file mode 100644 index def54362..00000000 --- a/apps/desktop/src/components/prelude.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub use gpui::prelude::*; - -pub use super::semantic::{SemanticStyled, theme}; diff --git a/apps/desktop/src/components/resizable.rs b/apps/desktop/src/components/resizable.rs index a8123a2b..0d163418 100644 --- a/apps/desktop/src/components/resizable.rs +++ b/apps/desktop/src/components/resizable.rs @@ -1,9 +1,9 @@ use gpui::{ AnyView, AppContext, ClickEvent, Context, DragMoveEvent, Entity, IntoElement, Render, Window, - div, px, relative, + div, prelude::*, px, relative, }; -use crate::components::prelude::*; +use crate::theme::ActiveTheme; #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub(crate) enum Orientation { @@ -90,7 +90,7 @@ impl ResizablePanelGroup { impl Render for ResizablePanelGroup { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - let theme = theme(window); + let colors = window.theme().colors; let orientation = self.orientation; let first_fraction = self.fraction; @@ -105,8 +105,8 @@ impl Render for ResizablePanelGroup { div() .w(px(1.0)) .h_full() - .bg_border(theme) - .group_hover("resizable", |style| style.bg_ring(theme)), + .bg(colors.border) + .group_hover("resizable", |style| style.bg(colors.ring)), ) }) .when(orientation == Orientation::Vertical, |this| { @@ -114,8 +114,8 @@ impl Render for ResizablePanelGroup { div() .h(px(1.0)) .w_full() - .bg_border(theme) - .group_hover("resizable", |style| style.bg_ring(theme)), + .bg(colors.border) + .group_hover("resizable", |style| style.bg(colors.ring)), ) }) .group("resizable") diff --git a/apps/desktop/src/components/semantic.rs b/apps/desktop/src/components/semantic.rs deleted file mode 100644 index 51a50cd1..00000000 --- a/apps/desktop/src/components/semantic.rs +++ /dev/null @@ -1,186 +0,0 @@ -use gpui::{Rems, Styled, Window}; - -use crate::theme::{ActiveTheme, Theme}; - -/// Resolves the active theme for the current window. This is the sole bridge -/// from UI components to the runtime theme source. -pub fn theme(window: &Window) -> &'static Theme { - window.theme() -} - -/// Tailwind-like semantic styling helpers for GPUI [`Styled`] elements. -pub trait SemanticStyled: Styled { - fn bg_background(self, theme: &Theme) -> Self { - self.bg(theme.colors.background) - } - - fn bg_card(self, theme: &Theme) -> Self { - self.bg(theme.colors.card) - } - - fn bg_popover(self, theme: &Theme) -> Self { - self.bg(theme.colors.popover) - } - - fn bg_primary(self, theme: &Theme) -> Self { - self.bg(theme.colors.primary) - } - - fn bg_secondary(self, theme: &Theme) -> Self { - self.bg(theme.colors.secondary) - } - - fn bg_muted(self, theme: &Theme) -> Self { - self.bg(theme.colors.muted) - } - - fn bg_accent(self, theme: &Theme) -> Self { - self.bg(theme.colors.accent) - } - - fn bg_destructive(self, theme: &Theme) -> Self { - self.bg(theme.colors.destructive) - } - - fn bg_input(self, theme: &Theme) -> Self { - self.bg(theme.colors.input) - } - - fn bg_sidebar(self, theme: &Theme) -> Self { - self.bg(theme.colors.sidebar) - } - - fn bg_sidebar_primary(self, theme: &Theme) -> Self { - self.bg(theme.colors.sidebar_primary) - } - - fn bg_sidebar_accent(self, theme: &Theme) -> Self { - self.bg(theme.colors.sidebar_accent) - } - - fn bg_chart_1(self, theme: &Theme) -> Self { - self.bg(theme.colors.chart_1) - } - - fn bg_chart_2(self, theme: &Theme) -> Self { - self.bg(theme.colors.chart_2) - } - - fn bg_chart_3(self, theme: &Theme) -> Self { - self.bg(theme.colors.chart_3) - } - - fn bg_chart_4(self, theme: &Theme) -> Self { - self.bg(theme.colors.chart_4) - } - - fn bg_chart_5(self, theme: &Theme) -> Self { - self.bg(theme.colors.chart_5) - } - - fn bg_border_subtle(self, theme: &Theme) -> Self { - self.bg(theme.colors.border.opacity(0.5)) - } - - fn bg_border(self, theme: &Theme) -> Self { - self.bg(theme.colors.border) - } - - fn bg_ring(self, theme: &Theme) -> Self { - self.bg(theme.colors.ring) - } - - fn text_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.foreground) - } - - fn text_card_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.card_foreground) - } - - fn text_popover_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.popover_foreground) - } - - fn text_primary(self, theme: &Theme) -> Self { - self.text_color(theme.colors.primary) - } - - fn text_primary_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.primary_foreground) - } - - fn text_secondary_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.secondary_foreground) - } - - fn text_muted_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.muted_foreground) - } - - fn text_accent_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.accent_foreground) - } - - fn text_destructive(self, theme: &Theme) -> Self { - self.text_color(theme.colors.destructive) - } - - fn text_sidebar_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.sidebar_foreground) - } - - fn text_sidebar_primary_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.sidebar_primary_foreground) - } - - fn text_sidebar_accent_foreground(self, theme: &Theme) -> Self { - self.text_color(theme.colors.sidebar_accent_foreground) - } - - fn border_border(self, theme: &Theme) -> Self { - self.border_color(theme.colors.border) - } - - fn border_input(self, theme: &Theme) -> Self { - self.border_color(theme.colors.input) - } - - fn border_ring(self, theme: &Theme) -> Self { - self.border_color(theme.colors.ring) - } - - fn border_sidebar(self, theme: &Theme) -> Self { - self.border_color(theme.colors.sidebar_border) - } - - fn border_sidebar_ring(self, theme: &Theme) -> Self { - self.border_color(theme.colors.sidebar_ring) - } - - fn border_foreground_muted(self, theme: &Theme) -> Self { - self.border_color(theme.colors.foreground.opacity(0.1)) - } - - fn rounded_theme(self, theme: &Theme) -> Self { - self.rounded(theme.radius) - } - - fn rounded_sm(self, theme: &Theme) -> Self { - self.rounded(theme_radius(theme.radius, 0.6)) - } - - fn rounded_md(self, theme: &Theme) -> Self { - self.rounded(theme_radius(theme.radius, 0.8)) - } - - fn rounded_lg(self, theme: &Theme) -> Self { - self.rounded(theme.radius) - } -} - -impl SemanticStyled for E {} - -fn theme_radius(base: Rems, scale: f32) -> Rems { - gpui::rems(base.0 * scale) -} diff --git a/apps/desktop/src/components/separator.rs b/apps/desktop/src/components/separator.rs index 76f05b1e..419f1964 100644 --- a/apps/desktop/src/components/separator.rs +++ b/apps/desktop/src/components/separator.rs @@ -1,7 +1,6 @@ -use gpui::{App, IntoElement, RenderOnce, Window, div, px}; +use gpui::{App, IntoElement, RenderOnce, Window, div, prelude::*, px}; -use crate::components::Orientation; -use crate::components::prelude::*; +use crate::{components::Orientation, theme::ActiveTheme}; #[derive(IntoElement)] pub(crate) struct Separator { @@ -25,11 +24,11 @@ impl Separator { impl RenderOnce for Separator { fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement { - let theme = theme(window); + let color = window.theme().colors.border.opacity(0.5); div() .flex_none() - .bg_border_subtle(theme) + .bg(color) .map(|this| match self.orientation { Orientation::Horizontal => this.w_full().h(px(1.0)), Orientation::Vertical => this.h_full().w(px(1.0)),