ui: Remove outdated/unused component stories (#43118)

Danilo Leal created

This PR removes basically all of the component stories, with the
exception of the context menu, which is a bit more intricate to set up.
All of the component that won't have a story after this PR will have an
entry in the Component Preview, which serves basically the same purpose.

Release Notes:

- N/A

Change summary

crates/storybook/src/story_selector.rs            |  14 -
crates/ui/src/components/list/list.rs             |  52 +++++
crates/ui/src/components/list/list_bullet_item.rs |  45 +++++
crates/ui/src/components/list/list_header.rs      |  82 +++++++++
crates/ui/src/components/list/list_item.rs        | 115 +++++++++++++
crates/ui/src/components/list/list_sub_header.rs  |  66 +++++++
crates/ui/src/components/stories.rs               |  14 -
crates/ui/src/components/stories/avatar.rs        |   0 
crates/ui/src/components/stories/button.rs        |   0 
crates/ui/src/components/stories/disclosure.rs    |  18 --
crates/ui/src/components/stories/icon_button.rs   | 148 -----------------
crates/ui/src/components/stories/keybinding.rs    | 136 ---------------
crates/ui/src/components/stories/list.rs          |  36 ----
crates/ui/src/components/stories/list_header.rs   |  31 ---
crates/ui/src/components/stories/list_item.rs     | 131 ---------------
crates/ui/src/components/stories/tab.rs           | 114 -------------
crates/ui/src/components/stories/tab_bar.rs       |  59 ------
17 files changed, 352 insertions(+), 709 deletions(-)

Detailed changes

crates/storybook/src/story_selector.rs 🔗

@@ -17,16 +17,9 @@ pub enum ComponentStory {
     ContextMenu,
     Cursor,
     Focus,
-    IconButton,
-    Keybinding,
-    List,
-    ListHeader,
-    ListItem,
     OverflowScroll,
     Picker,
     Scroll,
-    Tab,
-    TabBar,
     Text,
     ViewportUnits,
     WithRemSize,
@@ -46,16 +39,9 @@ impl ComponentStory {
             Self::ContextMenu => cx.new(|_| ui::ContextMenuStory).into(),
             Self::Cursor => cx.new(|_| crate::stories::CursorStory).into(),
             Self::Focus => FocusStory::model(window, cx).into(),
-            Self::IconButton => cx.new(|_| ui::IconButtonStory).into(),
-            Self::Keybinding => cx.new(|_| ui::KeybindingStory).into(),
-            Self::List => cx.new(|_| ui::ListStory).into(),
-            Self::ListHeader => cx.new(|_| ui::ListHeaderStory).into(),
-            Self::ListItem => cx.new(|_| ui::ListItemStory).into(),
             Self::OverflowScroll => cx.new(|_| crate::stories::OverflowScrollStory).into(),
             Self::Picker => PickerStory::new(window, cx).into(),
             Self::Scroll => ScrollStory::model(cx).into(),
-            Self::Tab => cx.new(|_| ui::TabStory).into(),
-            Self::TabBar => cx.new(|_| ui::TabBarStory).into(),
             Self::Text => TextStory::model(cx).into(),
             Self::ViewportUnits => cx.new(|_| crate::stories::ViewportUnitsStory).into(),
             Self::WithRemSize => cx.new(|_| crate::stories::WithRemSizeStory).into(),

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

@@ -1,14 +1,15 @@
+use component::{Component, ComponentScope, example_group_with_title, single_example};
 use gpui::AnyElement;
 use smallvec::SmallVec;
 
-use crate::{Label, ListHeader, prelude::*, v_flex};
+use crate::{Label, ListHeader, ListItem, prelude::*};
 
 pub enum EmptyMessage {
     Text(SharedString),
     Element(AnyElement),
 }
 
-#[derive(IntoElement)]
+#[derive(IntoElement, RegisterComponent)]
 pub struct List {
     /// Message to display when the list is empty
     /// Defaults to "No items"
@@ -92,3 +93,50 @@ impl RenderOnce for List {
             })
     }
 }
+
+impl Component for List {
+    fn scope() -> ComponentScope {
+        ComponentScope::Layout
+    }
+
+    fn description() -> Option<&'static str> {
+        Some(
+            "A container component for displaying a collection of list items with optional header and empty state.",
+        )
+    }
+
+    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+        Some(
+            v_flex()
+                .gap_6()
+                .children(vec![example_group_with_title(
+                    "Basic Lists",
+                    vec![
+                        single_example(
+                            "Simple List",
+                            List::new()
+                                .child(ListItem::new("item1").child(Label::new("Item 1")))
+                                .child(ListItem::new("item2").child(Label::new("Item 2")))
+                                .child(ListItem::new("item3").child(Label::new("Item 3")))
+                                .into_any_element(),
+                        ),
+                        single_example(
+                            "With Header",
+                            List::new()
+                                .header(ListHeader::new("Section Header"))
+                                .child(ListItem::new("item1").child(Label::new("Item 1")))
+                                .child(ListItem::new("item2").child(Label::new("Item 2")))
+                                .into_any_element(),
+                        ),
+                        single_example(
+                            "Empty List",
+                            List::new()
+                                .empty_message("No items to display")
+                                .into_any_element(),
+                        ),
+                    ],
+                )])
+                .into_any_element(),
+        )
+    }
+}

