Clean out UI

Nate Butler created

Change summary

crates/ui2/Cargo.toml                             |   4 
crates/ui2/src/components.rs                      |  28 -
crates/ui2/src/components/avatar.rs               |  28 -
crates/ui2/src/components/button.rs               | 168 ----------
crates/ui2/src/components/checkbox.rs             |  60 ---
crates/ui2/src/components/context_menu.rs         | 113 ------
crates/ui2/src/components/details.rs              |  83 -----
crates/ui2/src/components/elevated_surface.rs     |  28 -
crates/ui2/src/components/facepile.rs             |  33 --
crates/ui2/src/components/icon.rs                 |  28 -
crates/ui2/src/components/indicator.rs            |  37 --
crates/ui2/src/components/input.rs                |  23 -
crates/ui2/src/components/keybinding.rs           |  67 ----
crates/ui2/src/components/label.rs                |  32 -
crates/ui2/src/components/modal.rs                |  85 -----
crates/ui2/src/components/notification_toast.rs   |  40 --
crates/ui2/src/components/palette.rs              | 212 -------------
crates/ui2/src/components/panel.rs                | 152 ---------
crates/ui2/src/components/player.rs               | 174 ----------
crates/ui2/src/components/player_stack.rs         |  67 ----
crates/ui2/src/components/stories/avatar.rs       |  27 +
crates/ui2/src/components/stories/button.rs       | 167 ++++++++++
crates/ui2/src/components/stories/checkbox.rs     |  59 +++
crates/ui2/src/components/stories/context_menu.rs | 112 ++++++
crates/ui2/src/components/stories/icon.rs         |  27 +
crates/ui2/src/components/stories/input.rs        |  22 +
crates/ui2/src/components/stories/keybinding.rs   |  66 ++++
crates/ui2/src/components/stories/label.rs        |  31 +
crates/ui2/src/components/stories/mod.rs          |   8 
crates/ui2/src/components/tab.rs                  | 276 -----------------
crates/ui2/src/components/toast.rs                | 117 -------
crates/ui2/src/components/tool_divider.rs         |  23 -
crates/ui2/src/prelude.rs                         |   1 
crates/ui2/src/styles.rs                          |   2 
crates/ui2/src/styles/docs/elevation.md           |   0 
crates/ui2/src/styles/elevation.rs                |   2 
crates/ui2/src/ui2.rs                             |   4 
37 files changed, 530 insertions(+), 1,876 deletions(-)

Detailed changes

crates/ui2/Cargo.toml 🔗

@@ -4,6 +4,10 @@ version = "0.1.0"
 edition = "2021"
 publish = false
 
+[lib]
+name = "ui2"
+path = "src/ui2.rs"
+
 [dependencies]
 anyhow.workspace = true
 chrono = "0.4"

crates/ui2/src/components.rs 🔗

@@ -2,56 +2,32 @@ mod avatar;
 mod button;
 mod checkbox;
 mod context_menu;
-mod details;
 mod divider;
-mod elevated_surface;
-mod facepile;
 mod icon;
 mod icon_button;
-mod indicator;
 mod input;
 mod keybinding;
 mod label;
 mod list;
-mod modal;
-mod notification_toast;
-mod palette;
-mod panel;
-mod player;
-mod player_stack;
 mod slot;
 mod stack;
-mod tab;
-mod toast;
+mod stories;
 mod toggle;
-mod tool_divider;
 mod tooltip;
 
 pub use avatar::*;
 pub use button::*;
 pub use checkbox::*;
 pub use context_menu::*;
-pub use details::*;
 pub use divider::*;
-pub use elevated_surface::*;
-pub use facepile::*;
 pub use icon::*;
 pub use icon_button::*;
-pub use indicator::*;
 pub use input::*;
 pub use keybinding::*;
 pub use label::*;
 pub use list::*;
-pub use modal::*;
-pub use notification_toast::*;
-pub use palette::*;
-pub use panel::*;
-pub use player::*;
-pub use player_stack::*;
 pub use slot::*;
 pub use stack::*;
-pub use tab::*;
-pub use toast::*;
+pub use stories::*;
 pub use toggle::*;
-pub use tool_divider::*;
 pub use tooltip::*;

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

@@ -39,31 +39,3 @@ impl Avatar {
         self
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::Story;
-    use gpui::{Div, Render};
-
-    pub struct AvatarStory;
-
-    impl Render for AvatarStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Avatar>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(Avatar::new(
-                    "https://avatars.githubusercontent.com/u/1714999?v=4",
-                ))
-                .child(Avatar::new(
-                    "https://avatars.githubusercontent.com/u/326587?v=4",
-                ))
-        }
-    }
-}

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

@@ -231,171 +231,3 @@ impl ButtonGroup {
         Self { buttons }
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::{h_stack, v_stack, Story, TextColor};
-    use gpui::{rems, Div, Render};
-    use strum::IntoEnumIterator;
-
-    pub struct ButtonStory;
-
-    impl Render for ButtonStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            let states = InteractionState::iter();
-
-            Story::container(cx)
-                .child(Story::title_for::<Button>(cx))
-                .child(
-                    div()
-                        .flex()
-                        .gap_8()
-                        .child(
-                            div()
-                                .child(Story::label(cx, "Ghost (Default)"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label").variant(ButtonVariant::Ghost), // .state(state),
-                                        )
-                                })))
-                                .child(Story::label(cx, "Ghost – Left Icon"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Ghost)
-                                                .icon(Icon::Plus)
-                                                .icon_position(IconPosition::Left), // .state(state),
-                                        )
-                                })))
-                                .child(Story::label(cx, "Ghost – Right Icon"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Ghost)
-                                                .icon(Icon::Plus)
-                                                .icon_position(IconPosition::Right), // .state(state),
-                                        )
-                                }))),
-                        )
-                        .child(
-                            div()
-                                .child(Story::label(cx, "Filled"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label").variant(ButtonVariant::Filled), // .state(state),
-                                        )
-                                })))
-                                .child(Story::label(cx, "Filled – Left Button"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Filled)
-                                                .icon(Icon::Plus)
-                                                .icon_position(IconPosition::Left), // .state(state),
-                                        )
-                                })))
-                                .child(Story::label(cx, "Filled – Right Button"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Filled)
-                                                .icon(Icon::Plus)
-                                                .icon_position(IconPosition::Right), // .state(state),
-                                        )
-                                }))),
-                        )
-                        .child(
-                            div()
-                                .child(Story::label(cx, "Fixed With"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Filled)
-                                                // .state(state)
-                                                .width(Some(rems(6.).into())),
-                                        )
-                                })))
-                                .child(Story::label(cx, "Fixed With – Left Icon"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Filled)
-                                                // .state(state)
-                                                .icon(Icon::Plus)
-                                                .icon_position(IconPosition::Left)
-                                                .width(Some(rems(6.).into())),
-                                        )
-                                })))
-                                .child(Story::label(cx, "Fixed With – Right Icon"))
-                                .child(h_stack().gap_2().children(states.clone().map(|state| {
-                                    v_stack()
-                                        .gap_1()
-                                        .child(
-                                            Label::new(state.to_string()).color(TextColor::Muted),
-                                        )
-                                        .child(
-                                            Button::new("Label")
-                                                .variant(ButtonVariant::Filled)
-                                                // .state(state)
-                                                .icon(Icon::Plus)
-                                                .icon_position(IconPosition::Right)
-                                                .width(Some(rems(6.).into())),
-                                        )
-                                }))),
-                        ),
-                )
-                .child(Story::label(cx, "Button with `on_click`"))
-                .child(
-                    Button::new("Label")
-                        .variant(ButtonVariant::Ghost)
-                        .on_click(|_, cx| println!("Button clicked.")),
-                )
-        }
-    }
-}

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

