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