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] %} {% 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:

View File

@ -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,
) )

View File

@ -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) rendered_value = render_prop(getattr(self, field.name))
if isinstance(value, list): if rendered_value is not None:
children = [] yield field.name, rendered_value
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)
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.

View File

@ -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"}'