Skip to content

Commit 6773c85

Browse files
authored
Even better docs styling (+ new homepage) (#180)
1 parent 82c80c3 commit 6773c85

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2381
-1298
lines changed

Diff for: CHANGELOG.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Using the following categories, list your changes in this order:
5656
### Changed
5757

5858
- Bumped the minimum ReactPy version to `1.0.2`.
59-
- Prettier websocket URLs for components that do not have sessions.
59+
- Prettier WebSocket URLs for components that do not have sessions.
6060
- Template tag will now only validate `args`/`kwargs` if `settings.py:DEBUG` is enabled.
6161
- Bumped the minimum `@reactpy/client` version to `0.3.1`
6262
- Bumped the minimum Django version to `4.2`.
@@ -79,7 +79,7 @@ Using the following categories, list your changes in this order:
7979

8080
### Changed
8181

82-
- ReactPy will now provide a warning if your HTTP URLs are not on the same prefix as your websockets.
82+
- ReactPy will now provide a warning if your HTTP URLs are not on the same prefix as your WebSockets.
8383
- Cleaner logging output for auto-detected ReactPy root components.
8484

8585
### Deprecated
@@ -91,14 +91,14 @@ Using the following categories, list your changes in this order:
9191

9292
- Warning W007 (`REACTPY_WEBSOCKET_URL doesn't end with a slash`) has been removed. ReactPy now automatically handles slashes.
9393
- Warning W008 (`REACTPY_WEBSOCKET_URL doesn't start with an alphanumeric character`) has been removed. ReactPy now automatically handles this scenario.
94-
- Error E009 (`channels is not in settings.py:INSTALLED_APPS`) has been removed. Newer versions of `channels` do not require installation via `INSTALLED_APPS` to receive an ASGI webserver.
94+
- Error E009 (`channels is not in settings.py:INSTALLED_APPS`) has been removed. Newer versions of `channels` do not require installation via `INSTALLED_APPS` to receive an ASGI web server.
9595

9696
## [3.3.2] - 2023-08-13
9797

9898
### Added
9999

100-
- ReactPy Websocket will now decode messages via `orjson` resulting in an ~6% overall performance improvement.
101-
- Built-in `asyncio` event loops are now patched via `nest_asyncio`, resulting in an ~10% overall performance improvement. This has no performance impact if you are running your webserver with `uvloop`.
100+
- ReactPy WebSocket will now decode messages via `orjson` resulting in an ~6% overall performance improvement.
101+
- Built-in `asyncio` event loops are now patched via `nest_asyncio`, resulting in an ~10% overall performance improvement. This has no performance impact if you are running your web server with `uvloop`.
102102

103103
### Fixed
104104

Diff for: README.md

-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ def hello_world(recipient: str):
8181

8282
In your **Django app**'s HTML template, you can now embed your ReactPy component using the `component` template tag. Within this tag, you will need to type in the dotted path to the component.
8383

84-
<!--html-header-end-->
85-
8684
Additionally, you can pass in `args` and `kwargs` into your component function. After reading the code below, pay attention to how the function definition for `hello_world` (_from the previous example_) accepts a `recipient` argument.
8785

8886
<!--html-code-start-->

Diff for: docs/includes/orm.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<!--orm-excp-start-->
22

3-
Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a `SynchronousOnlyOperation` exception.
3+
Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a `#!python SynchronousOnlyOperation` exception.
44

5-
These `SynchronousOnlyOperation` exceptions may be resolved in a future version of Django containing an asynchronous ORM. However, it is best practice to always perform ORM calls in the background via hooks.
5+
These `#!python SynchronousOnlyOperation` exceptions may be resolved in a future version of Django containing an asynchronous ORM. However, it is best practice to always perform ORM calls in the background via hooks.
66

77
<!--orm-excp-end-->
88

99
<!--orm-fetch-start-->
1010

11-
By default, automatic recursive fetching of `ManyToMany` or `ForeignKey` fields is enabled within the default `QueryOptions.postprocessor`. This is needed to prevent `SynchronousOnlyOperation` exceptions when accessing these fields within your ReactPy components.
11+
By default, automatic recursive fetching of `#!python ManyToMany` or `#!python ForeignKey` fields is enabled within the default `#!python QueryOptions.postprocessor`. This is needed to prevent `#!python SynchronousOnlyOperation` exceptions when accessing these fields within your ReactPy components.
1212

1313
<!--orm-fetch-end-->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<div class="demo pop-right">
2+
<div class="white-bg">
3+
4+
<div class="browser-navbar">
5+
<div class="browser-nav-url">
6+
<svg class="text-tertiary me-1 opacity-60" width="12" height="12" viewBox="0 0 44 44" fill="none"
7+
xmlns="http://www.w3.org/2000/svg">
8+
<path fill-rule="evenodd" clip-rule="evenodd"
9+
d="M22 4C17.0294 4 13 8.0294 13 13V16H12.3103C10.5296 16 8.8601 16.8343 8.2855 18.5198C7.6489 20.387 7 23.4148 7 28C7 32.5852 7.6489 35.613 8.2855 37.4802C8.8601 39.1657 10.5296 40 12.3102 40H31.6897C33.4704 40 35.1399 39.1657 35.7145 37.4802C36.3511 35.613 37 32.5852 37 28C37 23.4148 36.3511 20.387 35.7145 18.5198C35.1399 16.8343 33.4704 16 31.6897 16H31V13C31 8.0294 26.9706 4 22 4ZM25 16V13C25 11.3431 23.6569 10 22 10C20.3431 10 19 11.3431 19 13V16H25Z"
10+
fill="currentColor"></path>
11+
</svg>
12+
example.com/videos.html
13+
</div>
14+
</div>
15+
16+
<div class="browser-viewport">
17+
<div class="search-header">
18+
<h1>Searchable Videos</h1>
19+
<p>Type a search query below.</p>
20+
<div class="search-bar">
21+
<svg width="1em" height="1em" viewBox="0 0 20 20" class="text-gray-30 w-4">
22+
<path
23+
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
24+
stroke="currentColor" fill="none" stroke-width="2" fill-rule="evenodd"
25+
stroke-linecap="round" stroke-linejoin="round"></path>
26+
</svg>
27+
<input type="text" placeholder="Search">
28+
</div>
29+
</div>
30+
31+
<h2>5 Videos</h2>
32+
33+
<div class="vid-row">
34+
<div class="vid-thumbnail">
35+
<svg width="36" height="36" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
36+
<path fill-rule="evenodd" clip-rule="evenodd"
37+
d="M36 69C54.2254 69 69 54.2254 69 36C69 17.7746 54.2254 3 36 3C17.7746 3 3 17.7746 3 36C3 54.2254 17.7746 69 36 69ZM52.1716 38.6337L28.4366 51.5801C26.4374 52.6705 24 51.2235 24 48.9464V23.0536C24 20.7764 26.4374 19.3295 28.4366 20.4199L52.1716 33.3663C54.2562 34.5034 54.2562 37.4966 52.1716 38.6337Z"
38+
fill="rgb(123 123 123 / 50%)"></path>
39+
</svg>
40+
</div>
41+
<div class="vid-text">
42+
<h3>ReactPy: The Documentary</h3>
43+
<p>From web library to taco delivery service</p>
44+
</div>
45+
<button class="like-btn">
46+
<svg width="34" height="34" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
47+
<path
48+
d="m12 5.184-.808-.771-.004-.004C11.065 4.299 8.522 2.003 6 2.003c-3.736 0-6 2.558-6 6.677 0 4.47 5.471 9.848 10 13.079.602.43 1.187.82 1.74 1.167A.497.497 0 0 0 12 23v-.003c.09 0 .182-.026.26-.074C16.977 19.97 24 13.737 24 8.677 24 4.557 21.743 2 18 2c-2.569 0-5.166 2.387-5.192 2.413L12 5.184zm-.002 15.525c2.071-1.388 4.477-3.342 6.427-5.47C20.72 12.733 22 10.401 22 8.677c0-1.708-.466-2.855-1.087-3.55C20.316 4.459 19.392 4 18 4c-.726 0-1.63.364-2.5.9-.67.412-1.148.82-1.266.92-.03.025-.037.031-.019.014l-.013.013L12 7.949 9.832 5.88a10.08 10.08 0 0 0-1.33-.977C7.633 4.367 6.728 4.003 6 4.003c-1.388 0-2.312.459-2.91 1.128C2.466 5.826 2 6.974 2 8.68c0 1.726 1.28 4.058 3.575 6.563 1.948 2.127 4.352 4.078 6.423 5.466z"
49+
fill="black" fill-rule="evenodd" clip-rule="evenodd" onclick="t"></path>
50+
</svg>
51+
</button>
52+
</div>
53+
54+
<div class="vid-row">
55+
<div class="vid-thumbnail">
56+
<svg width="36" height="36" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
57+
<path fill-rule="evenodd" clip-rule="evenodd"
58+
d="M36 69C54.2254 69 69 54.2254 69 36C69 17.7746 54.2254 3 36 3C17.7746 3 3 17.7746 3 36C3 54.2254 17.7746 69 36 69ZM52.1716 38.6337L28.4366 51.5801C26.4374 52.6705 24 51.2235 24 48.9464V23.0536C24 20.7764 26.4374 19.3295 28.4366 20.4199L52.1716 33.3663C54.2562 34.5034 54.2562 37.4966 52.1716 38.6337Z"
59+
fill="rgb(123 123 123 / 50%)"></path>
60+
</svg>
61+
</div>
62+
<div class="vid-text">
63+
<h3>Code using Worst Practices</h3>
64+
<p>Harriet Potter (2013)</p>
65+
</div>
66+
<button class="like-btn">
67+
<svg width="34" height="34" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
68+
<path
69+
d="m12 5.184-.808-.771-.004-.004C11.065 4.299 8.522 2.003 6 2.003c-3.736 0-6 2.558-6 6.677 0 4.47 5.471 9.848 10 13.079.602.43 1.187.82 1.74 1.167A.497.497 0 0 0 12 23v-.003c.09 0 .182-.026.26-.074C16.977 19.97 24 13.737 24 8.677 24 4.557 21.743 2 18 2c-2.569 0-5.166 2.387-5.192 2.413L12 5.184zm-.002 15.525c2.071-1.388 4.477-3.342 6.427-5.47C20.72 12.733 22 10.401 22 8.677c0-1.708-.466-2.855-1.087-3.55C20.316 4.459 19.392 4 18 4c-.726 0-1.63.364-2.5.9-.67.412-1.148.82-1.266.92-.03.025-.037.031-.019.014l-.013.013L12 7.949 9.832 5.88a10.08 10.08 0 0 0-1.33-.977C7.633 4.367 6.728 4.003 6 4.003c-1.388 0-2.312.459-2.91 1.128C2.466 5.826 2 6.974 2 8.68c0 1.726 1.28 4.058 3.575 6.563 1.948 2.127 4.352 4.078 6.423 5.466z"
70+
fill="black" fill-rule="evenodd" clip-rule="evenodd" onclick="t"></path>
71+
</svg>
72+
</button>
73+
</div>
74+
75+
<div class="vid-row">
76+
<div class="vid-thumbnail">
77+
<svg width="36" height="36" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
78+
<path fill-rule="evenodd" clip-rule="evenodd"
79+
d="M36 69C54.2254 69 69 54.2254 69 36C69 17.7746 54.2254 3 36 3C17.7746 3 3 17.7746 3 36C3 54.2254 17.7746 69 36 69ZM52.1716 38.6337L28.4366 51.5801C26.4374 52.6705 24 51.2235 24 48.9464V23.0536C24 20.7764 26.4374 19.3295 28.4366 20.4199L52.1716 33.3663C54.2562 34.5034 54.2562 37.4966 52.1716 38.6337Z"
80+
fill="rgb(123 123 123 / 50%)"></path>
81+
</svg>
82+
</div>
83+
<div class="vid-text">
84+
<h3>Introducing ReactPy Foriegn</h3>
85+
<p>Tim Cooker (2015)</p>
86+
</div>
87+
<button class="like-btn">
88+
<svg width="34" height="34" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
89+
<path
90+
d="m12 5.184-.808-.771-.004-.004C11.065 4.299 8.522 2.003 6 2.003c-3.736 0-6 2.558-6 6.677 0 4.47 5.471 9.848 10 13.079.602.43 1.187.82 1.74 1.167A.497.497 0 0 0 12 23v-.003c.09 0 .182-.026.26-.074C16.977 19.97 24 13.737 24 8.677 24 4.557 21.743 2 18 2c-2.569 0-5.166 2.387-5.192 2.413L12 5.184zm-.002 15.525c2.071-1.388 4.477-3.342 6.427-5.47C20.72 12.733 22 10.401 22 8.677c0-1.708-.466-2.855-1.087-3.55C20.316 4.459 19.392 4 18 4c-.726 0-1.63.364-2.5.9-.67.412-1.148.82-1.266.92-.03.025-.037.031-.019.014l-.013.013L12 7.949 9.832 5.88a10.08 10.08 0 0 0-1.33-.977C7.633 4.367 6.728 4.003 6 4.003c-1.388 0-2.312.459-2.91 1.128C2.466 5.826 2 6.974 2 8.68c0 1.726 1.28 4.058 3.575 6.563 1.948 2.127 4.352 4.078 6.423 5.466z"
91+
fill="black" fill-rule="evenodd" clip-rule="evenodd" onclick="t"></path>
92+
</svg>
93+
</button>
94+
</div>
95+
96+
<div class="vid-row">
97+
<div class="vid-thumbnail">
98+
<svg width="36" height="36" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
99+
<path fill-rule="evenodd" clip-rule="evenodd"
100+
d="M36 69C54.2254 69 69 54.2254 69 36C69 17.7746 54.2254 3 36 3C17.7746 3 3 17.7746 3 36C3 54.2254 17.7746 69 36 69ZM52.1716 38.6337L28.4366 51.5801C26.4374 52.6705 24 51.2235 24 48.9464V23.0536C24 20.7764 26.4374 19.3295 28.4366 20.4199L52.1716 33.3663C54.2562 34.5034 54.2562 37.4966 52.1716 38.6337Z"
101+
fill="rgb(123 123 123 / 50%)"></path>
102+
</svg>
103+
</div>
104+
<div class="vid-text">
105+
<h3>Introducing ReactPy Cooks</h3>
106+
<p>Soap Boat and Dinosaur Dan (2018)</p>
107+
</div>
108+
<button class="like-btn">
109+
<svg width="34" height="34" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
110+
<path
111+
d="m12 5.184-.808-.771-.004-.004C11.065 4.299 8.522 2.003 6 2.003c-3.736 0-6 2.558-6 6.677 0 4.47 5.471 9.848 10 13.079.602.43 1.187.82 1.74 1.167A.497.497 0 0 0 12 23v-.003c.09 0 .182-.026.26-.074C16.977 19.97 24 13.737 24 8.677 24 4.557 21.743 2 18 2c-2.569 0-5.166 2.387-5.192 2.413L12 5.184zm-.002 15.525c2.071-1.388 4.477-3.342 6.427-5.47C20.72 12.733 22 10.401 22 8.677c0-1.708-.466-2.855-1.087-3.55C20.316 4.459 19.392 4 18 4c-.726 0-1.63.364-2.5.9-.67.412-1.148.82-1.266.92-.03.025-.037.031-.019.014l-.013.013L12 7.949 9.832 5.88a10.08 10.08 0 0 0-1.33-.977C7.633 4.367 6.728 4.003 6 4.003c-1.388 0-2.312.459-2.91 1.128C2.466 5.826 2 6.974 2 8.68c0 1.726 1.28 4.058 3.575 6.563 1.948 2.127 4.352 4.078 6.423 5.466z"
112+
fill="black" fill-rule="evenodd" clip-rule="evenodd" onclick="t"></path>
113+
</svg>
114+
</button>
115+
</div>
116+
117+
<div class="vid-row">
118+
<div class="vid-thumbnail">
119+
<svg width="36" height="36" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
120+
<path fill-rule="evenodd" clip-rule="evenodd"
121+
d="M36 69C54.2254 69 69 54.2254 69 36C69 17.7746 54.2254 3 36 3C17.7746 3 3 17.7746 3 36C3 54.2254 17.7746 69 36 69ZM52.1716 38.6337L28.4366 51.5801C26.4374 52.6705 24 51.2235 24 48.9464V23.0536C24 20.7764 26.4374 19.3295 28.4366 20.4199L52.1716 33.3663C54.2562 34.5034 54.2562 37.4966 52.1716 38.6337Z"
122+
fill="rgb(123 123 123 / 50%)"></path>
123+
</svg>
124+
</div>
125+
<div class="vid-text">
126+
<h3>Introducing Quantum Components</h3>
127+
<p>Isaac Asimov and Lauren-kun (2020)</p>
128+
</div>
129+
<button class="like-btn">
130+
<svg width="34" height="34" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
131+
<path
132+
d="m12 5.184-.808-.771-.004-.004C11.065 4.299 8.522 2.003 6 2.003c-3.736 0-6 2.558-6 6.677 0 4.47 5.471 9.848 10 13.079.602.43 1.187.82 1.74 1.167A.497.497 0 0 0 12 23v-.003c.09 0 .182-.026.26-.074C16.977 19.97 24 13.737 24 8.677 24 4.557 21.743 2 18 2c-2.569 0-5.166 2.387-5.192 2.413L12 5.184zm-.002 15.525c2.071-1.388 4.477-3.342 6.427-5.47C20.72 12.733 22 10.401 22 8.677c0-1.708-.466-2.855-1.087-3.55C20.316 4.459 19.392 4 18 4c-.726 0-1.63.364-2.5.9-.67.412-1.148.82-1.266.92-.03.025-.037.031-.019.014l-.013.013L12 7.949 9.832 5.88a10.08 10.08 0 0 0-1.33-.977C7.633 4.367 6.728 4.003 6 4.003c-1.388 0-2.312.459-2.91 1.128C2.466 5.826 2 6.974 2 8.68c0 1.726 1.28 4.058 3.575 6.563 1.948 2.127 4.352 4.078 6.423 5.466z"
133+
fill="black" fill-rule="evenodd" clip-rule="evenodd" onclick="t"></path>
134+
</svg>
135+
</button>
136+
</div>
137+
</div>
138+
139+
<script>
140+
document
141+
.querySelector(".search-bar input")
142+
.addEventListener("keyup", function () {
143+
let titles = document.querySelectorAll(".browser-viewport .vid-text");
144+
let search = this.value.toLowerCase();
145+
let numVids = 0;
146+
for (let i = 0; i < titles.length; i++) {
147+
let title =
148+
titles[i].querySelector("h3").innerText.toLowerCase() +
149+
titles[i].querySelector("p").innerText.toLowerCase();
150+
if (search.length == 0) {
151+
titles[i].parentElement.style.display = "";
152+
numVids++;
153+
} else if (title.indexOf(search) > -1) {
154+
titles[i].parentElement.style.display = "";
155+
numVids++;
156+
} else {
157+
titles[i].parentElement.style.display = "none";
158+
}
159+
}
160+
document.querySelector(".browser-viewport h2").innerText =
161+
numVids + " Videos";
162+
});
163+
</script>
164+
</div>
165+
</div>
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from reactpy import component, html, use_state
2+
3+
4+
def filter_videos(videos, search_text):
5+
return None
6+
7+
8+
def search_input(dictionary, value):
9+
return None
10+
11+
12+
def video_list(videos, empty_heading):
13+
return None
14+
15+
16+
@component
17+
def searchable_video_list(videos):
18+
search_text, set_search_text = use_state("")
19+
found_videos = filter_videos(videos, search_text)
20+
21+
return html._(
22+
search_input(
23+
{"on_change": lambda new_text: set_search_text(new_text)},
24+
value=search_text,
25+
),
26+
video_list(
27+
videos=found_videos,
28+
empty_heading=f"No matches for “{search_text}”",
29+
),
30+
)

Diff for: docs/overrides/home-code-examples/code-block.html

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div class="tabbed-set tabbed-alternate {{ class }}">
2+
<input checked="checked" type="radio" />
3+
<div class="tabbed-labels"><label>app.py</label></div>
4+
<div class="tabbed-content">
5+
<img src="assets/img/{{ image }}">
6+
</div>
7+
</div>

0 commit comments

Comments
 (0)