theme: Ensure all elements to use radius. (#596)

- Fix menu dispatch action.
This commit is contained in:
Jason Lee 2025-02-03 19:03:16 +08:00 committed by GitHub
parent eaec664a8d
commit 3ffbbb0688
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 113 additions and 72 deletions

View file

@ -259,7 +259,7 @@ impl Render for DropdownStory {
.w_full()
.items_center()
.p_10()
.rounded_lg()
.rounded(cx.theme().radius)
.bg(cx.theme().card)
.border_1()
.border_color(cx.theme().border)

View file

@ -74,7 +74,13 @@ pub struct SelectLocale(SharedString);
#[derive(Clone, PartialEq, Eq, Deserialize)]
pub struct SelectFont(usize);
impl_internal_actions!(story, [SelectLocale, SelectFont, SelectScrollbarShow,]);
#[derive(Clone, PartialEq, Eq, Deserialize)]
pub struct SelectRadius(usize);
impl_internal_actions!(
story,
[SelectLocale, SelectFont, SelectRadius, SelectScrollbarShow,]
);
actions!(story, [Quit, Open, CloseWindow]);
@ -231,7 +237,7 @@ pub fn section(title: impl IntoElement, cx: &App) -> Div {
.gap_4()
.p_4()
.w_full()
.rounded_lg()
.rounded(cx.theme().radius)
.border_1()
.border_color(theme.border)
.flex_wrap()

View file

@ -128,7 +128,7 @@ impl RenderOnce for CompanyListItem {
.child(
h_flex().w(px(65.)).justify_end().child(
div()
.rounded_md()
.rounded(cx.theme().radius)
.whitespace_nowrap()
.text_size(px(12.))
.px_1()
@ -428,7 +428,7 @@ impl Render for ListStory {
.w_full()
.border_1()
.border_color(cx.theme().border)
.rounded_md()
.rounded(cx.theme().radius)
.child(self.company_list.clone()),
)
}

View file

@ -324,7 +324,7 @@ impl ModalStory {
div()
.border_1()
.border_color(cx.theme().border)
.rounded_md()
.rounded(cx.theme().radius)
.size_full()
.flex_1()
.h(list_h)

View file

@ -11,7 +11,7 @@ use ui::{
progress::Progress,
skeleton::Skeleton,
slider::{Slider, SliderEvent},
v_flex, Colorize as _, ContextModal, IconName, Sizable,
v_flex, ActiveTheme as _, Colorize as _, ContextModal, IconName, Sizable,
};
pub struct ProgressStory {
@ -271,7 +271,7 @@ impl Render for ProgressStory {
h_flex()
.w_32()
.p_1()
.rounded_lg()
.rounded(cx.theme().radius)
.justify_center()
.bg(self.slider_hsl_value)
.child(rgb.clone())

View file

@ -200,7 +200,7 @@ impl Render for SidebarStory {
];
h_flex()
.rounded_md()
.rounded(cx.theme().radius)
.border_1()
.border_color(cx.theme().border)
.h_full()
@ -216,7 +216,7 @@ impl Render for SidebarStory {
.flex()
.items_center()
.justify_center()
.rounded_md()
.rounded(cx.theme().radius)
.bg(ui::blue_500())
.text_color(ui::white())
.size_8()

View file

@ -84,7 +84,7 @@ impl Render for SwitchStory {
.gap_4()
.p_4()
.w_full()
.rounded_lg()
.rounded(cx.theme().radius)
.border_1()
.border_color(theme.border)
}

View file

@ -1,7 +1,7 @@
use std::rc::Rc;
use gpui::{
div, AnyElement, App, AppContext, ClickEvent, Context, Corner, Entity, FocusHandle, Hsla,
div, px, AnyElement, App, AppContext, ClickEvent, Context, Corner, Entity, FocusHandle, Hsla,
InteractiveElement as _, IntoElement, MouseButton, ParentElement as _, Render, SharedString,
Styled as _, Window,
};
@ -15,7 +15,7 @@ use ui::{
ActiveTheme as _, ContextModal as _, IconName, Sizable as _, Theme, TitleBar,
};
use crate::{SelectFont, SelectLocale, SelectScrollbarShow};
use crate::{SelectFont, SelectLocale, SelectRadius, SelectScrollbarShow};
pub struct AppTitleBar {
title: SharedString,
@ -226,7 +226,17 @@ impl FontSizeSelector {
window: &mut Window,
cx: &mut Context<Self>,
) {
Theme::global_mut(cx).font_size = font_size.0 as f32;
Theme::global_mut(cx).font_size = px(font_size.0 as f32);
window.refresh();
}
fn on_select_radius(
&mut self,
radius: &SelectRadius,
window: &mut Window,
cx: &mut Context<Self>,
) {
Theme::global_mut(cx).radius = px(radius.0 as f32);
window.refresh();
}
@ -244,13 +254,15 @@ impl FontSizeSelector {
impl Render for FontSizeSelector {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let focus_handle = self.focus_handle.clone();
let font_size = cx.theme().font_size as i32;
let font_size = cx.theme().font_size.0 as i32;
let radius = cx.theme().radius.0 as i32;
let scroll_show = cx.theme().scrollbar_show;
div()
.id("font-size-selector")
.track_focus(&focus_handle)
.on_action(cx.listener(Self::on_select_font))
.on_action(cx.listener(Self::on_select_radius))
.on_action(cx.listener(Self::on_select_scrollbar_show))
.child(
Button::new("btn")
@ -266,6 +278,14 @@ impl Render for FontSizeSelector {
.menu_with_check("Font Default", font_size == 16, Box::new(SelectFont(16)))
.menu_with_check("Font Small", font_size == 14, Box::new(SelectFont(14)))
.separator()
.menu_with_check("Radius 8px", radius == 8, Box::new(SelectRadius(8)))
.menu_with_check(
"Radius 4px (default)",
radius == 4,
Box::new(SelectRadius(4)),
)
.menu_with_check("Radius 0px", radius == 0, Box::new(SelectRadius(0)))
.separator()
.menu_with_check(
"Scrolling to show Scrollbar",
scroll_show == ScrollbarShow::Scrolling,

View file

@ -223,7 +223,9 @@ impl RenderOnce for AccordionItem {
.bg(cx.theme().accordion)
.overflow_hidden()
.when(self.bordered, |this| {
this.border_1().border_color(cx.theme().border).rounded_md()
this.border_1()
.border_color(cx.theme().border)
.rounded(cx.theme().radius)
})
.text_size(text_size)
.child(

View file

@ -3,8 +3,8 @@ use crate::{
Selectable, Sizable, Size,
};
use gpui::{
div, prelude::FluentBuilder as _, px, relative, AnyElement, App, ClickEvent, Corners, Div,
Edges, ElementId, Hsla, InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels,
div, prelude::FluentBuilder as _, relative, AnyElement, App, ClickEvent, Corners, Div, Edges,
ElementId, Hsla, InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels,
RenderOnce, SharedString, StatefulInteractiveElement as _, Styled, Window,
};
@ -359,9 +359,9 @@ impl RenderOnce for Button {
.when(
self.border_corners.top_left && self.border_corners.bottom_left,
|this| match self.rounded {
ButtonRounded::Small => this.rounded_l(px(cx.theme().radius * 0.5)),
ButtonRounded::Medium => this.rounded_l(px(cx.theme().radius)),
ButtonRounded::Large => this.rounded_l(px(cx.theme().radius * 2.0)),
ButtonRounded::Small => this.rounded_l(cx.theme().radius * 0.5),
ButtonRounded::Medium => this.rounded_l(cx.theme().radius),
ButtonRounded::Large => this.rounded_l(cx.theme().radius * 2.0),
ButtonRounded::Size(px) => this.rounded_l(px),
ButtonRounded::None => this.rounded_none(),
},
@ -369,9 +369,9 @@ impl RenderOnce for Button {
.when(
self.border_corners.top_right && self.border_corners.bottom_right,
|this| match self.rounded {
ButtonRounded::Small => this.rounded_r(px(cx.theme().radius * 0.5)),
ButtonRounded::Medium => this.rounded_r(px(cx.theme().radius)),
ButtonRounded::Large => this.rounded_r(px(cx.theme().radius * 2.0)),
ButtonRounded::Small => this.rounded_r(cx.theme().radius * 0.5),
ButtonRounded::Medium => this.rounded_r(cx.theme().radius),
ButtonRounded::Large => this.rounded_r(cx.theme().radius * 2.0),
ButtonRounded::Size(px) => this.rounded_r(px),
ButtonRounded::None => this.rounded_none(),
},

View file

@ -1,6 +1,6 @@
use crate::{h_flex, v_flex, ActiveTheme, Disableable, IconName, Selectable};
use gpui::{
div, prelude::FluentBuilder as _, relative, svg, App, ElementId, InteractiveElement,
div, prelude::FluentBuilder as _, px, relative, svg, App, ElementId, InteractiveElement,
IntoElement, ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _,
Styled as _, Window,
};
@ -69,6 +69,7 @@ impl RenderOnce for Checkbox {
} else {
(cx.theme().primary, cx.theme().primary_foreground)
};
let radius = (cx.theme().radius / 2.).min(px(6.));
// wrap a flex to patch for let Checkbox display inline
div().flex().child(
@ -82,7 +83,7 @@ impl RenderOnce for Checkbox {
.relative()
.border_1()
.border_color(color)
.rounded_sm()
.rounded(radius)
.size_4()
.flex_shrink_0()
.map(|this| match self.checked {

View file

@ -260,7 +260,7 @@ impl ColorPicker {
.border_1()
.border_color(hovered_color.darken(0.2))
.size_5()
.rounded(px(cx.theme().radius)),
.rounded(cx.theme().radius),
)
.child(self.color_input.clone()),
)
@ -320,7 +320,7 @@ impl Render for ColorPicker {
.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().input)
.rounded(px(cx.theme().radius))
.rounded(cx.theme().radius)
.bg(cx.theme().background)
.shadow_sm()
.overflow_hidden()
@ -359,12 +359,12 @@ impl Render for ColorPicker {
})
.w_72()
.overflow_hidden()
.rounded_lg()
.rounded(cx.theme().radius)
.p_3()
.border_1()
.border_color(cx.theme().border)
.shadow_lg()
.rounded_lg()
.rounded(cx.theme().radius)
.bg(cx.theme().background)
.on_mouse_up_out(
MouseButton::Left,

View file

@ -55,7 +55,7 @@ impl Render for DragPanel {
.whitespace_nowrap()
.border_1()
.border_color(cx.theme().border)
.rounded_md()
.rounded(cx.theme().radius)
.text_color(cx.theme().tab_foreground)
.bg(cx.theme().tab_active)
.opacity(0.75)

View file

@ -608,6 +608,7 @@ where
let bounds = self.bounds;
let allow_open = !(self.open || self.disabled);
let outline_visible = self.open || is_focused && !self.disabled;
let popup_radius = cx.theme().radius.min(px(8.));
// If the size has change, set size to self.list, to change the QueryInput size.
if self.list.read(cx).size != self.size {
@ -636,7 +637,7 @@ where
.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().input)
.rounded(px(cx.theme().radius))
.rounded(cx.theme().radius)
.when(cx.theme().shadow, |this| this.shadow_sm())
.map(|this| {
if self.disabled {
@ -726,7 +727,7 @@ where
.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().border)
.rounded(px(cx.theme().radius))
.rounded(popup_radius)
.shadow_md()
.on_mouse_down_out(|_, _, cx| {
cx.dispatch_action(&Escape);

View file

@ -1619,7 +1619,7 @@ impl Render for TextInput {
})
.border_color(cx.theme().input)
.border_1()
.rounded(px(cx.theme().radius))
.rounded(cx.theme().radius)
.when(cx.theme().shadow, |this| this.shadow_sm())
.when(focused, |this| this.outline(cx))
})

View file

@ -178,7 +178,7 @@ impl Render for NumberInput {
.bg(cx.theme().background)
.border_color(cx.theme().input)
.border_1()
.rounded_md()
.rounded(cx.theme().radius)
.when(focused, |this| this.outline(cx))
.child(
Button::new("minus")

View file

@ -233,7 +233,7 @@ impl Render for OtpInput {
.when(cx.theme().shadow, |this| this.shadow_sm())
.items_center()
.justify_center()
.rounded_md()
.rounded(cx.theme().radius)
.text_size(text_size)
.map(|this| match self.size {
Size::XSmall => this.w_6().h_6(),

View file

@ -112,11 +112,13 @@ pub(crate) fn overlay_color(overlay: bool, _: &Window, cx: &App) -> Hsla {
impl Modal {
pub fn new(_: &mut Window, cx: &mut App) -> Self {
let radius = (cx.theme().radius * 2.).min(px(20.));
let base = v_flex()
.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().border)
.rounded_lg()
.rounded(radius)
.shadow_xl()
.min_h_24()
.p_4()

View file

@ -224,7 +224,7 @@ impl Render for Notification {
.border_1()
.border_color(cx.theme().border)
.bg(cx.theme().popover)
.rounded_md()
.rounded(cx.theme().radius)
.shadow_md()
.py_2()
.px_4()

View file

@ -274,7 +274,7 @@ impl PopupMenu {
window.focus(&handle);
}
cx.dispatch_action(action.as_ref());
window.dispatch_action(action.boxed_clone(), cx);
})
}
@ -521,6 +521,7 @@ impl Render for PopupMenu {
);
const ITEM_HEIGHT: Pixels = px(26.);
let item_radius = cx.theme().radius.min(px(8.));
v_flex()
.id("popup-menu")
@ -573,7 +574,7 @@ impl Render for PopupMenu {
.text_sm()
.py_0()
.px_1()
.rounded_md()
.rounded(item_radius)
.items_center()
.on_mouse_enter(cx.listener(move |this, _, _, cx| {
this.hovered_menu_ix = Some(ix);

View file

@ -27,7 +27,8 @@ impl Progress {
impl RenderOnce for Progress {
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
let rounded = px(self.height / 2.);
// Match the theme radius, if theme radius is zero use it.
let radius = px(self.height / 2.).min(cx.theme().radius);
let relative_w = relative(match self.value {
v if v < 0. => 0.,
v if v > 100. => 1.,
@ -37,7 +38,7 @@ impl RenderOnce for Progress {
div()
.relative()
.h(px(self.height))
.rounded(rounded)
.rounded(radius)
.bg(cx.theme().progress_bar.opacity(0.2))
.child(
div()
@ -48,8 +49,8 @@ impl RenderOnce for Progress {
.w(relative_w)
.bg(cx.theme().progress_bar)
.map(|this| match self.value {
v if v >= 100. => this.rounded(rounded),
_ => this.rounded_l(rounded),
v if v >= 100. => this.rounded(radius),
_ => this.rounded_l(radius),
}),
)
}

View file

@ -63,7 +63,7 @@ impl RenderOnce for SidebarFooter {
.w_full()
.justify_between()
.cursor_pointer()
.rounded_md()
.rounded(cx.theme().radius)
.hover(|this| {
this.bg(cx.theme().sidebar_accent)
.text_color(cx.theme().sidebar_accent_foreground)

View file

@ -53,7 +53,7 @@ impl<E: Collapsible + IntoElement> RenderOnce for SidebarGroup<E> {
div()
.flex_shrink_0()
.px_2()
.rounded_md()
.rounded(cx.theme().radius)
.text_xs()
.text_color(cx.theme().sidebar_foreground.opacity(0.7))
.h_8()

View file

@ -63,7 +63,7 @@ impl RenderOnce for SidebarHeader {
.w_full()
.justify_between()
.cursor_pointer()
.rounded_md()
.rounded(cx.theme().radius)
.hover(|this| {
this.bg(cx.theme().sidebar_accent)
.text_color(cx.theme().sidebar_accent_foreground)

View file

@ -167,7 +167,7 @@ impl SidebarMenuItem {
.p_2()
.gap_2()
.items_center()
.rounded_md()
.rounded(cx.theme().radius)
.text_sm()
.cursor_pointer()
.hover(|this| {

View file

@ -13,7 +13,7 @@ pub struct Skeleton {
impl Skeleton {
pub fn new() -> Self {
Self {
base: div().w_full().h_4().rounded_md(),
base: div().w_full().h_4(),
secondary: false,
}
}

View file

@ -138,7 +138,7 @@ pub trait StyledExt: Styled + Sized {
.border_1()
.border_color(cx.theme().border)
.shadow_lg()
.rounded(px(cx.theme().radius))
.rounded(cx.theme().radius)
}
}

View file

@ -122,6 +122,11 @@ impl Element for Switch {
_ => px(16.),
};
let inset = px(2.);
let radius = if cx.theme().radius >= px(4.) {
bg_height
} else {
cx.theme().radius
};
let mut element = div()
.flex()
@ -137,7 +142,7 @@ impl Element for Switch {
.id(self.id.clone())
.w(bg_width)
.h(bg_height)
.rounded(bg_height / 2.)
.rounded(radius)
.flex()
.items_center()
.border(inset)
@ -146,7 +151,7 @@ impl Element for Switch {
.when(!self.disabled, |this| this.cursor_pointer())
.child(
// Switch Toggle
div().rounded_full().bg(toggle_bg).size(bar_width).map(
div().rounded(radius).bg(toggle_bg).size(bar_width).map(
|this| {
let prev_checked = state.prev_checked.clone();
if !self.disabled

View file

@ -1008,7 +1008,7 @@ where
.id(("icon-sort", col_ix))
.cursor_pointer()
.p(px(2.))
.rounded_sm()
.rounded(cx.theme().radius / 2.)
.map(|this| match is_on {
true => this,
false => this.opacity(0.5),
@ -1594,7 +1594,9 @@ where
div()
.size_full()
.when(self.border, |this| {
this.rounded_md().border_1().border_color(cx.theme().border)
this.rounded(cx.theme().radius)
.border_1()
.border_color(cx.theme().border)
})
.bg(cx.theme().table)
.when(loading, |this| {

View file

@ -61,9 +61,9 @@ pub struct Tag {
impl Tag {
fn new() -> Self {
Self {
base: div().flex().items_center().rounded_md().border_1(),
base: div().flex().items_center().border_1(),
variant: TagVariant::default(),
size: Size::Medium,
size: Size::default(),
}
}
@ -111,9 +111,10 @@ impl RenderOnce for Tag {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
self.base
.line_height(relative(1.3))
.text_xs()
.map(|this| match self.size {
Size::XSmall | Size::Small => this.text_xs().px_1p5().py_0(),
_ => this.text_xs().px_2p5().py_0p5(),
Size::XSmall | Size::Small => this.px_1p5().py_0().rounded(cx.theme().radius / 2.),
_ => this.px_2p5().py_0p5().rounded(cx.theme().radius),
})
.bg(self.variant.bg(cx))
.text_color(self.variant.fg(cx))

View file

@ -1,7 +1,7 @@
use std::ops::{Deref, DerefMut};
use gpui::{
hsla, point, App, BoxShadow, Global, Hsla, Pixels, SharedString, Window, WindowAppearance,
hsla, point, px, App, BoxShadow, Global, Hsla, Pixels, SharedString, Window, WindowAppearance,
};
use crate::{scroll::ScrollbarShow, Colorize as _};
@ -364,8 +364,8 @@ pub struct Theme {
pub mode: ThemeMode,
pub font_family: SharedString,
pub font_size: f32,
pub radius: f32,
pub font_size: Pixels,
pub radius: Pixels,
pub shadow: bool,
pub transparent: Hsla,
/// Show the scrollbar mode, default: Scrolling
@ -508,7 +508,7 @@ impl From<ThemeColor> for Theme {
Theme {
mode: ThemeMode::default(),
transparent: Hsla::transparent_black(),
font_size: 16.0,
font_size: px(16.),
font_family: if cfg!(target_os = "macos") {
".SystemUIFont".into()
} else if cfg!(target_os = "windows") {
@ -516,7 +516,7 @@ impl From<ThemeColor> for Theme {
} else {
"FreeMono".into()
},
radius: 4.0,
radius: px(4.),
shadow: true,
scrollbar_show: ScrollbarShow::default(),
colors,

View file

@ -350,9 +350,9 @@ impl Calendar {
) -> impl IntoElement {
h_flex()
.map(|this| match self.size {
Size::Small => this.size_7().rounded_sm(),
Size::Large => this.size_10().rounded_md(),
_ => this.size_9().rounded_md(),
Size::Small => this.size_7().rounded(cx.theme().radius / 2.0),
Size::Large => this.size_10().rounded(cx.theme().radius),
_ => this.size_9().rounded(cx.theme().radius),
})
.justify_center()
.text_color(cx.theme().muted_foreground)
@ -374,9 +374,9 @@ impl Calendar {
h_flex()
.id(id.into())
.map(|this| match self.size {
Size::Small => this.size_7().rounded_md(),
Size::Large => this.size_10().rounded_lg(),
_ => this.size_9().rounded_lg(),
Size::Small => this.size_7().rounded(cx.theme().radius),
Size::Large => this.size_10().rounded(cx.theme().radius * 2.),
_ => this.size_9().rounded(cx.theme().radius * 2.),
})
.justify_center()
.cursor_pointer()

View file

@ -307,7 +307,7 @@ impl Render for DatePicker {
.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().input)
.rounded(px(cx.theme().radius))
.rounded(cx.theme().radius)
.when(cx.theme().shadow, |this| this.shadow_sm())
.cursor_pointer()
.overflow_hidden()
@ -345,12 +345,11 @@ impl Render for DatePicker {
div()
.occlude()
.mt_1p5()
.rounded_lg()
.p_3()
.border_1()
.border_color(cx.theme().border)
.shadow_lg()
.rounded_lg()
.rounded((cx.theme().radius * 2.).min(px(8.)))
.bg(cx.theme().background)
.on_mouse_up_out(
MouseButton::Left,