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

Add json-tree example app #281

Merged
merged 3 commits into from
Dec 3, 2024
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
13 changes: 13 additions & 0 deletions json-tree/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# json-tree

This example demonstrates "dynamic components", wherein a component is created
and stored in a State var or returned from a computed var. Dynamic components can be
constructed imperatively from complex data without having to
use `rx.cond` or `rx.foreach` as is required for normal UI components.

Although dynamic components can be less performant and affect SEO, they are more
flexible when rendering nested data and allow components to be constructed using
regular python code.

To use the example app, paste in valid JSON and see the structure of the JSON
displayed as a nested `rx.data_list`.
Binary file added json-tree/assets/favicon.ico
Binary file not shown.
Empty file added json-tree/json_tree/__init__.py
Empty file.
67 changes: 67 additions & 0 deletions json-tree/json_tree/json_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Render nested JSON data as a tree using `rx.data_list`"""

import json

import reflex as rx


class State(rx.State):
_json: str = ""
info: rx.Component = rx.text("Paste JSON data")

@rx.var(cache=True)
def comp_json_view(self) -> rx.Component:
if not self._json:
return rx.text("No JSON data")
try:
obj = json.loads(self._json)
except json.JSONDecodeError as e:
return rx.text(f"Invalid JSON: {e}")

def make_json(node) -> rx.Component:
children = []
if isinstance(node, dict):
for key, value in node.items():
children.append(
rx.data_list.item(
rx.data_list.label(key),
rx.data_list.value(make_json(value)),
),
)
return rx.data_list.root(*children, margin_bottom="1rem")
if isinstance(node, list):
for item in node:
children.append(rx.list_item(make_json(item)))
return rx.unordered_list(*children)
return rx.text(str(node))

return make_json(obj)

@rx.event
def handle_paste_json(self, data: list[tuple[str, str]]):
self.info = rx.spinner()
yield
for mime_type, raw in data:
if mime_type == "text/plain":
try:
json.loads(raw)
self._json = raw
self.info = rx.text(f"Loaded {len(raw)} bytes of JSON data.")
except json.JSONDecodeError:
self._json = ""
break


def index() -> rx.Component:
return rx.fragment(
rx.vstack(
State.info,
State.comp_json_view,
padding_x="10px",
),
rx.clipboard(on_paste=State.handle_paste_json),
)


app = rx.App()
app.add_page(index)
1 change: 1 addition & 0 deletions json-tree/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
reflex>=0.6.5
5 changes: 5 additions & 0 deletions json-tree/rxconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import reflex as rx

config = rx.Config(
app_name="json_tree",
)
Loading