alert_modal.rs

  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}