@@ -283,63 +283,3 @@ impl Checkbox {
             )
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::{h_stack, Story};
-    use gpui::{Div, Render, ViewContext};
-
-    pub struct CheckboxStory;
-
-    impl Render for CheckboxStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Checkbox>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(
-                    h_stack()
-                        .p_2()
-                        .gap_2()
-                        .rounded_md()
-                        .border()
-                        .border_color(cx.theme().colors().border)
-                        .child(Checkbox::new("checkbox-enabled", Selection::Unselected))
-                        .child(Checkbox::new(
-                            "checkbox-intermediate",
-                            Selection::Indeterminate,
-                        ))
-                        .child(Checkbox::new("checkbox-selected", Selection::Selected)),
-                )
-                .child(Story::label(cx, "Disabled"))
-                .child(
-                    h_stack()
-                        .p_2()
-                        .gap_2()
-                        .rounded_md()
-                        .border()
-                        .border_color(cx.theme().colors().border)
-                        .child(
-                            Checkbox::new("checkbox-disabled", Selection::Unselected)
-                                .disabled(true),
-                        )
-                        .child(
-                            Checkbox::new(
-                                "checkbox-disabled-intermediate",
-                                Selection::Indeterminate,
-                            )
-                            .disabled(true),
-                        )
-                        .child(
-                            Checkbox::new("checkbox-disabled-selected", Selection::Selected)
-                                .disabled(true),
-                        ),
-                )
-        }
-    }
-}

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

@@ -297,116 +297,3 @@ impl<M: ManagedView> RenderOnce for MenuHandle<M> {
         self
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::{story::Story, Label};
-    use gpui::{actions, Div, Render};
-
-    actions!(PrintCurrentDate, PrintBestFood);
-
-    fn build_menu(cx: &mut WindowContext, header: impl Into<SharedString>) -> View<ContextMenu> {
-        ContextMenu::build(cx, |menu, _| {
-            menu.header(header)
-                .separator()
-                .entry(
-                    ListItem::new("Print current time", Label::new("Print current time")),
-                    |v, cx| {
-                        println!("dispatching PrintCurrentTime action");
-                        cx.dispatch_action(PrintCurrentDate.boxed_clone())
-                    },
-                )
-                .entry(
-                    ListItem::new("Print best food", Label::new("Print best food")),
-                    |v, cx| cx.dispatch_action(PrintBestFood.boxed_clone()),
-                )
-        })
-    }
-
-    pub struct ContextMenuStory;
-
-    impl Render for ContextMenuStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .on_action(|_: &PrintCurrentDate, _| {
-                    println!("printing unix time!");
-                    if let Ok(unix_time) = std::time::UNIX_EPOCH.elapsed() {
-                        println!("Current Unix time is {:?}", unix_time.as_secs());
-                    }
-                })
-                .on_action(|_: &PrintBestFood, _| {
-                    println!("burrito");
-                })
-                .flex()
-                .flex_row()
-                .justify_between()
-                .child(
-                    div()
-                        .flex()
-                        .flex_col()
-                        .justify_between()
-                        .child(
-                            menu_handle("test2")
-                                .child(|is_open| {
-                                    Label::new(if is_open {
-                                        "TOP LEFT"
-                                    } else {
-                                        "RIGHT CLICK ME"
-                                    })
-                                })
-                                .menu(move |cx| build_menu(cx, "top left")),
-                        )
-                        .child(
-                            menu_handle("test1")
-                                .child(|is_open| {
-                                    Label::new(if is_open {
-                                        "BOTTOM LEFT"
-                                    } else {
-                                        "RIGHT CLICK ME"
-                                    })
-                                })
-                                .anchor(AnchorCorner::BottomLeft)
-                                .attach(AnchorCorner::TopLeft)
-                                .menu(move |cx| build_menu(cx, "bottom left")),
-                        ),
-                )
-                .child(
-                    div()
-                        .flex()
-                        .flex_col()
-                        .justify_between()
-                        .child(
-                            menu_handle("test3")
-                                .child(|is_open| {
-                                    Label::new(if is_open {
-                                        "TOP RIGHT"
-                                    } else {
-                                        "RIGHT CLICK ME"
-                                    })
-                                })
-                                .anchor(AnchorCorner::TopRight)
-                                .menu(move |cx| build_menu(cx, "top right")),
-                        )
-                        .child(
-                            menu_handle("test4")
-                                .child(|is_open| {
-                                    Label::new(if is_open {
-                                        "BOTTOM RIGHT"
-                                    } else {
-                                        "RIGHT CLICK ME"
-                                    })
-                                })
-                                .anchor(AnchorCorner::BottomRight)
-                                .attach(AnchorCorner::TopRight)
-                                .menu(move |cx| build_menu(cx, "bottom right")),
-                        ),
-                )
-        }
-    }
-}

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

@@ -1,83 +0,0 @@
-use crate::prelude::*;
-use crate::{v_stack, ButtonGroup};
-
-#[derive(RenderOnce)]
-pub struct Details {
-    text: &'static str,
-    meta: Option<&'static str>,
-    actions: Option<ButtonGroup>,
-}
-
-impl Component for Details {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        v_stack()
-            .p_1()
-            .gap_0p5()
-            .text_ui_sm()
-            .text_color(cx.theme().colors().text)
-            .size_full()
-            .child(self.text)
-            .children(self.meta.map(|m| m))
-            .children(self.actions.map(|a| a))
-    }
-}
-
-impl Details {
-    pub fn new(text: &'static str) -> Self {
-        Self {
-            text,
-            meta: None,
-            actions: None,
-        }
-    }
-
-    pub fn meta_text(mut self, meta: &'static str) -> Self {
-        self.meta = Some(meta);
-        self
-    }
-
-    pub fn actions(mut self, actions: ButtonGroup) -> Self {
-        self.actions = Some(actions);
-        self
-    }
-}
-
-use gpui::{Div, RenderOnce};
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::{Button, Story};
-    use gpui::{Div, Render};
-
-    pub struct DetailsStory;
-
-    impl Render for DetailsStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Details>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(Details::new("The quick brown fox jumps over the lazy dog"))
-                .child(Story::label(cx, "With meta"))
-                .child(
-                    Details::new("The quick brown fox jumps over the lazy dog")
-                        .meta_text("Sphinx of black quartz, judge my vow."),
-                )
-                .child(Story::label(cx, "With meta and actions"))
-                .child(
-                    Details::new("The quick brown fox jumps over the lazy dog")
-                        .meta_text("Sphinx of black quartz, judge my vow.")
-                        .actions(ButtonGroup::new(vec![
-                            Button::new("Decline"),
-                            Button::new("Accept").variant(crate::ButtonVariant::Filled),
-                        ])),
-                )
-        }
-    }
-}

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

@@ -1,28 +0,0 @@
-use gpui::Div;
-
-use crate::{prelude::*, v_stack};
-
-/// Create an elevated surface.
-///
-/// Must be used inside of a relative parent element
-pub fn elevated_surface(level: ElevationIndex, cx: &mut WindowContext) -> Div {
-    let colors = cx.theme().colors();
-
-    // let shadow = BoxShadow {
-    //     color: hsla(0., 0., 0., 0.1),
-    //     offset: point(px(0.), px(1.)),
-    //     blur_radius: px(3.),
-    //     spread_radius: px(0.),
-    // };
-
-    v_stack()
-        .rounded_lg()
-        .bg(colors.elevated_surface_background)
-        .border()
-        .border_color(colors.border)
-        .shadow(level.shadow())
-}
-
-pub fn modal(cx: &mut WindowContext) -> Div {
-    elevated_surface(ElevationIndex::ModalSurface, cx)
-}

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

@@ -1,33 +0,0 @@
-use crate::prelude::*;
-use crate::{Avatar, Player};
-
-#[derive(RenderOnce)]
-pub struct Facepile {
-    players: Vec<Player>,
-}
-
-impl Component for Facepile {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        let player_count = self.players.len();
-        let player_list = self.players.iter().enumerate().map(|(ix, player)| {
-            let isnt_last = ix < player_count - 1;
-
-            div()
-                .when(isnt_last, |div| div.neg_mr_1())
-                .child(Avatar::new(player.avatar_src().to_string()))
-        });
-        div().p_1().flex().items_center().children(player_list)
-    }
-}
-
-impl Facepile {
-    pub fn new<P: Iterator<Item = Player>>(players: P) -> Self {
-        Self {
-            players: players.collect(),
-        }
-    }
-}
-
-use gpui::{Div, RenderOnce};

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

