Give each `Tab` its own ID

Marshall Bowers created

Change summary

crates/ui2/src/components/tab.rs      | 35 +++++++++++++++++++--------
crates/ui2/src/components/tab_bar.rs  | 18 +++++++-------
crates/ui2/src/components/terminal.rs |  4 +-
crates/ui2/src/static_data.rs         | 36 +++++++++++++++-------------
4 files changed, 54 insertions(+), 39 deletions(-)

Detailed changes

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

@@ -6,6 +6,7 @@ use crate::{Icon, IconColor, IconElement, Label, LabelColor};
 #[derive(Element, Clone)]
 pub struct Tab<S: 'static + Send + Sync + Clone> {
     state_type: PhantomData<S>,
+    id: ElementId,
     title: String,
     icon: Option<Icon>,
     current: bool,
@@ -17,9 +18,10 @@ pub struct Tab<S: 'static + Send + Sync + Clone> {
 }
 
 impl<S: 'static + Send + Sync + Clone> Tab<S> {
-    pub fn new() -> Self {
+    pub fn new(id: impl Into<ElementId>) -> Self {
         Self {
             state_type: PhantomData,
+            id: id.into(),
             title: "untitled".to_string(),
             icon: None,
             current: false,
@@ -110,7 +112,7 @@ impl<S: 'static + Send + Sync + Clone> Tab<S> {
         };
 
         div()
-            .id("tab")
+            .id(self.id.clone())
             .px_2()
             .py_0p5()
             .flex()
@@ -146,6 +148,7 @@ impl<S: 'static + Send + Sync + Clone> Tab<S> {
     }
 }
 
+use gpui3::ElementId;
 #[cfg(feature = "stories")]
 pub use stories::*;
 
@@ -184,7 +187,7 @@ mod stories {
                         v_stack()
                             .gap_2()
                             .child(Story::label(cx, "Default"))
-                            .child(Tab::new()),
+                            .child(Tab::new("default")),
                     ),
                 )
                 .child(
@@ -192,8 +195,16 @@ mod stories {
                         v_stack().gap_2().child(Story::label(cx, "Current")).child(
                             h_stack()
                                 .gap_4()
-                                .child(Tab::new().title("Current".to_string()).current(true))
-                                .child(Tab::new().title("Not Current".to_string()).current(false)),
+                                .child(
+                                    Tab::new("current")
+                                        .title("Current".to_string())
+                                        .current(true),
+                                )
+                                .child(
+                                    Tab::new("not_current")
+                                        .title("Not Current".to_string())
+                                        .current(false),
+                                ),
                         ),
                     ),
                 )
@@ -202,7 +213,7 @@ mod stories {
                         v_stack()
                             .gap_2()
                             .child(Story::label(cx, "Titled"))
-                            .child(Tab::new().title("label".to_string())),
+                            .child(Tab::new("titled").title("label".to_string())),
                     ),
                 )
                 .child(
@@ -211,7 +222,7 @@ mod stories {
                             .gap_2()
                             .child(Story::label(cx, "With Icon"))
                             .child(
-                                Tab::new()
+                                Tab::new("with_icon")
                                     .title("label".to_string())
                                     .icon(Some(Icon::Envelope)),
                             ),
@@ -226,11 +237,11 @@ mod stories {
                                 h_stack()
                                     .gap_4()
                                     .child(
-                                        Tab::new()
+                                        Tab::new("left")
                                             .title("Left".to_string())
                                             .close_side(IconSide::Left),
                                     )
-                                    .child(Tab::new().title("Right".to_string())),
+                                    .child(Tab::new("right").title("Right".to_string())),
                             ),
                     ),
                 )
@@ -239,7 +250,7 @@ mod stories {
                         .gap_2()
                         .child(Story::label(cx, "Git Status"))
                         .child(h_stack().gap_4().children(git_statuses.map(|git_status| {
-                            Tab::new()
+                            Tab::new("git_status")
                                 .title(git_status.to_string())
                                 .git_status(git_status)
                         }))),
@@ -249,7 +260,9 @@ mod stories {
                         .gap_2()
                         .child(Story::label(cx, "File System Status"))
                         .child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
-                            Tab::new().title(fs_status.to_string()).fs_status(fs_status)
+                            Tab::new("file_system_status")
+                                .title(fs_status.to_string())
+                                .fs_status(fs_status)
                         }))),
                 )
         }

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

