diff --git a/thaw/src/toast/docs/mod.md b/thaw/src/toast/docs/mod.md
index 151717a..3cfc550 100644
--- a/thaw/src/toast/docs/mod.md
+++ b/thaw/src/toast/docs/mod.md
@@ -102,6 +102,12 @@ let toaster = ToasterInjection::expect_context();
let id = uuid::Uuid::new_v4();
+let mounted = RwSignal::new(false);
+
+let on_status_change = move |status| {
+ mounted.set(status == ToastStatus::Mounted);
+};
+
let dispatch = move |_| {
toaster.dispatch_toast(move || view! {
@@ -113,7 +119,7 @@ let dispatch = move |_| {
- },ToastOptions::default().with_id(id));
+ },ToastOptions::default().with_id(id).with_on_status_change(on_status_change))
};
let dismiss = move |_| {
@@ -121,8 +127,45 @@ let dismiss = move |_| {
};
view! {
-
-
+ {move || {if !mounted.get() {
+ view!{}
+ } else {
+ view!{}
+ }
+}}}
+```
+
+### Dismiss All
+
+```rust demo
+let toaster = ToasterInjection::expect_context();
+
+fn dispatch_toast(toaster: ToasterInjection) {
+ toaster.dispatch_toast(move || view! {
+
+ "Email sent"
+
+ "This is a toast body"
+
+ "Subtitle"
+
+
+
+ "Footer"
+
+
+ }, ToastOptions::default());
+};
+
+let dismiss_all = move || {
+ toaster.dismiss_all();
+};
+
+view! {
+
+
+
+
}
```
@@ -160,11 +203,12 @@ view! {
### ToastOptions Props
-| Name | Type | Description |
-| ------------- | --------------------------------------- | ------------------------------------- |
-| with_position | `Fn(mut self, position: ToastPosition)` | The position the toast should render. |
-| with_timeout | `Fn(mut self, timeout: Duration)` | Auto dismiss timeout in milliseconds. |
-| with_intent | `Fn(mut self, intent: ToastIntent)` | The intent of the toast. |
+| Name | Type | Description |
+| --------------------- | ----------------------------------------------------- | ------------------------------------- |
+| with_position | `Fn(mut self, position: ToastPosition)` | The position the toast should render. |
+| with_timeout | `Fn(mut self, timeout: Duration)` | Auto dismiss timeout in milliseconds. |
+| with_intent | `Fn(mut self, intent: ToastIntent)` | The intent of the toast. |
+| with_on_status_change | `Fn(mut self, on_status_change: Fn(ToastStatus))` | The intent of the toast. |
### Toast & ToastFooter Props
diff --git a/thaw/src/toast/mod.rs b/thaw/src/toast/mod.rs
index 3014c96..73c4deb 100644
--- a/thaw/src/toast/mod.rs
+++ b/thaw/src/toast/mod.rs
@@ -24,6 +24,7 @@ pub struct ToasterInjection {
enum ToasterMessage {
Dispatch(Children, ToastOptions),
Dismiss(uuid::Uuid),
+ DismissAll,
}
impl ToasterInjection {
@@ -53,6 +54,15 @@ impl ToasterInjection {
self.trigger.with_value(|trigger| trigger.notify());
}
+ pub fn dismiss_all(&self) {
+ self.sender.with_value(|sender| {
+ sender
+ .send(ToasterMessage::DismissAll)
+ .unwrap_throw()
+ });
+ self.trigger.with_value(|trigger| trigger.notify());
+ }
+
pub fn dispatch_toast(&self, children: C, options: ToastOptions)
where
C: FnOnce() -> IV + Send + 'static,
diff --git a/thaw/src/toast/toast.rs b/thaw/src/toast/toast.rs
index 2f7dbfb..6b93df1 100644
--- a/thaw/src/toast/toast.rs
+++ b/thaw/src/toast/toast.rs
@@ -1,6 +1,6 @@
use leptos::prelude::*;
use std::time::Duration;
-use thaw_utils::class_list;
+use thaw_utils::{class_list, ArcOneCallback};
#[component]
pub fn Toast(
@@ -43,12 +43,19 @@ pub enum ToastIntent {
Error,
}
+#[derive(Debug, Clone, PartialEq)]
+pub enum ToastStatus {
+ Mounted,
+ Unmounted,
+}
+
#[derive(Clone)]
pub struct ToastOptions {
pub(crate) id: uuid::Uuid,
pub(crate) position: Option,
pub(crate) timeout: Option,
pub(crate) intent: Option,
+ pub(crate) on_status_change: Option>,
}
impl Default for ToastOptions {
@@ -58,6 +65,7 @@ impl Default for ToastOptions {
position: None,
timeout: None,
intent: None,
+ on_status_change: None,
}
}
}
@@ -86,4 +94,13 @@ impl ToastOptions {
self.intent = Some(intent);
self
}
+
+ /// Status change callback.
+ pub fn with_on_status_change(
+ mut self,
+ on_status_change: impl Fn(ToastStatus) + Send + Sync + 'static,
+ ) -> Self {
+ self.on_status_change = Some(on_status_change.into());
+ self
+ }
}
diff --git a/thaw/src/toast/toaster.rs b/thaw/src/toast/toaster.rs
index 2522674..012f9f7 100644
--- a/thaw/src/toast/toaster.rs
+++ b/thaw/src/toast/toaster.rs
@@ -1,5 +1,5 @@
use super::{ToastIntent, ToastOptions, ToastPosition, ToasterReceiver};
-use crate::{toast::ToasterMessage, ConfigInjection};
+use crate::{toast::ToasterMessage, ConfigInjection, ToastStatus};
use leptos::{context::Provider, either::Either, html, prelude::*};
use send_wrapper::SendWrapper;
use std::{collections::HashMap, time::Duration};
@@ -51,10 +51,14 @@ pub fn Toaster(
if options.intent.is_none() {
options.intent = Some(intent);
}
-
let list = id_list(&options.position.unwrap_throw());
let id = options.id;
let is_show = owner.with(|| RwSignal::new(true));
+
+ if let Some(on_status_change) = options.on_status_change.clone() {
+ on_status_change(ToastStatus::Mounted)
+ }
+
toasts.update_value(|map| {
map.insert(id, (SendWrapper::new(view), options, is_show));
});
@@ -66,7 +70,18 @@ pub fn Toaster(
});
}
ToasterMessage::Dismiss(toast_id) => {
- toast_show_list.with_value(|map| map.get(&toast_id).unwrap_throw().set(false));
+ toast_show_list.with_value(|map| {
+ if let Some(is_show) = map.get(&toast_id) {
+ is_show.set(false)
+ }
+ });
+ },
+ ToasterMessage::DismissAll => {
+ toast_show_list.with_value(|map| {
+ for is_show in map.values() {
+ is_show.set(false)
+ }
+ });
}
}
}
@@ -238,6 +253,7 @@ fn ToasterContainer(
timeout,
position,
intent,
+ on_status_change,
..
} = options;
@@ -266,6 +282,9 @@ fn ToasterContainer(
f(id, position);
}
});
+ if let Some(on_status_change) = on_status_change.clone() {
+ on_status_change(ToastStatus::Unmounted);
+ }
};
view! {