diff --git a/crates/storybook2/src/stories/components.rs b/crates/storybook2/src/stories/components.rs index 7a6b95837a..df8e4f825c 100644 --- a/crates/storybook2/src/stories/components.rs +++ b/crates/storybook2/src/stories/components.rs @@ -1 +1,2 @@ +pub mod assistant_panel; pub mod panel; diff --git a/crates/storybook2/src/stories/components/assistant_panel.rs b/crates/storybook2/src/stories/components/assistant_panel.rs new file mode 100644 index 0000000000..2c1eac71d3 --- /dev/null +++ b/crates/storybook2/src/stories/components/assistant_panel.rs @@ -0,0 +1,26 @@ +use std::marker::PhantomData; + +use ui::prelude::*; +use ui::AssistantPanel; + +use crate::story::Story; + +#[derive(Element)] +pub struct AssistantPanelStory { + state_type: PhantomData, +} + +impl AssistantPanelStory { + pub fn new() -> Self { + Self { + state_type: PhantomData, + } + } + + fn render(&mut self, cx: &mut ViewContext) -> impl Element { + Story::container(cx) + .child(Story::title_for::<_, AssistantPanel>(cx)) + .child(Story::label(cx, "Default")) + .child(AssistantPanel::new()) + } +} diff --git a/crates/storybook2/src/story_selector.rs b/crates/storybook2/src/story_selector.rs index 1bf4b8d77a..9d2892da79 100644 --- a/crates/storybook2/src/story_selector.rs +++ b/crates/storybook2/src/story_selector.rs @@ -32,6 +32,7 @@ impl ElementStory { #[derive(Debug, PartialEq, Eq, Clone, Copy, strum::Display, EnumString, EnumIter)] #[strum(serialize_all = "snake_case")] pub enum ComponentStory { + AssistantPanel, Panel, } @@ -40,6 +41,9 @@ impl ComponentStory { use crate::stories::components; match self { + Self::AssistantPanel => { + components::assistant_panel::AssistantPanelStory::new().into_any() + } Self::Panel => components::panel::PanelStory::new().into_any(), } } diff --git a/crates/ui2/src/components.rs b/crates/ui2/src/components.rs index a49f9d1949..943ff0a14f 100644 --- a/crates/ui2/src/components.rs +++ b/crates/ui2/src/components.rs @@ -1,7 +1,9 @@ +mod assistant_panel; mod icon_button; mod list; mod panel; +pub use assistant_panel::*; pub use icon_button::*; pub use list::*; pub use panel::*; diff --git a/crates/ui2/src/components/assistant_panel.rs b/crates/ui2/src/components/assistant_panel.rs new file mode 100644 index 0000000000..81a5cd2693 --- /dev/null +++ b/crates/ui2/src/components/assistant_panel.rs @@ -0,0 +1,90 @@ +use std::marker::PhantomData; + +use gpui3::{rems, AbsoluteLength}; + +use crate::prelude::*; +use crate::{Icon, IconButton, Label, Panel, PanelSide}; + +#[derive(Element)] +pub struct AssistantPanel { + state_type: PhantomData, + scroll_state: ScrollState, + current_side: PanelSide, +} + +impl AssistantPanel { + pub fn new() -> Self { + Self { + state_type: PhantomData, + scroll_state: ScrollState::default(), + current_side: PanelSide::default(), + } + } + + pub fn side(mut self, side: PanelSide) -> Self { + self.current_side = side; + self + } + + fn render(&mut self, cx: &mut ViewContext) -> impl Element { + let theme = theme(cx); + + struct PanelPayload { + pub scroll_state: ScrollState, + } + + Panel::new( + self.scroll_state.clone(), + |_, payload| { + let payload = payload.downcast_ref::().unwrap(); + + vec![div() + .flex() + .flex_col() + .h_full() + .px_2() + .gap_2() + // Header + .child( + div() + .flex() + .justify_between() + .gap_2() + .child( + div() + .flex() + .child(IconButton::new(Icon::Menu)) + .child(Label::new("New Conversation")), + ) + .child( + div() + .flex() + .items_center() + .gap_px() + .child(IconButton::new(Icon::SplitMessage)) + .child(IconButton::new(Icon::Quote)) + .child(IconButton::new(Icon::MagicWand)) + .child(IconButton::new(Icon::Plus)) + .child(IconButton::new(Icon::Maximize)), + ), + ) + // Chat Body + .child( + div() + .w_full() + .flex() + .flex_col() + .gap_3() + .overflow_y_scroll(payload.scroll_state.clone()) + .child(Label::new("Is this thing on?")), + ) + .into_any()] + }, + Box::new(PanelPayload { + scroll_state: self.scroll_state.clone(), + }), + ) + .side(self.current_side) + .width(AbsoluteLength::Rems(rems(32.))) + } +}