@@ -197,31 +197,3 @@ impl IconElement {
             .text_color(self.color.color(cx))
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use gpui::{Div, Render};
-    use strum::IntoEnumIterator;
-
-    use crate::Story;
-
-    use super::*;
-
-    pub struct IconStory;
-
-    impl Render for IconStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            let icons = Icon::iter();
-
-            Story::container(cx)
-                .child(Story::title_for::<IconElement>(cx))
-                .child(Story::label(cx, "All Icons"))
-                .child(div().flex().gap_3().children(icons.map(IconElement::new)))
-        }
-    }
-}

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

@@ -1,37 +0,0 @@
-use crate::prelude::*;
-use gpui::{px, Div, RenderOnce};
-
-#[derive(RenderOnce)]
-pub struct UnreadIndicator;
-
-impl Component for UnreadIndicator {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        div()
-            .rounded_full()
-            .border_2()
-            .border_color(cx.theme().colors().surface_background)
-            .w(px(9.0))
-            .h(px(9.0))
-            .z_index(2)
-            .bg(cx.theme().status().info)
-    }
-}
-
-impl UnreadIndicator {
-    pub fn new() -> Self {
-        Self
-    }
-
-    fn render(self, cx: &mut WindowContext) -> impl Element {
-        div()
-            .rounded_full()
-            .border_2()
-            .border_color(cx.theme().colors().surface_background)
-            .w(px(9.0))
-            .h(px(9.0))
-            .z_index(2)
-            .bg(cx.theme().status().info)
-    }
-}

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

@@ -106,26 +106,3 @@ impl Input {
         self
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::Story;
-    use gpui::{Div, Render};
-
-    pub struct InputStory;
-
-    impl Render for InputStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Input>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(div().flex().child(Input::new("Search")))
-        }
-    }
-}

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

@@ -69,70 +69,3 @@ impl Key {
         Self { key: key.into() }
     }
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    pub use crate::KeyBinding;
-    use crate::Story;
-    use gpui::{actions, Div, Render};
-    use itertools::Itertools;
-    pub struct KeybindingStory;
-
-    actions!(NoAction);
-
-    pub fn binding(key: &str) -> gpui::KeyBinding {
-        gpui::KeyBinding::new(key, NoAction {}, None)
-    }
-
-    impl Render for KeybindingStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            let all_modifier_permutations =
-                ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
-
-            Story::container(cx)
-                .child(Story::title_for::<KeyBinding>(cx))
-                .child(Story::label(cx, "Single Key"))
-                .child(KeyBinding::new(binding("Z")))
-                .child(Story::label(cx, "Single Key with Modifier"))
-                .child(
-                    div()
-                        .flex()
-                        .gap_3()
-                        .child(KeyBinding::new(binding("ctrl-c")))
-                        .child(KeyBinding::new(binding("alt-c")))
-                        .child(KeyBinding::new(binding("cmd-c")))
-                        .child(KeyBinding::new(binding("shift-c"))),
-                )
-                .child(Story::label(cx, "Single Key with Modifier (Permuted)"))
-                .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::new(binding(&*(permutation.join("-") + "-x")))
-                                    }))
-                            }),
-                    ),
-                )
-                .child(Story::label(cx, "Single Key with All Modifiers"))
-                .child(KeyBinding::new(binding("ctrl-alt-cmd-shift-z")))
-                .child(Story::label(cx, "Chord"))
-                .child(KeyBinding::new(binding("a z")))
-                .child(Story::label(cx, "Chord with Modifier"))
-                .child(KeyBinding::new(binding("ctrl-a shift-z")))
-                .child(KeyBinding::new(binding("fn-s")))
-        }
-    }
-}

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

@@ -230,35 +230,3 @@ struct Run {
     pub text: String,
     pub color: Hsla,
 }
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::Story;
-    use gpui::{Div, Render};
-
-    pub struct LabelStory;
-
-    impl Render for LabelStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Label>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(Label::new("Hello, world!"))
-                .child(Story::label(cx, "Highlighted"))
-                .child(HighlightedLabel::new(
-                    "Hello, world!",
-                    vec![0, 1, 2, 7, 8, 12],
-                ))
-                .child(HighlightedLabel::new(
-                    "Héllo, world!",
-                    vec![0, 1, 3, 8, 9, 13],
-                ))
-        }
-    }
-}

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

@@ -1,85 +0,0 @@
-use gpui::{AnyElement, Div, RenderOnce};
-use smallvec::SmallVec;
-
-use crate::{h_stack, prelude::*, v_stack, Button, Icon, IconButton, Label};
-
-#[derive(RenderOnce)]
-pub struct Modal {
-    id: ElementId,
-    title: Option<SharedString>,
-    primary_action: Option<Button>,
-    secondary_action: Option<Button>,
-    children: SmallVec<[AnyElement; 2]>,
-}
-
-impl Component for Modal {
-    type Rendered = gpui::Stateful<Div>;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        v_stack()
-            .id(self.id.clone())
-            .w_96()
-            // .rounded_xl()
-            .bg(cx.theme().colors().background)
-            .border()
-            .border_color(cx.theme().colors().border)
-            .shadow_2xl()
-            .child(
-                h_stack()
-                    .justify_between()
-                    .p_1()
-                    .border_b()
-                    .border_color(cx.theme().colors().border)
-                    .child(div().children(self.title.clone().map(|t| Label::new(t))))
-                    .child(IconButton::new("close", Icon::Close)),
-            )
-            .child(v_stack().p_1().children(self.children))
-            .when(
-                self.primary_action.is_some() || self.secondary_action.is_some(),
-                |this| {
-                    this.child(
-                        h_stack()
-                            .border_t()
-                            .border_color(cx.theme().colors().border)
-                            .p_1()
-                            .justify_end()
-                            .children(self.secondary_action)
-                            .children(self.primary_action),
-                    )
-                },
-            )
-    }
-}
-
-impl Modal {
-    pub fn new(id: impl Into<ElementId>) -> Self {
-        Self {
-            id: id.into(),
-            title: None,
-            primary_action: None,
-            secondary_action: None,
-            children: SmallVec::new(),
-        }
-    }
-
-    pub fn title(mut self, title: impl Into<SharedString>) -> Self {
-        self.title = Some(title.into());
-        self
-    }
-
-    pub fn primary_action(mut self, action: Button) -> Self {
-        self.primary_action = Some(action);
-        self
-    }
-
-    pub fn secondary_action(mut self, action: Button) -> Self {
-        self.secondary_action = Some(action);
-        self
-    }
-}
-
-impl ParentElement for Modal {
-    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
-        &mut self.children
-    }
-}

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

@@ -1,40 +0,0 @@
-use gpui::rems;
-
-use crate::prelude::*;
-use crate::{h_stack, Icon};
-
-// #[derive(RenderOnce)]
-pub struct NotificationToast {
-    label: SharedString,
-    icon: Option<Icon>,
-}
-
-impl NotificationToast {
-    pub fn new(label: SharedString) -> Self {
-        Self { label, icon: None }
-    }
-
-    pub fn icon<I>(mut self, icon: I) -> Self
-    where
-        I: Into<Option<Icon>>,
-    {
-        self.icon = icon.into();
-        self
-    }
-
-    fn render(self, cx: &mut WindowContext) -> impl Element {
-        h_stack()
-            .z_index(5)
-            .absolute()
-            .top_1()
-            .right_1()
-            .w(rems(9999.))
-            .max_w_56()
-            .py_1()
-            .px_1p5()
-            .rounded_lg()
-            .shadow_md()
-            .bg(cx.theme().colors().elevated_surface_background)
-            .child(div().size_full().child(self.label.clone()))
-    }
-}

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

