diff --git a/reflex/app.py b/reflex/app.py index 6f97d3bb3..6e66257b4 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -75,6 +75,7 @@ from reflex.components.core.client_side_routing import ( from reflex.components.core.sticky import sticky from reflex.components.core.upload import Upload, get_upload_dir from reflex.components.radix import themes +from reflex.components.sonner.toast import toast from reflex.config import ExecutorType, environment, get_config from reflex.event import ( _EVENT_FIELDS, @@ -411,7 +412,7 @@ class App(MiddlewareMixin, LifespanMixin): ] = default_backend_exception_handler # Put the toast provider in the app wrap. - bundle_toaster: bool = True + toaster: Component | None = dataclasses.field(default_factory=toast.provider) @property def api(self) -> FastAPI | None: @@ -1186,15 +1187,12 @@ class App(MiddlewareMixin, LifespanMixin): # Add the custom components from the page to the set. custom_components |= component._get_all_custom_components() - if self.bundle_toaster: + if (toaster := self.toaster) is not None: from reflex.components.component import memo - from reflex.components.sonner.toast import toast - - internal_toast_provider = toast.provider() @memo def memoized_toast_provider(): - return internal_toast_provider + return toaster toast_provider = Fragment.create(memoized_toast_provider()) diff --git a/reflex/components/core/banner.py b/reflex/components/core/banner.py index e8c72daf6..c0e88b23e 100644 --- a/reflex/components/core/banner.py +++ b/reflex/components/core/banner.py @@ -17,7 +17,7 @@ from reflex.components.radix.themes.components.dialog import ( ) from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.typography.text import Text -from reflex.components.sonner.toast import ToastProps +from reflex.components.sonner.toast import ToastProps, toast_ref from reflex.config import environment from reflex.constants import Dirs, Hooks, Imports from reflex.constants.compiler import CompileVars @@ -114,11 +114,11 @@ class ConnectionToaster(Fragment): if environment.REFLEX_DOES_BACKEND_COLD_START.get(): loading_message = Var.create("Backend is starting.") backend_is_loading_toast_var = Var( - f"toast.loading({loading_message!s}, {{...toast_props, description: '', closeButton: false, onDismiss: () => setUserDismissed(true)}},)" + f"toast?.loading({loading_message!s}, {{...toast_props, description: '', closeButton: false, onDismiss: () => setUserDismissed(true)}},)" ) backend_is_not_responding = Var.create("Backend is not responding.") backend_is_down_toast_var = Var( - f"toast.error({backend_is_not_responding!s}, {{...toast_props, description: '', onDismiss: () => setUserDismissed(true)}},)" + f"toast?.error({backend_is_not_responding!s}, {{...toast_props, description: '', onDismiss: () => setUserDismissed(true)}},)" ) toast_var = Var( f""" @@ -139,10 +139,11 @@ setTimeout(() => {{ f"Cannot connect to server: {connection_error}." ) toast_var = Var( - f"toast.error({loading_message!s}, {{...toast_props, onDismiss: () => setUserDismissed(true)}},)" + f"toast?.error({loading_message!s}, {{...toast_props, onDismiss: () => setUserDismissed(true)}},)" ) individual_hooks = [ + Var(f"const toast = {toast_ref};"), f"const toast_props = {LiteralVar.create(props)!s};", "const [userDismissed, setUserDismissed] = useState(false);", "const [waitedForBackend, setWaitedForBackend] = useState(false);", @@ -164,7 +165,7 @@ setTimeout(() => {{ {toast_var!s} }} }} else {{ - toast.dismiss("{toast_id}"); + toast?.dismiss("{toast_id}"); setUserDismissed(false); // after reconnection reset dismissed state }} }} diff --git a/reflex/components/sonner/toast.py b/reflex/components/sonner/toast.py index eabc9ea6a..247b897b8 100644 --- a/reflex/components/sonner/toast.py +++ b/reflex/components/sonner/toast.py @@ -383,7 +383,6 @@ class Toaster(Component): Returns: The toaster component. """ - cls.is_used = True return super().create(*children, **props)