toast.rs

 1use gpui::AnyElement;
 2use smallvec::SmallVec;
 3
 4use crate::prelude::*;
 5
 6#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
 7pub enum ToastOrigin {
 8    #[default]
 9    Bottom,
10    BottomRight,
11}
12
13/// Don't use toast directly:
14///
15/// - For messages with a required action, use a `NotificationToast`.
16/// - For messages that convey information, use a `StatusToast`.
17///
18/// A toast is a small, temporary window that appears to show a message to the user
19/// or indicate a required action.
20///
21/// Toasts should not persist on the screen for more than a few seconds unless
22/// they are actively showing the a process in progress.
23///
24/// Only one toast may be visible at a time.
25#[derive(Component)]
26pub struct Toast<V: 'static> {
27    origin: ToastOrigin,
28    children: SmallVec<[AnyElement<V>; 2]>,
29}
30
31impl<V: 'static> Toast<V> {
32    pub fn new(origin: ToastOrigin) -> Self {
33        Self {
34            origin,
35            children: SmallVec::new(),
36        }
37    }
38
39    fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
40        let mut div = div();
41
42        if self.origin == ToastOrigin::Bottom {
43            div = div.right_1_2();
44        } else {
45            div = div.right_2();
46        }
47
48        div.z_index(5)
49            .absolute()
50            .bottom_9()
51            .flex()
52            .py_1()
53            .px_1p5()
54            .rounded_lg()
55            .shadow_md()
56            .overflow_hidden()
57            .bg(cx.theme().colors().elevated_surface_background)
58            .children(self.children)
59    }
60}
61
62impl<V: 'static> ParentElement<V> for Toast<V> {
63    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
64        &mut self.children
65    }
66}
67
68#[cfg(feature = "stories")]
69pub use stories::*;
70
71#[cfg(feature = "stories")]
72mod stories {
73    use gpui::{Div, Render};
74
75    use crate::{Label, Story};
76
77    use super::*;
78
79    pub struct ToastStory;
80
81    impl Render for ToastStory {
82        type Element = Div<Self>;
83
84        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
85            Story::container(cx)
86                .child(Story::title_for::<_, Toast<Self>>(cx))
87                .child(Story::label(cx, "Default"))
88                .child(Toast::new(ToastOrigin::Bottom).child(Label::new("label")))
89        }
90    }
91}