From 9d160a7ef51d86f1f25bc3ddb867a4691de11809 Mon Sep 17 00:00:00 2001 From: spinline Date: Wed, 11 Feb 2026 21:43:06 +0300 Subject: [PATCH] fix(ui): use thread_local for toast signal to fix context issue --- frontend/src/components/ui/toast.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/ui/toast.rs b/frontend/src/components/ui/toast.rs index 901c936..9d1f7f4 100644 --- a/frontend/src/components/ui/toast.rs +++ b/frontend/src/components/ui/toast.rs @@ -138,8 +138,18 @@ pub fn SonnerList( } } +// Thread local storage for global access without Context +thread_local! { + static TOASTS: std::cell::RefCell>>> = std::cell::RefCell::new(None); +} + pub fn provide_toaster() { let toasts = RwSignal::new(Vec::::new()); + + // Set global thread_local + TOASTS.with(|t| *t.borrow_mut() = Some(toasts)); + + // Also provide context for components provide_context(ToasterStore { toasts }); } @@ -191,7 +201,9 @@ pub fn Toaster(#[prop(default = SonnerPosition::default())] position: SonnerPosi // Global Helper Functions pub fn toast(title: impl Into, variant: ToastType) { - if let Some(store) = use_context::() { + let signal_opt = TOASTS.with(|t| *t.borrow()); + + if let Some(toasts) = signal_opt { let id = js_sys::Math::random().to_bits(); let new_toast = ToastData { id, @@ -201,18 +213,16 @@ pub fn toast(title: impl Into, variant: ToastType) { duration: 4000, }; - store.toasts.update(|t| t.push(new_toast.clone())); + toasts.update(|t| t.push(new_toast.clone())); // Auto remove after duration let duration = new_toast.duration; leptos::task::spawn_local(async move { gloo_timers::future::TimeoutFuture::new(duration as u32).await; - if let Some(store) = use_context::() { - store.toasts.update(|vec| vec.retain(|t| t.id != id)); - } + toasts.update(|vec| vec.retain(|t| t.id != id)); }); } else { - gloo_console::warn!("ToasterStore not found. Make sure is mounted."); + gloo_console::warn!("ToasterStore not found (global static). Make sure provide_toaster() is called."); } }