group_box: Update GroupBox style. (#1167)
- Removed padding x of the Group Title. - Added `fill` variant and change default to use no background and paddings style. <img width="1120" height="1337" alt="image" src="https://github.com/user-attachments/assets/958e902f-3481-424c-a923-62746175aabf" />
This commit is contained in:
parent
554082b969
commit
4e5aca3842
3 changed files with 114 additions and 36 deletions
|
|
@ -7,7 +7,9 @@ use gpui_component::{
|
|||
button::{Button, ButtonVariants},
|
||||
checkbox::Checkbox,
|
||||
group_box::GroupBox,
|
||||
h_flex,
|
||||
radio::{Radio, RadioGroup},
|
||||
switch::Switch,
|
||||
text::TextView,
|
||||
v_flex, ActiveTheme as _, StyledExt,
|
||||
};
|
||||
|
|
@ -24,7 +26,8 @@ impl super::Story for GroupBoxStory {
|
|||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A styled container element that with an optional title to groups related content together."
|
||||
"A styled container element that with an optional title \
|
||||
to groups related content together."
|
||||
}
|
||||
|
||||
fn new_view(window: &mut Window, cx: &mut App) -> Entity<impl Render + Focusable> {
|
||||
|
|
@ -58,21 +61,57 @@ impl Render for GroupBoxStory {
|
|||
.justify_center()
|
||||
.gap_4()
|
||||
.child(
|
||||
section("A simple GroupBox").w_128().child(
|
||||
section("Default Style").w_128().child(
|
||||
GroupBox::new()
|
||||
.title(Checkbox::new("all").label("Subscribe All"))
|
||||
.child("Subscriptions")
|
||||
.child(Checkbox::new("all").label("All"))
|
||||
.child(Checkbox::new("news-letter").label("News Letter"))
|
||||
.child(Checkbox::new("account-activity").label("Account Activity"))
|
||||
.child(Button::new("ok").primary().label("Send Mail")),
|
||||
.child(Button::new("ok").primary().label("Update Subscriptions")),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Outline style").w_128().child(
|
||||
GroupBox::new().outline().title("Appearance").child(
|
||||
RadioGroup::vertical("theme")
|
||||
.child(Radio::new("light").label("Light"))
|
||||
.child(Radio::new("dark").label("Dark"))
|
||||
.child(Radio::new("system").label("System")),
|
||||
section("Fill Style").w_128().child(
|
||||
GroupBox::new()
|
||||
.id("activity")
|
||||
.fill()
|
||||
.title("Contributions & activity")
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child("Make profile private and hide activity")
|
||||
.child(Switch::new("toggle-0").checked(true)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child("Include private contributions on my profile")
|
||||
.child(Switch::new("toggle-1").checked(false)),
|
||||
)
|
||||
.child(Button::new("btn-1").primary().label("Save")),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Outline Style").w_128().child(
|
||||
GroupBox::new()
|
||||
.id("appearance")
|
||||
.outline()
|
||||
.title("Appearance")
|
||||
.child(
|
||||
RadioGroup::vertical("theme")
|
||||
.child(Radio::new("light").label("Light"))
|
||||
.child(Radio::new("dark").label("Dark"))
|
||||
.child(Radio::new("system").label("System")),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Without Title").w_128().child(
|
||||
GroupBox::new().outline().child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child("Make profile private and hide activity")
|
||||
.child(Switch::new("toggle-1").checked(true)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -84,16 +123,23 @@ impl Render for GroupBoxStory {
|
|||
.rounded_xl()
|
||||
.p_5()
|
||||
.title("This is a custom style")
|
||||
.title_style(StyleRefinement::default().font_semibold().line_height(relative(1.0)).px_3())
|
||||
.title_style(
|
||||
StyleRefinement::default()
|
||||
.font_semibold()
|
||||
.line_height(relative(1.0))
|
||||
.px_3(),
|
||||
)
|
||||
.content_style(
|
||||
StyleRefinement::default().rounded_xl()
|
||||
StyleRefinement::default()
|
||||
.rounded_xl()
|
||||
.py_3()
|
||||
.px_4()
|
||||
.border_2()
|
||||
.border_2(),
|
||||
)
|
||||
.child(TextView::markdown(
|
||||
"custom-style",
|
||||
"You can use `title_style` to customize the style of the title. \n \
|
||||
"You can use `title_style` to customize the style \
|
||||
of the title. \n \
|
||||
And any style in `GroupBox` will apply to the content container.",
|
||||
)),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -408,7 +408,6 @@ impl RenderOnce for StorySection {
|
|||
.gap_4()
|
||||
.child(self.title),
|
||||
)
|
||||
.title_style(StyleRefinement::default().px_2())
|
||||
.content_style(
|
||||
StyleRefinement::default()
|
||||
.rounded_lg()
|
||||
|
|
|
|||
|
|
@ -1,35 +1,71 @@
|
|||
use gpui::{
|
||||
div, prelude::FluentBuilder, relative, AnyElement, App, IntoElement, ParentElement, RenderOnce,
|
||||
StyleRefinement, Styled, Window,
|
||||
div, prelude::FluentBuilder, relative, AnyElement, App, ElementId, InteractiveElement as _,
|
||||
IntoElement, ParentElement, RenderOnce, StyleRefinement, Styled, Window,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{v_flex, ActiveTheme, StyledExt as _};
|
||||
|
||||
#[derive(Debug, Clone, Default, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum GroupBoxVariant {
|
||||
#[default]
|
||||
Normal,
|
||||
Fill,
|
||||
Outline,
|
||||
}
|
||||
|
||||
/// GroupBox is a styled container element that with
|
||||
/// an optional title to groups related content together.
|
||||
#[derive(IntoElement)]
|
||||
pub struct GroupBox {
|
||||
id: Option<ElementId>,
|
||||
variant: GroupBoxVariant,
|
||||
style: StyleRefinement,
|
||||
title_style: StyleRefinement,
|
||||
title: Option<AnyElement>,
|
||||
content_style: StyleRefinement,
|
||||
outline: bool,
|
||||
children: SmallVec<[AnyElement; 1]>,
|
||||
}
|
||||
|
||||
impl GroupBox {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: None,
|
||||
variant: GroupBoxVariant::default(),
|
||||
style: StyleRefinement::default(),
|
||||
title_style: StyleRefinement::default(),
|
||||
content_style: StyleRefinement::default(),
|
||||
title: None,
|
||||
outline: false,
|
||||
children: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the variant of the group box.
|
||||
pub fn variant(mut self, variant: GroupBoxVariant) -> Self {
|
||||
self.variant = variant;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set to use Fill variant.
|
||||
pub fn fill(mut self) -> Self {
|
||||
self.variant = GroupBoxVariant::Fill;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set use outline style of the group box.
|
||||
///
|
||||
/// If true, the group box will have a border around it, and no background color.
|
||||
pub fn outline(mut self) -> Self {
|
||||
self.variant = GroupBoxVariant::Outline;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the id of the group box, default is None.
|
||||
pub fn id(mut self, id: impl Into<ElementId>) -> Self {
|
||||
self.id = Some(id.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the title of the group box, default is None.
|
||||
pub fn title(mut self, title: impl IntoElement) -> Self {
|
||||
self.title = Some(title.into_any_element());
|
||||
|
|
@ -47,14 +83,6 @@ impl GroupBox {
|
|||
self.content_style = style;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set use outline style of the group box, default is false.
|
||||
///
|
||||
/// If true, the group box will have a border around it, and no background color.
|
||||
pub fn outline(mut self) -> Self {
|
||||
self.outline = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ParentElement for GroupBox {
|
||||
|
|
@ -71,15 +99,22 @@ impl Styled for GroupBox {
|
|||
|
||||
impl RenderOnce for GroupBox {
|
||||
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
let (bg, border, has_paddings) = match self.variant {
|
||||
GroupBoxVariant::Normal => (None, None, false),
|
||||
GroupBoxVariant::Fill => (Some(cx.theme().group_box), None, true),
|
||||
GroupBoxVariant::Outline => (None, Some(cx.theme().border), true),
|
||||
};
|
||||
|
||||
v_flex()
|
||||
.id(self.id.unwrap_or("group-box".into()))
|
||||
.size_full()
|
||||
.gap_2()
|
||||
.when(has_paddings, |this| this.gap_3())
|
||||
.when(!has_paddings, |this| this.gap_4())
|
||||
.refine_style(&self.style)
|
||||
.when_some(self.title, |this, title| {
|
||||
this.child(
|
||||
div()
|
||||
.px_4()
|
||||
.text_color(cx.theme().group_box_foreground)
|
||||
.text_color(cx.theme().muted_foreground)
|
||||
.line_height(relative(1.))
|
||||
.refine_style(&self.title_style)
|
||||
.child(title),
|
||||
|
|
@ -87,13 +122,11 @@ impl RenderOnce for GroupBox {
|
|||
})
|
||||
.child(
|
||||
v_flex()
|
||||
.when(!self.outline, |this| this.bg(cx.theme().group_box))
|
||||
.when(self.outline, |this| {
|
||||
this.border_color(cx.theme().border).border_1()
|
||||
})
|
||||
.when_some(bg, |this, bg| this.bg(bg))
|
||||
.when_some(border, |this, border| this.border_color(border).border_1())
|
||||
.text_color(cx.theme().group_box_foreground)
|
||||
.p_4()
|
||||
.gap_3()
|
||||
.when(has_paddings, |this| this.p_4())
|
||||
.gap_4()
|
||||
.rounded(cx.theme().radius)
|
||||
.refine_style(&self.content_style)
|
||||
.children(self.children),
|
||||
|
|
|
|||
Loading…
Reference in a new issue