@@ -1,212 +0,0 @@
-use crate::{h_stack, prelude::*, v_stack, KeyBinding, Label};
-use gpui::prelude::*;
-use gpui::Div;
-
-#[derive(RenderOnce)]
-pub struct Palette {
-    id: ElementId,
-    input_placeholder: SharedString,
-    empty_string: SharedString,
-    items: Vec<PaletteItem>,
-    default_order: OrderMethod,
-}
-
-impl Component for Palette {
-    type Rendered = gpui::Stateful<Div>;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        v_stack()
-            .id(self.id)
-            .w_96()
-            .rounded_lg()
-            .bg(cx.theme().colors().elevated_surface_background)
-            .border()
-            .border_color(cx.theme().colors().border)
-            .child(
-                v_stack()
-                    .gap_px()
-                    .child(v_stack().py_0p5().px_1().child(
-                        div().px_2().py_0p5().child(
-                            Label::new(self.input_placeholder).color(TextColor::Placeholder),
-                        ),
-                    ))
-                    .child(
-                        div()
-                            .h_px()
-                            .w_full()
-                            .bg(cx.theme().colors().element_background),
-                    )
-                    .child(
-                        v_stack()
-                            .id("items")
-                            .py_0p5()
-                            .px_1()
-                            .grow()
-                            .max_h_96()
-                            .overflow_y_scroll()
-                            .children(
-                                vec![if self.items.is_empty() {
-                                    Some(h_stack().justify_between().px_2().py_1().child(
-                                        Label::new(self.empty_string).color(TextColor::Muted),
-                                    ))
-                                } else {
-                                    None
-                                }]
-                                .into_iter()
-                                .flatten(),
-                            )
-                            .children(self.items.into_iter().enumerate().map(|(index, item)| {
-                                h_stack()
-                                    .id(index)
-                                    .justify_between()
-                                    .px_2()
-                                    .py_0p5()
-                                    .rounded_lg()
-                                    .hover(|style| {
-                                        style.bg(cx.theme().colors().ghost_element_hover)
-                                    })
-                                    .active(|style| {
-                                        style.bg(cx.theme().colors().ghost_element_active)
-                                    })
-                                    .child(item)
-                            })),
-                    ),
-            )
-    }
-}
-
-impl Palette {
-    pub fn new(id: impl Into<ElementId>) -> Self {
-        Self {
-            id: id.into(),
-            input_placeholder: "Find something...".into(),
-            empty_string: "No items found.".into(),
-            items: vec![],
-            default_order: OrderMethod::default(),
-        }
-    }
-
-    pub fn items(mut self, items: Vec<PaletteItem>) -> Self {
-        self.items = items;
-        self
-    }
-
-    pub fn placeholder(mut self, input_placeholder: impl Into<SharedString>) -> Self {
-        self.input_placeholder = input_placeholder.into();
-        self
-    }
-
-    pub fn empty_string(mut self, empty_string: impl Into<SharedString>) -> Self {
-        self.empty_string = empty_string.into();
-        self
-    }
-
-    // TODO: Hook up sort order
-    pub fn default_order(mut self, default_order: OrderMethod) -> Self {
-        self.default_order = default_order;
-        self
-    }
-}
-
-#[derive(RenderOnce)]
-pub struct PaletteItem {
-    pub label: SharedString,
-    pub sublabel: Option<SharedString>,
-    pub key_binding: Option<KeyBinding>,
-}
-
-impl Component for PaletteItem {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        div()
-            .flex()
-            .flex_row()
-            .grow()
-            .justify_between()
-            .child(
-                v_stack()
-                    .child(Label::new(self.label))
-                    .children(self.sublabel.map(|sublabel| Label::new(sublabel))),
-            )
-            .children(self.key_binding)
-    }
-}
-
-impl PaletteItem {
-    pub fn new(label: impl Into<SharedString>) -> Self {
-        Self {
-            label: label.into(),
-            sublabel: None,
-            key_binding: None,
-        }
-    }
-
-    pub fn label(mut self, label: impl Into<SharedString>) -> Self {
-        self.label = label.into();
-        self
-    }
-
-    pub fn sublabel(mut self, sublabel: impl Into<Option<SharedString>>) -> Self {
-        self.sublabel = sublabel.into();
-        self
-    }
-
-    pub fn key_binding(mut self, key_binding: impl Into<Option<KeyBinding>>) -> Self {
-        self.key_binding = key_binding.into();
-        self
-    }
-}
-
-use gpui::ElementId;
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use gpui::{Div, Render};
-
-    use crate::{binding, Story};
-
-    use super::*;
-
-    pub struct PaletteStory;
-
-    impl Render for PaletteStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            {
-                Story::container(cx)
-                    .child(Story::title_for::<Palette>(cx))
-                    .child(Story::label(cx, "Default"))
-                    .child(Palette::new("palette-1"))
-                    .child(Story::label(cx, "With Items"))
-                    .child(
-                        Palette::new("palette-2")
-                            .placeholder("Execute a command...")
-                            .items(vec![
-                                PaletteItem::new("theme selector: toggle")
-                                    .key_binding(KeyBinding::new(binding("cmd-k cmd-t"))),
-                                PaletteItem::new("assistant: inline assist")
-                                    .key_binding(KeyBinding::new(binding("cmd-enter"))),
-                                PaletteItem::new("assistant: quote selection")
-                                    .key_binding(KeyBinding::new(binding("cmd-<"))),
-                                PaletteItem::new("assistant: toggle focus")
-                                    .key_binding(KeyBinding::new(binding("cmd-?"))),
-                                PaletteItem::new("auto update: check"),
-                                PaletteItem::new("auto update: view release notes"),
-                                PaletteItem::new("branches: open recent")
-                                    .key_binding(KeyBinding::new(binding("cmd-alt-b"))),
-                                PaletteItem::new("chat panel: toggle focus"),
-                                PaletteItem::new("cli: install"),
-                                PaletteItem::new("client: sign in"),
-                                PaletteItem::new("client: sign out"),
-                                PaletteItem::new("editor: cancel")
-                                    .key_binding(KeyBinding::new(binding("escape"))),
-                            ]),
-                    )
-            }
-        }
-    }
-}

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

@@ -1,152 +0,0 @@
-use gpui::px;
-use gpui::{prelude::*, AbsoluteLength, AnyElement, Div, RenderOnce};
-use smallvec::SmallVec;
-
-use crate::prelude::*;
-use crate::v_stack;
-
-#[derive(Default, Debug, PartialEq, Eq, Hash, Clone, Copy)]
-pub enum PanelAllowedSides {
-    LeftOnly,
-    RightOnly,
-    BottomOnly,
-    #[default]
-    LeftAndRight,
-    All,
-}
-
-impl PanelAllowedSides {
-    /// Return a `HashSet` that contains the allowable `PanelSide`s.
-    pub fn allowed_sides(&self) -> HashSet<PanelSide> {
-        match self {
-            Self::LeftOnly => HashSet::from_iter([PanelSide::Left]),
-            Self::RightOnly => HashSet::from_iter([PanelSide::Right]),
-            Self::BottomOnly => HashSet::from_iter([PanelSide::Bottom]),
-            Self::LeftAndRight => HashSet::from_iter([PanelSide::Left, PanelSide::Right]),
-            Self::All => HashSet::from_iter([PanelSide::Left, PanelSide::Right, PanelSide::Bottom]),
-        }
-    }
-}
-
-#[derive(Default, Debug, PartialEq, Eq, Hash, Clone, Copy)]
-pub enum PanelSide {
-    #[default]
-    Left,
-    Right,
-    Bottom,
-}
-
-use std::collections::HashSet;
-
-#[derive(RenderOnce)]
-pub struct Panel {
-    id: ElementId,
-    current_side: PanelSide,
-    /// Defaults to PanelAllowedSides::LeftAndRight
-    allowed_sides: PanelAllowedSides,
-    initial_width: AbsoluteLength,
-    width: Option<AbsoluteLength>,
-    children: SmallVec<[AnyElement; 2]>,
-}
-
-impl Component for Panel {
-    type Rendered = gpui::Stateful<Div>;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        let current_size = self.width.unwrap_or(self.initial_width);
-
-        v_stack()
-            .id(self.id.clone())
-            .flex_initial()
-            .map(|this| match self.current_side {
-                PanelSide::Left | PanelSide::Right => this.h_full().w(current_size),
-                PanelSide::Bottom => this,
-            })
-            .map(|this| match self.current_side {
-                PanelSide::Left => this.border_r(),
-                PanelSide::Right => this.border_l(),
-                PanelSide::Bottom => this.border_b().w_full().h(current_size),
-            })
-            .bg(cx.theme().colors().surface_background)
-            .border_color(cx.theme().colors().border)
-            .children(self.children)
-    }
-}
-
-impl Panel {
-    pub fn new(id: impl Into<ElementId>, cx: &mut WindowContext) -> Self {
-        Self {
-            id: id.into(),
-            current_side: PanelSide::default(),
-            allowed_sides: PanelAllowedSides::default(),
-            initial_width: px(320.).into(),
-            width: None,
-            children: SmallVec::new(),
-        }
-    }
-
-    pub fn initial_width(mut self, initial_width: AbsoluteLength) -> Self {
-        self.initial_width = initial_width;
-        self
-    }
-
-    pub fn width(mut self, width: AbsoluteLength) -> Self {
-        self.width = Some(width);
-        self
-    }
-
-    pub fn allowed_sides(mut self, allowed_sides: PanelAllowedSides) -> Self {
-        self.allowed_sides = allowed_sides;
-        self
-    }
-
-    pub fn side(mut self, side: PanelSide) -> Self {
-        let allowed_sides = self.allowed_sides.allowed_sides();
-
-        if allowed_sides.contains(&side) {
-            self.current_side = side;
-        } else {
-            panic!(
-                "The panel side {:?} was not added as allowed before it was set.",
-                side
-            );
-        }
-        self
-    }
-}
-
-impl ParentElement for Panel {
-    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
-        &mut self.children
-    }
-}
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use super::*;
-    use crate::{Label, Story};
-    use gpui::{Div, InteractiveElement, Render};
-
-    pub struct PanelStory;
-
-    impl Render for PanelStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Panel>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(
-                    Panel::new("panel", cx).child(
-                        div()
-                            .id("panel-contents")
-                            .overflow_y_scroll()
-                            .children((0..100).map(|ix| Label::new(format!("Item {}", ix + 1)))),
-                    ),
-                )
-        }
-    }
-}

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

