Просмотр исходного кода

fix tag render to be recursive (#4714)

Khaleel Al-Adhami 3 месяцев назад
Родитель
Сommit
2c3257d4ea

+ 1 - 1
reflex/.templates/jinja/web/pages/utils.js.jinja2

@@ -86,7 +86,7 @@
             {% for condition in case[:-1] %}
             {% for condition in case[:-1] %}
                 case JSON.stringify({{ condition._js_expr }}):
                 case JSON.stringify({{ condition._js_expr }}):
             {% endfor %}
             {% endfor %}
-                return {{ case[-1] }};
+                return {{ render(case[-1]) }};
                 break;
                 break;
         {% endfor %}
         {% endfor %}
             default:
             default:

+ 2 - 2
reflex/components/component.py

@@ -2389,7 +2389,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
     if tag["name"] == "match":
     if tag["name"] == "match":
         element = tag["cond"]
         element = tag["cond"]
 
 
-        conditionals = tag["default"]
+        conditionals = render_dict_to_var(tag["default"], imported_names)
 
 
         for case in tag["match_cases"][::-1]:
         for case in tag["match_cases"][::-1]:
             condition = case[0].to_string() == element.to_string()
             condition = case[0].to_string() == element.to_string()
@@ -2398,7 +2398,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
 
 
             conditionals = ternary_operation(
             conditionals = ternary_operation(
                 condition,
                 condition,
-                case[-1],
+                render_dict_to_var(case[-1], imported_names),
                 conditionals,
                 conditionals,
             )
             )
 
 

+ 24 - 19
reflex/components/tags/tag.py

@@ -3,13 +3,33 @@
 from __future__ import annotations
 from __future__ import annotations
 
 
 import dataclasses
 import dataclasses
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional, Sequence, Union
 
 
 from reflex.event import EventChain
 from reflex.event import EventChain
 from reflex.utils import format, types
 from reflex.utils import format, types
 from reflex.vars.base import LiteralVar, Var
 from reflex.vars.base import LiteralVar, Var
 
 
 
 
+def render_prop(value: Any) -> Any:
+    """Render the prop.
+
+    Args:
+        value: The value to render.
+
+    Returns:
+        The rendered value.
+    """
+    from reflex.components.component import BaseComponent
+
+    if isinstance(value, BaseComponent):
+        return value.render()
+    if isinstance(value, Sequence) and not isinstance(value, str):
+        return [render_prop(v) for v in value]
+    if callable(value) and not isinstance(value, Var):
+        return None
+    return value
+
+
 @dataclasses.dataclass()
 @dataclasses.dataclass()
 class Tag:
 class Tag:
     """A React tag."""
     """A React tag."""
@@ -65,25 +85,10 @@ class Tag:
         Yields:
         Yields:
             Tuple[str, Any]: The field name and value.
             Tuple[str, Any]: The field name and value.
         """
         """
-        from reflex.components.component import BaseComponent
-
         for field in dataclasses.fields(self):
         for field in dataclasses.fields(self):
-            value = getattr(self, field.name)
-            if isinstance(value, list):
-                children = []
-                for child in value:
-                    if isinstance(child, BaseComponent):
-                        children.append(child.render())
-                    else:
-                        children.append(child)
-                yield field.name, children
-                continue
-            if isinstance(value, BaseComponent):
-                yield field.name, value.render()
-                continue
-            if callable(value) and not isinstance(value, Var):
-                continue
-            yield field.name, getattr(self, field.name)
+            rendered_value = render_prop(getattr(self, field.name))
+            if rendered_value is not None:
+                yield field.name, rendered_value
 
 
     def add_props(self, **kwargs: Optional[Any]) -> Tag:
     def add_props(self, **kwargs: Optional[Any]) -> Tag:
         """Add props to the tag.
         """Add props to the tag.

+ 6 - 6
tests/units/components/core/test_match.py

@@ -42,7 +42,7 @@ def test_match_components():
 
 
     assert match_cases[0][0]._js_expr == "1"
     assert match_cases[0][0]._js_expr == "1"
     assert match_cases[0][0]._var_type is int
     assert match_cases[0][0]._var_type is int
-    first_return_value_render = match_cases[0][1].render()
+    first_return_value_render = match_cases[0][1]
     assert first_return_value_render["name"] == "RadixThemesText"
     assert first_return_value_render["name"] == "RadixThemesText"
     assert first_return_value_render["children"][0]["contents"] == '{"first value"}'
     assert first_return_value_render["children"][0]["contents"] == '{"first value"}'
 
 
@@ -50,31 +50,31 @@ def test_match_components():
     assert match_cases[1][0]._var_type is int
     assert match_cases[1][0]._var_type is int
     assert match_cases[1][1]._js_expr == "3"
     assert match_cases[1][1]._js_expr == "3"
     assert match_cases[1][1]._var_type is int
     assert match_cases[1][1]._var_type is int
-    second_return_value_render = match_cases[1][2].render()
+    second_return_value_render = match_cases[1][2]
     assert second_return_value_render["name"] == "RadixThemesText"
     assert second_return_value_render["name"] == "RadixThemesText"
     assert second_return_value_render["children"][0]["contents"] == '{"second value"}'
     assert second_return_value_render["children"][0]["contents"] == '{"second value"}'
 
 
     assert match_cases[2][0]._js_expr == "[1, 2]"
     assert match_cases[2][0]._js_expr == "[1, 2]"
     assert match_cases[2][0]._var_type == List[int]
     assert match_cases[2][0]._var_type == List[int]
-    third_return_value_render = match_cases[2][1].render()
+    third_return_value_render = match_cases[2][1]
     assert third_return_value_render["name"] == "RadixThemesText"
     assert third_return_value_render["name"] == "RadixThemesText"
     assert third_return_value_render["children"][0]["contents"] == '{"third value"}'
     assert third_return_value_render["children"][0]["contents"] == '{"third value"}'
 
 
     assert match_cases[3][0]._js_expr == '"random"'
     assert match_cases[3][0]._js_expr == '"random"'
     assert match_cases[3][0]._var_type is str
     assert match_cases[3][0]._var_type is str
-    fourth_return_value_render = match_cases[3][1].render()
+    fourth_return_value_render = match_cases[3][1]
     assert fourth_return_value_render["name"] == "RadixThemesText"
     assert fourth_return_value_render["name"] == "RadixThemesText"
     assert fourth_return_value_render["children"][0]["contents"] == '{"fourth value"}'
     assert fourth_return_value_render["children"][0]["contents"] == '{"fourth value"}'
 
 
     assert match_cases[4][0]._js_expr == '({ ["foo"] : "bar" })'
     assert match_cases[4][0]._js_expr == '({ ["foo"] : "bar" })'
     assert match_cases[4][0]._var_type == Mapping[str, str]
     assert match_cases[4][0]._var_type == Mapping[str, str]
-    fifth_return_value_render = match_cases[4][1].render()
+    fifth_return_value_render = match_cases[4][1]
     assert fifth_return_value_render["name"] == "RadixThemesText"
     assert fifth_return_value_render["name"] == "RadixThemesText"
     assert fifth_return_value_render["children"][0]["contents"] == '{"fifth value"}'
     assert fifth_return_value_render["children"][0]["contents"] == '{"fifth value"}'
 
 
     assert match_cases[5][0]._js_expr == f"({MatchState.get_name()}.num + 1)"
     assert match_cases[5][0]._js_expr == f"({MatchState.get_name()}.num + 1)"
     assert match_cases[5][0]._var_type is int
     assert match_cases[5][0]._var_type is int
-    fifth_return_value_render = match_cases[5][1].render()
+    fifth_return_value_render = match_cases[5][1]
     assert fifth_return_value_render["name"] == "RadixThemesText"
     assert fifth_return_value_render["name"] == "RadixThemesText"
     assert fifth_return_value_render["children"][0]["contents"] == '{"sixth value"}'
     assert fifth_return_value_render["children"][0]["contents"] == '{"sixth value"}'