Skip to content

Commit

Permalink
Redo dict (#83)
Browse files Browse the repository at this point in the history
* Work on remastering dict

* Dict v2

* Improved dictv2 rendering.

* Progress

* Minor fix

* More fixes

* white space

* Fix merge

* Fix indentation

* Fix render list

* Added more customization

* Replaced old dict impl

* Made it possible to specify border classes

* Removed reference to js

* Removed unused button
  • Loading branch information
Declow authored Jan 5, 2025
1 parent 60608e3 commit b46e09a
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 48 deletions.
16 changes: 13 additions & 3 deletions examples/dict_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

def create_nav():
with ui.nav():
ui.button("this is from a method")
ui.themeSelector()


Expand All @@ -18,18 +17,29 @@ async def test():
json_data = {
"name": "John Doe",
"age": 50,
"address": {"street": "123 Main St", "city": "Anytown", "country": "USA"},
"address": {
"street": "123 Main St",
"city": "Anytown",
"country": "USA",
"more": {"obj": "nesting"},
},
"hobbies": ["reading", "swimming", "coding"],
"family": {
"spouse": "Jane Doe",
"children": [
{"name": "Billy", "age": 20, "children": [{"name": "test", "age": 1}]},
{
"name": "Billy",
"age": 20,
"children": [{"name": "test", "age": 1}],
},
{"name": "Sally", "age": 18},
],
},
}
ui.dict(json_data)

ui.dict([json_data, {"name": "Jane Doe", "age": 40}]).border_classes("")


if __name__ == "__main__":
uvicorn.run("dict_example:app", reload=True)
43 changes: 0 additions & 43 deletions uiwiz/elements/dict.py

This file was deleted.

103 changes: 103 additions & 0 deletions uiwiz/elements/dict/dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import numbers
from pathlib import Path
from typing import Iterable, Union

from uiwiz.element import Element


class Dict(Element):
def __init__(self, data: Union[Iterable[dict], dict]) -> None:
if not data:
raise ValueError("Data cannot be None or empty")
if not isinstance(data, (Iterable, dict)):
raise ValueError("Data not of type list or dict")
super().__init__()
self.data = data
self.did_render = False
self.key_class = ""
self.value_class = "text-primary"
self._border_classes = "border border-base-content rounded-lg shadow-lg w-96 shadow-md w-full mb-5"

def key_classes(self, classes):
self.key_class = classes
return self

def value_classes(self, classes):
self.value_class = classes
return self

def border_classes(self, classes: str):
self._border_classes = classes
return self

def before_render(self):
super().before_render()
if not self.did_render:
self.did_render = True
self.generate(self.data)

def generate(self, data):
def format_data(
data: Union[dict, list],
depth: int = 0,
is_last_item: bool = False,
do_indent: bool = False,
obj: bool = False,
):
indent = " " * depth

if isinstance(data, list):
last_item = data[-1]
Element("pre", content=indent + "[")
for item in data:
is_last = item == last_item
with Element().classes("flex flex-col flex-wrap"):
format_data(item, depth=depth + 2, is_last_item=is_last, do_indent=True)
Element("pre", content=indent + "]")
return
if isinstance(data, dict):
last_item = list(data.values())[-1]
is_last = data == last_item

if not obj:
Element("pre", content=indent + "{")
format_data(data, depth=depth + 2, is_last_item=is_last, obj=True)
else:
for key, value in data.items():
is_last = last_item == value
key_content = indent + f'"{key}"' + ":"
if isinstance(value, list):
key_content += " ["
with Element(tag="pre", content=key_content).classes("flex flex-col flex-wrap"):
for _item in value:
format_data(_item, depth=depth + 2, is_last_item=_item == value[-1], do_indent=True)
Element(tag="pre", content=indent + "]" + ("," if not is_last else ""))
elif isinstance(value, dict):
key_content += " {"
with Element(tag="pre", content=key_content).classes("flex flex-col flex-wrap"):
format_data(value, depth=depth + 2, is_last_item=is_last, obj=True)
Element(tag="pre", content=indent + "}" + ("," if not is_last else ""))
else:
with Element(tag="pre", content=key_content).classes("flex flex-row flex-wrap gap-2"):
format_data(value, depth=depth + 2, is_last_item=is_last)
if not obj:
Element("pre", content=indent + "}" + ("," if not is_last_item else ""))

return

if isinstance(data, str):
with Element().classes("flex flex-row"):
if do_indent:
Element(tag="pre", content=indent)
Element(content=f'"{data}"').classes(self.value_class)
Element(content="," if not is_last_item else "")

if isinstance(data, numbers.Number):
with Element().classes("flex flex-row"):
if do_indent:
Element(tag="pre", content=indent)
Element(content=str(data)).classes(self.value_class)
Element(tag="div", content="," if not is_last_item else "")

with self.classes(self._border_classes):
format_data(data, is_last_item=True)
2 changes: 1 addition & 1 deletion uiwiz/page_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ async def decorated(*dec_args, **dec_kwargs) -> Response:

if not route_exists(path):
register_path(path, decorated)

_router = router or self

return _router.post(path, include_in_schema=False, **kwargs)(decorated)
Expand Down
2 changes: 1 addition & 1 deletion uiwiz/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from uiwiz.elements.code import Code as code
from uiwiz.elements.col import Col as col
from uiwiz.elements.datepicker import Datepicker as datepicker
from uiwiz.elements.dict import Dict as dict
from uiwiz.elements.dict.dict import Dict as dict
from uiwiz.elements.divider import Divider as divider
from uiwiz.elements.drawer import Drawer as drawer
from uiwiz.elements.dropdown import Dropdown as dropdown
Expand Down

0 comments on commit b46e09a

Please sign in to comment.