Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format component as React string #1848

Merged
merged 3 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions reflex/.templates/jinja/web/pages/component.js.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{% import 'web/pages/utils.js.jinja2' as utils %}
{{utils.render(component.render())}}
12 changes: 12 additions & 0 deletions reflex/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,18 @@ def _compile_root_stylesheet(stylesheets: List[str]) -> str:
return templates.STYLE.render(stylesheets=sheets)


def _compile_component(component: Component) -> str:
"""Compile a single component.

Args:
component: The component to compile.

Returns:
The compiled component.
"""
return templates.COMPONENT.render(component=component)


def _compile_components(components: Set[CustomComponent]) -> str:
"""Compile the components.

Expand Down
3 changes: 3 additions & 0 deletions reflex/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def get_template(name: str) -> Template:
# Template for Tailwind config.
TAILWIND_CONFIG = get_template("web/tailwind.config.js.jinja2")

# Template to render a component tag.
COMPONENT = get_template("web/pages/component.js.jinja2")

# Code to render a single NextJS page.
PAGE = get_template("web/pages/index.js.jinja2")

Expand Down
4 changes: 3 additions & 1 deletion reflex/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,9 @@ def __str__(self) -> str:
Returns:
The code to render the component.
"""
return format.json_dumps(self.render())
from reflex.compiler.compiler import _compile_component

return _compile_component(self)

def _render(self) -> Tag:
"""Define how to render the component in React.
Expand Down
20 changes: 20 additions & 0 deletions tests/components/test_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,3 +534,23 @@ def test_component_with_only_valid_children(fixture, request):
== f"The component `{component.__name__}` only allows the components: `Text` as children. "
f"Got `Box` instead."
)


@pytest.mark.parametrize(
"component,rendered",
[
(rx.text("hi"), "<Text>\n {`hi`}\n</Text>"),
(
rx.box(rx.heading("test", size="md")),
"<Box>\n <Heading size={`md`}>\n {`test`}\n</Heading>\n</Box>",
),
],
)
def test_format_component(component, rendered):
"""Test that a component is formatted correctly.

Args:
component: The component to format.
rendered: The expected rendered component.
"""
assert str(component) == rendered
Loading