From a8d4abea69f9e13a02ad2eee6f1478859404642c Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 13 Sep 2024 12:00:47 +0800 Subject: [PATCH] button: Improve ButtonGroup to add style, size methods. (#241) - Add `ButtonStyled` trait to apply the style for Button and ButtonGroup. --- crates/app/src/story_workspace.rs | 2 +- crates/story/src/button_story.rs | 144 ++++++++++++++-------------- crates/story/src/modal_story.rs | 2 +- crates/story/src/popup_story.rs | 2 +- crates/ui/src/button.rs | 88 +++++++++-------- crates/ui/src/button_group.rs | 71 ++++++++++---- crates/ui/src/clipboard.rs | 5 +- crates/ui/src/dock/tab_panel.rs | 2 +- crates/ui/src/drawer.rs | 9 +- crates/ui/src/input/clear_button.rs | 5 +- crates/ui/src/modal.rs | 6 +- crates/ui/src/notification.rs | 7 +- crates/ui/src/theme.rs | 8 +- crates/ui/src/time/calendar.rs | 8 +- 14 files changed, 211 insertions(+), 148 deletions(-) diff --git a/crates/app/src/story_workspace.rs b/crates/app/src/story_workspace.rs index 150e4b78..4be99858 100644 --- a/crates/app/src/story_workspace.rs +++ b/crates/app/src/story_workspace.rs @@ -9,7 +9,7 @@ use story::{ SwitchStory, TableStory, TextStory, TooltipStory, }; use ui::{ - button::Button, + button::{Button, ButtonStyled as _}, color_picker::{ColorPicker, ColorPickerEvent}, dock::{DockArea, DockEvent, DockItem, DockItemState}, h_flex, diff --git a/crates/story/src/button_story.rs b/crates/story/src/button_story.rs index c2e8b013..018e9ec6 100644 --- a/crates/story/src/button_story.rs +++ b/crates/story/src/button_story.rs @@ -4,7 +4,7 @@ use gpui::{ }; use ui::{ - button::{Button, ButtonCustomStyle}, + button::{Button, ButtonCustomStyle, ButtonStyled as _}, button_group::ButtonGroup, checkbox::Checkbox, h_flex, @@ -21,7 +21,7 @@ pub struct ButtonStory { loading: bool, selected: bool, compact: bool, - multiple: bool, + toggle_multiple: bool, } impl ButtonStory { @@ -32,7 +32,7 @@ impl ButtonStory { loading: false, selected: false, compact: false, - multiple: false, + toggle_multiple: false, }) } @@ -71,7 +71,7 @@ impl Render for ButtonStory { let loading = self.loading; let selected = self.selected; let compact = self.compact; - let multiple = self.multiple; + let toggle_multiple = self.toggle_multiple; v_flex() .gap_6() @@ -436,79 +436,81 @@ impl Render for ButtonStory { ), ) .child( - section("Button Group", cx).child( - ButtonGroup::new("button-group") - .disabled(disabled) - .child( - Button::new("button-one", cx) - .label("One") - .disabled(disabled) - .selected(selected) - .loading(loading) - .when(compact, |this| this.compact()) - .on_click(Self::on_click), - ) - .child( - Button::new("button-two", cx) - .label("Two") - .disabled(disabled) - .selected(selected) - .loading(loading) - .when(compact, |this| this.compact()) - .on_click(Self::on_click), - ) - .child( - Button::new("button-three", cx) - .label("Three") - .disabled(disabled) - .selected(selected) - .loading(loading) - .when(compact, |this| this.compact()) - .on_click(Self::on_click), - ), - ), - ) - .child( - section("Toggle Button Group", cx) + section("Button Group", cx) .child( - Checkbox::new("multiple-button") - .label("Multiple") - .checked(self.multiple) - .on_click(cx.listener(|view, _, cx| { - view.multiple = !view.multiple; - cx.notify(); - })), + ButtonGroup::new("button-group") + .small() + .disabled(disabled) + .child( + Button::new("button-one", cx) + .label("One") + .disabled(disabled) + .selected(selected) + .when(compact, |this| this.compact()) + .on_click(Self::on_click), + ) + .child( + Button::new("button-two", cx) + .label("Two") + .disabled(disabled) + .selected(selected) + .when(compact, |this| this.compact()) + .on_click(Self::on_click), + ) + .child( + Button::new("button-three", cx) + .label("Three") + .disabled(disabled) + .selected(selected) + .when(compact, |this| this.compact()) + .on_click(Self::on_click), + ), ) .child( - ButtonGroup::new("toggle-button-group") - .multiple(multiple) + h_flex() + .gap_2() .child( - Button::new("disabled-toggle-button", cx) - .label("Disabled") - .selected(disabled), + Checkbox::new("multiple-button") + .label("Multiple") + .checked(toggle_multiple) + .on_click(cx.listener(|view, _, cx| { + view.toggle_multiple = !view.toggle_multiple; + cx.notify(); + })), ) .child( - Button::new("loading-toggle-button", cx) - .label("Loading") - .selected(loading), - ) - .child( - Button::new("selected-toggle-button", cx) - .label("Selected") - .selected(selected), - ) - .child( - Button::new("compact-toggle-button", cx) - .label("Compact") - .selected(compact), - ) - .on_click(cx.listener(|view, selected: &Vec, cx| { - view.disabled = selected.contains(&0); - view.loading = selected.contains(&1); - view.selected = selected.contains(&2); - view.compact = selected.contains(&3); - cx.notify(); - })), + ButtonGroup::new("toggle-button-group") + .primary() + .compact() + .multiple(toggle_multiple) + .child( + Button::new("disabled-toggle-button", cx) + .label("Disabled") + .selected(disabled), + ) + .child( + Button::new("loading-toggle-button", cx) + .label("Loading") + .selected(loading), + ) + .child( + Button::new("selected-toggle-button", cx) + .label("Selected") + .selected(selected), + ) + .child( + Button::new("compact-toggle-button", cx) + .label("Compact") + .selected(compact), + ) + .on_click(cx.listener(|view, selected: &Vec, cx| { + view.disabled = selected.contains(&0); + view.loading = selected.contains(&1); + view.selected = selected.contains(&2); + view.compact = selected.contains(&3); + cx.notify(); + })), + ), ), ) .child( diff --git a/crates/story/src/modal_story.rs b/crates/story/src/modal_story.rs index 67ef8867..70222112 100644 --- a/crates/story/src/modal_story.rs +++ b/crates/story/src/modal_story.rs @@ -8,7 +8,7 @@ use gpui::{ }; use ui::{ - button::{Button, ButtonStyle}, + button::{Button, ButtonStyle, ButtonStyled as _}, checkbox::Checkbox, date_picker::DatePicker, h_flex, diff --git a/crates/story/src/popup_story.rs b/crates/story/src/popup_story.rs index 189aca34..9643a06c 100644 --- a/crates/story/src/popup_story.rs +++ b/crates/story/src/popup_story.rs @@ -6,7 +6,7 @@ use gpui::{ }; use serde::Deserialize; use ui::{ - button::Button, + button::{Button, ButtonStyled as _}, context_menu::ContextMenuExt, divider::Divider, h_flex, diff --git a/crates/ui/src/button.rs b/crates/ui/src/button.rs index f3d80346..201359a4 100644 --- a/crates/ui/src/button.rs +++ b/crates/ui/src/button.rs @@ -34,6 +34,45 @@ pub struct ButtonCustomStyle { active: Hsla, } +pub trait ButtonStyled: Sized { + fn with_style(self, style: ButtonStyle) -> Self; + + /// With the primary style for the Button. + fn primary(self) -> Self { + self.with_style(ButtonStyle::Primary) + } + + /// With the danger style for the Button. + fn danger(self) -> Self { + self.with_style(ButtonStyle::Danger) + } + + /// With the outline style for the Button. + fn outline(self) -> Self { + self.with_style(ButtonStyle::Outline) + } + + /// With the ghost style for the Button. + fn ghost(self) -> Self { + self.with_style(ButtonStyle::Ghost) + } + + /// With the link style for the Button. + fn link(self) -> Self { + self.with_style(ButtonStyle::Link) + } + + /// With the text style for the Button, it will no padding look like a normal text. + fn text(self) -> Self { + self.with_style(ButtonStyle::Text) + } + + /// With the custom style for the Button. + fn custom(self, style: ButtonCustomStyle) -> Self { + self.with_style(ButtonStyle::Custom(style)) + } +} + impl ButtonCustomStyle { pub fn new(cx: &WindowContext) -> Self { Self { @@ -149,48 +188,6 @@ impl Button { } } - /// With the primary style for the Button. - pub fn primary(mut self) -> Self { - self.style = ButtonStyle::Primary; - self - } - - /// With the secondary style for the Button. - pub fn danger(mut self) -> Self { - self.style = ButtonStyle::Danger; - self - } - - /// With the ghost style for the Button. - pub fn ghost(mut self) -> Self { - self.style = ButtonStyle::Ghost; - self - } - - /// With the outline style for the Button. - pub fn outline(mut self) -> Self { - self.style = ButtonStyle::Outline; - self - } - - /// With the link style for the Button. - pub fn link(mut self) -> Self { - self.style = ButtonStyle::Link; - self - } - - /// With the text style for the Button, it will no padding look like a normal text. - pub fn text(mut self) -> Self { - self.style = ButtonStyle::Text; - self - } - - /// With the custom style for the Button. - pub fn custom(mut self, custom: ButtonCustomStyle) -> Self { - self.style = ButtonStyle::Custom(custom); - self - } - /// Set the border radius of the Button. pub fn rounded(mut self, rounded: impl Into) -> Self { self.rounded = rounded.into(); @@ -277,6 +274,13 @@ impl Sizable for Button { } } +impl ButtonStyled for Button { + fn with_style(mut self, style: ButtonStyle) -> Self { + self.style = style; + self + } +} + impl Styled for Button { fn style(&mut self) -> &mut gpui::StyleRefinement { self.base.style() diff --git a/crates/ui/src/button_group.rs b/crates/ui/src/button_group.rs index 13e23d65..3db8a1f2 100644 --- a/crates/ui/src/button_group.rs +++ b/crates/ui/src/button_group.rs @@ -4,7 +4,10 @@ use gpui::{ }; use std::{cell::Cell, rc::Rc}; -use crate::{button::Button, Disableable}; +use crate::{ + button::{Button, ButtonStyle, ButtonStyled}, + Disableable, Sizable, Size, +}; #[derive(IntoElement)] pub struct ButtonGroup { @@ -13,6 +16,12 @@ pub struct ButtonGroup { children: Vec