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