crates/ui/src/components/list/list_bullet_item.rs 🔗

@@ -1,7 +1,8 @@
 use crate::{ListItem, prelude::*};
+use component::{Component, ComponentScope, example_group_with_title, single_example};
 use gpui::{IntoElement, ParentElement, SharedString};
 
-#[derive(IntoElement)]
+#[derive(IntoElement, RegisterComponent)]
 pub struct ListBulletItem {
     label: SharedString,
 }
@@ -38,3 +39,45 @@ impl RenderOnce for ListBulletItem {
             .into_any_element()
     }
 }
+
+impl Component for ListBulletItem {
+    fn scope() -> ComponentScope {
+        ComponentScope::DataDisplay
+    }
+
+    fn description() -> Option<&'static str> {
+        Some("A list item with a bullet point indicator for unordered lists.")
+    }
+
+    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+        Some(
+            v_flex()
+                .gap_6()
+                .child(example_group_with_title(
+                    "Bullet Items",
+                    vec![
+                        single_example(
+                            "Simple",
+                            ListBulletItem::new("First bullet item").into_any_element(),
+                        ),
+                        single_example(
+                            "Multiple Lines",
+                            v_flex()
+                                .child(ListBulletItem::new("First item"))
+                                .child(ListBulletItem::new("Second item"))
+                                .child(ListBulletItem::new("Third item"))
+                                .into_any_element(),
+                        ),
+                        single_example(
+                            "Long Text",
+                            ListBulletItem::new(
+                                "A longer bullet item that demonstrates text wrapping behavior",
+                            )
+                            .into_any_element(),
+                        ),
+                    ],
+                ))
+                .into_any_element(),
+        )
+    }
+}

crates/ui/src/components/list/list_header.rs 🔗

@@ -1,11 +1,12 @@
 use std::sync::Arc;
 
-use crate::{Disclosure, Label, h_flex, prelude::*};
+use crate::{Disclosure, prelude::*};
+use component::{Component, ComponentScope, example_group_with_title, single_example};
 use gpui::{AnyElement, ClickEvent};
 use settings::Settings;
 use theme::ThemeSettings;
 
-#[derive(IntoElement)]
+#[derive(IntoElement, RegisterComponent)]
 pub struct ListHeader {
     /// The label of the header.
     label: SharedString,
@@ -138,3 +139,80 @@ impl RenderOnce for ListHeader {
             )
     }
 }
