From b136d21ebf1332f918eac2e636030ee11c833d65 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 15 Jan 2024 10:43:03 -0500 Subject: [PATCH] Make tab close button square (#4052) This PR makes the close button for tabs square. `IconButton` now accepts a `shape`, and using `IconButtonShape::Square` will ensure the `IconButton` is square with respect to its contained icon. #### Before Screenshot 2024-01-15 at 10 32 40 AM #### After Screenshot 2024-01-15 at 10 32 24 AM Release Notes: - Changed the tab close button to be square. --- .../ui/src/components/button/button_like.rs | 9 ++++- .../ui/src/components/button/icon_button.rs | 39 ++++++++++++++----- crates/ui/src/components/stories/tab.rs | 3 +- crates/workspace/src/pane.rs | 5 ++- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/crates/ui/src/components/button/button_like.rs b/crates/ui/src/components/button/button_like.rs index 3e4b478a9a237c44b95e5de09158e35e40e55449..018d31dafdb4491bc88733117c8e42f66e789aa3 100644 --- a/crates/ui/src/components/button/button_like.rs +++ b/crates/ui/src/components/button/button_like.rs @@ -300,6 +300,7 @@ pub struct ButtonLike { pub(super) selected: bool, pub(super) selected_style: Option, pub(super) width: Option, + pub(super) height: Option, size: ButtonSize, rounding: Option, tooltip: Option AnyView>>, @@ -317,6 +318,7 @@ impl ButtonLike { selected: false, selected_style: None, width: None, + height: None, size: ButtonSize::Default, rounding: Some(ButtonLikeRounding::All), tooltip: None, @@ -325,6 +327,11 @@ impl ButtonLike { } } + pub(crate) fn height(mut self, height: DefiniteLength) -> Self { + self.height = Some(height); + self + } + pub(crate) fn rounding(mut self, rounding: impl Into>) -> Self { self.rounding = rounding.into(); self @@ -417,7 +424,7 @@ impl RenderOnce for ButtonLike { .id(self.id.clone()) .group("") .flex_none() - .h(self.size.height()) + .h(self.height.unwrap_or(self.size.height().into())) .when_some(self.width, |this, width| this.w(width).justify_center()) .when_some(self.rounding, |this, rounding| match rounding { ButtonLikeRounding::All => this.rounded_md(), diff --git a/crates/ui/src/components/button/icon_button.rs b/crates/ui/src/components/button/icon_button.rs index 7c5313497c77ff6532838966001d2cbd4a3688e0..1e37a872922b4473616b551352f8100bbd9b1327 100644 --- a/crates/ui/src/components/button/icon_button.rs +++ b/crates/ui/src/components/button/icon_button.rs @@ -5,9 +5,17 @@ use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSiz use super::button_icon::ButtonIcon; +/// The shape of an [`IconButton`]. +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] +pub enum IconButtonShape { + Square, + Wide, +} + #[derive(IntoElement)] pub struct IconButton { base: ButtonLike, + shape: IconButtonShape, icon: IconName, icon_size: IconSize, icon_color: Color, @@ -18,6 +26,7 @@ impl IconButton { pub fn new(id: impl Into, icon: IconName) -> Self { Self { base: ButtonLike::new(id), + shape: IconButtonShape::Wide, icon, icon_size: IconSize::default(), icon_color: Color::Default, @@ -25,6 +34,11 @@ impl IconButton { } } + pub fn shape(mut self, shape: IconButtonShape) -> Self { + self.shape = shape; + self + } + pub fn icon_size(mut self, icon_size: IconSize) -> Self { self.icon_size = icon_size; self @@ -118,14 +132,21 @@ impl RenderOnce for IconButton { let is_selected = self.base.selected; let selected_style = self.base.selected_style; - self.base.child( - ButtonIcon::new(self.icon) - .disabled(is_disabled) - .selected(is_selected) - .selected_icon(self.selected_icon) - .when_some(selected_style, |this, style| this.selected_style(style)) - .size(self.icon_size) - .color(self.icon_color), - ) + self.base + .map(|this| match self.shape { + IconButtonShape::Square => this + .width(self.icon_size.rems().into()) + .height(self.icon_size.rems().into()), + IconButtonShape::Wide => this, + }) + .child( + ButtonIcon::new(self.icon) + .disabled(is_disabled) + .selected(is_selected) + .selected_icon(self.selected_icon) + .when_some(selected_style, |this, style| this.selected_style(style)) + .size(self.icon_size) + .color(self.icon_color), + ) } } diff --git a/crates/ui/src/components/stories/tab.rs b/crates/ui/src/components/stories/tab.rs index bd7b602620938775b32be3d46a41b519f2639f63..9c5c694439f74862d93e7c37155a2c340354e95b 100644 --- a/crates/ui/src/components/stories/tab.rs +++ b/crates/ui/src/components/stories/tab.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; use gpui::Render; use story::Story; -use crate::{prelude::*, TabPosition}; +use crate::{prelude::*, IconButtonShape, TabPosition}; use crate::{Indicator, Tab}; pub struct TabStory; @@ -28,6 +28,7 @@ impl Render for TabStory { Tab::new("tab_1") .end_slot( IconButton::new("close_button", IconName::Close) + .shape(IconButtonShape::Square) .icon_color(Color::Muted) .size(ButtonSize::None) .icon_size(IconSize::XSmall), diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 1b95671398a613a01f41590bdce20e0a846592d0..90b27e094b612a5f461fe061cb0c2a77693464e4 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -32,8 +32,8 @@ use std::{ use theme::ThemeSettings; use ui::{ - prelude::*, right_click_menu, ButtonSize, Color, IconButton, IconName, IconSize, Indicator, - Label, Tab, TabBar, TabPosition, Tooltip, + prelude::*, right_click_menu, ButtonSize, Color, IconButton, IconButtonShape, IconName, + IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip, }; use ui::{v_stack, ContextMenu}; use util::{maybe, truncate_and_remove_front, ResultExt}; @@ -1341,6 +1341,7 @@ impl Pane { .start_slot::(indicator) .end_slot( IconButton::new("close tab", IconName::Close) + .shape(IconButtonShape::Square) .icon_color(Color::Muted) .size(ButtonSize::None) .icon_size(IconSize::XSmall)