@@ -122,33 +122,33 @@ mod stories {
                 .child(Story::title_for::<_, TabBar<S>>(cx))
                 .child(Story::label(cx, "Default"))
                 .child(TabBar::new(vec![
-                    Tab::new()
+                    Tab::new(1)
                         .title("Cargo.toml".to_string())
                         .current(false)
                         .git_status(GitStatus::Modified),
-                    Tab::new()
+                    Tab::new(2)
                         .title("Channels Panel".to_string())
                         .current(false),
-                    Tab::new()
+                    Tab::new(3)
                         .title("channels_panel.rs".to_string())
                         .current(true)
                         .git_status(GitStatus::Modified),
-                    Tab::new()
+                    Tab::new(4)
                         .title("workspace.rs".to_string())
                         .current(false)
                         .git_status(GitStatus::Modified),
-                    Tab::new()
+                    Tab::new(5)
                         .title("icon_button.rs".to_string())
                         .current(false),
-                    Tab::new()
+                    Tab::new(6)
                         .title("storybook.rs".to_string())
                         .current(false)
                         .git_status(GitStatus::Created),
-                    Tab::new().title("theme.rs".to_string()).current(false),
-                    Tab::new()
+                    Tab::new(7).title("theme.rs".to_string()).current(false),
+                    Tab::new(8)
                         .title("theme_registry.rs".to_string())
                         .current(false),
-                    Tab::new()
+                    Tab::new(9)
                         .title("styleable_helpers.rs".to_string())
                         .current(false),
                 ]))

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

@@ -54,14 +54,14 @@ impl<S: 'static + Send + Sync + Clone> Terminal<S> {
                             div()
                                 .flex()
                                 .child(
-                                    Tab::new()
+                                    Tab::new(1)
                                         .title("zed — fish".to_string())
                                         .icon(Icon::Terminal)
                                         .close_side(IconSide::Right)
                                         .current(true),
                                 )
                                 .child(
-                                    Tab::new()
+                                    Tab::new(2)
                                         .title("zed — fish".to_string())
                                         .icon(Icon::Terminal)
                                         .close_side(IconSide::Right)

crates/ui2/src/static_data.rs 🔗

@@ -14,48 +14,48 @@ use crate::{
 
 pub fn static_tabs_example<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
     vec![
-        Tab::new()
+        Tab::new("wip.rs")
             .title("wip.rs".to_string())
             .icon(Icon::FileRust)
             .current(false)
             .fs_status(FileSystemStatus::Deleted),
-        Tab::new()
+        Tab::new("Cargo.toml")
             .title("Cargo.toml".to_string())
             .icon(Icon::FileToml)
             .current(false)
             .git_status(GitStatus::Modified),
-        Tab::new()
+        Tab::new("Channels Panel")
             .title("Channels Panel".to_string())
             .icon(Icon::Hash)
             .current(false),
-        Tab::new()
+        Tab::new("channels_panel.rs")
             .title("channels_panel.rs".to_string())
             .icon(Icon::FileRust)
             .current(true)
             .git_status(GitStatus::Modified),
-        Tab::new()
+        Tab::new("workspace.rs")
             .title("workspace.rs".to_string())
             .current(false)
             .icon(Icon::FileRust)
             .git_status(GitStatus::Modified),
-        Tab::new()
+        Tab::new("icon_button.rs")
             .title("icon_button.rs".to_string())
             .icon(Icon::FileRust)
             .current(false),
-        Tab::new()
+        Tab::new("storybook.rs")
             .title("storybook.rs".to_string())
             .icon(Icon::FileRust)
             .current(false)
             .git_status(GitStatus::Created),
-        Tab::new()
+        Tab::new("theme.rs")
             .title("theme.rs".to_string())
             .icon(Icon::FileRust)
             .current(false),
-        Tab::new()
+        Tab::new("theme_registry.rs")
             .title("theme_registry.rs".to_string())
             .icon(Icon::FileRust)
             .current(false),
-        Tab::new()
+        Tab::new("styleable_helpers.rs")
             .title("styleable_helpers.rs".to_string())
             .icon(Icon::FileRust)
             .current(false),
@@ -64,21 +64,21 @@ pub fn static_tabs_example<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
 
 pub fn static_tabs_1<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
     vec![
-        Tab::new()
+        Tab::new("project_panel.rs")
             .title("project_panel.rs".to_string())
             .icon(Icon::FileRust)
             .current(false)
             .fs_status(FileSystemStatus::Deleted),
-        Tab::new()
+        Tab::new("tab_bar.rs")
             .title("tab_bar.rs".to_string())
             .icon(Icon::FileRust)
             .current(false)
             .git_status(GitStatus::Modified),
-        Tab::new()
+        Tab::new("workspace.rs")
             .title("workspace.rs".to_string())
             .icon(Icon::FileRust)
             .current(false),
-        Tab::new()
+        Tab::new("tab.rs")
             .title("tab.rs".to_string())
             .icon(Icon::FileRust)
             .current(true)
@@ -88,12 +88,12 @@ pub fn static_tabs_1<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
 
 pub fn static_tabs_2<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
     vec![
-        Tab::new()
+        Tab::new("tab_bar.rs")
             .title("tab_bar.rs".to_string())
             .icon(Icon::FileRust)
             .current(false)
             .fs_status(FileSystemStatus::Deleted),
-        Tab::new()
+        Tab::new("static_data.rs")
             .title("static_data.rs".to_string())
             .icon(Icon::FileRust)
             .current(true)
@@ -102,7 +102,9 @@ pub fn static_tabs_2<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
 }
 
 pub fn static_tabs_3<S: 'static + Send + Sync + Clone>() -> Vec<Tab<S>> {
-    vec![Tab::new().git_status(GitStatus::Created).current(true)]
+    vec![Tab::new("static_tabs_3")
+        .git_status(GitStatus::Created)
+        .current(true)]
 }
 
 pub fn static_players() -> Vec<Player> {