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

<img width="119" alt="Screenshot 2024-01-15 at 10 32 40 AM"
src="https://github.com/zed-industries/zed/assets/1486634/dc806b9b-411f-4cd9-8c10-676d2cbd298b">

#### After

<img width="116" alt="Screenshot 2024-01-15 at 10 32 24 AM"
src="https://github.com/zed-industries/zed/assets/1486634/8b4ef43c-14b6-449f-a235-5d7affd82c4e">

Release Notes:

- Changed the tab close button to be square.
This commit is contained in:
Marshall Bowers 2024-01-15 10:43:03 -05:00 committed by GitHub
parent 1da9c8b1e9
commit b136d21ebf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 13 deletions

View file

@ -300,6 +300,7 @@ pub struct ButtonLike {
pub(super) selected: bool, pub(super) selected: bool,
pub(super) selected_style: Option<ButtonStyle>, pub(super) selected_style: Option<ButtonStyle>,
pub(super) width: Option<DefiniteLength>, pub(super) width: Option<DefiniteLength>,
pub(super) height: Option<DefiniteLength>,
size: ButtonSize, size: ButtonSize,
rounding: Option<ButtonLikeRounding>, rounding: Option<ButtonLikeRounding>,
tooltip: Option<Box<dyn Fn(&mut WindowContext) -> AnyView>>, tooltip: Option<Box<dyn Fn(&mut WindowContext) -> AnyView>>,
@ -317,6 +318,7 @@ impl ButtonLike {
selected: false, selected: false,
selected_style: None, selected_style: None,
width: None, width: None,
height: None,
size: ButtonSize::Default, size: ButtonSize::Default,
rounding: Some(ButtonLikeRounding::All), rounding: Some(ButtonLikeRounding::All),
tooltip: None, 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<Option<ButtonLikeRounding>>) -> Self { pub(crate) fn rounding(mut self, rounding: impl Into<Option<ButtonLikeRounding>>) -> Self {
self.rounding = rounding.into(); self.rounding = rounding.into();
self self
@ -417,7 +424,7 @@ impl RenderOnce for ButtonLike {
.id(self.id.clone()) .id(self.id.clone())
.group("") .group("")
.flex_none() .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.width, |this, width| this.w(width).justify_center())
.when_some(self.rounding, |this, rounding| match rounding { .when_some(self.rounding, |this, rounding| match rounding {
ButtonLikeRounding::All => this.rounded_md(), ButtonLikeRounding::All => this.rounded_md(),

View file

@ -5,9 +5,17 @@ use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSiz
use super::button_icon::ButtonIcon; 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)] #[derive(IntoElement)]
pub struct IconButton { pub struct IconButton {
base: ButtonLike, base: ButtonLike,
shape: IconButtonShape,
icon: IconName, icon: IconName,
icon_size: IconSize, icon_size: IconSize,
icon_color: Color, icon_color: Color,
@ -18,6 +26,7 @@ impl IconButton {
pub fn new(id: impl Into<ElementId>, icon: IconName) -> Self { pub fn new(id: impl Into<ElementId>, icon: IconName) -> Self {
Self { Self {
base: ButtonLike::new(id), base: ButtonLike::new(id),
shape: IconButtonShape::Wide,
icon, icon,
icon_size: IconSize::default(), icon_size: IconSize::default(),
icon_color: Color::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 { pub fn icon_size(mut self, icon_size: IconSize) -> Self {
self.icon_size = icon_size; self.icon_size = icon_size;
self self
@ -118,7 +132,14 @@ impl RenderOnce for IconButton {
let is_selected = self.base.selected; let is_selected = self.base.selected;
let selected_style = self.base.selected_style; let selected_style = self.base.selected_style;
self.base.child( 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) ButtonIcon::new(self.icon)
.disabled(is_disabled) .disabled(is_disabled)
.selected(is_selected) .selected(is_selected)

View file

@ -3,7 +3,7 @@ use std::cmp::Ordering;
use gpui::Render; use gpui::Render;
use story::Story; use story::Story;
use crate::{prelude::*, TabPosition}; use crate::{prelude::*, IconButtonShape, TabPosition};
use crate::{Indicator, Tab}; use crate::{Indicator, Tab};
pub struct TabStory; pub struct TabStory;
@ -28,6 +28,7 @@ impl Render for TabStory {
Tab::new("tab_1") Tab::new("tab_1")
.end_slot( .end_slot(
IconButton::new("close_button", IconName::Close) IconButton::new("close_button", IconName::Close)
.shape(IconButtonShape::Square)
.icon_color(Color::Muted) .icon_color(Color::Muted)
.size(ButtonSize::None) .size(ButtonSize::None)
.icon_size(IconSize::XSmall), .icon_size(IconSize::XSmall),

View file

@ -32,8 +32,8 @@ use std::{
use theme::ThemeSettings; use theme::ThemeSettings;
use ui::{ use ui::{
prelude::*, right_click_menu, ButtonSize, Color, IconButton, IconName, IconSize, Indicator, prelude::*, right_click_menu, ButtonSize, Color, IconButton, IconButtonShape, IconName,
Label, Tab, TabBar, TabPosition, Tooltip, IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip,
}; };
use ui::{v_stack, ContextMenu}; use ui::{v_stack, ContextMenu};
use util::{maybe, truncate_and_remove_front, ResultExt}; use util::{maybe, truncate_and_remove_front, ResultExt};
@ -1341,6 +1341,7 @@ impl Pane {
.start_slot::<Indicator>(indicator) .start_slot::<Indicator>(indicator)
.end_slot( .end_slot(
IconButton::new("close tab", IconName::Close) IconButton::new("close tab", IconName::Close)
.shape(IconButtonShape::Square)
.icon_color(Color::Muted) .icon_color(Color::Muted)
.size(ButtonSize::None) .size(ButtonSize::None)
.icon_size(IconSize::XSmall) .icon_size(IconSize::XSmall)