alert_modal.rs

  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}