@@ -1,174 +0,0 @@
-use gpui::Hsla;
-
-use crate::prelude::*;
-
-/// Represents a person with a Zed account's public profile.
-/// All data in this struct should be considered public.
-pub struct PublicPlayer {
-    pub username: SharedString,
-    pub avatar: SharedString,
-    pub is_contact: bool,
-}
-
-impl PublicPlayer {
-    pub fn new(username: impl Into<SharedString>, avatar: impl Into<SharedString>) -> Self {
-        Self {
-            username: username.into(),
-            avatar: avatar.into(),
-            is_contact: false,
-        }
-    }
-}
-
-#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
-pub enum PlayerStatus {
-    #[default]
-    Offline,
-    Online,
-    InCall,
-    Away,
-    DoNotDisturb,
-    Invisible,
-}
-
-#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
-pub enum MicStatus {
-    Muted,
-    #[default]
-    Unmuted,
-}
-
-impl MicStatus {
-    pub fn inverse(&self) -> Self {
-        match self {
-            Self::Muted => Self::Unmuted,
-            Self::Unmuted => Self::Muted,
-        }
-    }
-}
-
-#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
-pub enum VideoStatus {
-    On,
-    #[default]
-    Off,
-}
-
-impl VideoStatus {
-    pub fn inverse(&self) -> Self {
-        match self {
-            Self::On => Self::Off,
-            Self::Off => Self::On,
-        }
-    }
-}
-
-#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
-pub enum ScreenShareStatus {
-    Shared,
-    #[default]
-    NotShared,
-}
-
-impl ScreenShareStatus {
-    pub fn inverse(&self) -> Self {
-        match self {
-            Self::Shared => Self::NotShared,
-            Self::NotShared => Self::Shared,
-        }
-    }
-}
-
-#[derive(Clone)]
-pub struct PlayerCallStatus {
-    pub mic_status: MicStatus,
-    /// Indicates if the player is currently speaking
-    /// And the intensity of the volume coming through
-    ///
-    /// 0.0 - 1.0
-    pub voice_activity: f32,
-    pub video_status: VideoStatus,
-    pub screen_share_status: ScreenShareStatus,
-    pub in_current_project: bool,
-    pub disconnected: bool,
-    pub following: Option<Vec<Player>>,
-    pub followers: Option<Vec<Player>>,
-}
-
-impl PlayerCallStatus {
-    pub fn new() -> Self {
-        Self {
-            mic_status: MicStatus::default(),
-            voice_activity: 0.,
-            video_status: VideoStatus::default(),
-            screen_share_status: ScreenShareStatus::default(),
-            in_current_project: true,
-            disconnected: false,
-            following: None,
-            followers: None,
-        }
-    }
-}
-
-#[derive(PartialEq, Clone)]
-pub struct Player {
-    index: usize,
-    avatar_src: String,
-    username: String,
-    status: PlayerStatus,
-}
-
-#[derive(Clone)]
-pub struct PlayerWithCallStatus {
-    player: Player,
-    call_status: PlayerCallStatus,
-}
-
-impl PlayerWithCallStatus {
-    pub fn new(player: Player, call_status: PlayerCallStatus) -> Self {
-        Self {
-            player,
-            call_status,
-        }
-    }
-
-    pub fn get_player(&self) -> &Player {
-        &self.player
-    }
-
-    pub fn get_call_status(&self) -> &PlayerCallStatus {
-        &self.call_status
-    }
-}
-
-impl Player {
-    pub fn new(index: usize, avatar_src: String, username: String) -> Self {
-        Self {
-            index,
-            avatar_src,
-            username,
-            status: Default::default(),
-        }
-    }
-
-    pub fn set_status(mut self, status: PlayerStatus) -> Self {
-        self.status = status;
-        self
-    }
-
-    pub fn cursor_color(&self, cx: &mut WindowContext) -> Hsla {
-        cx.theme().styles.player.0[self.index % cx.theme().styles.player.0.len()].cursor
-    }
-
-    pub fn selection_color(&self, cx: &mut WindowContext) -> Hsla {
-        cx.theme().styles.player.0[self.index % cx.theme().styles.player.0.len()].selection
-    }
-
-    pub fn avatar_src(&self) -> &str {
-        &self.avatar_src
-    }
-
-    pub fn index(&self) -> usize {
-        self.index
-    }
-}

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

@@ -1,67 +0,0 @@
-use gpui::{Div, RenderOnce};
-
-use crate::prelude::*;
-use crate::{Avatar, Facepile, PlayerWithCallStatus};
-
-#[derive(RenderOnce)]
-pub struct PlayerStack {
-    player_with_call_status: PlayerWithCallStatus,
-}
-
-impl Component for PlayerStack {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        let player = self.player_with_call_status.get_player();
-
-        let followers = self
-            .player_with_call_status
-            .get_call_status()
-            .followers
-            .as_ref()
-            .map(|followers| followers.clone());
-
-        // if we have no followers return a slightly different element
-        // if mic_status == muted add a red ring to avatar
-
-        div()
-            .h_full()
-            .flex()
-            .flex_col()
-            .gap_px()
-            .justify_center()
-            .child(
-                div()
-                    .flex()
-                    .justify_center()
-                    .w_full()
-                    .child(div().w_4().h_0p5().rounded_sm().bg(player.cursor_color(cx))),
-            )
-            .child(
-                div()
-                    .flex()
-                    .items_center()
-                    .justify_center()
-                    .h_6()
-                    .pl_1()
-                    .rounded_lg()
-                    .bg(if followers.is_none() {
-                        cx.theme().styles.system.transparent
-                    } else {
-                        player.selection_color(cx)
-                    })
-                    .child(Avatar::new(player.avatar_src().to_string()))
-                    .children(followers.map(|followers| {
-                        div().neg_ml_2().child(Facepile::new(followers.into_iter()))
-                    })),
-            )
-    }
-}
-
-impl PlayerStack {
-    pub fn new(player_with_call_status: PlayerWithCallStatus) -> Self {
-        Self {
-            player_with_call_status,
-        }
-    }
-}

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

@@ -0,0 +1,27 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    use crate::Story;
+    use gpui::{Div, Render};
+
+    pub struct AvatarStory;
+
+    impl Render for AvatarStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            Story::container(cx)
+                .child(Story::title_for::<Avatar>(cx))
+                .child(Story::label(cx, "Default"))
+                .child(Avatar::new(
+                    "https://avatars.githubusercontent.com/u/1714999?v=4",
+                ))
+                .child(Avatar::new(
+                    "https://avatars.githubusercontent.com/u/326587?v=4",
+                ))
+        }
+    }
+}

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

