Add `ListItem` story (#3411)

Marshall Bowers created

This PR adds a story for the `ListItem` component, so we can work on it
in isolation.

Release Notes:

- N/A

Change summary

crates/gpui2/src/elements/uniform_list.rs      |  2 
crates/storybook2/src/story_selector.rs        | 13 +++++----
crates/ui2/src/components/stories.rs           |  2 +
crates/ui2/src/components/stories/list_item.rs | 26 ++++++++++++++++++++
4 files changed, 36 insertions(+), 7 deletions(-)

Detailed changes

crates/gpui2/src/elements/uniform_list.rs 🔗

@@ -9,7 +9,7 @@ use taffy::style::Overflow;
 
 /// uniform_list provides lazy rendering for a set of items that are of uniform height.
 /// When rendered into a container with overflow-y: hidden and a fixed (or max) height,
-/// uniform_list will only render the visibile subset of items.
+/// uniform_list will only render the visible subset of items.
 pub fn uniform_list<I, R, V>(
     view: View<V>,
     id: I,

crates/storybook2/src/story_selector.rs 🔗

@@ -8,7 +8,6 @@ use clap::ValueEnum;
 use gpui::{AnyView, VisualContext};
 use strum::{EnumIter, EnumString, IntoEnumIterator};
 use ui::prelude::*;
-use ui::{AvatarStory, ButtonStory, IconStory, InputStory, LabelStory};
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy, strum::Display, EnumString, EnumIter)]
 #[strum(serialize_all = "snake_case")]
@@ -22,6 +21,7 @@ pub enum ComponentStory {
     Input,
     Keybinding,
     Label,
+    ListItem,
     Scroll,
     Text,
     ZIndex,
@@ -31,15 +31,16 @@ pub enum ComponentStory {
 impl ComponentStory {
     pub fn story(&self, cx: &mut WindowContext) -> AnyView {
         match self {
-            Self::Avatar => cx.build_view(|_| AvatarStory).into(),
-            Self::Button => cx.build_view(|_| ButtonStory).into(),
+            Self::Avatar => cx.build_view(|_| ui::AvatarStory).into(),
+            Self::Button => cx.build_view(|_| ui::ButtonStory).into(),
             Self::Checkbox => cx.build_view(|_| ui::CheckboxStory).into(),
             Self::ContextMenu => cx.build_view(|_| ui::ContextMenuStory).into(),
             Self::Focus => FocusStory::view(cx).into(),
-            Self::Icon => cx.build_view(|_| IconStory).into(),
-            Self::Input => cx.build_view(|_| InputStory).into(),
+            Self::Icon => cx.build_view(|_| ui::IconStory).into(),
+            Self::Input => cx.build_view(|_| ui::InputStory).into(),
             Self::Keybinding => cx.build_view(|_| ui::KeybindingStory).into(),
-            Self::Label => cx.build_view(|_| LabelStory).into(),
+            Self::Label => cx.build_view(|_| ui::LabelStory).into(),
+            Self::ListItem => cx.build_view(|_| ui::ListItemStory).into(),
             Self::Scroll => ScrollStory::view(cx).into(),
             Self::Text => TextStory::view(cx).into(),
             Self::ZIndex => cx.build_view(|_| ZIndexStory).into(),

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

@@ -6,6 +6,7 @@ mod icon;
 mod input;
 mod keybinding;
 mod label;
+mod list_item;
 
 pub use avatar::*;
 pub use button::*;
@@ -15,3 +16,4 @@ pub use icon::*;
 pub use input::*;
 pub use keybinding::*;
 pub use label::*;
+pub use list_item::*;

crates/ui2/src/components/stories/list_item.rs 🔗

@@ -0,0 +1,26 @@
+use gpui::{Div, Render};
+use story::Story;
+
+use crate::prelude::*;
+use crate::ListItem;
+
+pub struct ListItemStory;
+
+impl Render for ListItemStory {
+    type Element = Div;
+
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+        Story::container()
+            .child(Story::title_for::<ListItem>())
+            .child(Story::label("Default"))
+            .child(ListItem::new("hello_world").child("Hello, world!"))
+            .child(Story::label("With `on_click`"))
+            .child(
+                ListItem::new("with_on_click")
+                    .child("Click me")
+                    .on_click(|_event, _cx| {
+                        println!("Clicked!");
+                    }),
+            )
+    }
+}