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