@@ -0,0 +1,167 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    use crate::{h_stack, v_stack, Story, TextColor};
+    use gpui::{rems, Div, Render};
+    use strum::IntoEnumIterator;
+
+    pub struct ButtonStory;
+
+    impl Render for ButtonStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            let states = InteractionState::iter();
+
+            Story::container(cx)
+                .child(Story::title_for::<Button>(cx))
+                .child(
+                    div()
+                        .flex()
+                        .gap_8()
+                        .child(
+                            div()
+                                .child(Story::label(cx, "Ghost (Default)"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label").variant(ButtonVariant::Ghost), // .state(state),
+                                        )
+                                })))
+                                .child(Story::label(cx, "Ghost – Left Icon"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Ghost)
+                                                .icon(Icon::Plus)
+                                                .icon_position(IconPosition::Left), // .state(state),
+                                        )
+                                })))
+                                .child(Story::label(cx, "Ghost – Right Icon"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Ghost)
+                                                .icon(Icon::Plus)
+                                                .icon_position(IconPosition::Right), // .state(state),
+                                        )
+                                }))),
+                        )
+                        .child(
+                            div()
+                                .child(Story::label(cx, "Filled"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label").variant(ButtonVariant::Filled), // .state(state),
+                                        )
+                                })))
+                                .child(Story::label(cx, "Filled – Left Button"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Filled)
+                                                .icon(Icon::Plus)
+                                                .icon_position(IconPosition::Left), // .state(state),
+                                        )
+                                })))
+                                .child(Story::label(cx, "Filled – Right Button"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Filled)
+                                                .icon(Icon::Plus)
+                                                .icon_position(IconPosition::Right), // .state(state),
+                                        )
+                                }))),
+                        )
+                        .child(
+                            div()
+                                .child(Story::label(cx, "Fixed With"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Filled)
+                                                // .state(state)
+                                                .width(Some(rems(6.).into())),
+                                        )
+                                })))
+                                .child(Story::label(cx, "Fixed With – Left Icon"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Filled)
+                                                // .state(state)
+                                                .icon(Icon::Plus)
+                                                .icon_position(IconPosition::Left)
+                                                .width(Some(rems(6.).into())),
+                                        )
+                                })))
+                                .child(Story::label(cx, "Fixed With – Right Icon"))
+                                .child(h_stack().gap_2().children(states.clone().map(|state| {
+                                    v_stack()
+                                        .gap_1()
+                                        .child(
+                                            Label::new(state.to_string()).color(TextColor::Muted),
+                                        )
+                                        .child(
+                                            Button::new("Label")
+                                                .variant(ButtonVariant::Filled)
+                                                // .state(state)
+                                                .icon(Icon::Plus)
+                                                .icon_position(IconPosition::Right)
+                                                .width(Some(rems(6.).into())),
+                                        )
+                                }))),
+                        ),
+                )
+                .child(Story::label(cx, "Button with `on_click`"))
+                .child(
+                    Button::new("Label")
+                        .variant(ButtonVariant::Ghost)
+                        .on_click(|_, cx| println!("Button clicked.")),
+                )
+        }
+    }
+}

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

@@ -0,0 +1,59 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    use crate::{h_stack, Story};
+    use gpui::{Div, Render, ViewContext};
+
+    pub struct CheckboxStory;
+
+    impl Render for CheckboxStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            Story::container(cx)
+                .child(Story::title_for::<Checkbox>(cx))
+                .child(Story::label(cx, "Default"))
+                .child(
+                    h_stack()
+                        .p_2()
+                        .gap_2()
+                        .rounded_md()
+                        .border()
+                        .border_color(cx.theme().colors().border)
+                        .child(Checkbox::new("checkbox-enabled", Selection::Unselected))
+                        .child(Checkbox::new(
+                            "checkbox-intermediate",
+                            Selection::Indeterminate,
+                        ))
+                        .child(Checkbox::new("checkbox-selected", Selection::Selected)),
+                )
+                .child(Story::label(cx, "Disabled"))
+                .child(
+                    h_stack()
+                        .p_2()
+                        .gap_2()
+                        .rounded_md()
+                        .border()
+                        .border_color(cx.theme().colors().border)
+                        .child(
+                            Checkbox::new("checkbox-disabled", Selection::Unselected)
+                                .disabled(true),
+                        )
+                        .child(
+                            Checkbox::new(
+                                "checkbox-disabled-intermediate",
+                                Selection::Indeterminate,
+                            )
+                            .disabled(true),
+                        )
+                        .child(
+                            Checkbox::new("checkbox-disabled-selected", Selection::Selected)
+                                .disabled(true),
+                        ),
+                )
+        }
+    }
+}

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

@@ -0,0 +1,112 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    use crate::{story::Story, Label};
+    use gpui::{actions, Div, Render};
+
+    actions!(PrintCurrentDate, PrintBestFood);
+
+    fn build_menu(cx: &mut WindowContext, header: impl Into<SharedString>) -> View<ContextMenu> {
+        ContextMenu::build(cx, |menu, _| {
+            menu.header(header)
+                .separator()
+                .entry(
+                    ListItem::new("Print current time", Label::new("Print current time")),
+                    |v, cx| {
+                        println!("dispatching PrintCurrentTime action");
+                        cx.dispatch_action(PrintCurrentDate.boxed_clone())
+                    },
+                )
+                .entry(
+                    ListItem::new("Print best food", Label::new("Print best food")),
+                    |v, cx| cx.dispatch_action(PrintBestFood.boxed_clone()),
+                )
+        })
+    }
+
+    pub struct ContextMenuStory;
+
+    impl Render for ContextMenuStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            Story::container(cx)
+                .on_action(|_: &PrintCurrentDate, _| {
+                    println!("printing unix time!");
+                    if let Ok(unix_time) = std::time::UNIX_EPOCH.elapsed() {
+                        println!("Current Unix time is {:?}", unix_time.as_secs());
+                    }
+                })
+                .on_action(|_: &PrintBestFood, _| {
+                    println!("burrito");
+                })
+                .flex()
+                .flex_row()
+                .justify_between()
+                .child(
+                    div()
+                        .flex()
+                        .flex_col()
+                        .justify_between()
+                        .child(
+                            menu_handle("test2")
+                                .child(|is_open| {
+                                    Label::new(if is_open {
+                                        "TOP LEFT"
+                                    } else {
+                                        "RIGHT CLICK ME"
+                                    })
+                                })
+                                .menu(move |cx| build_menu(cx, "top left")),
+                        )
+                        .child(
+                            menu_handle("test1")
+                                .child(|is_open| {
+                                    Label::new(if is_open {
+                                        "BOTTOM LEFT"
+                                    } else {
+                                        "RIGHT CLICK ME"
+                                    })
+                                })
+                                .anchor(AnchorCorner::BottomLeft)
+                                .attach(AnchorCorner::TopLeft)
+                                .menu(move |cx| build_menu(cx, "bottom left")),
+                        ),
+                )
+                .child(
+                    div()
+                        .flex()
+                        .flex_col()
+                        .justify_between()
+                        .child(
+                            menu_handle("test3")
+                                .child(|is_open| {
+                                    Label::new(if is_open {
+                                        "TOP RIGHT"
+                                    } else {
+                                        "RIGHT CLICK ME"
+                                    })
+                                })
+                                .anchor(AnchorCorner::TopRight)
+                                .menu(move |cx| build_menu(cx, "top right")),
+                        )
+                        .child(
+                            menu_handle("test4")
+                                .child(|is_open| {
+                                    Label::new(if is_open {
+                                        "BOTTOM RIGHT"
+                                    } else {
+                                        "RIGHT CLICK ME"
+                                    })
+                                })
+                                .anchor(AnchorCorner::BottomRight)
+                                .attach(AnchorCorner::TopRight)
+                                .menu(move |cx| build_menu(cx, "bottom right")),
+                        ),
+                )
+        }
+    }
+}

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

@@ -0,0 +1,27 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use gpui::{Div, Render};
+    use strum::IntoEnumIterator;
+
+    use crate::Story;
+
+    use super::*;
+
+    pub struct IconStory;
+
+    impl Render for IconStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            let icons = Icon::iter();
+
+            Story::container(cx)
+                .child(Story::title_for::<IconElement>(cx))
+                .child(Story::label(cx, "All Icons"))
+                .child(div().flex().gap_3().children(icons.map(IconElement::new)))
+        }
+    }
+}

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

