1use crate::prelude::*;
2use gpui::IntoElement;
3use smallvec::{SmallVec, smallvec};
4
5#[derive(IntoElement, RegisterComponent)]
6pub struct AlertModal {
7 id: ElementId,
8 children: SmallVec<[AnyElement; 2]>,
9 title: SharedString,
10 primary_action: SharedString,
11 dismiss_label: SharedString,
12}
13
14impl AlertModal {
15 pub fn new(id: impl Into<ElementId>, title: impl Into<SharedString>) -> Self {
16 Self {
17 id: id.into(),
18 children: smallvec![],
19 title: title.into(),
20 primary_action: "Ok".into(),
21 dismiss_label: "Cancel".into(),
22 }
23 }
24
25 pub fn primary_action(mut self, primary_action: impl Into<SharedString>) -> Self {
26 self.primary_action = primary_action.into();
27 self
28 }
29
30 pub fn dismiss_label(mut self, dismiss_label: impl Into<SharedString>) -> Self {
31 self.dismiss_label = dismiss_label.into();
32 self
33 }
34}
35
36impl RenderOnce for AlertModal {
37 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
38 v_flex()
39 .id(self.id)
40 .elevation_3(cx)
41 .w(px(440.))
42 .p_5()
43 .child(
44 v_flex()
45 .text_ui(cx)
46 .text_color(Color::Muted.color(cx))
47 .gap_1()
48 .child(Headline::new(self.title).size(HeadlineSize::Small))
49 .children(self.children),
50 )
51 .child(
52 h_flex()
53 .h(rems(1.75))
54 .items_center()
55 .child(div().flex_1())
56 .child(
57 h_flex()
58 .items_center()
59 .gap_1()
60 .child(
61 Button::new(self.dismiss_label.clone(), self.dismiss_label.clone())
62 .color(Color::Muted),
63 )
64 .child(Button::new(
65 self.primary_action.clone(),
66 self.primary_action.clone(),
67 )),
68 ),
69 )
70 }
71}
72
73impl ParentElement for AlertModal {
74 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
75 self.children.extend(elements)
76 }
77}
78
79impl Component for AlertModal {
80 fn scope() -> ComponentScope {
81 ComponentScope::Notification
82 }
83
84 fn description() -> Option<&'static str> {
85 Some("A modal dialog that presents an alert message with primary and dismiss actions.")
86 }
87
88 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
89 Some(
90 v_flex()
91 .gap_6()
92 .p_4()
93 .children(vec![example_group(
94 vec![
95 single_example(
96 "Basic Alert",
97 AlertModal::new("simple-modal", "Do you want to leave the current call?")
98 .child("The current window will be closed, and connections to any shared projects will be terminated."
99 )
100 .primary_action("Leave Call")
101 .into_any_element(),
102 )
103 ],
104 )])
105 .into_any_element()
106 )
107 }
108}