1use std::marker::PhantomData;
2
3use gpui2::{rems, AbsoluteLength};
4
5use crate::prelude::*;
6use crate::{Icon, IconButton, Label, Panel, PanelSide};
7
8#[derive(Element)]
9pub struct AssistantPanel<S: 'static + Send + Sync> {
10 id: ElementId,
11 state_type: PhantomData<S>,
12 current_side: PanelSide,
13}
14
15impl<S: 'static + Send + Sync> AssistantPanel<S> {
16 pub fn new(id: impl Into<ElementId>) -> Self {
17 Self {
18 id: id.into(),
19 state_type: PhantomData,
20 current_side: PanelSide::default(),
21 }
22 }
23
24 pub fn side(mut self, side: PanelSide) -> Self {
25 self.current_side = side;
26 self
27 }
28
29 fn render(&mut self, view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
30 Panel::new(self.id.clone(), cx)
31 .children(vec![div()
32 .flex()
33 .flex_col()
34 .h_full()
35 .px_2()
36 .gap_2()
37 // Header
38 .child(
39 div()
40 .flex()
41 .justify_between()
42 .gap_2()
43 .child(
44 div()
45 .flex()
46 .child(IconButton::new("menu", Icon::Menu))
47 .child(Label::new("New Conversation")),
48 )
49 .child(
50 div()
51 .flex()
52 .items_center()
53 .gap_px()
54 .child(IconButton::new("split_message", Icon::SplitMessage))
55 .child(IconButton::new("quote", Icon::Quote))
56 .child(IconButton::new("magic_wand", Icon::MagicWand))
57 .child(IconButton::new("plus", Icon::Plus))
58 .child(IconButton::new("maximize", Icon::Maximize)),
59 ),
60 )
61 // Chat Body
62 .child(
63 div()
64 .id("chat-body")
65 .w_full()
66 .flex()
67 .flex_col()
68 .gap_3()
69 .overflow_y_scroll()
70 .child(Label::new("Is this thing on?")),
71 )
72 .into_any()])
73 .side(self.current_side)
74 .width(AbsoluteLength::Rems(rems(32.)))
75 }
76}
77
78#[cfg(feature = "stories")]
79pub use stories::*;
80
81#[cfg(feature = "stories")]
82mod stories {
83 use crate::Story;
84
85 use super::*;
86
87 #[derive(Element)]
88 pub struct AssistantPanelStory<S: 'static + Send + Sync> {
89 state_type: PhantomData<S>,
90 }
91
92 impl<S: 'static + Send + Sync> AssistantPanelStory<S> {
93 pub fn new() -> Self {
94 Self {
95 state_type: PhantomData,
96 }
97 }
98
99 fn render(
100 &mut self,
101 _view: &mut S,
102 cx: &mut ViewContext<S>,
103 ) -> impl Element<ViewState = S> {
104 Story::container(cx)
105 .child(Story::title_for::<_, AssistantPanel<S>>(cx))
106 .child(Story::label(cx, "Default"))
107 .child(AssistantPanel::new("assistant-panel"))
108 }
109 }
110}