@@ -0,0 +1,22 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    use crate::Story;
+    use gpui::{Div, Render};
+
+    pub struct InputStory;
+
+    impl Render for InputStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            Story::container(cx)
+                .child(Story::title_for::<Input>(cx))
+                .child(Story::label(cx, "Default"))
+                .child(div().flex().child(Input::new("Search")))
+        }
+    }
+}

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

@@ -0,0 +1,66 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    pub use crate::KeyBinding;
+    use crate::Story;
+    use gpui::{actions, Div, Render};
+    use itertools::Itertools;
+    pub struct KeybindingStory;
+
+    actions!(NoAction);
+
+    pub fn binding(key: &str) -> gpui::KeyBinding {
+        gpui::KeyBinding::new(key, NoAction {}, None)
+    }
+
+    impl Render for KeybindingStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            let all_modifier_permutations =
+                ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
+
+            Story::container(cx)
+                .child(Story::title_for::<KeyBinding>(cx))
+                .child(Story::label(cx, "Single Key"))
+                .child(KeyBinding::new(binding("Z")))
+                .child(Story::label(cx, "Single Key with Modifier"))
+                .child(
+                    div()
+                        .flex()
+                        .gap_3()
+                        .child(KeyBinding::new(binding("ctrl-c")))
+                        .child(KeyBinding::new(binding("alt-c")))
+                        .child(KeyBinding::new(binding("cmd-c")))
+                        .child(KeyBinding::new(binding("shift-c"))),
+                )
+                .child(Story::label(cx, "Single Key with Modifier (Permuted)"))
+                .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::new(binding(&*(permutation.join("-") + "-x")))
+                                    }))
+                            }),
+                    ),
+                )
+                .child(Story::label(cx, "Single Key with All Modifiers"))
+                .child(KeyBinding::new(binding("ctrl-alt-cmd-shift-z")))
+                .child(Story::label(cx, "Chord"))
+                .child(KeyBinding::new(binding("a z")))
+                .child(Story::label(cx, "Chord with Modifier"))
+                .child(KeyBinding::new(binding("ctrl-a shift-z")))
+                .child(KeyBinding::new(binding("fn-s")))
+        }
+    }
+}

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

@@ -0,0 +1,31 @@
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+    use super::*;
+    use crate::Story;
+    use gpui::{Div, Render};
+
+    pub struct LabelStory;
+
+    impl Render for LabelStory {
+        type Element = Div;
+
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+            Story::container(cx)
+                .child(Story::title_for::<Label>(cx))
+                .child(Story::label(cx, "Default"))
+                .child(Label::new("Hello, world!"))
+                .child(Story::label(cx, "Highlighted"))
+                .child(HighlightedLabel::new(
+                    "Hello, world!",
+                    vec![0, 1, 2, 7, 8, 12],
+                ))
+                .child(HighlightedLabel::new(
+                    "Héllo, world!",
+                    vec![0, 1, 3, 8, 9, 13],
+                ))
+        }
+    }
+}

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

@@ -1,276 +0,0 @@
-// use crate::prelude::*;
-// use crate::{Icon, IconElement, Label, TextColor};
-// use gpui::{prelude::*, red, Div, ElementId, Render, RenderOnce, View};
-
-// #[derive(RenderOnce, Clone)]
-// pub struct Tab {
-//     id: ElementId,
-//     title: String,
-//     icon: Option<Icon>,
-//     current: bool,
-//     dirty: bool,
-//     fs_status: FileSystemStatus,
-//     git_status: GitStatus,
-//     diagnostic_status: DiagnosticStatus,
-//     close_side: IconSide,
-// }
-
-// #[derive(Clone, Debug)]
-// struct TabDragState {
-//     title: String,
-// }
-
-// impl Render for TabDragState {
-//     type Element = Div;
-
-//     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-//         div().w_8().h_4().bg(red())
-//     }
-// }
-
-// impl Component for Tab {
-//     type Rendered = gpui::Stateful<Div>;
-
-//     fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-//         let has_fs_conflict = self.fs_status == FileSystemStatus::Conflict;
-//         let is_deleted = self.fs_status == FileSystemStatus::Deleted;
-
-//         let label = match (self.git_status, is_deleted) {
-//             (_, true) | (GitStatus::Deleted, false) => Label::new(self.title.clone())
-//                 .color(TextColor::Hidden)
-//                 .set_strikethrough(true),
-//             (GitStatus::None, false) => Label::new(self.title.clone()),
-//             (GitStatus::Created, false) => Label::new(self.title.clone()).color(TextColor::Created),
-//             (GitStatus::Modified, false) => {
-//                 Label::new(self.title.clone()).color(TextColor::Modified)
-//             }
-//             (GitStatus::Renamed, false) => Label::new(self.title.clone()).color(TextColor::Accent),
-//             (GitStatus::Conflict, false) => Label::new(self.title.clone()),
-//         };
-
-//         let close_icon = || IconElement::new(Icon::Close).color(TextColor::Muted);
-
-//         let (tab_bg, tab_hover_bg, tab_active_bg) = match self.current {
-//             false => (
-//                 cx.theme().colors().tab_inactive_background,
-//                 cx.theme().colors().ghost_element_hover,
-//                 cx.theme().colors().ghost_element_active,
-//             ),
-//             true => (
-//                 cx.theme().colors().tab_active_background,
-//                 cx.theme().colors().element_hover,
-//                 cx.theme().colors().element_active,
-//             ),
-//         };
-
-//         let drag_state = TabDragState {
-//             title: self.title.clone(),
-//         };
-
-//         div()
-//             .id(self.id.clone())
-//             .on_drag(move |_view, cx| cx.build_view(|cx| drag_state.clone()))
-//             .drag_over::<TabDragState>(|d| d.bg(cx.theme().colors().drop_target_background))
-//             .on_drop(|_view, state: View<TabDragState>, cx| {
-//                 eprintln!("{:?}", state.read(cx));
-//             })
-//             .px_2()
-//             .py_0p5()
-//             .flex()
-//             .items_center()
-//             .justify_center()
-//             .bg(tab_bg)
-//             .hover(|h| h.bg(tab_hover_bg))
-//             .active(|a| a.bg(tab_active_bg))
-//             .child(
-//                 div()
-//                     .px_1()
-//                     .flex()
-//                     .items_center()
-//                     .gap_1p5()
-//                     .children(has_fs_conflict.then(|| {
-//                         IconElement::new(Icon::ExclamationTriangle)
-//                             .size(crate::IconSize::Small)
-//                             .color(TextColor::Warning)
-//                     }))
-//                     .children(self.icon.map(IconElement::new))
-//                     .children(if self.close_side == IconSide::Left {
-//                         Some(close_icon())
-//                     } else {
-//                         None
-//                     })
-//                     .child(label)
-//                     .children(if self.close_side == IconSide::Right {
-//                         Some(close_icon())
-//                     } else {
-//                         None
-//                     }),
-//             )
-//     }
-// }
-
-// impl Tab {
-//     pub fn new(id: impl Into<ElementId>) -> Self {
-//         Self {
-//             id: id.into(),
-//             title: "untitled".to_string(),
-//             icon: None,
-//             current: false,
-//             dirty: false,
-//             fs_status: FileSystemStatus::None,
-//             git_status: GitStatus::None,
-//             diagnostic_status: DiagnosticStatus::None,
-//             close_side: IconSide::Right,
-//         }
-//     }
-
-//     pub fn current(mut self, current: bool) -> Self {
-//         self.current = current;
-//         self
-//     }
-
-//     pub fn title(mut self, title: String) -> Self {
-//         self.title = title;
-//         self
-//     }
-
-//     pub fn icon<I>(mut self, icon: I) -> Self
-//     where
-//         I: Into<Option<Icon>>,
-//     {
-//         self.icon = icon.into();
-//         self
-//     }
-
-//     pub fn dirty(mut self, dirty: bool) -> Self {
-//         self.dirty = dirty;
-//         self
-//     }
-
-//     pub fn fs_status(mut self, fs_status: FileSystemStatus) -> Self {
-//         self.fs_status = fs_status;
-//         self
-//     }
-
-//     pub fn git_status(mut self, git_status: GitStatus) -> Self {
-//         self.git_status = git_status;
-//         self
-//     }
-
-//     pub fn diagnostic_status(mut self, diagnostic_status: DiagnosticStatus) -> Self {
-//         self.diagnostic_status = diagnostic_status;
-//         self
-//     }
-
-//     pub fn close_side(mut self, close_side: IconSide) -> Self {
-//         self.close_side = close_side;
-//         self
-//     }
-// }
-
-// #[cfg(feature = "stories")]
-// pub use stories::*;
-
-// #[cfg(feature = "stories")]
-// mod stories {
-//     use super::*;
-//     use crate::{h_stack, v_stack, Icon, Story};
-//     use strum::IntoEnumIterator;
-
-//     pub struct TabStory;
-
-//     impl Render for TabStory {
-//         type Element = Div;
-
-//         fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-//             let git_statuses = GitStatus::iter();
-//             let fs_statuses = FileSystemStatus::iter();
-
-//             Story::container(cx)
-//                 .child(Story::title_for::<_, Tab>(cx))
-//                 .child(
-//                     h_stack().child(
-//                         v_stack()
-//                             .gap_2()
-//                             .child(Story::label(cx, "Default"))
-//                             .child(Tab::new("default")),
-//                     ),
-//                 )
-//                 .child(
-//                     h_stack().child(
-//                         v_stack().gap_2().child(Story::label(cx, "Current")).child(
-//                             h_stack()
-//                                 .gap_4()
-//                                 .child(
-//                                     Tab::new("current")
-//                                         .title("Current".to_string())
-//                                         .current(true),
-//                                 )
-//                                 .child(
-//                                     Tab::new("not_current")
-//                                         .title("Not Current".to_string())
-//                                         .current(false),
-//                                 ),
-//                         ),
-//                     ),
-//                 )
-//                 .child(
-//                     h_stack().child(
-//                         v_stack()
-//                             .gap_2()
-//                             .child(Story::label(cx, "Titled"))
-//                             .child(Tab::new("titled").title("label".to_string())),
-//                     ),
-//                 )
-//                 .child(
-//                     h_stack().child(
-//                         v_stack()
-//                             .gap_2()
-//                             .child(Story::label(cx, "With Icon"))
-//                             .child(
-//                                 Tab::new("with_icon")
-//                                     .title("label".to_string())
-//                                     .icon(Some(Icon::Envelope)),
-//                             ),
-//                     ),
-//                 )
-//                 .child(
-//                     h_stack().child(
-//                         v_stack()
-//                             .gap_2()
-//                             .child(Story::label(cx, "Close Side"))
-//                             .child(
-//                                 h_stack()
-//                                     .gap_4()
-//                                     .child(
-//                                         Tab::new("left")
-//                                             .title("Left".to_string())
-//                                             .close_side(IconSide::Left),
-//                                     )
-//                                     .child(Tab::new("right").title("Right".to_string())),
-//                             ),
-//                     ),
-//                 )
-//                 .child(
-//                     v_stack()
-//                         .gap_2()
-//                         .child(Story::label(cx, "Git Status"))
-//                         .child(h_stack().gap_4().children(git_statuses.map(|git_status| {
-//                             Tab::new("git_status")
-//                                 .title(git_status.to_string())
-//                                 .git_status(git_status)
-//                         }))),
-//                 )
-//                 .child(
-//                     v_stack()
-//                         .gap_2()
-//                         .child(Story::label(cx, "File System Status"))
-//                         .child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
-//                             Tab::new("file_system_status")
-//                                 .title(fs_status.to_string())
-//                                 .fs_status(fs_status)
-//                         }))),
-//                 )
-//         }
-//     }
-// }

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