+
+impl Component for ListHeader {
+    fn scope() -> ComponentScope {
+        ComponentScope::DataDisplay
+    }
+
+    fn description() -> Option<&'static str> {
+        Some(
+            "A header component for lists with support for icons, actions, and collapsible sections.",
+        )
+    }
+
+    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+        Some(
+            v_flex()
+                .gap_6()
+                .children(vec![
+                    example_group_with_title(
+                        "Basic Headers",
+                        vec![
+                            single_example(
+                                "Simple",
+                                ListHeader::new("Section Header").into_any_element(),
+                            ),
+                            single_example(
+                                "With Icon",
+                                ListHeader::new("Files")
+                                    .start_slot(Icon::new(IconName::File))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "With End Slot",
+                                ListHeader::new("Recent")
+                                    .end_slot(Label::new("5").color(Color::Muted))
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Collapsible Headers",
+                        vec![
+                            single_example(
+                                "Expanded",
+                                ListHeader::new("Expanded Section")
+                                    .toggle(Some(true))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Collapsed",
+                                ListHeader::new("Collapsed Section")
+                                    .toggle(Some(false))
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "States",
+                        vec![
+                            single_example(
+                                "Selected",
+                                ListHeader::new("Selected Header")
+                                    .toggle_state(true)
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Inset",
+                                ListHeader::new("Inset Header")
+                                    .inset(true)
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                ])
+                .into_any_element(),
+        )
+    }
+}

crates/ui/src/components/list/list_item.rs 🔗

@@ -1,5 +1,6 @@
 use std::sync::Arc;
 
+use component::{Component, ComponentScope, example_group_with_title, single_example};
 use gpui::{AnyElement, AnyView, ClickEvent, MouseButton, MouseDownEvent, Pixels, px};
 use smallvec::SmallVec;
 
@@ -13,7 +14,7 @@ pub enum ListItemSpacing {
     Sparse,
 }
 
-#[derive(IntoElement)]
+#[derive(IntoElement, RegisterComponent)]
 pub struct ListItem {
     id: ElementId,
     group_name: Option<SharedString>,
@@ -355,3 +356,115 @@ impl RenderOnce for ListItem {
             )
     }
 }
+
+impl Component for ListItem {
+    fn scope() -> ComponentScope {
+        ComponentScope::DataDisplay
+    }
+
+    fn description() -> Option<&'static str> {
+        Some(
+            "A flexible list item component with support for icons, actions, disclosure toggles, and hierarchical display.",
+        )
+    }
+
+    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+        Some(
+            v_flex()
+                .gap_6()
+                .children(vec![
+                    example_group_with_title(
+                        "Basic List Items",
+                        vec![
+                            single_example(
+                                "Simple",
+                                ListItem::new("simple")
+                                    .child(Label::new("Simple list item"))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "With Icon",
+                                ListItem::new("with_icon")
+                                    .start_slot(Icon::new(IconName::File))
+                                    .child(Label::new("List item with icon"))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Selected",
+                                ListItem::new("selected")
+                                    .toggle_state(true)
+                                    .start_slot(Icon::new(IconName::Check))
+                                    .child(Label::new("Selected item"))
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "List Item Spacing",
+                        vec![
+                            single_example(
+                                "Dense",
+                                ListItem::new("dense")
+                                    .spacing(ListItemSpacing::Dense)
+                                    .child(Label::new("Dense spacing"))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Extra Dense",
+                                ListItem::new("extra_dense")
+                                    .spacing(ListItemSpacing::ExtraDense)
+                                    .child(Label::new("Extra dense spacing"))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Sparse",
+                                ListItem::new("sparse")
+                                    .spacing(ListItemSpacing::Sparse)
+                                    .child(Label::new("Sparse spacing"))
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "With Slots",
+                        vec![
+                            single_example(
+                                "End Slot",
+                                ListItem::new("end_slot")
+                                    .child(Label::new("Item with end slot"))
+                                    .end_slot(Icon::new(IconName::ChevronRight))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "With Toggle",
+                                ListItem::new("with_toggle")
+                                    .toggle(Some(true))
+                                    .child(Label::new("Expandable item"))
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "States",
+                        vec![
+                            single_example(
+                                "Disabled",
+                                ListItem::new("disabled")
+                                    .disabled(true)
+                                    .child(Label::new("Disabled item"))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Non-selectable",
+                                ListItem::new("non_selectable")
+                                    .selectable(false)
+                                    .child(Label::new("Non-selectable item"))
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                ])
+                .into_any_element(),
+        )
+    }
+}

crates/ui/src/components/list/list_sub_header.rs 🔗

@@ -1,7 +1,7 @@
 use crate::prelude::*;
-use crate::{Icon, IconName, IconSize, Label, h_flex};
+use component::{Component, ComponentScope, example_group_with_title, single_example};
 
-#[derive(IntoElement)]
+#[derive(IntoElement, RegisterComponent)]
 pub struct ListSubHeader {
     label: SharedString,
     start_slot: Option<IconName>,
@@ -85,3 +85,65 @@ impl RenderOnce for ListSubHeader {
             )
     }
 }
+
+impl Component for ListSubHeader {
+    fn scope() -> ComponentScope {
+        ComponentScope::DataDisplay
+    }
+
+    fn description() -> Option<&'static str> {
+        Some(
+            "A sub-header component for organizing list content into subsections with optional icons and end slots.",
+        )
+    }
+
+    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+        Some(
+            v_flex()
+                .gap_6()
+                .children(vec![
+                    example_group_with_title(
+                        "Basic Sub-headers",
+                        vec![
+                            single_example(
+                                "Simple",
+                                ListSubHeader::new("Subsection").into_any_element(),
+                            ),
+                            single_example(
+                                "With Icon",
+                                ListSubHeader::new("Documents")
+                                    .left_icon(Some(IconName::File))
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "With End Slot",
+                                ListSubHeader::new("Recent")
+                                    .end_slot(
+                                        Label::new("3").color(Color::Muted).into_any_element(),
+                                    )
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "States",
+                        vec![
+                            single_example(
+                                "Selected",
+                                ListSubHeader::new("Selected")
+                                    .toggle_state(true)
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Inset",
+                                ListSubHeader::new("Inset Sub-header")
+                                    .inset(true)
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                ])
+                .into_any_element(),
+        )
+    }
+}

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

@@ -1,17 +1,3 @@
 mod context_menu;
-mod icon_button;
-mod keybinding;
-mod list;
-mod list_header;
-mod list_item;
-mod tab;
-mod tab_bar;
 
 pub use context_menu::*;
-pub use icon_button::*;
-pub use keybinding::*;
-pub use list::*;
-pub use list_header::*;
-pub use list_item::*;
-pub use tab::*;
-pub use tab_bar::*;

crates/ui/src/components/stories/disclosure.rs 🔗

@@ -1,18 +0,0 @@
-use gpui::Render;
-use story::Story;
-
-use crate::Disclosure;
-use crate::prelude::*;
-
-pub struct DisclosureStory;
-
-impl Render for DisclosureStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        Story::container(cx)
-            .child(Story::title_for::<Disclosure>(cx))
-            .child(Story::label("Toggled"))
-            .child(Disclosure::new("toggled", true))
-            .child(Story::label("Not Toggled"))
-            .child(Disclosure::new("not_toggled", false))
-    }
-}

crates/ui/src/components/stories/icon_button.rs 🔗

@@ -1,148 +0,0 @@
-use gpui::Render;
-use story::{Story, StoryItem, StorySection};
-
-use crate::{IconButton, IconName};
-use crate::{IconButtonShape, Tooltip, prelude::*};
-
-pub struct IconButtonStory;
-
-impl Render for IconButtonStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let default_button = StoryItem::new(
-            "Default",
-            IconButton::new("default_icon_button", IconName::Hash),
-        )
-        .description("Displays an icon button.")
-        .usage(
-            r#"
-            IconButton::new("default_icon_button", Icon::Hash)
-        "#,
-        );
-
-        let selected_button = StoryItem::new(
-            "Selected",
-            IconButton::new("selected_icon_button", IconName::Hash).toggle_state(true),
-        )
-        .description("Displays an icon button that is selected.")
-        .usage(
-            r#"
-            IconButton::new("selected_icon_button", Icon::Hash).selected(true)
-        "#,
-        );
-
-        let selected_with_selected_icon = StoryItem::new(
-            "Selected with `selected_icon`",
-            IconButton::new("selected_with_selected_icon_button", IconName::AudioOn)
-                .toggle_state(true)
-                .selected_icon(IconName::AudioOff),
-        )
-        .description(
-            "Displays an icon button that is selected and shows a different icon when selected.",
-        )
-        .usage(
-            r#"
-            IconButton::new("selected_with_selected_icon_button", Icon::AudioOn)
-                .selected(true)
-                .selected_icon(Icon::AudioOff)
-        "#,
-        );
-
-        let disabled_button = StoryItem::new(
-            "Disabled",
-            IconButton::new("disabled_icon_button", IconName::Hash).disabled(true),
-        )
-        .description("Displays an icon button that is disabled.")
-        .usage(
-            r#"
-            IconButton::new("disabled_icon_button", Icon::Hash).disabled(true)
-        "#,
-        );
-
-        let with_on_click_button = StoryItem::new(
-            "With `on_click`",
-            IconButton::new("with_on_click_button", IconName::Ai).on_click(
-                |_event, _window, _cx| {
-                    println!("Clicked!");
-                },
-            ),
-        )
-        .description("Displays an icon button which triggers an event on click.")
-        .usage(
-            r#"
-            IconButton::new("with_on_click_button", Icon::Ai).on_click(|_event, _cx| {
-                println!("Clicked!");
-            })
-        "#,
-        );
-
-        let with_tooltip_button = StoryItem::new(
-            "With `tooltip`",
-            IconButton::new("with_tooltip_button", IconName::Chat)
-                .tooltip(Tooltip::text("Open messages")),
-        )
-        .description("Displays an icon button that has a tooltip when hovered.")
-        .usage(
-            r#"
-            IconButton::new("with_tooltip_button", Icon::MessageBubbles)
-                .tooltip(Tooltip::text_f("Open messages"))
-        "#,
-        );
-
-        let selected_with_tooltip_button = StoryItem::new(
-            "Selected with `tooltip`",
-            IconButton::new("selected_with_tooltip_button", IconName::CaseSensitive)
-                .toggle_state(true)
-                .tooltip(Tooltip::text("Toggle inlay hints")),
-        )
-        .description("Displays a selected icon button with tooltip.")
-        .usage(
-            r#"
-            IconButton::new("selected_with_tooltip_button", Icon::InlayHint)
-                .selected(true)
-                .tooltip(Tooltip::text_f("Toggle inlay hints"))
-        "#,
-        );
-
-        let buttons = vec![
-            default_button,
-            selected_button,
-            selected_with_selected_icon,
-            disabled_button,
-            with_on_click_button,
-            with_tooltip_button,
-            selected_with_tooltip_button,
-        ];
-
-        Story::container(cx)
-            .child(Story::title_for::<IconButton>(cx))
-            .child(StorySection::new().children(buttons))
-            .child(
-                StorySection::new().child(StoryItem::new(
-                    "Square",
-                    h_flex()
-                        .gap_2()
-                        .child(
-                            IconButton::new("square-medium", IconName::Close)
-                                .shape(IconButtonShape::Square)
-                                .icon_size(IconSize::Medium),
-                        )
-                        .child(
-                            IconButton::new("square-small", IconName::Close)
-                                .shape(IconButtonShape::Square)
-                                .icon_size(IconSize::Small),
-                        )
-                        .child(
-                            IconButton::new("square-xsmall", IconName::Close)
-                                .shape(IconButtonShape::Square)
-                                .icon_size(IconSize::XSmall),
-                        )
-                        .child(
-                            IconButton::new("square-indicator", IconName::Close)
-                                .shape(IconButtonShape::Square)
-                                .icon_size(IconSize::Indicator),
-                        ),
-                )),
-            )
-            .into_element()
-    }
-}

crates/ui/src/components/stories/keybinding.rs 🔗

@@ -1,136 +0,0 @@
-use gpui::NoAction;
-use gpui::Render;
-use itertools::Itertools;
-use settings::KeybindSource;
-use story::Story;
-
-use crate::{KeyBinding, prelude::*};
-
-pub struct KeybindingStory;
-
-pub fn binding(key: &str) -> gpui::KeyBinding {
-    gpui::KeyBinding::new(key, NoAction {}, None)
-}
-
-impl Render for KeybindingStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
-
-        const SOURCE: KeybindSource = KeybindSource::Base;
-
-        Story::container(cx)
-            .child(Story::title_for::<KeyBinding>(cx))
-            .child(Story::label("Single Key", cx))
-            .child(KeyBinding::from_keystrokes(
-                binding("Z").keystrokes().into(),
-                SOURCE,
-            ))
-            .child(Story::label("Single Key with Modifier", cx))
-            .child(
-                div()
-                    .flex()
-                    .gap_3()
-                    .child(KeyBinding::from_keystrokes(
-                        binding("ctrl-c").keystrokes().into(),
-                        SOURCE,
-                    ))
-                    .child(KeyBinding::from_keystrokes(
-                        binding("alt-c").keystrokes().into(),
-                        SOURCE,
-                    ))
-                    .child(KeyBinding::from_keystrokes(
-                        binding("cmd-c").keystrokes().into(),
-                        SOURCE,
-                    ))
-                    .child(KeyBinding::from_keystrokes(
-                        binding("shift-c").keystrokes().into(),
-                        SOURCE,
-                    )),
-            )
-            .child(Story::label("Single Key with Modifier (Permuted)", cx))
-            .child(
-                div().flex().flex_col().children(
-                    all_modifier_permutations
-                        .chunks(4)
-                        .into_iter()
-                        .map(|chunk| {
-                            div()
-                                .flex()
-                                .gap_4()
-                                .py_3()
-                                .children(chunk.map(|permutation| {
-                                    KeyBinding::from_keystrokes(
-                                        binding(&(permutation.join("-") + "-x"))
-                                            .keystrokes()
-                                            .into(),
-                                        SOURCE,
-                                    )
-                                }))
-                        }),
-                ),
-            )
-            .child(Story::label("Single Key with All Modifiers", cx))
-            .child(KeyBinding::from_keystrokes(
-                binding("ctrl-alt-cmd-shift-z").keystrokes().into(),
-                SOURCE,
-            ))
-            .child(Story::label("Chord", cx))
-            .child(KeyBinding::from_keystrokes(
-                binding("a z").keystrokes().into(),
-                SOURCE,
-            ))
-            .child(Story::label("Chord with Modifier", cx))
-            .child(KeyBinding::from_keystrokes(
-                binding("ctrl-a shift-z").keystrokes().into(),
-                SOURCE,
-            ))
-            .child(KeyBinding::from_keystrokes(
-                binding("fn-s").keystrokes().into(),
-                SOURCE,
-            ))
-            .child(Story::label("Single Key with All Modifiers (Linux)", cx))
-            .child(
-                KeyBinding::from_keystrokes(
-                    binding("ctrl-alt-cmd-shift-z").keystrokes().into(),
-                    SOURCE,
-                )
-                .platform_style(PlatformStyle::Linux),
-            )
-            .child(Story::label("Chord (Linux)", cx))
-            .child(
-                KeyBinding::from_keystrokes(binding("a z").keystrokes().into(), SOURCE)
-                    .platform_style(PlatformStyle::Linux),
-            )
-            .child(Story::label("Chord with Modifier (Linux)", cx))
-            .child(
-                KeyBinding::from_keystrokes(binding("ctrl-a shift-z").keystrokes().into(), SOURCE)
-                    .platform_style(PlatformStyle::Linux),
-            )
-            .child(
-                KeyBinding::from_keystrokes(binding("fn-s").keystrokes().into(), SOURCE)
-                    .platform_style(PlatformStyle::Linux),
-            )
-            .child(Story::label("Single Key with All Modifiers (Windows)", cx))
-            .child(
-                KeyBinding::from_keystrokes(
-                    binding("ctrl-alt-cmd-shift-z").keystrokes().into(),
-                    SOURCE,
-                )
-                .platform_style(PlatformStyle::Windows),
-            )
-            .child(Story::label("Chord (Windows)", cx))
-            .child(
-                KeyBinding::from_keystrokes(binding("a z").keystrokes().into(), SOURCE)
-                    .platform_style(PlatformStyle::Windows),
-            )
-            .child(Story::label("Chord with Modifier (Windows)", cx))
-            .child(
-                KeyBinding::from_keystrokes(binding("ctrl-a shift-z").keystrokes().into(), SOURCE)
-                    .platform_style(PlatformStyle::Windows),
-            )
-            .child(
-                KeyBinding::from_keystrokes(binding("fn-s").keystrokes().into(), SOURCE)
-                    .platform_style(PlatformStyle::Windows),
-            )
-    }
-}

crates/ui/src/components/stories/list.rs 🔗

@@ -1,36 +0,0 @@
-use gpui::Render;
-use story::Story;
-
-use crate::{List, ListItem};
-use crate::{ListHeader, ListSeparator, ListSubHeader, prelude::*};
-
-pub struct ListStory;
-
-impl Render for ListStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        Story::container(cx)
-            .child(Story::title_for::<List>(cx))
-            .child(Story::label("Default", cx))
-            .child(
-                List::new()
-                    .child(ListItem::new("apple").child("Apple"))
-                    .child(ListItem::new("banana").child("Banana"))
-                    .child(ListItem::new("cherry").child("Cherry")),
-            )
-            .child(Story::label("With sections", cx))
-            .child(
-                List::new()
-                    .header(ListHeader::new("Produce"))
-                    .child(ListSubHeader::new("Fruits"))
-                    .child(ListItem::new("apple").child("Apple"))
-                    .child(ListItem::new("banana").child("Banana"))
-                    .child(ListItem::new("cherry").child("Cherry"))
-                    .child(ListSeparator)
-                    .child(ListSubHeader::new("Root Vegetables"))
-                    .child(ListItem::new("carrot").child("Carrot"))
-                    .child(ListItem::new("potato").child("Potato"))
-                    .child(ListSubHeader::new("Leafy Vegetables"))
-                    .child(ListItem::new("kale").child("Kale")),
-            )
-    }
-}

crates/ui/src/components/stories/list_header.rs 🔗

@@ -1,31 +0,0 @@
-use gpui::Render;
-use story::Story;
-
-use crate::{IconButton, prelude::*};
-use crate::{IconName, ListHeader};
-
-pub struct ListHeaderStory;
-
-impl Render for ListHeaderStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        Story::container(cx)
-            .child(Story::title_for::<ListHeader>(cx))
-            .child(Story::label("Default", cx))
-            .child(ListHeader::new("Section 1"))
-            .child(Story::label("With left icon", cx))
-            .child(ListHeader::new("Section 2").start_slot(Icon::new(IconName::Bell)))
-            .child(Story::label("With left icon and meta", cx))
-            .child(
-                ListHeader::new("Section 3")
-                    .start_slot(Icon::new(IconName::BellOff))
-                    .end_slot(IconButton::new("action_1", IconName::BoltFilled)),
-            )
-            .child(Story::label("With multiple meta", cx))
-            .child(
-                ListHeader::new("Section 4")
-                    .end_slot(IconButton::new("action_1", IconName::BoltFilled))
-                    .end_slot(IconButton::new("action_2", IconName::Warning))
-                    .end_slot(IconButton::new("action_3", IconName::Plus)),
-            )
-    }
-}

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

@@ -1,131 +0,0 @@
-use gpui::Render;
-use story::Story;
-
-use crate::{Avatar, prelude::*};
-use crate::{IconName, ListItem};
-
-const OVERFLOWING_TEXT: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean mauris ligula, luctus vel dignissim eu, vestibulum sed libero. Sed at convallis velit.";
-
-pub struct ListItemStory;
-
-impl Render for ListItemStory {
-    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        Story::container(cx)
-            .bg(cx.theme().colors().background)
-            .child(Story::title_for::<ListItem>(cx))
-            .child(Story::label("Default", cx))
-            .child(ListItem::new("hello_world").child("Hello, world!"))
-            .child(Story::label("Inset", cx))
-            .child(
-                ListItem::new("inset_list_item")
-                    .inset(true)
-                    .start_slot(
-                        Icon::new(IconName::Bell)
-                            .size(IconSize::Small)
-                            .color(Color::Muted),
-                    )
-                    .child("Hello, world!")
-                    .end_slot(
-                        Icon::new(IconName::Bell)
-                            .size(IconSize::Small)
-                            .color(Color::Muted),
-                    ),
-            )
-            .child(Story::label("With start slot icon", cx))
-            .child(
-                ListItem::new("with start slot_icon")
-                    .child("Hello, world!")
-                    .start_slot(
-                        Icon::new(IconName::Bell)
-                            .size(IconSize::Small)
-                            .color(Color::Muted),
-                    ),
-            )
-            .child(Story::label("With start slot avatar", cx))
-            .child(
-                ListItem::new("with_start slot avatar")
-                    .child("Hello, world!")
-                    .start_slot(Avatar::new(
-                        "https://avatars.githubusercontent.com/u/1714999?v=4",
-                    )),
-            )
-            .child(Story::label("With end slot", cx))
-            .child(
-                ListItem::new("with_left_avatar")
-                    .child("Hello, world!")
-                    .end_slot(Avatar::new(
-                        "https://avatars.githubusercontent.com/u/1714999?v=4",
-                    )),
-            )
-            .child(Story::label("With end hover slot", cx))
-            .child(
-                ListItem::new("with_end_hover_slot")
-                    .child("Hello, world!")
-                    .end_slot(
-                        h_flex()
-                            .gap_2()
-                            .child(Avatar::new(
-                                "https://avatars.githubusercontent.com/u/1789?v=4",
-                            ))
-                            .child(Avatar::new(
-                                "https://avatars.githubusercontent.com/u/1789?v=4",
-                            ))
-                            .child(Avatar::new(
-                                "https://avatars.githubusercontent.com/u/1789?v=4",
-                            ))
-                            .child(Avatar::new(
-                                "https://avatars.githubusercontent.com/u/1789?v=4",
-                            ))
-                            .child(Avatar::new(
-                                "https://avatars.githubusercontent.com/u/1789?v=4",
-                            )),
-                    )
-                    .end_hover_slot(Avatar::new(
-                        "https://avatars.githubusercontent.com/u/1714999?v=4",
-                    )),
-            )
-            .child(Story::label("With `on_click`", cx))
-            .child(ListItem::new("with_on_click").child("Click me").on_click(
-                |_event, _window, _cx| {
-                    println!("Clicked!");
-                },
-            ))
-            .child(Story::label("With `on_secondary_mouse_down`", cx))
-            .child(
-                ListItem::new("with_on_secondary_mouse_down")
-                    .child("Right click me")
-                    .on_secondary_mouse_down(|_event, _window, _cx| {
-                        println!("Right mouse down!");
-                    }),
-            )
-            .child(Story::label(
-                "With overflowing content in the `end_slot`",
-                cx,
-            ))
-            .child(
-                ListItem::new("with_overflowing_content_in_end_slot")
-                    .child("An excerpt")
-                    .end_slot(Label::new(OVERFLOWING_TEXT).color(Color::Muted)),
-            )
-            .child(Story::label(
-                "`inset` with overflowing content in the `end_slot`",
-                cx,
-            ))
-            .child(
-                ListItem::new("inset_with_overflowing_content_in_end_slot")
-                    .inset(true)
-                    .child("An excerpt")
-                    .end_slot(Label::new(OVERFLOWING_TEXT).color(Color::Muted)),
-            )
-            .child(Story::label(
-                "`inset` with overflowing content in `children` and `end_slot`",
-                cx,
-            ))
-            .child(
-                ListItem::new("inset_with_overflowing_content_in_children_and_end_slot")
-                    .inset(true)
-                    .child(Label::new(OVERFLOWING_TEXT))
-                    .end_slot(Label::new(OVERFLOWING_TEXT).color(Color::Muted)),
-            )
-    }
-}

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

@@ -1,114 +0,0 @@
-use std::cmp::Ordering;
-
-use gpui::Render;
-use story::Story;
-
-use crate::{IconButtonShape, TabPosition, prelude::*};
-use crate::{Indicator, Tab};
-
-pub struct TabStory;
-
-impl Render for TabStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        Story::container(cx)
-            .child(Story::title_for::<Tab>(cx))
-            .child(Story::label("Default", cx))
-            .child(h_flex().child(Tab::new("tab_1").child("Tab 1")))
-            .child(Story::label("With indicator", cx))
-            .child(
-                h_flex().child(
-                    Tab::new("tab_1")
-                        .start_slot(Indicator::dot().color(Color::Warning))
-                        .child("Tab 1"),
-                ),
-            )
-            .child(Story::label("With close button", cx))
-            .child(
-                h_flex().child(
-                    Tab::new("tab_1")
-                        .end_slot(
-                            IconButton::new("close_button", IconName::Close)
-                                .visible_on_hover("")
-                                .shape(IconButtonShape::Square)
-                                .icon_color(Color::Muted)
-                                .size(ButtonSize::None)
-                                .icon_size(IconSize::XSmall),
-                        )
-                        .child("Tab 1"),
-                ),
-            )
-            .child(Story::label("List of tabs", cx))
-            .child(
-                h_flex()
-                    .child(Tab::new("tab_1").child("Tab 1"))
-                    .child(Tab::new("tab_2").child("Tab 2")),
-            )
-            .child(Story::label("List of tabs with first tab selected", cx))
-            .child(
-                h_flex()
-                    .child(
-                        Tab::new("tab_1")
-                            .toggle_state(true)
-                            .position(TabPosition::First)
-                            .child("Tab 1"),
-                    )
-                    .child(
-                        Tab::new("tab_2")
-                            .position(TabPosition::Middle(Ordering::Greater))
-                            .child("Tab 2"),
-                    )
-                    .child(
-                        Tab::new("tab_3")
-                            .position(TabPosition::Middle(Ordering::Greater))
-                            .child("Tab 3"),
-                    )
-                    .child(Tab::new("tab_4").position(TabPosition::Last).child("Tab 4")),
-            )
-            .child(Story::label("List of tabs with last tab selected", cx))
-            .child(
-                h_flex()
-                    .child(
-                        Tab::new("tab_1")
-                            .position(TabPosition::First)
-                            .child("Tab 1"),
-                    )
-                    .child(
-                        Tab::new("tab_2")
-                            .position(TabPosition::Middle(Ordering::Less))
-                            .child("Tab 2"),
-                    )
-                    .child(
-                        Tab::new("tab_3")
-                            .position(TabPosition::Middle(Ordering::Less))
-                            .child("Tab 3"),
-                    )
-                    .child(
-                        Tab::new("tab_4")
-                            .position(TabPosition::Last)
-                            .toggle_state(true)
-                            .child("Tab 4"),
-                    ),
-            )
-            .child(Story::label("List of tabs with second tab selected", cx))
-            .child(
-                h_flex()
-                    .child(
-                        Tab::new("tab_1")
-                            .position(TabPosition::First)
-                            .child("Tab 1"),
-                    )
-                    .child(
-                        Tab::new("tab_2")
-                            .position(TabPosition::Middle(Ordering::Equal))
-                            .toggle_state(true)
-                            .child("Tab 2"),
-                    )
-                    .child(
-                        Tab::new("tab_3")
-                            .position(TabPosition::Middle(Ordering::Greater))
-                            .child("Tab 3"),
-                    )
-                    .child(Tab::new("tab_4").position(TabPosition::Last).child("Tab 4")),
-            )
-    }
-}

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

