1use std::marker::PhantomData;
2
3use gpui2::AnyElement;
4use smallvec::SmallVec;
5
6use crate::{h_stack, prelude::*, v_stack, Button, Icon, IconButton, Label};
7
8#[derive(Element)]
9pub struct Modal<S: 'static + Send + Sync> {
10 id: ElementId,
11 state_type: PhantomData<S>,
12 title: Option<SharedString>,
13 primary_action: Option<Button<S>>,
14 secondary_action: Option<Button<S>>,
15 children: SmallVec<[AnyElement<S>; 2]>,
16}
17
18impl<S: 'static + Send + Sync> Modal<S> {
19 pub fn new(id: impl Into<ElementId>) -> Self {
20 Self {
21 id: id.into(),
22 state_type: PhantomData,
23 title: None,
24 primary_action: None,
25 secondary_action: None,
26 children: SmallVec::new(),
27 }
28 }
29
30 pub fn title(mut self, title: impl Into<SharedString>) -> Self {
31 self.title = Some(title.into());
32 self
33 }
34
35 pub fn primary_action(mut self, action: Button<S>) -> Self {
36 self.primary_action = Some(action);
37 self
38 }
39
40 pub fn secondary_action(mut self, action: Button<S>) -> Self {
41 self.secondary_action = Some(action);
42 self
43 }
44
45 fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
46 let theme = theme(cx);
47
48 v_stack()
49 .id(self.id.clone())
50 .w_96()
51 // .rounded_xl()
52 .bg(theme.background)
53 .border()
54 .border_color(theme.border)
55 .shadow_2xl()
56 .child(
57 h_stack()
58 .justify_between()
59 .p_1()
60 .border_b()
61 .border_color(theme.border)
62 .child(div().children(self.title.clone().map(|t| Label::new(t))))
63 .child(IconButton::new("close", Icon::Close)),
64 )
65 .child(v_stack().p_1().children(self.children.drain(..)))
66 .when(
67 self.primary_action.is_some() || self.secondary_action.is_some(),
68 |this| {
69 this.child(
70 h_stack()
71 .border_t()
72 .border_color(theme.border)
73 .p_1()
74 .justify_end()
75 .children(self.secondary_action.take())
76 .children(self.primary_action.take()),
77 )
78 },
79 )
80 }
81}
82
83impl<S: 'static + Send + Sync> ParentElement for Modal<S> {
84 fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> {
85 &mut self.children
86 }
87}