Label component states in stories (#3019)

Marshall Bowers created

This PR updates the UI component stories to label the various states
that they are in.

Release Notes:

- N/A

Change summary

crates/storybook/src/stories/components/facepile.rs       | 57 +++-----
crates/storybook/src/stories/components/traffic_lights.rs |  3 
crates/storybook/src/stories/elements/avatar.rs           | 21 +--
crates/storybook/src/story.rs                             | 15 ++
crates/ui/src/components/facepile.rs                      |  6 
crates/ui/src/components/follow_group.rs                  |  2 
6 files changed, 53 insertions(+), 51 deletions(-)

Detailed changes

crates/storybook/src/stories/components/facepile.rs 🔗

@@ -13,47 +13,38 @@ impl FacepileStory {
     fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
         let theme = theme(cx);
 
+        let avatars = vec![
+            avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
+            avatar("https://avatars.githubusercontent.com/u/482957?v=4"),
+            avatar("https://avatars.githubusercontent.com/u/1789?v=4"),
+        ];
+
         Story::container()
-            .child(Story::title(std::any::type_name::<ui::Facepile>()))
+            .child(Story::title_for::<_, ui::Facepile>())
+            .child(Story::label("Default"))
             .child(
                 div()
                     .flex()
                     .gap_3()
-                    .child(facepile(vec![avatar(
-                        "https://avatars.githubusercontent.com/u/1714999?v=4",
-                    )]))
-                    .child(facepile(vec![
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
-                    ]))
-                    .child(facepile(vec![
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
-                    ])),
+                    .child(facepile(avatars.clone().into_iter().take(1)))
+                    .child(facepile(avatars.clone().into_iter().take(2)))
+                    .child(facepile(avatars.clone().into_iter().take(3))),
             )
-            .child(
+            .child(Story::label("Rounded rectangle avatars"))
+            .child({
+                let shape = Shape::RoundedRectangle;
+
+                let avatars = avatars
+                    .clone()
+                    .into_iter()
+                    .map(|avatar| avatar.shape(Shape::RoundedRectangle));
+
                 div()
                     .flex()
                     .gap_3()
-                    .child(facepile(vec![avatar(
-                        "https://avatars.githubusercontent.com/u/1714999?v=4",
-                    )
-                    .shape(Shape::RoundedRectangle)]))
-                    .child(facepile(vec![
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
-                            .shape(Shape::RoundedRectangle),
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
-                            .shape(Shape::RoundedRectangle),
-                    ]))
-                    .child(facepile(vec![
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
-                            .shape(Shape::RoundedRectangle),
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
-                            .shape(Shape::RoundedRectangle),
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
-                            .shape(Shape::RoundedRectangle),
-                    ])),
-            )
+                    .child(facepile(avatars.clone().take(1)))
+                    .child(facepile(avatars.clone().take(2)))
+                    .child(facepile(avatars.clone().take(3)))
+            })
     }
 }

crates/storybook/src/stories/components/traffic_lights.rs 🔗

@@ -11,7 +11,8 @@ impl TrafficLightsStory {
         let theme = theme(cx);
 
         Story::container()
-            .child(Story::title(std::any::type_name::<ui::TrafficLights>()))
+            .child(Story::title_for::<_, ui::TrafficLights>())
+            .child(Story::label("Default"))
             .child(traffic_lights())
     }
 }

crates/storybook/src/stories/elements/avatar.rs 🔗

@@ -1,5 +1,3 @@
-use gpui2::elements::div;
-use gpui2::style::StyleHelpers;
 use gpui2::{Element, IntoElement, ParentElement, ViewContext};
 use ui::prelude::*;
 use ui::{avatar, theme};
@@ -14,18 +12,15 @@ impl AvatarStory {
         let theme = theme(cx);
 
         Story::container()
-            .child(Story::title(std::any::type_name::<ui::Avatar>()))
+            .child(Story::title_for::<_, ui::Avatar>())
+            .child(Story::label("Default"))
+            .child(avatar(
+                "https://avatars.githubusercontent.com/u/1714999?v=4",
+            ))
+            .child(Story::label("Rounded rectangle"))
             .child(
-                div()
-                    .flex()
-                    .gap_3()
-                    .child(avatar(
-                        "https://avatars.githubusercontent.com/u/1714999?v=4",
-                    ))
-                    .child(
-                        avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
-                            .shape(Shape::RoundedRectangle),
-                    ),
+                avatar("https://avatars.githubusercontent.com/u/1714999?v=4")
+                    .shape(Shape::RoundedRectangle),
             )
     }
 }

crates/storybook/src/story.rs 🔗

@@ -18,8 +18,21 @@ impl Story {
 
     pub fn title<V: 'static>(title: &str) -> impl Element<V> {
         div()
-            .text_2xl()
+            .text_xl()
             .text_color(rgb::<Hsla>(0xffffff))
             .child(title.to_owned())
     }
+
+    pub fn title_for<V: 'static, T>() -> impl Element<V> {
+        Self::title(std::any::type_name::<T>())
+    }
+
+    pub fn label<V: 'static>(label: &str) -> impl Element<V> {
+        div()
+            .mt_4()
+            .mb_2()
+            .text_xs()
+            .text_color(rgb::<Hsla>(0xffffff))
+            .child(label.to_owned())
+    }
 }

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

@@ -9,8 +9,10 @@ pub struct Facepile {
     players: Vec<Avatar>,
 }
 
-pub fn facepile(players: Vec<Avatar>) -> Facepile {
-    Facepile { players }
+pub fn facepile<P: Iterator<Item = Avatar>>(players: P) -> Facepile {
+    Facepile {
+        players: players.collect(),
+    }
 }
 
 impl Facepile {

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

@@ -46,7 +46,7 @@ impl FollowGroup {
                     .px_1()
                     .rounded_lg()
                     .fill(player_bg)
-                    .child(facepile(self.players.clone())),
+                    .child(facepile(self.players.clone().into_iter())),
             )
     }
 }