@@ -1,59 +0,0 @@
-use gpui::Render;
-use story::Story;
-
-use crate::{Tab, TabBar, TabPosition, prelude::*};
-
-pub struct TabBarStory;
-
-impl Render for TabBarStory {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let tab_count = 20;
-        let selected_tab_index = 3;
-
-        let tabs = (0..tab_count)
-            .map(|index| {
-                Tab::new(index)
-                    .toggle_state(index == selected_tab_index)
-                    .position(if index == 0 {
-                        TabPosition::First
-                    } else if index == tab_count - 1 {
-                        TabPosition::Last
-                    } else {
-                        TabPosition::Middle(index.cmp(&selected_tab_index))
-                    })
-                    .child(Label::new(format!("Tab {}", index + 1)).color(
-                        if index == selected_tab_index {
-                            Color::Default
-                        } else {
-                            Color::Muted
-                        },
-                    ))
-            })
-            .collect::<Vec<_>>();
-
-        Story::container(cx)
-            .child(Story::title_for::<TabBar>(cx))
-            .child(Story::label("Default", cx))
-            .child(
-                h_flex().child(
-                    TabBar::new("tab_bar_1")
-                        .start_child(
-                            IconButton::new("navigate_backward", IconName::ArrowLeft)
-                                .icon_size(IconSize::Small),
-                        )
-                        .start_child(
-                            IconButton::new("navigate_forward", IconName::ArrowRight)
-                                .icon_size(IconSize::Small),
-                        )
-                        .end_child(
-                            IconButton::new("new", IconName::Plus).icon_size(IconSize::Small),
-                        )
-                        .end_child(
-                            IconButton::new("split_pane", IconName::Split)
-                                .icon_size(IconSize::Small),
-                        )
-                        .children(tabs),
-                ),
-            )
-    }
-}