Skip to content

Commit 3a0d107

Browse files
committed
Thinking in React
1 parent 067279f commit 3a0d107

File tree

5 files changed

+221
-173
lines changed

5 files changed

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

0 commit comments

Comments
 (0)