-
-
Notifications
You must be signed in to change notification settings - Fork 321
/
Copy pathadd_inverse_data_flow.py
121 lines (99 loc) · 3.19 KB
/
add_inverse_data_flow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from reactpy import component, html, use_state
# start
@component
def filterable_product_table(products):
filter_text, set_filter_text = use_state("")
in_stock_only, set_in_stock_only = use_state(False)
return html.div(
search_bar(
filter_text=filter_text,
in_stock_only=in_stock_only,
set_filter_text=set_filter_text,
set_in_stock_only=set_in_stock_only,
),
product_table(
products=products, filter_text=filter_text, in_stock_only=in_stock_only
),
)
@component
def product_category_row(category):
return html.tr(
html.th({"colspan": 2}, category),
)
@component
def product_row(product):
if product["stocked"]:
name = product["name"]
else:
name = html.span({"style": {"color": "red"}}, product["name"])
return html.tr(
html.td(name),
html.td(product["price"]),
)
@component
def product_table(products, filter_text, in_stock_only):
rows = []
last_category = None
for product in products:
if filter_text.lower() not in product["name"].lower():
continue
if in_stock_only and not product["stocked"]:
continue
if product["category"] != last_category:
rows.append(
product_category_row(product["category"], key=product["category"])
)
rows.append(product_row(product, key=product["name"]))
last_category = product["category"]
return html.table(
html.thead(
html.tr(
html.th("Name"),
html.th("Price"),
),
),
html.tbody(rows),
)
@component
def search_bar(filter_text, in_stock_only, set_filter_text, set_in_stock_only):
return html.form(
html.input(
{
"type": "text",
"value": filter_text,
"placeholder": "Search...",
"on_change": lambda event: set_filter_text(event["target"]["value"]),
}
),
html.label(
html.input(
{
"type": "checkbox",
"checked": in_stock_only,
"on_change": lambda event: set_in_stock_only(
event["target"]["checked"]
),
}
),
"Only show products in stock",
),
)
PRODUCTS = [
{"category": "Fruits", "price": "$1", "stocked": True, "name": "Apple"},
{"category": "Fruits", "price": "$1", "stocked": True, "name": "Dragonfruit"},
{"category": "Fruits", "price": "$2", "stocked": False, "name": "Passionfruit"},
{"category": "Vegetables", "price": "$2", "stocked": True, "name": "Spinach"},
{"category": "Vegetables", "price": "$4", "stocked": False, "name": "Pumpkin"},
{"category": "Vegetables", "price": "$1", "stocked": True, "name": "Peas"},
]
@component
def app():
return filterable_product_table(PRODUCTS)
# end
if __name__ == "__main__":
from reactpy import run
from reactpy.utils import _read_docs_css
@component
def styled_app():
return html._(html.style(_read_docs_css()), app())
run(styled_app)