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(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}