modal.rs

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