feat: change the any_view prop of dispatch_toast to children (#267)

This commit is contained in:
luoxiaozero 2024-09-22 18:08:24 +08:00 committed by GitHub
parent 687350102a
commit c87b989c3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 29 deletions

View file

@ -5,13 +5,13 @@ let toaster = ToasterInjection::expect_context();
let on_select = move |key: String| { let on_select = move |key: String| {
leptos::logging::warn!("{}", key); leptos::logging::warn!("{}", key);
toaster.dispatch_toast(view! { toaster.dispatch_toast(move || view! {
<Toast> <Toast>
<ToastBody> <ToastBody>
"key" "key"
</ToastBody> </ToastBody>
</Toast> </Toast>
}.into_any(), Default::default()); }, Default::default());
}; };
view! { view! {

View file

@ -38,14 +38,14 @@ view! {
let toaster = ToasterInjection::expect_context(); let toaster = ToasterInjection::expect_context();
let on_dismiss = move |_| { let on_dismiss = move |_| {
toaster.dispatch_toast(view! { toaster.dispatch_toast(move || view! {
<Toast> <Toast>
<ToastTitle>"Tag"</ToastTitle> <ToastTitle>"Tag"</ToastTitle>
<ToastBody> <ToastBody>
"Tag dismiss" "Tag dismiss"
</ToastBody> </ToastBody>
</Toast> </Toast>
}.into_any(), Default::default()); }, Default::default());
}; };
view! { view! {

View file

@ -4,7 +4,7 @@
let toaster = ToasterInjection::expect_context(); let toaster = ToasterInjection::expect_context();
let on_click = move |_| { let on_click = move |_| {
toaster.dispatch_toast(view! { toaster.dispatch_toast(move || view! {
<Toast> <Toast>
<ToastTitle>"Email sent"</ToastTitle> <ToastTitle>"Email sent"</ToastTitle>
<ToastBody> <ToastBody>
@ -19,7 +19,7 @@ let on_click = move |_| {
// <Link>Action</Link> // <Link>Action</Link>
</ToastFooter> </ToastFooter>
</Toast> </Toast>
}.into_any(), Default::default()); }, Default::default());
}; };
view! { view! {
@ -33,7 +33,7 @@ view! {
let toaster = ToasterInjection::expect_context(); let toaster = ToasterInjection::expect_context();
fn dispatch_toast(toaster: ToasterInjection, position: ToastPosition) { fn dispatch_toast(toaster: ToasterInjection, position: ToastPosition) {
toaster.dispatch_toast(view! { toaster.dispatch_toast(move || view! {
<Toast> <Toast>
<ToastTitle>"Email sent"</ToastTitle> <ToastTitle>"Email sent"</ToastTitle>
<ToastBody> <ToastBody>
@ -48,7 +48,7 @@ fn dispatch_toast(toaster: ToasterInjection, position: ToastPosition) {
// <Link>Action</Link> // <Link>Action</Link>
</ToastFooter> </ToastFooter>
</Toast> </Toast>
}.into_any(), ToastOptions::default().with_position(position)); }, ToastOptions::default().with_position(position));
}; };
view! { view! {

View file

@ -13,12 +13,11 @@ pub use toaster_provider::*;
use leptos::prelude::*; use leptos::prelude::*;
use std::sync::mpsc::{channel, Receiver, Sender, TryIter}; use std::sync::mpsc::{channel, Receiver, Sender, TryIter};
use tachys::view::any_view::AnyView;
use wasm_bindgen::UnwrapThrowExt; use wasm_bindgen::UnwrapThrowExt;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct ToasterInjection { pub struct ToasterInjection {
sender: StoredValue<Sender<(AnyView<Dom>, ToastOptions)>>, sender: StoredValue<Sender<(Children, ToastOptions)>>,
trigger: StoredValue<ArcTrigger>, trigger: StoredValue<ArcTrigger>,
} }
@ -28,7 +27,7 @@ impl ToasterInjection {
} }
pub fn channel() -> (Self, ToasterReceiver) { pub fn channel() -> (Self, ToasterReceiver) {
let (sender, receiver) = channel::<(AnyView<Dom>, ToastOptions)>(); let (sender, receiver) = channel::<(Children, ToastOptions)>();
let trigger = ArcTrigger::new(); let trigger = ArcTrigger::new();
( (
@ -40,24 +39,31 @@ impl ToasterInjection {
) )
} }
pub fn dispatch_toast(&self, any_view: AnyView<Dom>, options: ToastOptions) { pub fn dispatch_toast<C, IV>(&self, children: C, options: ToastOptions)
self.sender where
.with_value(|sender| sender.send((any_view, options)).unwrap_throw()); C: FnOnce() -> IV + Send + 'static,
IV: IntoView + 'static,
{
self.sender.with_value(|sender| {
sender
.send((Box::new(move || children().into_any()), options))
.unwrap_throw()
});
self.trigger.with_value(|trigger| trigger.notify()); self.trigger.with_value(|trigger| trigger.notify());
} }
} }
pub struct ToasterReceiver { pub struct ToasterReceiver {
receiver: Receiver<(AnyView<Dom>, ToastOptions)>, receiver: Receiver<(Children, ToastOptions)>,
trigger: ArcTrigger, trigger: ArcTrigger,
} }
impl ToasterReceiver { impl ToasterReceiver {
pub fn new(receiver: Receiver<(AnyView<Dom>, ToastOptions)>, trigger: ArcTrigger) -> Self { pub fn new(receiver: Receiver<(Children, ToastOptions)>, trigger: ArcTrigger) -> Self {
Self { receiver, trigger } Self { receiver, trigger }
} }
pub fn try_recv(&self) -> TryIter<'_, (AnyView<Dom>, ToastOptions)> { pub fn try_recv(&self) -> TryIter<'_, (Children, ToastOptions)> {
self.trigger.track(); self.trigger.track();
self.receiver.try_iter() self.receiver.try_iter()
} }

View file

@ -1,6 +1,6 @@
use super::{ToastOptions, ToastPosition, ToasterReceiver}; use super::{ToastOptions, ToastPosition, ToasterReceiver};
use crate::ConfigInjection; use crate::ConfigInjection;
use leptos::{either::Either, html, prelude::*, tachys::view::any_view::AnyView}; use leptos::{either::Either, html, prelude::*};
use send_wrapper::SendWrapper; use send_wrapper::SendWrapper;
use std::{collections::HashMap, time::Duration}; use std::{collections::HashMap, time::Duration};
use thaw_components::{CSSTransition, Teleport}; use thaw_components::{CSSTransition, Teleport};
@ -21,7 +21,7 @@ pub fn Toaster(
let bottom_id_list = RwSignal::<Vec<uuid::Uuid>>::new(Default::default()); let bottom_id_list = RwSignal::<Vec<uuid::Uuid>>::new(Default::default());
let bottom_start_id_list = RwSignal::<Vec<uuid::Uuid>>::new(Default::default()); let bottom_start_id_list = RwSignal::<Vec<uuid::Uuid>>::new(Default::default());
let bottom_end_id_list = RwSignal::<Vec<uuid::Uuid>>::new(Default::default()); let bottom_end_id_list = RwSignal::<Vec<uuid::Uuid>>::new(Default::default());
let toasts = StoredValue::<HashMap<uuid::Uuid, (SendWrapper<AnyView<Dom>>, ToastOptions)>>::new( let toasts = StoredValue::<HashMap<uuid::Uuid, (SendWrapper<Children>, ToastOptions)>>::new(
Default::default(), Default::default(),
); );
@ -77,7 +77,7 @@ pub fn Toaster(
.flatten() .flatten()
{ {
Either::Left( Either::Left(
view! { <ToasterContainer on_close view=view.take() options /> }, view! { <ToasterContainer on_close children=view.take() options /> },
) )
} else { } else {
Either::Right(()) Either::Right(())
@ -91,7 +91,7 @@ pub fn Toaster(
.flatten() .flatten()
{ {
Either::Left( Either::Left(
view! { <ToasterContainer on_close view=view.take() options /> }, view! { <ToasterContainer on_close children=view.take() options /> },
) )
} else { } else {
Either::Right(()) Either::Right(())
@ -105,7 +105,7 @@ pub fn Toaster(
.flatten() .flatten()
{ {
Either::Left( Either::Left(
view! { <ToasterContainer on_close view=view.take() options /> }, view! { <ToasterContainer on_close children=view.take() options /> },
) )
} else { } else {
Either::Right(()) Either::Right(())
@ -119,7 +119,7 @@ pub fn Toaster(
.flatten() .flatten()
{ {
Either::Left( Either::Left(
view! { <ToasterContainer on_close view=view.take() options /> }, view! { <ToasterContainer on_close children=view.take() options /> },
) )
} else { } else {
Either::Right(()) Either::Right(())
@ -133,7 +133,7 @@ pub fn Toaster(
.flatten() .flatten()
{ {
Either::Left( Either::Left(
view! { <ToasterContainer on_close view=view.take() options /> }, view! { <ToasterContainer on_close children=view.take() options /> },
) )
} else { } else {
Either::Right(()) Either::Right(())
@ -147,7 +147,7 @@ pub fn Toaster(
.flatten() .flatten()
{ {
Either::Left( Either::Left(
view! { <ToasterContainer on_close view=view.take() options /> }, view! { <ToasterContainer on_close children=view.take() options /> },
) )
} else { } else {
Either::Right(()) Either::Right(())
@ -161,9 +161,9 @@ pub fn Toaster(
#[component] #[component]
fn ToasterContainer( fn ToasterContainer(
view: AnyView<Dom>,
options: ToastOptions, options: ToastOptions,
#[prop(into)] on_close: StoredValue<ArcTwoCallback<uuid::Uuid, ToastPosition>>, #[prop(into)] on_close: StoredValue<ArcTwoCallback<uuid::Uuid, ToastPosition>>,
children: Children,
) -> impl IntoView { ) -> impl IntoView {
let container_ref = NodeRef::<html::Div>::new(); let container_ref = NodeRef::<html::Div>::new();
let is_show = RwSignal::new(true); let is_show = RwSignal::new(true);
@ -210,7 +210,7 @@ fn ToasterContainer(
let:_ let:_
> >
<div class="thaw-toaster-container" node_ref=container_ref> <div class="thaw-toaster-container" node_ref=container_ref>
{view} {children()}
</div> </div>
</CSSTransition> </CSSTransition>
} }

View file

@ -28,13 +28,13 @@ let toaster = ToasterInjection::expect_context();
let custom_request = move |file_list: FileList| { let custom_request = move |file_list: FileList| {
let len = file_list.length(); let len = file_list.length();
toaster.dispatch_toast(view! { toaster.dispatch_toast(move || view! {
<Toast> <Toast>
<ToastBody> <ToastBody>
{format!("Number of uploaded files: {len}")} {format!("Number of uploaded files: {len}")}
</ToastBody> </ToastBody>
</Toast> </Toast>
}.into_any(), Default::default()); }, Default::default());
}; };
view! { view! {