|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
|
|
|
from datetime import datetime
|
|
|
from pathlib import Path
|
|
|
-from typing import TYPE_CHECKING, Dict, Iterable, Optional, Tuple, Type, Union
|
|
|
+from typing import TYPE_CHECKING, Dict, Iterable, Optional, Sequence, Tuple, Type, Union
|
|
|
|
|
|
from reflex import constants
|
|
|
from reflex.compiler import templates, utils
|
|
@@ -545,7 +545,47 @@ def purge_web_pages_dir():
|
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
- from reflex.app import UnevaluatedPage
|
|
|
+ from reflex.app import ComponentCallable, UnevaluatedPage
|
|
|
+
|
|
|
+
|
|
|
+def _into_component_once(component: Component | ComponentCallable) -> Component | None:
|
|
|
+ """Convert a component to a Component.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ component: The component to convert.
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ The converted component.
|
|
|
+ """
|
|
|
+ if isinstance(component, Component):
|
|
|
+ return component
|
|
|
+ if isinstance(component, (Var, int, float, str)):
|
|
|
+ return Fragment.create(component)
|
|
|
+ if isinstance(component, Sequence):
|
|
|
+ return Fragment.create(*component)
|
|
|
+ return None
|
|
|
+
|
|
|
+
|
|
|
+def into_component(component: Component | ComponentCallable) -> Component:
|
|
|
+ """Convert a component to a Component.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ component: The component to convert.
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ The converted component.
|
|
|
+
|
|
|
+ Raises:
|
|
|
+ TypeError: If the component is not a Component.
|
|
|
+ """
|
|
|
+ if (converted := _into_component_once(component)) is not None:
|
|
|
+ return converted
|
|
|
+ if (
|
|
|
+ callable(component)
|
|
|
+ and (converted := _into_component_once(component())) is not None
|
|
|
+ ):
|
|
|
+ return converted
|
|
|
+ raise TypeError(f"Expected a Component, got {type(component)}")
|
|
|
|
|
|
|
|
|
def compile_unevaluated_page(
|
|
@@ -568,12 +608,7 @@ def compile_unevaluated_page(
|
|
|
The compiled component and whether state should be enabled.
|
|
|
"""
|
|
|
# Generate the component if it is a callable.
|
|
|
- component = page.component
|
|
|
- component = component if isinstance(component, Component) else component()
|
|
|
-
|
|
|
- # unpack components that return tuples in an rx.fragment.
|
|
|
- if isinstance(component, tuple):
|
|
|
- component = Fragment.create(*component)
|
|
|
+ component = into_component(page.component)
|
|
|
|
|
|
component._add_style_recursive(style or {}, theme)
|
|
|
|
|
@@ -678,10 +713,8 @@ class ExecutorSafeFunctions:
|
|
|
The route, compiled component, and compiled page.
|
|
|
"""
|
|
|
component, enable_state = compile_unevaluated_page(
|
|
|
- route, cls.UNCOMPILED_PAGES[route]
|
|
|
+ route, cls.UNCOMPILED_PAGES[route], cls.STATE, style, theme
|
|
|
)
|
|
|
- component = component if isinstance(component, Component) else component()
|
|
|
- component._add_style_recursive(style, theme)
|
|
|
return route, component, compile_page(route, component, cls.STATE)
|
|
|
|
|
|
@classmethod
|