diff --git a/crates/story/src/button_story.rs b/crates/story/src/button_story.rs index ec6cc90d..c2e8b013 100644 --- a/crates/story/src/button_story.rs +++ b/crates/story/src/button_story.rs @@ -21,6 +21,7 @@ pub struct ButtonStory { loading: bool, selected: bool, compact: bool, + multiple: bool, } impl ButtonStory { @@ -31,6 +32,7 @@ impl ButtonStory { loading: false, selected: false, compact: false, + multiple: false, }) } @@ -69,6 +71,7 @@ impl Render for ButtonStory { let loading = self.loading; let selected = self.selected; let compact = self.compact; + let multiple = self.multiple; v_flex() .gap_6() @@ -435,6 +438,7 @@ impl Render for ButtonStory { .child( section("Button Group", cx).child( ButtonGroup::new("button-group") + .disabled(disabled) .child( Button::new("button-one", cx) .label("One") @@ -464,6 +468,49 @@ impl Render for ButtonStory { ), ), ) + .child( + section("Toggle 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(); + })), + ) + .child( + ButtonGroup::new("toggle-button-group") + .multiple(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( section("Icon Button", cx) .child( diff --git a/crates/ui/src/button.rs b/crates/ui/src/button.rs index 1592663f..f3d80346 100644 --- a/crates/ui/src/button.rs +++ b/crates/ui/src/button.rs @@ -106,7 +106,7 @@ pub struct Button { label: Option, children: Vec, disabled: bool, - selected: bool, + pub(crate) selected: bool, style: ButtonStyle, rounded: ButtonRounded, border_corners: Corners, @@ -115,6 +115,7 @@ pub struct Button { compact: bool, tooltip: Option, on_click: Option>, + pub(crate) stop_propagation: bool, loading: bool, } @@ -141,6 +142,7 @@ impl Button { size: Size::Medium, tooltip: None, on_click: None, + stop_propagation: true, loading: false, compact: false, children: Vec::new(), @@ -247,6 +249,11 @@ impl Button { self.on_click = Some(Box::new(handler)); self } + + pub fn stop_propagation(mut self, val: bool) -> Self { + self.stop_propagation = val; + self + } } impl Disableable for Button { @@ -371,9 +378,12 @@ impl RenderOnce for Button { .when_some( self.on_click.filter(|_| !self.disabled && !self.loading), |this, on_click| { - this.on_mouse_down(MouseButton::Left, |_, cx| { + let stop_propagation = self.stop_propagation; + this.on_mouse_down(MouseButton::Left, move |_, cx| { cx.prevent_default(); - cx.stop_propagation() + if stop_propagation { + cx.stop_propagation(); + } }) .on_click(move |event, cx| { (on_click)(event, cx); diff --git a/crates/ui/src/button_group.rs b/crates/ui/src/button_group.rs index 15080921..13e23d65 100644 --- a/crates/ui/src/button_group.rs +++ b/crates/ui/src/button_group.rs @@ -1,15 +1,26 @@ use gpui::{ - div, Corners, Div, Edges, ElementId, InteractiveElement, IntoElement, ParentElement, - RenderOnce, Styled, WindowContext, + div, prelude::FluentBuilder as _, Corners, Div, Edges, ElementId, InteractiveElement, + IntoElement, ParentElement, RenderOnce, StatefulInteractiveElement as _, Styled, WindowContext, }; +use std::{cell::Cell, rc::Rc}; -use crate::button::Button; +use crate::{button::Button, Disableable}; #[derive(IntoElement)] pub struct ButtonGroup { pub base: Div, id: ElementId, children: Vec