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(self.dismiss_label.clone(), self.dismiss_label.clone())
63 .color(Color::Muted),
64 )
65 .child(Button::new(
66 self.primary_action.clone(),
67 self.primary_action,
68 )),
69 ),
70 )
71 }
72}
73
74impl ParentElement for AlertModal {
75 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
76 self.children.extend(elements)
77 }
78}
79
80impl Component for AlertModal {
81 fn scope() -> ComponentScope {
82 ComponentScope::Notification
83 }
84
85 fn status() -> ComponentStatus {
86 ComponentStatus::WorkInProgress
87 }
88
89 fn description() -> Option<&'static str> {
90 Some("A modal dialog that presents an alert message with primary and dismiss actions.")
91 }
92
93 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
94 Some(
95 v_flex()
96 .gap_6()
97 .p_4()
98 .children(vec![example_group(
99 vec![
100 single_example(
101 "Basic Alert",
102 AlertModal::new("simple-modal", "Do you want to leave the current call?")
103 .child("The current window will be closed, and connections to any shared projects will be terminated."
104 )
105 .primary_action("Leave Call")
106 .into_any_element(),
107 )
108 ],
109 )])
110 .into_any_element()
111 )
112 }
113}