瀏覽代碼

fix toast provider needed (#4801)

* fix toast provider needed

* fix tests
Khaleel Al-Adhami 3 月之前
父節點
當前提交
6cbdd00169
共有 5 個文件被更改,包括 42 次插入6 次删除
  1. 24 1
      reflex/app.py
  2. 0 3
      reflex/components/component.py
  3. 5 1
      reflex/components/sonner/toast.py
  4. 7 1
      reflex/components/sonner/toast.pyi
  5. 6 0
      tests/units/test_app.py

+ 24 - 1
reflex/app.py

@@ -355,6 +355,9 @@ class App(MiddlewareMixin, LifespanMixin):
         [Exception], Union[EventSpec, List[EventSpec], None]
     ] = default_backend_exception_handler
 
+    # Put the toast provider in the app wrap.
+    bundle_toaster: bool = True
+
     @property
     def api(self) -> FastAPI | None:
         """Get the backend api.
@@ -1010,6 +1013,10 @@ class App(MiddlewareMixin, LifespanMixin):
         should_compile = self._should_compile()
 
         if not should_compile:
+            if self.bundle_toaster:
+                from reflex.components.sonner.toast import Toaster
+
+                Toaster.is_used = True
             with console.timing("Evaluate Pages (Backend)"):
                 for route in self._unevaluated_pages:
                     console.debug(f"Evaluating page: {route}")
@@ -1039,6 +1046,20 @@ class App(MiddlewareMixin, LifespanMixin):
             + adhoc_steps_without_executor,
         )
 
+        if self.bundle_toaster:
+            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
+
+            toast_provider = Fragment.create(memoized_toast_provider())
+
+            app_wrappers[(1, "ToasterProvider")] = toast_provider
+
         with console.timing("Evaluate Pages (Frontend)"):
             for route in self._unevaluated_pages:
                 console.debug(f"Evaluating page: {route}")
@@ -1081,7 +1102,9 @@ class App(MiddlewareMixin, LifespanMixin):
             component = app_wrap(self._state is not None)
             if component is not None:
                 app_wrappers[key] = component
-                custom_components |= component._get_all_custom_components()
+
+        for component in app_wrappers.values():
+            custom_components |= component._get_all_custom_components()
 
         if self.error_boundary:
             console.deprecate(

+ 0 - 3
reflex/components/component.py

@@ -1792,9 +1792,6 @@ class CustomComponent(Component):
             include_children=include_children, ignore_ids=ignore_ids
         )
         yield from filter(lambda prop: isinstance(prop, Var), self.props.values())
-        yield from self.get_component(self)._get_vars(
-            include_children=include_children, ignore_ids=ignore_ids
-        )
 
     @lru_cache(maxsize=None)  # noqa: B019
     def get_component(self) -> Component:

+ 5 - 1
reflex/components/sonner/toast.py

@@ -8,6 +8,7 @@ from reflex.base import Base
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.lucide.icon import Icon
 from reflex.components.props import NoExtrasAllowedProps, PropsBase
+from reflex.constants.base import Dirs
 from reflex.event import EventSpec, run_script
 from reflex.style import Style, resolved_color_mode
 from reflex.utils import format
@@ -27,7 +28,10 @@ LiteralPosition = Literal[
     "bottom-right",
 ]
 
-toast_ref = Var(_js_expr="refs['__toast']")
+toast_ref = Var(
+    _js_expr="refs['__toast']",
+    _var_data=VarData(imports={f"$/{Dirs.STATE_PATH}": [ImportVar(tag="refs")]}),
+)
 
 
 class ToastAction(Base):

+ 7 - 1
reflex/components/sonner/toast.pyi

@@ -9,9 +9,12 @@ from reflex.base import Base
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.lucide.icon import Icon
 from reflex.components.props import NoExtrasAllowedProps, PropsBase
+from reflex.constants.base import Dirs
 from reflex.event import EventSpec, EventType
 from reflex.style import Style
+from reflex.utils.imports import ImportVar
 from reflex.utils.serializers import serializer
+from reflex.vars import VarData
 from reflex.vars.base import Var
 
 LiteralPosition = Literal[
@@ -22,7 +25,10 @@ LiteralPosition = Literal[
     "bottom-center",
     "bottom-right",
 ]
-toast_ref = Var(_js_expr="refs['__toast']")
+toast_ref = Var(
+    _js_expr="refs['__toast']",
+    _var_data=VarData(imports={f"$/{Dirs.STATE_PATH}": [ImportVar(tag="refs")]}),
+)
 
 class ToastAction(Base):
     label: str

+ 6 - 0
tests/units/test_app.py

@@ -1307,8 +1307,11 @@ def test_app_wrap_compile_theme(
         + "<RadixThemesColorModeProvider>"
         "<RadixThemesTheme accentColor={\"plum\"} css={{...theme.styles.global[':root'], ...theme.styles.global.body}}>"
         "<Fragment>"
+        "<MemoizedToastProvider/>"
+        "<Fragment>"
         "{children}"
         "</Fragment>"
+        "</Fragment>"
         "</RadixThemesTheme>"
         "</RadixThemesColorModeProvider>"
         + ("</StrictMode>" if react_strict_mode else "")
@@ -1371,8 +1374,11 @@ def test_app_wrap_priority(
         "<RadixThemesColorModeProvider>"
         "<Fragment2>"
         "<Fragment>"
+        "<MemoizedToastProvider/>"
+        "<Fragment>"
         "{children}"
         "</Fragment>"
+        "</Fragment>"
         "</Fragment2>"
         "</RadixThemesColorModeProvider>"
         "</RadixThemesText>"