1use gpui::prelude::*;
6use gpui::*;
7
8pub struct Card {
10 header: Option<AnyElement>,
11 content: Option<AnyElement>,
12 footer: Option<AnyElement>,
13 extra_classes: Vec<Box<dyn FnOnce(Div) -> Div>>,
15}
16
17impl Card {
18 pub fn new() -> Self {
20 Self {
21 header: None,
22 content: None,
23 footer: None,
24 extra_classes: Vec::new(),
25 }
26 }
27
28 pub fn header(mut self, element: impl IntoElement) -> Self {
30 self.header = Some(element.into_any_element());
31 self
32 }
33
34 pub fn content(mut self, element: impl IntoElement) -> Self {
36 self.content = Some(element.into_any_element());
37 self
38 }
39
40 pub fn footer(mut self, element: impl IntoElement) -> Self {
42 self.footer = Some(element.into_any_element());
43 self
44 }
45
46 pub fn style(mut self, f: impl FnOnce(Div) -> Div + 'static) -> Self {
48 self.extra_classes.push(Box::new(f));
49 self
50 }
51
52 pub fn build(self) -> Div {
54 let mut card = div()
55 .flex()
56 .flex_col()
57 .bg(rgb(0x1e1e1e))
58 .border_1()
59 .border_color(rgb(0x3a3a3a))
60 .rounded_lg()
61 .shadow_md()
62 .overflow_hidden();
63
64 for class_fn in self.extra_classes {
66 card = class_fn(card);
67 }
68
69 if let Some(header) = self.header {
71 card = card.child(
72 div()
73 .px_4()
74 .py_3()
75 .border_b_1()
76 .border_color(rgb(0x3a3a3a))
77 .child(header),
78 );
79 }
80
81 if let Some(content) = self.content {
83 card = card.child(div().px_4().py_4().child(content));
84 }
85
86 if let Some(footer) = self.footer {
88 card = card.child(
89 div()
90 .px_4()
91 .py_3()
92 .border_t_1()
93 .border_color(rgb(0x3a3a3a))
94 .child(footer),
95 );
96 }
97
98 card
99 }
100}
101
102impl Default for Card {
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108impl IntoElement for Card {
109 type Element = Div;
110
111 fn into_element(self) -> Self::Element {
112 self.build()
113 }
114}