@@ -1,117 +0,0 @@
-use crate::prelude::*;
-use gpui::{prelude::*, AnyElement, RenderOnce};
-use gpui::{Div, Element};
-use smallvec::SmallVec;
-
-#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
-pub enum ToastOrigin {
-    #[default]
-    Bottom,
-    BottomRight,
-}
-
-/// Don't use toast directly:
-///
-/// - For messages with a required action, use a `NotificationToast`.
-/// - For messages that convey information, use a `StatusToast`.
-///
-/// A toast is a small, temporary window that appears to show a message to the user
-/// or indicate a required action.
-///
-/// Toasts should not persist on the screen for more than a few seconds unless
-/// they are actively showing the a process in progress.
-///
-/// Only one toast may be visible at a time.
-#[derive(RenderOnce)]
-pub struct Toast {
-    origin: ToastOrigin,
-    children: SmallVec<[AnyElement; 2]>,
-}
-
-impl Component for Toast {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        let mut div = div();
-
-        if self.origin == ToastOrigin::Bottom {
-            div = div.right_1_2();
-        } else {
-            div = div.right_2();
-        }
-
-        div.z_index(5)
-            .absolute()
-            .bottom_9()
-            .flex()
-            .py_1()
-            .px_1p5()
-            .rounded_lg()
-            .shadow_md()
-            .overflow_hidden()
-            .bg(cx.theme().colors().elevated_surface_background)
-            .children(self.children)
-    }
-}
-
-impl Toast {
-    pub fn new(origin: ToastOrigin) -> Self {
-        Self {
-            origin,
-            children: SmallVec::new(),
-        }
-    }
-
-    fn render(self, cx: &mut WindowContext) -> impl Element {
-        let mut div = div();
-
-        if self.origin == ToastOrigin::Bottom {
-            div = div.right_1_2();
-        } else {
-            div = div.right_2();
-        }
-
-        div.z_index(5)
-            .absolute()
-            .bottom_9()
-            .flex()
-            .py_1()
-            .px_1p5()
-            .rounded_lg()
-            .shadow_md()
-            .overflow_hidden()
-            .bg(cx.theme().colors().elevated_surface_background)
-            .children(self.children)
-    }
-}
-
-impl ParentElement for Toast {
-    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
-        &mut self.children
-    }
-}
-
-#[cfg(feature = "stories")]
-pub use stories::*;
-
-#[cfg(feature = "stories")]
-mod stories {
-    use gpui::{Div, Render};
-
-    use crate::{Label, Story};
-
-    use super::*;
-
-    pub struct ToastStory;
-
-    impl Render for ToastStory {
-        type Element = Div;
-
-        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-            Story::container(cx)
-                .child(Story::title_for::<Toast>(cx))
-                .child(Story::label(cx, "Default"))
-                .child(Toast::new(ToastOrigin::Bottom).child(Label::new("label")))
-        }
-    }
-}

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

@@ -1,23 +0,0 @@
-use crate::prelude::*;
-use gpui::{Div, RenderOnce};
-
-#[derive(RenderOnce)]
-pub struct ToolDivider;
-
-impl Component for ToolDivider {
-    type Rendered = Div;
-
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        div().w_px().h_3().bg(cx.theme().colors().border)
-    }
-}
-
-impl ToolDivider {
-    pub fn new() -> Self {
-        Self
-    }
-
-    fn render(self, cx: &mut WindowContext) -> impl Element {
-        div().w_px().h_3().bg(cx.theme().colors().border)
-    }
-}

crates/ui2/src/prelude.rs 🔗

@@ -5,7 +5,6 @@ pub use gpui::{
     ViewContext, WindowContext,
 };
 
-pub use crate::elevation::*;
 pub use crate::StyledExt;
 pub use crate::{ButtonVariant, TextColor};
 pub use theme2::ActiveTheme;

crates/ui2/src/elevation.rs → crates/ui2/src/styles/elevation.rs 🔗

@@ -1,7 +1,7 @@
 use gpui::{hsla, point, px, BoxShadow};
 use smallvec::{smallvec, SmallVec};
 
-#[doc = include_str!("elevation.md")]
+#[doc = include_str!("docs/elevation.md")]
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum Elevation {
     ElevationIndex(ElevationIndex),

crates/ui2/src/lib.rs → crates/ui2/src/ui2.rs 🔗

@@ -15,15 +15,15 @@
 #![allow(dead_code, unused_variables)]
 
 mod components;
-mod elevation;
 pub mod prelude;
 mod styled_ext;
+mod styles;
 pub mod utils;
 
 pub use components::*;
 pub use prelude::*;
-// pub use static_data::*;
 pub use styled_ext::*;
+pub use styles::*;
 
 #[cfg(feature = "stories")]
 mod story;