toast.rs

  1use crate::prelude::*;
  2
  3#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
  4pub enum ToastOrigin {
  5    #[default]
  6    Bottom,
  7    BottomRight,
  8}
  9
 10#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
 11pub enum ToastVariant {
 12    #[default]
 13    Toast,
 14    Status,
 15}
 16
 17/// A toast is a small, temporary window that appears to show a message to the user
 18/// or indicate a required action.
 19///
 20/// Toasts should not persist on the screen for more than a few seconds unless
 21/// they are actively showing the a process in progress.
 22///
 23/// Only one toast may be visible at a time.
 24#[derive(Element)]
 25pub struct Toast<S: 'static + Send + Sync> {
 26    origin: ToastOrigin,
 27    children: HackyChildren<S>,
 28    payload: HackyChildrenPayload,
 29}
 30
 31impl<S: 'static + Send + Sync> Toast<S> {
 32    pub fn new(
 33        origin: ToastOrigin,
 34        children: HackyChildren<S>,
 35        payload: HackyChildrenPayload,
 36    ) -> Self {
 37        Self {
 38            origin,
 39            children,
 40            payload,
 41        }
 42    }
 43
 44    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
 45        let color = ThemeColor::new(cx);
 46
 47        let mut div = div();
 48
 49        if self.origin == ToastOrigin::Bottom {
 50            div = div.right_1_2();
 51        } else {
 52            div = div.right_4();
 53        }
 54
 55        div.z_index(5)
 56            .absolute()
 57            .bottom_4()
 58            .flex()
 59            .py_2()
 60            .px_1p5()
 61            .min_w_40()
 62            .rounded_md()
 63            .fill(color.elevated_surface)
 64            .max_w_64()
 65            .children_any((self.children)(cx, self.payload.as_ref()))
 66    }
 67}
 68
 69#[cfg(feature = "stories")]
 70pub use stories::*;
 71
 72#[cfg(feature = "stories")]
 73mod stories {
 74    use std::marker::PhantomData;
 75
 76    use crate::{Label, Story};
 77
 78    use super::*;
 79
 80    #[derive(Element)]
 81    pub struct ToastStory<S: 'static + Send + Sync + Clone> {
 82        state_type: PhantomData<S>,
 83    }
 84
 85    impl<S: 'static + Send + Sync + Clone> ToastStory<S> {
 86        pub fn new() -> Self {
 87            Self {
 88                state_type: PhantomData,
 89            }
 90        }
 91
 92        fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
 93            Story::container(cx)
 94                .child(Story::title_for::<_, Toast<S>>(cx))
 95                .child(Story::label(cx, "Default"))
 96                .child(Toast::new(
 97                    ToastOrigin::Bottom,
 98                    |_, _| vec![Label::new("label").into_any()],
 99                    Box::new(()),
100                ))
101        }
102    }
103}