modal.rs

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