Dynamic tab bar height (#19076)

Aaron Ruan created

Tracking issue: https://github.com/zed-industries/zed/issues/18078

Release Notes:

- Change tab bar height according to `ui-density`

---------

Signed-off-by: Aaron Ruan <aaron212cn@outlook.com>

Change summary

crates/collab_ui/src/chat_panel.rs         |  4 ++--
crates/collab_ui/src/notification_panel.rs |  6 ++++--
crates/ui/src/components/tab.rs            | 18 +++++++++++-------
crates/ui/src/components/tab_bar.rs        |  7 ++-----
crates/workspace/src/pane.rs               |  2 --
5 files changed, 19 insertions(+), 18 deletions(-)

Detailed changes

crates/collab_ui/src/chat_panel.rs 🔗

@@ -23,7 +23,7 @@ use std::{sync::Arc, time::Duration};
 use time::{OffsetDateTime, UtcOffset};
 use ui::{
     prelude::*, Avatar, Button, ContextMenu, IconButton, IconName, KeyBinding, Label, PopoverMenu,
-    TabBar, Tooltip,
+    Tab, TabBar, Tooltip,
 };
 use util::{ResultExt, TryFutureExt};
 use workspace::{
@@ -939,7 +939,7 @@ impl Render for ChatPanel {
                     TabBar::new("chat_header").child(
                         h_flex()
                             .w_full()
-                            .h(rems(ui::Tab::CONTAINER_HEIGHT_IN_REMS))
+                            .h(Tab::container_height(cx))
                             .px_2()
                             .child(Label::new(
                                 self.active_chat

crates/collab_ui/src/notification_panel.rs 🔗

@@ -19,7 +19,9 @@ use serde::{Deserialize, Serialize};
 use settings::{Settings, SettingsStore};
 use std::{sync::Arc, time::Duration};
 use time::{OffsetDateTime, UtcOffset};
-use ui::{h_flex, prelude::*, v_flex, Avatar, Button, Icon, IconButton, IconName, Label, Tooltip};
+use ui::{
+    h_flex, prelude::*, v_flex, Avatar, Button, Icon, IconButton, IconName, Label, Tab, Tooltip,
+};
 use util::{ResultExt, TryFutureExt};
 use workspace::notifications::NotificationId;
 use workspace::{
@@ -588,7 +590,7 @@ impl Render for NotificationPanel {
                     .px_2()
                     .py_1()
                     // Match the height of the tab bar so they line up.
-                    .h(rems(ui::Tab::CONTAINER_HEIGHT_IN_REMS))
+                    .h(Tab::container_height(cx))
                     .border_b_1()
                     .border_color(cx.theme().colors().border)
                     .child(Label::new("Notifications"))

crates/ui/src/components/tab.rs 🔗

@@ -4,7 +4,7 @@ use std::cmp::Ordering;
 use gpui::{AnyElement, IntoElement, Stateful};
 use smallvec::SmallVec;
 
-use crate::{prelude::*, BASE_REM_SIZE_IN_PX};
+use crate::prelude::*;
 
 /// The position of a [`Tab`] within a list of tabs.
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -54,10 +54,6 @@ impl Tab {
         }
     }
 
-    pub const CONTAINER_HEIGHT_IN_REMS: f32 = 29. / BASE_REM_SIZE_IN_PX;
-
-    const CONTENT_HEIGHT_IN_REMS: f32 = 28. / BASE_REM_SIZE_IN_PX;
-
     pub fn position(mut self, position: TabPosition) -> Self {
         self.position = position;
         self
@@ -77,6 +73,14 @@ impl Tab {
         self.end_slot = element.into().map(IntoElement::into_any_element);
         self
     }
+
+    pub fn content_height(cx: &mut WindowContext) -> Pixels {
+        DynamicSpacing::Base32.px(cx) - px(1.)
+    }
+
+    pub fn container_height(cx: &mut WindowContext) -> Pixels {
+        DynamicSpacing::Base32.px(cx)
+    }
 }
 
 impl InteractiveElement for Tab {
@@ -130,7 +134,7 @@ impl RenderOnce for Tab {
         };
 
         self.div
-            .h(rems(Self::CONTAINER_HEIGHT_IN_REMS))
+            .h(Tab::container_height(cx))
             .bg(tab_bg)
             .border_color(cx.theme().colors().border)
             .map(|this| match self.position {
@@ -157,7 +161,7 @@ impl RenderOnce for Tab {
                 h_flex()
                     .group("")
                     .relative()
-                    .h(rems(Self::CONTENT_HEIGHT_IN_REMS))
+                    .h(Tab::content_height(cx))
                     .px(DynamicSpacing::Base04.px(cx))
                     .gap(DynamicSpacing::Base04.rems(cx))
                     .text_color(text_color)

crates/ui/src/components/tab_bar.rs 🔗

@@ -3,6 +3,7 @@ use gpui::{AnyElement, ScrollHandle};
 use smallvec::SmallVec;
 
 use crate::prelude::*;
+use crate::Tab;
 
 #[derive(IntoElement)]
 pub struct TabBar {
@@ -97,11 +98,7 @@ impl RenderOnce for TabBar {
             .flex()
             .flex_none()
             .w_full()
-            .h(
-                // TODO: This should scale with [UiDensity], however tabs,
-                // and other tab bar tools need to scale dynamically first.
-                rems_from_px(29.),
-            )
+            .h(Tab::container_height(cx))
             .bg(cx.theme().colors().tab_bar_background)
             .when(!self.start_children.is_empty(), |this| {
                 this.child(

crates/workspace/src/pane.rs 🔗

@@ -2259,7 +2259,6 @@ impl Pane {
     fn render_tab_bar(&mut self, cx: &mut ViewContext<'_, Pane>) -> impl IntoElement {
         let focus_handle = self.focus_handle.clone();
         let navigate_backward = IconButton::new("navigate_backward", IconName::ArrowLeft)
-            .shape(IconButtonShape::Square)
             .icon_size(IconSize::Small)
             .on_click({
                 let view = cx.view().clone();
@@ -2272,7 +2271,6 @@ impl Pane {
             });
 
         let navigate_forward = IconButton::new("navigate_forward", IconName::ArrowRight)
-            .shape(IconButtonShape::Square)
             .icon_size(IconSize::Small)
             .on_click({
                 let view = cx.view().clone();