fix tag render to be recursive (#4714)

This commit is contained in:
Khaleel Al-Adhami 2025-01-29 12:16:54 -08:00 committed by GitHub
parent 1e8e82ec0e
commit 2c3257d4ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 33 additions and 28 deletions

View File

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

View File

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

View File

@ -3,13 +3,33 @@
from __future__ import annotations
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.utils import format, types
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()
class Tag:
"""A React tag."""
@ -65,25 +85,10 @@ class Tag:
Yields:
Tuple[str, Any]: The field name and value.
"""
from reflex.components.component import BaseComponent
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:
"""Add props to the tag.

View File

@ -42,7 +42,7 @@ def test_match_components():
assert match_cases[0][0]._js_expr == "1"
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["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][1]._js_expr == "3"
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["children"][0]["contents"] == '{"second value"}'
assert match_cases[2][0]._js_expr == "[1, 2]"
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["children"][0]["contents"] == '{"third value"}'
assert match_cases[3][0]._js_expr == '"random"'
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["children"][0]["contents"] == '{"fourth value"}'
assert match_cases[4][0]._js_expr == '({ ["foo"] : "bar" })'
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["children"][0]["contents"] == '{"fifth value"}'
assert match_cases[5][0]._js_expr == f"({MatchState.get_name()}.num + 1)"
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["children"][0]["contents"] == '{"sixth value"}'