Implement FixedWidth for all button types

Nate Butler and Marshall Bowers created

[no-ci]

Co-Authored-By: Marshall Bowers <1486634+maxdeviant@users.noreply.github.com>

Change summary

crates/ui2/src/components/button/button.rs      | 14 +++++++++++++-
crates/ui2/src/components/button/button_like.rs | 17 +++++++++++++++++
crates/ui2/src/components/button/icon_button.rs | 14 +++++++++++++-
3 files changed, 43 insertions(+), 2 deletions(-)

Detailed changes

crates/ui2/src/components/button/button.rs 🔗

@@ -1,4 +1,4 @@
-use gpui::AnyView;
+use gpui::{AnyView, DefiniteLength};
 
 use crate::prelude::*;
 use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, Label, LineHeightStyle};
@@ -49,6 +49,18 @@ impl Clickable for Button {
     }
 }
 
+impl FixedWidth for Button {
+    fn width(mut self, width: DefiniteLength) -> Self {
+        self.base = self.base.width(width);
+        self
+    }
+
+    fn full_width(mut self) -> Self {
+        self.base = self.base.full_width();
+        self
+    }
+}
+
 impl ButtonCommon for Button {
     fn id(&self) -> &ElementId {
         self.base.id()

crates/ui2/src/components/button/button_like.rs 🔗

@@ -1,3 +1,4 @@
+use gpui::{relative, DefiniteLength};
 use gpui::{rems, transparent_black, AnyElement, AnyView, ClickEvent, Div, Hsla, Rems, Stateful};
 use smallvec::SmallVec;
 
@@ -177,6 +178,7 @@ pub struct ButtonLike {
     pub(super) style: ButtonStyle,
     pub(super) disabled: bool,
     pub(super) selected: bool,
+    pub(super) width: Option<DefiniteLength>,
     size: ButtonSize,
     tooltip: Option<Box<dyn Fn(&mut WindowContext) -> AnyView>>,
     on_click: Option<Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
@@ -190,6 +192,7 @@ impl ButtonLike {
             style: ButtonStyle::default(),
             disabled: false,
             selected: false,
+            width: None,
             size: ButtonSize::Default,
             tooltip: None,
             children: SmallVec::new(),
@@ -219,6 +222,18 @@ impl Clickable for ButtonLike {
     }
 }
 
+impl FixedWidth for ButtonLike {
+    fn width(mut self, width: DefiniteLength) -> Self {
+        self.width = Some(width);
+        self
+    }
+
+    fn full_width(mut self) -> Self {
+        self.width = Some(relative(1.));
+        self
+    }
+}
+
 impl ButtonCommon for ButtonLike {
     fn id(&self) -> &ElementId {
         &self.id
@@ -252,7 +267,9 @@ impl RenderOnce for ButtonLike {
     fn render(self, cx: &mut WindowContext) -> Self::Rendered {
         h_stack()
             .id(self.id.clone())
+            .flex_none()
             .h(self.size.height())
+            .when_some(self.width, |this, width| this.w(width))
             .rounded_md()
             .cursor_pointer()
             .gap_1()

crates/ui2/src/components/button/icon_button.rs 🔗

@@ -1,4 +1,4 @@
-use gpui::{Action, AnyView};
+use gpui::{Action, AnyView, DefiniteLength};
 
 use crate::prelude::*;
 use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, Icon, IconElement, IconSize};
@@ -60,6 +60,18 @@ impl Clickable for IconButton {
     }
 }
 
+impl FixedWidth for IconButton {
+    fn width(mut self, width: DefiniteLength) -> Self {
+        self.base = self.base.width(width);
+        self
+    }
+
+    fn full_width(mut self) -> Self {
+        self.base = self.base.full_width();
+        self
+    }
+}
+
 impl ButtonCommon for IconButton {
     fn id(&self) -> &ElementId {
         self.base.id()