Skip to main content

gpui_component/dialog/
footer.rs

1use gpui::{
2    AnyElement, App, InteractiveElement as _, IntoElement, ParentElement, RenderOnce,
3    StatefulInteractiveElement, StyleRefinement, Styled, Window, div, relative,
4};
5
6use crate::{ActiveTheme as _, StyledExt as _, dialog::Confirm, h_flex};
7
8/// Footer section of a dialog, typically contains action buttons.
9///
10/// # Examples
11///
12/// ```ignore
13/// DialogFooter::new()
14///     .child(DialogClose::new().child(Button::new("cancel").label("Cancel")))
15///     .child(Button::new("confirm").label("Confirm"))
16/// ```
17#[derive(IntoElement)]
18pub struct DialogFooter {
19    style: StyleRefinement,
20    children: Vec<AnyElement>,
21}
22
23impl DialogFooter {
24    pub fn new() -> Self {
25        Self {
26            style: StyleRefinement::default(),
27            children: Vec::new(),
28        }
29    }
30}
31
32impl ParentElement for DialogFooter {
33    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
34        self.children.extend(elements);
35    }
36}
37
38impl Styled for DialogFooter {
39    fn style(&mut self) -> &mut StyleRefinement {
40        &mut self.style
41    }
42}
43
44impl RenderOnce for DialogFooter {
45    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
46        h_flex()
47            .gap_2()
48            .justify_end()
49            .line_height(relative(1.))
50            .rounded_b(cx.theme().radius_lg)
51            .refine_style(&self.style)
52            .children(self.children)
53    }
54}
55
56pub trait DialogFooterButton {
57    fn is_cancel(&self) -> bool {
58        false
59    }
60
61    fn is_action(&self) -> bool {
62        false
63    }
64}
65#[derive(IntoElement)]
66pub struct DialogClose {
67    base: gpui_base::DialogClose,
68}
69
70impl DialogClose {
71    pub fn new() -> Self {
72        Self {
73            base: gpui_base::DialogClose::new(),
74        }
75    }
76}
77
78impl ParentElement for DialogClose {
79    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
80        self.base.extend(elements);
81    }
82}
83
84impl RenderOnce for DialogClose {
85    fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
86        div().size_full().child(self.base)
87    }
88}
89
90#[derive(IntoElement)]
91pub struct DialogAction {
92    children: Vec<AnyElement>,
93}
94
95impl DialogAction {
96    pub fn new() -> Self {
97        Self {
98            children: Vec::new(),
99        }
100    }
101}
102
103impl ParentElement for DialogAction {
104    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
105        self.children.extend(elements);
106    }
107}
108
109impl RenderOnce for DialogAction {
110    fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
111        div()
112            .size_full()
113            .id("dialog-action")
114            .on_click(move |_, window, cx| {
115                window.dispatch_action(Box::new(Confirm { secondary: false }), cx)
116            })
117            .children(self.children)
118    }
119}