feat: add new theme #61
@@ -35,7 +35,7 @@ pub use layout::{
|
|||||||
pub use notification::*;
|
pub use notification::*;
|
||||||
pub use paint::{
|
pub use paint::{
|
||||||
INK_FILL_SCALE, INK_HAIRLINE_SCALE, SCRIM_ALPHA_DARK, band, current_appearance, hairline, ink,
|
INK_FILL_SCALE, INK_HAIRLINE_SCALE, SCRIM_ALPHA_DARK, band, current_appearance, hairline, ink,
|
||||||
scrim, set_current_appearance, surface_shadows, wash,
|
plate_active, plate_hover, scrim, set_current_appearance, surface_shadows, wash,
|
||||||
};
|
};
|
||||||
pub use platform_kind::PlatformKind;
|
pub use platform_kind::PlatformKind;
|
||||||
pub use registry::*;
|
pub use registry::*;
|
||||||
|
|||||||
@@ -179,3 +179,13 @@ pub(crate) fn plate_hover_for(appearance: ThemeMode, plate: gpui::Hsla) -> gpui:
|
|||||||
pub(crate) fn plate_active_for(appearance: ThemeMode, plate: gpui::Hsla) -> gpui::Hsla {
|
pub(crate) fn plate_active_for(appearance: ThemeMode, plate: gpui::Hsla) -> gpui::Hsla {
|
||||||
crate::color::flatten(ink_for(appearance, 0.16), plate)
|
crate::color::flatten(ink_for(appearance, 0.16), plate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Hover over an opaque plate, for call sites outside this crate.
|
||||||
|
pub fn plate_hover(plate: gpui::Hsla) -> gpui::Hsla {
|
||||||
|
plate_hover_for(current_appearance(), plate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pressed over an opaque plate, for call sites outside this crate.
|
||||||
|
pub fn plate_active(plate: gpui::Hsla) -> gpui::Hsla {
|
||||||
|
plate_active_for(current_appearance(), plate)
|
||||||
|
}
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ impl InteractiveElement for Avatar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for Avatar {
|
impl RenderOnce for Avatar {
|
||||||
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement {
|
||||||
let image_size = avatar_size(self.size).to_pixels(window.rem_size());
|
let image_size = avatar_size(self.size).to_pixels(window.rem_size());
|
||||||
|
|
||||||
let content = match self.picture {
|
let content = match self.picture {
|
||||||
@@ -429,7 +429,6 @@ impl RenderOnce for Avatar {
|
|||||||
.size(image_size)
|
.size(image_size)
|
||||||
.rounded_full()
|
.rounded_full()
|
||||||
.object_fit(ObjectFit::Cover)
|
.object_fit(ObjectFit::Cover)
|
||||||
.bg(cx.theme().ghost_element_background)
|
|
||||||
.with_fallback(move || generated_avatar(seed.as_deref(), image_size))
|
.with_fallback(move || generated_avatar(seed.as_deref(), image_size))
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|||||||
+48
-48
@@ -4,10 +4,10 @@ use gpui::prelude::FluentBuilder as _;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, ElementId, Hsla, InteractiveElement, IntoElement, MouseButton,
|
AnyElement, App, ClickEvent, ElementId, Hsla, InteractiveElement, IntoElement, MouseButton,
|
||||||
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, StyleRefinement,
|
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, StyleRefinement,
|
||||||
Styled, Window, div, relative,
|
Styled, Window, div, px, relative,
|
||||||
};
|
};
|
||||||
use gpui_base::Button as BaseButton;
|
use gpui_base::Button as BaseButton;
|
||||||
use theme::ActiveTheme;
|
use theme::{ActiveTheme, bubble_radius, button_radius, plate_active, plate_hover, wash};
|
||||||
|
|
||||||
use crate::indicator::Indicator;
|
use crate::indicator::Indicator;
|
||||||
use crate::tooltip::Tooltip;
|
use crate::tooltip::Tooltip;
|
||||||
@@ -24,10 +24,10 @@ pub struct ButtonCustomVariant {
|
|||||||
impl ButtonCustomVariant {
|
impl ButtonCustomVariant {
|
||||||
pub fn new(_window: &Window, cx: &App) -> Self {
|
pub fn new(_window: &Window, cx: &App) -> Self {
|
||||||
Self {
|
Self {
|
||||||
color: cx.theme().element_background,
|
color: cx.theme().solid,
|
||||||
foreground: cx.theme().element_foreground,
|
foreground: cx.theme().on_solid,
|
||||||
hover: cx.theme().element_hover,
|
hover: plate_hover(cx.theme().solid),
|
||||||
active: cx.theme().element_active,
|
active: plate_active(cx.theme().solid),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,9 +293,16 @@ impl RenderOnce for Button {
|
|||||||
.cursor_default()
|
.cursor_default()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.map(|this| match self.rounded {
|
.map(|this| match self.rounded {
|
||||||
false => this.rounded(cx.theme().radius),
|
false => this.rounded(px(button_radius())),
|
||||||
true => this.rounded_full(),
|
true => this.rounded(px(bubble_radius())),
|
||||||
})
|
})
|
||||||
|
.when_some(
|
||||||
|
match style {
|
||||||
|
ButtonVariant::Secondary => Some(cx.theme().border),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
|this, border_color| this.border_1().border_color(border_color),
|
||||||
|
)
|
||||||
.when(!self.compact, |this| {
|
.when(!self.compact, |this| {
|
||||||
if self.label.is_none() && self.children.is_empty() {
|
if self.label.is_none() && self.children.is_empty() {
|
||||||
// Icon Button
|
// Icon Button
|
||||||
@@ -424,15 +431,15 @@ impl ButtonVariant {
|
|||||||
|
|
||||||
fn bg_color(&self, cx: &App) -> Hsla {
|
fn bg_color(&self, cx: &App) -> Hsla {
|
||||||
match self {
|
match self {
|
||||||
ButtonVariant::Primary => cx.theme().element_background,
|
ButtonVariant::Primary => cx.theme().solid,
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_background,
|
ButtonVariant::Secondary => cx.theme().surface_raised,
|
||||||
ButtonVariant::Danger => cx.theme().danger_background,
|
ButtonVariant::Danger => cx.theme().danger_strong,
|
||||||
ButtonVariant::Warning => cx.theme().warning_background,
|
ButtonVariant::Warning => cx.theme().warning_muted,
|
||||||
ButtonVariant::Ghost { alt } => {
|
ButtonVariant::Ghost { alt } => {
|
||||||
if *alt {
|
if *alt {
|
||||||
cx.theme().ghost_element_background_alt
|
cx.theme().surface_raised
|
||||||
} else {
|
} else {
|
||||||
cx.theme().ghost_element_background
|
gpui::transparent_black()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ButtonVariant::Custom(colors) => colors.color,
|
ButtonVariant::Custom(colors) => colors.color,
|
||||||
@@ -442,11 +449,11 @@ impl ButtonVariant {
|
|||||||
|
|
||||||
fn text_color(&self, cx: &App) -> Hsla {
|
fn text_color(&self, cx: &App) -> Hsla {
|
||||||
match self {
|
match self {
|
||||||
ButtonVariant::Primary => cx.theme().element_foreground,
|
ButtonVariant::Primary => cx.theme().on_solid,
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_foreground,
|
ButtonVariant::Secondary => cx.theme().text,
|
||||||
ButtonVariant::Danger => cx.theme().danger_foreground,
|
ButtonVariant::Danger => cx.theme().on_accent,
|
||||||
ButtonVariant::Warning => cx.theme().warning_foreground,
|
ButtonVariant::Warning => cx.theme().text,
|
||||||
ButtonVariant::Transparent => cx.theme().text_placeholder,
|
ButtonVariant::Transparent => cx.theme().text_faint,
|
||||||
ButtonVariant::Ghost { alt } => {
|
ButtonVariant::Ghost { alt } => {
|
||||||
if *alt {
|
if *alt {
|
||||||
cx.theme().text
|
cx.theme().text
|
||||||
@@ -460,19 +467,19 @@ impl ButtonVariant {
|
|||||||
|
|
||||||
fn hovered(&self, cx: &App) -> ButtonVariantStyle {
|
fn hovered(&self, cx: &App) -> ButtonVariantStyle {
|
||||||
let bg = match self {
|
let bg = match self {
|
||||||
ButtonVariant::Primary => cx.theme().element_hover,
|
ButtonVariant::Primary => plate_hover(cx.theme().solid),
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_hover,
|
ButtonVariant::Secondary => cx.theme().surface_raised_hover,
|
||||||
ButtonVariant::Danger => cx.theme().danger_hover,
|
ButtonVariant::Danger => plate_hover(cx.theme().danger_strong),
|
||||||
ButtonVariant::Warning => cx.theme().warning_hover,
|
ButtonVariant::Warning => cx.theme().element_hover,
|
||||||
ButtonVariant::Ghost { .. } => cx.theme().ghost_element_hover,
|
ButtonVariant::Ghost { .. } => cx.theme().element_hover,
|
||||||
ButtonVariant::Transparent => gpui::transparent_black(),
|
ButtonVariant::Transparent => gpui::transparent_black(),
|
||||||
ButtonVariant::Custom(colors) => colors.hover,
|
ButtonVariant::Custom(colors) => colors.hover,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fg = match self {
|
let fg = match self {
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_foreground,
|
ButtonVariant::Secondary => cx.theme().text,
|
||||||
ButtonVariant::Ghost { .. } => cx.theme().text,
|
ButtonVariant::Ghost { .. } => cx.theme().text,
|
||||||
ButtonVariant::Transparent => cx.theme().text_placeholder,
|
ButtonVariant::Transparent => cx.theme().text_faint,
|
||||||
_ => self.text_color(cx),
|
_ => self.text_color(cx),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -481,18 +488,18 @@ impl ButtonVariant {
|
|||||||
|
|
||||||
fn active(&self, cx: &App) -> ButtonVariantStyle {
|
fn active(&self, cx: &App) -> ButtonVariantStyle {
|
||||||
let bg = match self {
|
let bg = match self {
|
||||||
ButtonVariant::Primary => cx.theme().element_active,
|
ButtonVariant::Primary => plate_active(cx.theme().solid),
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_active,
|
ButtonVariant::Secondary => plate_active(cx.theme().surface_raised),
|
||||||
ButtonVariant::Danger => cx.theme().danger_active,
|
ButtonVariant::Danger => plate_active(cx.theme().danger_strong),
|
||||||
ButtonVariant::Warning => cx.theme().warning_active,
|
ButtonVariant::Warning => cx.theme().element_active,
|
||||||
ButtonVariant::Ghost { .. } => cx.theme().ghost_element_active,
|
ButtonVariant::Ghost { .. } => cx.theme().element_active,
|
||||||
ButtonVariant::Transparent => gpui::transparent_black(),
|
ButtonVariant::Transparent => gpui::transparent_black(),
|
||||||
ButtonVariant::Custom(colors) => colors.active,
|
ButtonVariant::Custom(colors) => colors.active,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fg = match self {
|
let fg = match self {
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_foreground,
|
ButtonVariant::Secondary => cx.theme().text,
|
||||||
ButtonVariant::Transparent => cx.theme().text_placeholder,
|
ButtonVariant::Transparent => cx.theme().text_faint,
|
||||||
_ => self.text_color(cx),
|
_ => self.text_color(cx),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -501,18 +508,18 @@ impl ButtonVariant {
|
|||||||
|
|
||||||
fn selected(&self, cx: &App) -> ButtonVariantStyle {
|
fn selected(&self, cx: &App) -> ButtonVariantStyle {
|
||||||
let bg = match self {
|
let bg = match self {
|
||||||
ButtonVariant::Primary => cx.theme().element_selected,
|
ButtonVariant::Primary => cx.theme().element_active,
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_selected,
|
ButtonVariant::Secondary => cx.theme().element_active,
|
||||||
ButtonVariant::Danger => cx.theme().danger_selected,
|
ButtonVariant::Danger => plate_active(cx.theme().danger_strong),
|
||||||
ButtonVariant::Warning => cx.theme().warning_selected,
|
ButtonVariant::Warning => cx.theme().element_active,
|
||||||
ButtonVariant::Ghost { .. } => cx.theme().ghost_element_selected,
|
ButtonVariant::Ghost { .. } => cx.theme().element_active,
|
||||||
ButtonVariant::Transparent => gpui::transparent_black(),
|
ButtonVariant::Transparent => gpui::transparent_black(),
|
||||||
ButtonVariant::Custom(colors) => colors.active,
|
ButtonVariant::Custom(colors) => colors.active,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fg = match self {
|
let fg = match self {
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_foreground,
|
ButtonVariant::Secondary => cx.theme().text,
|
||||||
ButtonVariant::Transparent => cx.theme().text_placeholder,
|
ButtonVariant::Transparent => cx.theme().text_faint,
|
||||||
_ => self.text_color(cx),
|
_ => self.text_color(cx),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -520,14 +527,7 @@ impl ButtonVariant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn disabled(&self, cx: &App) -> ButtonVariantStyle {
|
fn disabled(&self, cx: &App) -> ButtonVariantStyle {
|
||||||
let bg = match self {
|
let bg = wash(0.08);
|
||||||
ButtonVariant::Danger => cx.theme().danger_disabled,
|
|
||||||
ButtonVariant::Warning => cx.theme().warning_disabled,
|
|
||||||
ButtonVariant::Ghost { .. } => cx.theme().ghost_element_disabled,
|
|
||||||
ButtonVariant::Secondary => cx.theme().secondary_disabled,
|
|
||||||
_ => cx.theme().element_disabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
let fg = cx.theme().text_muted;
|
let fg = cx.theme().text_muted;
|
||||||
|
|
||||||
ButtonVariantStyle { bg, fg }
|
ButtonVariantStyle { bg, fg }
|
||||||
|
|||||||
+20
-30
@@ -2,13 +2,13 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Animation, AnimationExt as _, AnyElement, App, BoxShadow, ClickEvent, Div, FocusHandle,
|
Animation, AnimationExt as _, AnyElement, App, ClickEvent, Div, FocusHandle, IntoElement,
|
||||||
IntoElement, ParentElement, Pixels, RenderOnce, SharedString, StyleRefinement, Styled, Window,
|
ParentElement, Pixels, RenderOnce, SharedString, StyleRefinement, Styled, Window, div, px,
|
||||||
div, hsla, point, px,
|
transparent_black,
|
||||||
};
|
};
|
||||||
use gpui_base::{DialogBackdrop, DialogPopup, DialogTitle};
|
use gpui_base::{DialogBackdrop, DialogPopup, DialogTitle};
|
||||||
use instant::Duration;
|
use instant::Duration;
|
||||||
use theme::ActiveTheme;
|
use theme::{ActiveTheme, SCRIM_ALPHA_DARK, hairline, scrim, surface_radius, surface_shadows};
|
||||||
|
|
||||||
use crate::animation::cubic_bezier;
|
use crate::animation::cubic_bezier;
|
||||||
use crate::button::{Button, ButtonCustomVariant, ButtonVariant, ButtonVariants as _};
|
use crate::button::{Button, ButtonCustomVariant, ButtonVariant, ButtonVariants as _};
|
||||||
@@ -278,7 +278,9 @@ impl RenderOnce for Dialog {
|
|||||||
let backdrop = DialogBackdrop::new()
|
let backdrop = DialogBackdrop::new()
|
||||||
.absolute()
|
.absolute()
|
||||||
.inset_0()
|
.inset_0()
|
||||||
.when(self.overlay_visible, |this| this.bg(cx.theme().overlay))
|
.when(self.overlay_visible, |this| {
|
||||||
|
this.bg(scrim(SCRIM_ALPHA_DARK))
|
||||||
|
})
|
||||||
.with_animation("fade-in", animation.clone(), move |this, delta| {
|
.with_animation("fade-in", animation.clone(), move |this, delta| {
|
||||||
this.opacity(delta)
|
this.opacity(delta)
|
||||||
});
|
});
|
||||||
@@ -286,11 +288,11 @@ impl RenderOnce for Dialog {
|
|||||||
let card = DialogPopup::new()
|
let card = DialogPopup::new()
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.bg(cx.theme().background)
|
.bg(cx.theme().surface_dialog)
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border.alpha(0.4))
|
.border_color(hairline(0.4))
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(px(surface_radius()))
|
||||||
.when(cx.theme().shadow, |this| this.shadow_xl())
|
.when(cx.theme().shadow, |this| this.shadow(surface_shadows()))
|
||||||
.min_h_24()
|
.min_h_24()
|
||||||
.refine_style(&self.style)
|
.refine_style(&self.style)
|
||||||
.relative()
|
.relative()
|
||||||
@@ -329,10 +331,10 @@ impl RenderOnce for Dialog {
|
|||||||
.icon(IconName::CloseCircleFill)
|
.icon(IconName::CloseCircleFill)
|
||||||
.custom(
|
.custom(
|
||||||
ButtonCustomVariant::new(window, cx)
|
ButtonCustomVariant::new(window, cx)
|
||||||
.foreground(cx.theme().icon_muted)
|
.foreground(cx.theme().text_faint)
|
||||||
.color(cx.theme().ghost_element_background)
|
.color(transparent_black())
|
||||||
.hover(cx.theme().ghost_element_background)
|
.hover(cx.theme().element_hover)
|
||||||
.active(cx.theme().ghost_element_background),
|
.active(cx.theme().element_active),
|
||||||
)
|
)
|
||||||
.on_click(move |_, window, cx| {
|
.on_click(move |_, window, cx| {
|
||||||
on_cancel(&ClickEvent::default(), window, cx);
|
on_cancel(&ClickEvent::default(), window, cx);
|
||||||
@@ -374,23 +376,11 @@ impl RenderOnce for Dialog {
|
|||||||
.with_animation("slide-down", animation, move |this, delta| {
|
.with_animation("slide-down", animation, move |this, delta| {
|
||||||
// Settle at the target offset; only the entrance is animated.
|
// Settle at the target offset; only the entrance is animated.
|
||||||
let y_offset = px(30.) * (delta - 1.);
|
let y_offset = px(30.) * (delta - 1.);
|
||||||
// This is equivalent to `shadow_xl` with an extra opacity.
|
let mut shadow = surface_shadows();
|
||||||
let shadow = vec![
|
// The shadows fade in with the slide.
|
||||||
BoxShadow {
|
for shadow in &mut shadow {
|
||||||
color: hsla(0., 0., 0., 0.1 * delta),
|
shadow.color.a *= delta;
|
||||||
offset: point(px(0.), px(20.)),
|
}
|
||||||
blur_radius: px(25.),
|
|
||||||
spread_radius: px(-5.),
|
|
||||||
inset: false,
|
|
||||||
},
|
|
||||||
BoxShadow {
|
|
||||||
color: hsla(0., 0., 0., 0.1 * delta),
|
|
||||||
offset: point(px(0.), px(8.)),
|
|
||||||
blur_radius: px(10.),
|
|
||||||
spread_radius: px(-6.),
|
|
||||||
inset: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
this.top(y_offset).shadow(shadow)
|
this.top(y_offset).shadow(shadow)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -17,7 +17,7 @@ use gpui_base::dock::{
|
|||||||
PaneRef, PanelId, TabGroupContext, TabGroupRenderer,
|
PaneRef, PanelId, TabGroupContext, TabGroupRenderer,
|
||||||
};
|
};
|
||||||
use gpui_base::{HandleEdge, Placement, ResizeHandleContext};
|
use gpui_base::{HandleEdge, Placement, ResizeHandleContext};
|
||||||
use theme::{ActiveTheme, TABBAR_HEIGHT};
|
use theme::{ActiveTheme, TABBAR_HEIGHT, button_radius, panel_radius};
|
||||||
|
|
||||||
use crate::button::{Button, ButtonVariants as _};
|
use crate::button::{Button, ButtonVariants as _};
|
||||||
use crate::resizable::{resize_handle, resize_handle_appearance};
|
use crate::resizable::{resize_handle, resize_handle_appearance};
|
||||||
@@ -348,12 +348,12 @@ impl Render for DragPreview {
|
|||||||
.justify_center()
|
.justify_center()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.whitespace_nowrap()
|
.whitespace_nowrap()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(button_radius()))
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.text_color(cx.theme().text)
|
.text_color(cx.theme().text)
|
||||||
.text_ellipsis()
|
.text_ellipsis()
|
||||||
.when(cx.theme().shadow, |this| this.shadow_xs())
|
.when(cx.theme().shadow, |this| this.shadow_xs())
|
||||||
.bg(cx.theme().background)
|
.bg(cx.theme().bg)
|
||||||
.child(panel_title(&self.panel, cx))
|
.child(panel_title(&self.panel, cx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,7 +448,7 @@ impl TabGroupSkin {
|
|||||||
.flex_grow_1()
|
.flex_grow_1()
|
||||||
.min_w_16()
|
.min_w_16()
|
||||||
.when(droppable, |this| {
|
.when(droppable, |this| {
|
||||||
this.drag_over::<DragPanel>(|this, _, _, cx| this.bg(cx.theme().surface_background))
|
this.drag_over::<DragPanel>(|this, _, _, cx| this.bg(cx.theme().drop_target))
|
||||||
.on_drop({
|
.on_drop({
|
||||||
let group = TabGroupContext::clone(group);
|
let group = TabGroupContext::clone(group);
|
||||||
move |drag: &DragPanel, window, cx| {
|
move |drag: &DragPanel, window, cx| {
|
||||||
@@ -467,7 +467,7 @@ impl TabGroupSkin {
|
|||||||
let bar = TabBar::new("tab-bar")
|
let bar = TabBar::new("tab-bar")
|
||||||
.track_scroll(&self.scroll_handle)
|
.track_scroll(&self.scroll_handle)
|
||||||
.h(TABBAR_HEIGHT)
|
.h(TABBAR_HEIGHT)
|
||||||
.bg(cx.theme().panel_background)
|
.bg(cx.theme().surface)
|
||||||
.when(needs_traffic_light_padding, |this| {
|
.when(needs_traffic_light_padding, |this| {
|
||||||
this.pl(px(TRAFFIC_LIGHT_PADDING))
|
this.pl(px(TRAFFIC_LIGHT_PADDING))
|
||||||
})
|
})
|
||||||
@@ -539,7 +539,7 @@ impl TabGroupSkin {
|
|||||||
this.rounded_l_none()
|
this.rounded_l_none()
|
||||||
.border_l_2()
|
.border_l_2()
|
||||||
.border_r_0()
|
.border_r_0()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().drop_line)
|
||||||
})
|
})
|
||||||
.on_drop({
|
.on_drop({
|
||||||
let group = TabGroupContext::clone(group);
|
let group = TabGroupContext::clone(group);
|
||||||
@@ -569,7 +569,7 @@ impl TabGroupSkin {
|
|||||||
h_flex()
|
h_flex()
|
||||||
.h(TABBAR_HEIGHT)
|
.h(TABBAR_HEIGHT)
|
||||||
.w_full()
|
.w_full()
|
||||||
.bg(cx.theme().panel_background)
|
.bg(cx.theme().surface)
|
||||||
.child(bar.flex_1())
|
.child(bar.flex_1())
|
||||||
.child(window_controls())
|
.child(window_controls())
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
@@ -718,7 +718,7 @@ impl TabGroupRenderer for TabGroupSkin {
|
|||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.size_full()
|
.size_full()
|
||||||
.bg(cx.theme().panel_background)
|
.bg(cx.theme().surface)
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(panel.cached(StyleRefinement::default().v_flex().size_full())),
|
.child(panel.cached(StyleRefinement::default().v_flex().size_full())),
|
||||||
)
|
)
|
||||||
@@ -759,10 +759,10 @@ impl TabGroupRenderer for TabGroupSkin {
|
|||||||
.top(top)
|
.top(top)
|
||||||
.w(width)
|
.w(width)
|
||||||
.h(height)
|
.h(height)
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(px(panel_radius()))
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().element_disabled)
|
.border_color(cx.theme().drop_line)
|
||||||
.bg(cx.theme().drop_target_background)
|
.bg(cx.theme().drop_target)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ElementId, InteractiveElement as _, IntoElement, ParentElement, RenderOnce,
|
AnyElement, App, ElementId, InteractiveElement as _, IntoElement, ParentElement, RenderOnce,
|
||||||
StyleRefinement, Styled, Window, div, relative,
|
StyleRefinement, Styled, Window, div, px, relative,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
@@ -95,7 +95,7 @@ impl RenderOnce for GroupBox {
|
|||||||
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let (bg, has_paddings) = match self.variant {
|
let (bg, has_paddings) = match self.variant {
|
||||||
GroupBoxVariant::Normal => (None, false),
|
GroupBoxVariant::Normal => (None, false),
|
||||||
GroupBoxVariant::Fill => (Some(cx.theme().surface_background), true),
|
GroupBoxVariant::Fill => (Some(cx.theme().surface), true),
|
||||||
};
|
};
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
@@ -120,7 +120,7 @@ impl RenderOnce for GroupBox {
|
|||||||
.text_color(cx.theme().text)
|
.text_color(cx.theme().text)
|
||||||
.when(has_paddings, |this| this.p_2())
|
.when(has_paddings, |this| this.p_2())
|
||||||
.gap_4()
|
.gap_4()
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(px(theme::panel_radius()))
|
||||||
.children(self.children),
|
.children(self.children),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ impl From<Icon> for AnyElement {
|
|||||||
|
|
||||||
impl Render for Icon {
|
impl Render for Icon {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let text_color = self.text_color.unwrap_or_else(|| cx.theme().icon);
|
let text_color = self.text_color.unwrap_or_else(|| cx.theme().text_muted);
|
||||||
let text_size = window.text_style().font_size.to_pixels(window.rem_size());
|
let text_size = window.text_style().font_size.to_pixels(window.rem_size());
|
||||||
let has_base_size = self.style.size.width.is_some() || self.style.size.height.is_some();
|
let has_base_size = self.style.size.width.is_some() || self.style.size.height.is_some();
|
||||||
|
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ pub(crate) fn clear_button(cx: &App) -> Button {
|
|||||||
.ghost()
|
.ghost()
|
||||||
.xsmall()
|
.xsmall()
|
||||||
.tab_stop(false)
|
.tab_stop(false)
|
||||||
.text_color(cx.theme().icon_muted)
|
.text_color(cx.theme().text_faint)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
use gpui_base::InputBase;
|
use gpui_base::InputBase;
|
||||||
use gpui_base::input::{InputBaseState, InputEditorStyle, InputMode, InputModeKind, TextareaMode};
|
use gpui_base::input::{InputBaseState, InputEditorStyle, InputMode, InputModeKind, TextareaMode};
|
||||||
use theme::ActiveTheme;
|
use theme::{ActiveTheme, button_radius};
|
||||||
|
|
||||||
use crate::indicator::Indicator;
|
use crate::indicator::Indicator;
|
||||||
use crate::input::clear_button;
|
use crate::input::clear_button;
|
||||||
@@ -15,9 +15,9 @@ use crate::{Sizable, Size, StyleSized, StyledExt, h_flex, v_flex};
|
|||||||
/// The background of an input frame, which reads muted while the input is disabled.
|
/// The background of an input frame, which reads muted while the input is disabled.
|
||||||
fn input_background(disabled: bool, cx: &App) -> Hsla {
|
fn input_background(disabled: bool, cx: &App) -> Hsla {
|
||||||
if disabled {
|
if disabled {
|
||||||
cx.theme().surface_background
|
cx.theme().surface
|
||||||
} else {
|
} else {
|
||||||
cx.theme().elevated_surface_background
|
cx.theme().input_bg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,11 +26,11 @@ fn input_editor_style(cx: &App) -> InputEditorStyle {
|
|||||||
let theme = cx.theme();
|
let theme = cx.theme();
|
||||||
InputEditorStyle {
|
InputEditorStyle {
|
||||||
foreground: theme.text,
|
foreground: theme.text,
|
||||||
muted_foreground: theme.text_muted,
|
muted_foreground: theme.text_faint,
|
||||||
background: theme.elevated_surface_background,
|
background: theme.input_bg,
|
||||||
border: theme.border,
|
border: theme.border_faint,
|
||||||
selection: theme.selection,
|
selection: theme.selection,
|
||||||
caret: theme.cursor,
|
caret: theme.caret,
|
||||||
..InputEditorStyle::default()
|
..InputEditorStyle::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ impl<M: InputModeKind> RenderOnce for Input<M> {
|
|||||||
.when(self.appearance, |this| {
|
.when(self.appearance, |this| {
|
||||||
this.bg(background)
|
this.bg(background)
|
||||||
.when(self.disabled, |this| this.opacity(0.5))
|
.when(self.disabled, |this| this.opacity(0.5))
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(button_radius()))
|
||||||
})
|
})
|
||||||
.tab_index(0)
|
.tab_index(0)
|
||||||
.gap(gap_x)
|
.gap(gap_x)
|
||||||
|
|||||||
@@ -171,9 +171,9 @@ impl RenderOnce for Kbd {
|
|||||||
fn render(self, _: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
|
fn render(self, _: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
|
||||||
div()
|
div()
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border_faint)
|
||||||
.text_color(cx.theme().text_muted)
|
.text_color(cx.theme().text_muted)
|
||||||
.bg(cx.theme().surface_background)
|
.bg(cx.theme().surface_raised)
|
||||||
.py_0p5()
|
.py_0p5()
|
||||||
.px_1()
|
.px_1()
|
||||||
.min_w_5()
|
.min_w_5()
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ElementId, IntoElement, SharedString, StyleRefinement, Styled as _, Window,
|
AnyElement, App, ElementId, HighlightStyle, IntoElement, SharedString, StyleRefinement,
|
||||||
|
Styled as _, Window,
|
||||||
};
|
};
|
||||||
use gpui_base::{TextView, TextViewStyle};
|
use gpui_base::{TextView, TextViewStyle};
|
||||||
use theme::ActiveTheme as _;
|
use theme::ActiveTheme as _;
|
||||||
@@ -63,14 +64,27 @@ impl RenderedText {
|
|||||||
pub fn element(&self, id: ElementId, _window: &Window, cx: &App) -> AnyElement {
|
pub fn element(&self, id: ElementId, _window: &Window, cx: &App) -> AnyElement {
|
||||||
let theme = cx.theme();
|
let theme = cx.theme();
|
||||||
let code_block = StyleRefinement::default().font_family(code_font_family());
|
let code_block = StyleRefinement::default().font_family(code_font_family());
|
||||||
|
let muted_heading = theme.text_muted;
|
||||||
|
|
||||||
TextView::markdown(id, self.text.clone())
|
TextView::markdown(id, self.text.clone())
|
||||||
.style(
|
.style(
|
||||||
TextViewStyle::default()
|
TextViewStyle::default()
|
||||||
.with_foreground(theme.text)
|
.with_foreground(theme.text)
|
||||||
.with_muted_foreground(theme.text_muted)
|
.with_muted_foreground(theme.text_muted)
|
||||||
.with_link(theme.text_accent)
|
// Deeply nested headings read as secondary text.
|
||||||
.with_code_background(theme.elevated_surface_background)
|
.with_heading(move |level| {
|
||||||
|
if level >= 4 {
|
||||||
|
StyleRefinement::default().text_color(muted_heading)
|
||||||
|
} else {
|
||||||
|
StyleRefinement::default()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.with_link(theme.accent)
|
||||||
|
.with_code_background(theme.code_wash)
|
||||||
|
.with_inline_code(HighlightStyle {
|
||||||
|
color: Some(theme.code_text),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
.with_border(theme.border)
|
.with_border(theme.border)
|
||||||
.with_code_block(code_block)
|
.with_code_block(code_block)
|
||||||
.with_dark(theme.is_dark()),
|
.with_dark(theme.is_dark()),
|
||||||
|
|||||||
@@ -101,12 +101,12 @@ impl RenderOnce for MenuItemElement {
|
|||||||
})
|
})
|
||||||
.when(!self.disabled, |this| {
|
.when(!self.disabled, |this| {
|
||||||
this.group_hover(self.group_name, |this| {
|
this.group_hover(self.group_name, |this| {
|
||||||
this.bg(cx.theme().secondary_background)
|
this.bg(cx.theme().element_hover)
|
||||||
.text_color(cx.theme().secondary_foreground)
|
.text_color(cx.theme().text)
|
||||||
})
|
})
|
||||||
.when(self.selected, |this| {
|
.when(self.selected, |this| {
|
||||||
this.bg(cx.theme().secondary_background)
|
this.bg(cx.theme().element_active)
|
||||||
.text_color(cx.theme().secondary_foreground)
|
.text_color(cx.theme().text)
|
||||||
})
|
})
|
||||||
.when_some(self.on_click, |this, on_click| {
|
.when_some(self.on_click, |this, on_click| {
|
||||||
this.on_mouse_down(MouseButton::Left, move |_, _, cx| {
|
this.on_mouse_down(MouseButton::Left, move |_, _, cx| {
|
||||||
@@ -115,7 +115,7 @@ impl RenderOnce for MenuItemElement {
|
|||||||
.on_click(on_click)
|
.on_click(on_click)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.when(self.disabled, |this| this.text_color(cx.theme().text_muted))
|
.when(self.disabled, |this| this.text_color(cx.theme().text_faint))
|
||||||
.children(self.children)
|
.children(self.children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ impl PopupMenu {
|
|||||||
checked: bool,
|
checked: bool,
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
_: &mut Window,
|
_: &mut Window,
|
||||||
_: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Option<impl IntoElement> {
|
) -> Option<impl IntoElement> {
|
||||||
if !has_icon {
|
if !has_icon {
|
||||||
return None;
|
return None;
|
||||||
@@ -586,7 +586,7 @@ impl PopupMenu {
|
|||||||
let icon = if let Some(icon) = icon {
|
let icon = if let Some(icon) = icon {
|
||||||
icon.clone()
|
icon.clone()
|
||||||
} else if checked {
|
} else if checked {
|
||||||
Icon::new(IconName::Check)
|
Icon::new(IconName::Check).text_color(cx.theme().accent)
|
||||||
} else {
|
} else {
|
||||||
Icon::empty()
|
Icon::empty()
|
||||||
};
|
};
|
||||||
@@ -657,7 +657,7 @@ impl PopupMenu {
|
|||||||
.my_0p5()
|
.my_0p5()
|
||||||
.mx_neg_1()
|
.mx_neg_1()
|
||||||
.border_b(px(2.))
|
.border_b(px(2.))
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border_faint)
|
||||||
.disabled(true),
|
.disabled(true),
|
||||||
PopupMenuItem::Label(label) => this.disabled(true).cursor_default().child(
|
PopupMenuItem::Label(label) => this.disabled(true).cursor_default().child(
|
||||||
h_flex().cursor_default().items_center().gap_x_1().child(
|
h_flex().cursor_default().items_center().gap_x_1().child(
|
||||||
@@ -790,7 +790,8 @@ impl Render for PopupMenu {
|
|||||||
|
|
||||||
let options = RenderOptions {
|
let options = RenderOptions {
|
||||||
has_left_icon,
|
has_left_icon,
|
||||||
radius: cx.theme().radius.min(px(8.)),
|
// Items sit p_1 (4px) inside the surface plate; keep corners concentric.
|
||||||
|
radius: px(theme::inset_radius(theme::surface_radius(), 4.0)),
|
||||||
};
|
};
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ impl RenderOnce for MessageRow {
|
|||||||
h_flex()
|
h_flex()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.text_color(cx.theme().text_placeholder)
|
.text_color(cx.theme().text_dim)
|
||||||
.when_some(author, |this, author| {
|
.when_some(author, |this, author| {
|
||||||
this.child(div().font_semibold().child(author))
|
this.child(div().font_semibold().child(author))
|
||||||
})
|
})
|
||||||
@@ -212,7 +212,7 @@ impl RenderOnce for MessageRow {
|
|||||||
.when_some(on_double_click, |this, listener| {
|
.when_some(on_double_click, |this, listener| {
|
||||||
this.on_double_click(listener)
|
this.on_double_click(listener)
|
||||||
})
|
})
|
||||||
.hover(|this| this.bg(cx.theme().surface_background))
|
.hover(|this| this.bg(cx.theme().element_hover))
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +305,7 @@ impl RenderOnce for WelcomeMessage {
|
|||||||
this.child(
|
this.child(
|
||||||
div()
|
div()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_color(cx.theme().text_placeholder)
|
.text_color(cx.theme().text_faint)
|
||||||
.child(message),
|
.child(message),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|||||||
+10
-6
@@ -4,7 +4,7 @@ use gpui::prelude::FluentBuilder as _;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, ElementId, InteractiveElement, Interactivity, IntoElement,
|
AnyElement, App, ClickEvent, ElementId, InteractiveElement, Interactivity, IntoElement,
|
||||||
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, StyleRefinement,
|
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, StyleRefinement,
|
||||||
Styled, Window, div,
|
Styled, Window, div, px,
|
||||||
};
|
};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
|
|
||||||
@@ -103,6 +103,11 @@ impl Styled for Nav {
|
|||||||
impl RenderOnce for Nav {
|
impl RenderOnce for Nav {
|
||||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let clickable = self.on_click.is_some() || self.clickable;
|
let clickable = self.on_click.is_some() || self.clickable;
|
||||||
|
let text_color = if self.selected {
|
||||||
|
cx.theme().text
|
||||||
|
} else {
|
||||||
|
cx.theme().text_muted
|
||||||
|
};
|
||||||
|
|
||||||
v_flex().h_10().w_full().items_center().child(
|
v_flex().h_10().w_full().items_center().child(
|
||||||
h_flex()
|
h_flex()
|
||||||
@@ -111,7 +116,8 @@ impl RenderOnce for Nav {
|
|||||||
.w_full()
|
.w_full()
|
||||||
.px_1p5()
|
.px_1p5()
|
||||||
.gap_1p5()
|
.gap_1p5()
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(px(theme::button_radius()))
|
||||||
|
.text_color(text_color)
|
||||||
.when_some(self.prefix, |this, prefix| this.child(prefix))
|
.when_some(self.prefix, |this, prefix| this.child(prefix))
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
@@ -125,10 +131,8 @@ impl RenderOnce for Nav {
|
|||||||
)
|
)
|
||||||
.when(clickable, |this| {
|
.when(clickable, |this| {
|
||||||
this.cursor_pointer()
|
this.cursor_pointer()
|
||||||
.hover(|this| this.bg(cx.theme().ghost_element_hover))
|
.hover(|this| this.bg(cx.theme().element_hover))
|
||||||
.when(self.selected, |this| {
|
.when(self.selected, |this| this.bg(cx.theme().element_active))
|
||||||
this.bg(cx.theme().ghost_element_active)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.when_some(self.on_click, |this, handler| {
|
.when_some(self.on_click, |this, handler| {
|
||||||
this.on_click(move |event, window, cx| handler(event, window, cx))
|
this.on_click(move |event, window, cx| handler(event, window, cx))
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use gpui::prelude::FluentBuilder as _;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, ElementId, InteractiveElement, Interactivity, IntoElement,
|
AnyElement, App, ClickEvent, ElementId, InteractiveElement, Interactivity, IntoElement,
|
||||||
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, StyleRefinement,
|
ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, StyleRefinement,
|
||||||
Styled, Window, div,
|
Styled, Window, div, px,
|
||||||
};
|
};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
|
|
||||||
@@ -86,6 +86,11 @@ impl Styled for NavItem {
|
|||||||
impl RenderOnce for NavItem {
|
impl RenderOnce for NavItem {
|
||||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let clickable = self.on_click.is_some();
|
let clickable = self.on_click.is_some();
|
||||||
|
let text_color = if self.selected {
|
||||||
|
cx.theme().text
|
||||||
|
} else {
|
||||||
|
cx.theme().text_muted
|
||||||
|
};
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(self.id)
|
.id(self.id)
|
||||||
@@ -94,8 +99,8 @@ impl RenderOnce for NavItem {
|
|||||||
.py_1()
|
.py_1()
|
||||||
.w_full()
|
.w_full()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(theme::button_radius()))
|
||||||
.text_color(cx.theme().text)
|
.text_color(text_color)
|
||||||
.child(self.icon)
|
.child(self.icon)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
@@ -110,10 +115,8 @@ impl RenderOnce for NavItem {
|
|||||||
})
|
})
|
||||||
.when(clickable, |this| {
|
.when(clickable, |this| {
|
||||||
this.cursor_pointer()
|
this.cursor_pointer()
|
||||||
.hover(|this| this.bg(cx.theme().ghost_element_hover))
|
.hover(|this| this.bg(cx.theme().element_hover))
|
||||||
.when(self.selected, |this| {
|
.when(self.selected, |this| this.bg(cx.theme().element_active))
|
||||||
this.bg(cx.theme().ghost_element_active)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.when_some(self.on_click, |this, handler| {
|
.when_some(self.on_click, |this, handler| {
|
||||||
this.on_click(move |event, window, cx| handler(event, window, cx))
|
this.on_click(move |event, window, cx| handler(event, window, cx))
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ pub enum NotificationKind {
|
|||||||
impl NotificationKind {
|
impl NotificationKind {
|
||||||
fn icon(&self, cx: &App) -> Icon {
|
fn icon(&self, cx: &App) -> Icon {
|
||||||
let (name, color) = match self {
|
let (name, color) = match self {
|
||||||
Self::Info => (IconName::Info, cx.theme().icon),
|
Self::Info => (IconName::Info, cx.theme().text_muted),
|
||||||
Self::Success => (IconName::CheckCircle, cx.theme().icon_accent),
|
Self::Success => (IconName::CheckCircle, cx.theme().success),
|
||||||
Self::Warning => (IconName::Warning, cx.theme().text_warning),
|
Self::Warning => (IconName::Warning, cx.theme().warning),
|
||||||
Self::Error => (IconName::CloseCircle, cx.theme().danger_foreground),
|
Self::Error => (IconName::CloseCircle, cx.theme().on_accent),
|
||||||
};
|
};
|
||||||
Icon::new(name).with_size(Size::Medium).text_color(color)
|
Icon::new(name).with_size(Size::Medium).text_color(color)
|
||||||
}
|
}
|
||||||
@@ -279,12 +279,12 @@ impl Render for Notification {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let background = match self.kind {
|
let background = match self.kind {
|
||||||
Some(NotificationKind::Error) => cx.theme().danger_background,
|
Some(NotificationKind::Error) => cx.theme().danger_strong,
|
||||||
_ => cx.theme().surface_background,
|
_ => cx.theme().surface_overlay,
|
||||||
};
|
};
|
||||||
|
|
||||||
let text_color = match self.kind {
|
let text_color = match self.kind {
|
||||||
Some(NotificationKind::Error) => cx.theme().danger_foreground,
|
Some(NotificationKind::Error) => cx.theme().on_accent,
|
||||||
_ => cx.theme().text,
|
_ => cx.theme().text,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -305,8 +305,10 @@ impl Render for Notification {
|
|||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.bg(background)
|
.bg(background)
|
||||||
.text_color(text_color)
|
.text_color(text_color)
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(px(theme::surface_radius()))
|
||||||
.when(cx.theme().shadow, |this| this.shadow_md())
|
.when(cx.theme().shadow, |this| {
|
||||||
|
this.shadow(theme::surface_shadows())
|
||||||
|
})
|
||||||
.p_2()
|
.p_2()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.justify_start()
|
.justify_start()
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ pub(crate) fn resize_handle_appearance() -> ResizeHandleRenderer {
|
|||||||
Rc::new(
|
Rc::new(
|
||||||
|context: &ResizeHandleContext, _: &mut Window, cx: &mut App| {
|
|context: &ResizeHandleContext, _: &mut Window, cx: &mut App| {
|
||||||
let color = if context.is_active() {
|
let color = if context.is_active() {
|
||||||
cx.theme().border_selected
|
cx.theme().border_strong
|
||||||
} else {
|
} else {
|
||||||
cx.theme().border
|
cx.theme().element_hover
|
||||||
};
|
};
|
||||||
let axis = context.axis();
|
let axis = context.axis();
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
div()
|
div()
|
||||||
.bg(cx.theme().border_variant)
|
.bg(cx.theme().border_faint)
|
||||||
.group_hover("handle", move |this| this.bg(color))
|
.group_hover("handle", move |this| this.bg(color))
|
||||||
.when(axis.is_horizontal(), |this| this.h_full().w(HANDLE_SIZE))
|
.when(axis.is_horizontal(), |this| this.h_full().w(HANDLE_SIZE))
|
||||||
.when(axis.is_vertical(), |this| this.w_full().h(HANDLE_SIZE))
|
.when(axis.is_vertical(), |this| this.w_full().h(HANDLE_SIZE))
|
||||||
|
|||||||
+7
-18
@@ -4,14 +4,14 @@ use std::rc::Rc;
|
|||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyView, App, AppContext, Bounds, Context, CursorStyle, Decorations, ElementId, Entity,
|
AnyView, App, AppContext, Bounds, Context, CursorStyle, Decorations, ElementId, Entity,
|
||||||
FocusHandle, HitboxBehavior, Hsla, InteractiveElement, IntoElement, MouseButton,
|
FocusHandle, HitboxBehavior, InteractiveElement, IntoElement, MouseButton, ParentElement as _,
|
||||||
ParentElement as _, Pixels, Point, Render, ResizeEdge, Size, Styled, Tiling, WeakFocusHandle,
|
Pixels, Point, Render, ResizeEdge, Size, Styled, Tiling, WeakFocusHandle, Window, canvas, div,
|
||||||
Window, canvas, div, point, px, size,
|
point, px, size,
|
||||||
};
|
};
|
||||||
use gpui_base::TextSelectionLayer;
|
use gpui_base::TextSelectionLayer;
|
||||||
use theme::{
|
use theme::{
|
||||||
ActiveTheme, CLIENT_SIDE_DECORATION_BORDER, CLIENT_SIDE_DECORATION_ROUNDING,
|
ActiveTheme, CLIENT_SIDE_DECORATION_BORDER, CLIENT_SIDE_DECORATION_ROUNDING,
|
||||||
CLIENT_SIDE_DECORATION_SHADOW,
|
CLIENT_SIDE_DECORATION_SHADOW, surface_shadows,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::dialog::Dialog;
|
use crate::dialog::Dialog;
|
||||||
@@ -354,19 +354,8 @@ impl Render for Root {
|
|||||||
.when(!tiling.right, |div| {
|
.when(!tiling.right, |div| {
|
||||||
div.border_r(CLIENT_SIDE_DECORATION_BORDER)
|
div.border_r(CLIENT_SIDE_DECORATION_BORDER)
|
||||||
})
|
})
|
||||||
.when(!tiling.is_tiled(), |div| {
|
.when(!tiling.is_tiled() && cx.theme().shadow, |div| {
|
||||||
div.shadow(vec![gpui::BoxShadow {
|
div.shadow(surface_shadows())
|
||||||
color: Hsla {
|
|
||||||
h: 0.,
|
|
||||||
s: 0.,
|
|
||||||
l: 0.,
|
|
||||||
a: 0.4,
|
|
||||||
},
|
|
||||||
blur_radius: CLIENT_SIDE_DECORATION_SHADOW / 2.,
|
|
||||||
spread_radius: px(0.),
|
|
||||||
offset: point(px(0.0), px(0.0)),
|
|
||||||
inset: false,
|
|
||||||
}])
|
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.on_mouse_move(|_e, _, cx| {
|
.on_mouse_move(|_e, _, cx| {
|
||||||
@@ -374,7 +363,7 @@ impl Render for Root {
|
|||||||
})
|
})
|
||||||
.size_full()
|
.size_full()
|
||||||
.font_family(font_family)
|
.font_family(font_family)
|
||||||
.bg(cx.theme().surface_background)
|
.bg(cx.theme().bg)
|
||||||
.text_color(cx.theme().text)
|
.text_color(cx.theme().text)
|
||||||
.child(TextSelectionLayer)
|
.child(TextSelectionLayer)
|
||||||
.child(self.view.clone()),
|
.child(self.view.clone()),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use gpui::{App, Div, Pixels, Refineable, StyleRefinement, Styled, div, px};
|
use gpui::{App, Div, Pixels, Refineable, StyleRefinement, Styled, div, px};
|
||||||
pub use gpui_base::component_traits::{Disableable, Selectable};
|
pub use gpui_base::component_traits::{Disableable, Selectable};
|
||||||
use theme::ActiveTheme;
|
use theme::{ActiveTheme, surface_radius, surface_shadows};
|
||||||
|
|
||||||
/// Returns a `Div` as horizontal flex layout.
|
/// Returns a `Div` as horizontal flex layout.
|
||||||
pub fn h_flex() -> Div {
|
pub fn h_flex() -> Div {
|
||||||
@@ -14,7 +14,7 @@ pub fn v_flex() -> Div {
|
|||||||
|
|
||||||
/// Returns a `Div` as divider.
|
/// Returns a `Div` as divider.
|
||||||
pub fn divider(cx: &App) -> Div {
|
pub fn divider(cx: &App) -> Div {
|
||||||
div().my_1().w_full().h_px().bg(cx.theme().border_variant)
|
div().my_1().w_full().h_px().bg(cx.theme().border_faint)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! font_weight {
|
macro_rules! font_weight {
|
||||||
@@ -53,11 +53,13 @@ pub trait StyledExt: Styled + Sized {
|
|||||||
/// Set as Popover style
|
/// Set as Popover style
|
||||||
#[inline]
|
#[inline]
|
||||||
fn popover_style(self, cx: &mut App) -> Self {
|
fn popover_style(self, cx: &mut App) -> Self {
|
||||||
self.bg(cx.theme().background)
|
let shadows = cx.theme().shadow.then(surface_shadows).unwrap_or_default();
|
||||||
|
|
||||||
|
self.bg(cx.theme().surface_overlay)
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.shadow_md()
|
.shadow(shadows)
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(px(surface_radius()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -4,7 +4,7 @@ use std::time::Duration;
|
|||||||
use gpui::prelude::FluentBuilder as _;
|
use gpui::prelude::FluentBuilder as _;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, ElementId, IntoElement, ParentElement as _, RenderOnce, SharedString, Styled as _, Window,
|
App, ElementId, IntoElement, ParentElement as _, RenderOnce, SharedString, Styled as _, Window,
|
||||||
div, px, white,
|
div, px, transparent_black,
|
||||||
};
|
};
|
||||||
use gpui_base::{Spring, Switch as BaseSwitch, SwitchThumb, SwitchTrack, spring};
|
use gpui_base::{Spring, Switch as BaseSwitch, SwitchThumb, SwitchTrack, spring};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
@@ -63,11 +63,17 @@ impl RenderOnce for Switch {
|
|||||||
let on_click = self.on_click.clone();
|
let on_click = self.on_click.clone();
|
||||||
|
|
||||||
let bg = if checked {
|
let bg = if checked {
|
||||||
cx.theme().element_background
|
cx.theme().accent_strong
|
||||||
} else {
|
} else {
|
||||||
cx.theme().elevated_surface_background
|
cx.theme().input_bg
|
||||||
|
};
|
||||||
|
let toggle_bg = cx.theme().on_solid;
|
||||||
|
// The border is structural (it insets the thumb); it only paints when off.
|
||||||
|
let track_border = if checked {
|
||||||
|
transparent_black()
|
||||||
|
} else {
|
||||||
|
cx.theme().border
|
||||||
};
|
};
|
||||||
let toggle_bg = white();
|
|
||||||
|
|
||||||
let bg_width = px(36.);
|
let bg_width = px(36.);
|
||||||
let bg_height = px(20.);
|
let bg_height = px(20.);
|
||||||
@@ -119,7 +125,7 @@ impl RenderOnce for Switch {
|
|||||||
.flex()
|
.flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
.border(inset)
|
.border(inset)
|
||||||
.border_color(cx.theme().border_transparent)
|
.border_color(track_border)
|
||||||
.bg(bg)
|
.bg(bg)
|
||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
+10
-12
@@ -3,7 +3,7 @@ use std::rc::Rc;
|
|||||||
use gpui::prelude::FluentBuilder as _;
|
use gpui::prelude::FluentBuilder as _;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, Div, InteractiveElement, IntoElement, MouseButton, ParentElement,
|
AnyElement, App, ClickEvent, Div, InteractiveElement, IntoElement, MouseButton, ParentElement,
|
||||||
RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div,
|
RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div, px,
|
||||||
};
|
};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
|
|
||||||
@@ -145,9 +145,9 @@ impl RenderOnce for Tab {
|
|||||||
let foreground = if disabled {
|
let foreground = if disabled {
|
||||||
cx.theme().text_muted
|
cx.theme().text_muted
|
||||||
} else if selected {
|
} else if selected {
|
||||||
cx.theme().tab_active_foreground
|
cx.theme().text
|
||||||
} else {
|
} else {
|
||||||
cx.theme().tab_foreground
|
cx.theme().text_muted
|
||||||
};
|
};
|
||||||
|
|
||||||
let content = h_flex()
|
let content = h_flex()
|
||||||
@@ -173,13 +173,13 @@ impl RenderOnce for Tab {
|
|||||||
this.text_xs()
|
this.text_xs()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.h_6()
|
.h_6()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(theme::button_radius()))
|
||||||
.when(selected && !disabled, |this| {
|
.when(selected && !disabled, |this| {
|
||||||
this.bg(cx.theme().tab_active_background)
|
this.bg(cx.theme().bg)
|
||||||
.when(cx.theme().shadow, |this| this.shadow_sm())
|
.when(cx.theme().shadow, |this| this.shadow_sm())
|
||||||
})
|
})
|
||||||
.when(!selected && !disabled, |this| {
|
.when(!selected && !disabled, |this| {
|
||||||
this.hover(|this| this.bg(cx.theme().tab_hover_background))
|
this.hover(|this| this.bg(cx.theme().element_hover))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.when(!segmented, |this| {
|
.when(!segmented, |this| {
|
||||||
@@ -189,15 +189,13 @@ impl RenderOnce for Tab {
|
|||||||
.gap_1()
|
.gap_1()
|
||||||
.px_1p5()
|
.px_1p5()
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(theme::button_radius()))
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.when(selected && !disabled, |this| {
|
.when(selected && !disabled, |this| this.bg(cx.theme().bg))
|
||||||
this.bg(cx.theme().tab_background)
|
|
||||||
})
|
|
||||||
.when(!selected && !disabled, |this| {
|
.when(!selected && !disabled, |this| {
|
||||||
this.hover(|this| {
|
this.hover(|this| {
|
||||||
this.bg(cx.theme().tab_hover_background)
|
this.bg(cx.theme().element_hover)
|
||||||
.text_color(cx.theme().tab_active_foreground)
|
.text_color(cx.theme().text)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -122,9 +122,9 @@ impl RenderOnce for TabBar {
|
|||||||
.min_w_0()
|
.min_w_0()
|
||||||
.refine_style(&self.style)
|
.refine_style(&self.style)
|
||||||
.when(segmented, |this| {
|
.when(segmented, |this| {
|
||||||
this.bg(cx.theme().tab_background)
|
this.bg(cx.theme().surface)
|
||||||
.p_0p5()
|
.p_0p5()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(theme::button_radius()))
|
||||||
})
|
})
|
||||||
.when_some(self.prefix, |this, prefix| this.child(prefix))
|
.when_some(self.prefix, |this, prefix| this.child(prefix))
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use gpui::{
|
|||||||
RenderOnce, Stateful, StatefulInteractiveElement as _, Styled, Window, WindowControlArea, div,
|
RenderOnce, Stateful, StatefulInteractiveElement as _, Styled, Window, WindowControlArea, div,
|
||||||
px,
|
px,
|
||||||
};
|
};
|
||||||
use theme::ActiveTheme;
|
use theme::{ActiveTheme, plate_active};
|
||||||
|
|
||||||
use crate::{Icon, IconName, Sizable as _, h_flex};
|
use crate::{Icon, IconName, Sizable as _, h_flex};
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ impl ControlIcon {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn hover_fg(&self, cx: &App) -> Hsla {
|
fn hover_fg(&self, cx: &App) -> Hsla {
|
||||||
if self.is_close() {
|
if self.is_close() {
|
||||||
cx.theme().danger_foreground
|
cx.theme().on_accent
|
||||||
} else {
|
} else {
|
||||||
cx.theme().text
|
cx.theme().text
|
||||||
}
|
}
|
||||||
@@ -79,18 +79,18 @@ impl ControlIcon {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn hover_bg(&self, cx: &App) -> Hsla {
|
fn hover_bg(&self, cx: &App) -> Hsla {
|
||||||
if self.is_close() {
|
if self.is_close() {
|
||||||
cx.theme().danger_background
|
cx.theme().danger_strong
|
||||||
} else {
|
} else {
|
||||||
cx.theme().ghost_element_hover
|
cx.theme().element_hover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn active_bg(&self, cx: &mut App) -> Hsla {
|
fn active_bg(&self, cx: &mut App) -> Hsla {
|
||||||
if self.is_close() {
|
if self.is_close() {
|
||||||
cx.theme().danger_active
|
plate_active(cx.theme().danger_strong)
|
||||||
} else {
|
} else {
|
||||||
cx.theme().ghost_element_active
|
cx.theme().element_active
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
|
App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
|
||||||
Window, relative,
|
Window, px, relative,
|
||||||
};
|
};
|
||||||
use gpui_base::Tooltip as BaseTooltip;
|
use gpui_base::Tooltip as BaseTooltip;
|
||||||
use theme::ActiveTheme;
|
use theme::{ActiveTheme, control_radius};
|
||||||
|
|
||||||
pub struct Tooltip {
|
pub struct Tooltip {
|
||||||
text: SharedString,
|
text: SharedString,
|
||||||
@@ -24,9 +24,9 @@ impl Render for Tooltip {
|
|||||||
.p_1p5()
|
.p_1p5()
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.bg(cx.theme().surface_background)
|
.bg(cx.theme().surface_overlay)
|
||||||
.when(cx.theme().shadow, |this| this.shadow_sm())
|
.when(cx.theme().shadow, |this| this.shadow_sm())
|
||||||
.rounded(cx.theme().radius)
|
.rounded(px(control_radius()))
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_color(cx.theme().text)
|
.text_color(cx.theme().text)
|
||||||
.line_height(relative(1.25))
|
.line_height(relative(1.25))
|
||||||
|
|||||||
@@ -281,51 +281,90 @@ Keep public APIs (D2). Per file, replace old token reads with new tokens,
|
|||||||
radii with ratio functions, ad-hoc spacing with `SPACE` steps where it is a
|
radii with ratio functions, ad-hoc spacing with `SPACE` steps where it is a
|
||||||
real deviation, and state washes with the paint helpers.
|
real deviation, and state washes with the paint helpers.
|
||||||
|
|
||||||
- [ ] `button.rs` — variant table: Primary → `solid`/`on_solid` +
|
- [x] `button.rs` — variant table: Primary → `solid`/`on_solid` +
|
||||||
`surface_raised_hover`-style plate hover; Secondary →
|
`surface_raised_hover`-style plate hover; Secondary →
|
||||||
`surface_raised` + `border` + `text`; Danger → `danger_strong` +
|
`surface_raised` + `border` + `text`; Danger → `danger_strong` +
|
||||||
`on_accent`; Warning → `warning_muted` chip treatment; Ghost →
|
`on_accent`; Warning → `warning_muted` chip treatment; Ghost →
|
||||||
transparent + `element_hover`/`element_active`; Custom stays (sources
|
transparent + `element_hover`/`element_active`; Custom stays (sources
|
||||||
defaults from new tokens). Size → bezel `ControlSize` ladder values via
|
defaults from new tokens). Size → bezel `ControlSize` ladder values via
|
||||||
the existing `Size` enum. Radius: `button_radius()`, `bubble_radius()`
|
the existing `Size` enum. Radius: `button_radius()`, `bubble_radius()`
|
||||||
when `rounded`.
|
when `rounded`. *(Size ladder heights kept — bezel's 24px control
|
||||||
- [ ] `input/` — `input_bg`, `border_faint` resting / `border_strong` focus,
|
heights are a consumer-visible layout change, deferred.)*
|
||||||
`ring`, `caret`, `selection`, `text_faint` placeholder.
|
- [x] `input/` — `input_bg`, `border_faint` resting / `border_strong` focus,
|
||||||
- [ ] `dialog.rs` — `surface_dialog` over `scrim()`, `surface_radius()`,
|
`ring`, `caret`, `selection`, `text_faint` placeholder. *(coop's Input
|
||||||
frame shadows.
|
paints no frame border/ring of its own — focus mechanics untouched;
|
||||||
- [ ] `popover.rs`, `menu/` — `surface_overlay`, hairline border,
|
`InputEditorStyle::border` now `border_faint`, placeholder reaches
|
||||||
`popover_surface` stub (D6: plain wash for now).
|
gpui-base's `muted_foreground`, now `text_faint`.)*
|
||||||
- [ ] `tab.rs` — mapping table row: `bg` active plane, `element_hover`
|
- [x] `dialog.rs` — `surface_dialog` over `scrim(SCRIM_ALPHA_DARK)`,
|
||||||
hover, `text_muted`/`text` labels, `border_faint` separators.
|
`surface_radius()`, `surface_shadows()` (entrance animation scales the
|
||||||
- [ ] `nav.rs`, `nav_item.rs` — `element_hover`/`element_active` states,
|
helper's shadow alphas).
|
||||||
`accent` selection markers.
|
- [x] `popover.rs`, `menu/` — `surface_overlay`, hairline border,
|
||||||
- [ ] `title_bar.rs` — `surface`; drag handlers unchanged; height stays 36.
|
`popover_surface` stub (D6: plain wash for now). *(The floating plate
|
||||||
- [ ] `tooltip.rs` — `surface_overlay` plate, `text` label.
|
is `StyledExt::popover_style` in styled.rs; popover.rs itself paints no
|
||||||
- [ ] `switch.rs` — on: `accent_strong` track + `on_solid` knob; off:
|
theme values. Menu item corners are concentric:
|
||||||
|
`inset_radius(surface_radius(), 4)`.)*
|
||||||
|
- [x] `tab.rs` — mapping table row: `bg` active plane, `element_hover`
|
||||||
|
hover, `text_muted`/`text` labels, `border_faint` separators. *(No
|
||||||
|
separator was painted before; none added — structure frozen. Segmented
|
||||||
|
track is `surface`.)*
|
||||||
|
- [x] `nav.rs`, `nav_item.rs` — `element_hover`/`element_active` states,
|
||||||
|
`accent` selection markers. *(Resting labels are now `text_muted` —
|
||||||
|
intentional visible change; radius 12→8.)*
|
||||||
|
- [x] `title_bar.rs` — the crate never read `title_bar`/`title_bar_inactive`
|
||||||
|
(consumers paint the strip); close-button danger hover reskinned to
|
||||||
|
`danger_strong`/`on_accent`/`plate_active`. Drag handlers and heights
|
||||||
|
untouched.
|
||||||
|
- [x] `tooltip.rs` — `surface_overlay` plate, `text` label,
|
||||||
|
`control_radius()`.
|
||||||
|
- [x] `switch.rs` — on: `accent_strong` track + `on_solid` knob; off:
|
||||||
`input_bg` track + `border`.
|
`input_bg` track + `border`.
|
||||||
- [ ] `indicator.rs`, `kbd.rs` — indicator gets `success`/`busy`/`danger`
|
- [x] `indicator.rs`, `kbd.rs` — indicator turned out to be the loading
|
||||||
dots; kbd: `surface_raised` + `border_faint` + `text_muted`.
|
spinner and paints no theme values (no status dots exist in `crates/ui`
|
||||||
- [ ] `avatar.rs` — `border_faint` ring; keep blob behavior.
|
— the `success`/`busy`/`danger` mapping lands at consumer call sites in
|
||||||
- [ ] `message.rs` — `bubble_radius()` on bubbles, `text_dim` for file-path /
|
Phase 3). kbd: `surface_raised` + `border_faint` + `text_muted`.
|
||||||
secondary labels, `success`/`busy`/`danger` delivery states, `band` for
|
- [x] `avatar.rs` — no ring/border is painted today; dropped the
|
||||||
composer strips.
|
`ghost_element_background` underlay. Blob behavior kept.
|
||||||
- [ ] `markdown.rs` — `code_text`/`code_wash`, `SyntaxPalette`,
|
- [x] `message.rs` — `text_dim` on the author/timestamp row, `text_faint`
|
||||||
`text_muted` headings hierarchy.
|
welcome body, `element_hover` row wash. *(No bubbles, delivery states,
|
||||||
- [ ] `notification.rs` — `surface_overlay` plate + semantic accents.
|
composer strips or report banners live in this file — those are
|
||||||
- [ ] `group_box.rs` — `panel_radius()`, `border_faint`, `band` header.
|
consumer-side, Phase 3.)*
|
||||||
- [ ] `dock/`, `resizable/` — `drop_target`, `drop_line`, `border_faint`.
|
- [x] `markdown.rs` — `code_text`/`code_wash` (added `with_inline_code`),
|
||||||
- [ ] `scroll/` — scrollbar paints from gpui-base tokens; verify
|
heading hierarchy (`with_heading`: h1–h3 `text`, h4–h6 `text_muted`),
|
||||||
`ScrollbarMode` setting still lands via `sync_base`.
|
links `accent`. *(Fenced-code highlighting comes from gpui-base's theme
|
||||||
- [ ] `root.rs` — `bg` + `border` window frame, frame shadows.
|
via `sync_base`; `SyntaxPalette` stays unconsumed until a coop-side
|
||||||
- [ ] `icon.rs` — tones from text tokens; keep the `IconName` set as-is.
|
highlighter exists.)*
|
||||||
- [ ] `styled.rs` — `divider()` → `border_faint` / `hairline()`;
|
- [x] `notification.rs` — `surface_overlay` plate + `surface_radius()` +
|
||||||
`popover_style()` → `surface_overlay` + `surface_radius()`. Keep
|
`surface_shadows()`; error is a full `danger_strong` plate with
|
||||||
|
`on_accent`, success/warning icons `success`/`warning`.
|
||||||
|
- [x] `group_box.rs` — `surface` plate, `panel_radius()`. *(No border or
|
||||||
|
header strip is painted today; adding them is a design change, deferred
|
||||||
|
to Phase 3/4 review.)*
|
||||||
|
- [x] `dock/`, `resizable/` — `drop_target`, `drop_line`, `border_faint`.
|
||||||
|
*(Tab-insertion line and drop-region outline both use `drop_line` now —
|
||||||
|
slightly more prominent than the old muted outline, intentional. Drag
|
||||||
|
preview/empty-space drag-over also reskinned.)*
|
||||||
|
- [x] `scroll/` — verified: zero theme reads; scrollbar paint comes from
|
||||||
|
gpui-base via `sync_base`, `ScrollbarMode` still lands.
|
||||||
|
- [x] `root.rs` — `bg` plane, `surface_shadows()` on the window frame (now
|
||||||
|
gated on `cx.theme().shadow`); decoration consts untouched.
|
||||||
|
- [x] `icon.rs` — default tone `text_muted` (was `icon`); `IconName` set and
|
||||||
|
APIs unchanged.
|
||||||
|
- [x] `styled.rs` — `divider()` → `border_faint`; `popover_style()` →
|
||||||
|
`surface_overlay` + `px(surface_radius())` + `surface_shadows()` gated
|
||||||
|
on `cx.theme().shadow` (was always-on `shadow_md`). Keep
|
||||||
`h_flex`/`v_flex` names (bezel's `stack::row`/`column` equivalents).
|
`h_flex`/`v_flex` names (bezel's `stack::row`/`column` equivalents).
|
||||||
- [ ] `animation.rs` — leave as-is this pass; note bezel's named-motion
|
- [x] `animation.rs` — left as-is this pass; bezel's named-motion catalog is
|
||||||
catalog as follow-up.
|
a follow-up.
|
||||||
|
|
||||||
Validation: `cargo check -p ui`, run desktop, walk every component in
|
Outcome: `theme::plate_hover`/`plate_active` were made public (wrappers over
|
||||||
light/dark against Phase 0 screenshots.
|
the crate-internal `*_for` helpers) so `crates/ui` can reskin opaque plates.
|
||||||
|
Zero legacy-token reads remain in `crates/ui` (the Phase 3 grep already
|
||||||
|
passes inside this crate); `cargo check -p ui`, `cargo check --workspace`,
|
||||||
|
`cargo test -p theme` (11 tests) and `cargo clippy -p ui -p theme` are green.
|
||||||
|
Public APIs, element structure, sizes and heights unchanged (D2, D7).
|
||||||
|
|
||||||
|
Validation remaining: run desktop, walk every component in light/dark
|
||||||
|
against the Phase 0 screenshots.
|
||||||
|
|
||||||
### Phase 3 — Migrate consumers
|
### Phase 3 — Migrate consumers
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user