|
24 | 24 | },
|
25 | 25 | {
|
26 | 26 | "cell_type": "code",
|
27 |
| - "execution_count": null, |
| 27 | + "execution_count": 1, |
28 | 28 | "metadata": {
|
29 | 29 | "tags": []
|
30 | 30 | },
|
31 |
| - "outputs": [], |
| 31 | + "outputs": [ |
| 32 | + { |
| 33 | + "data": { |
| 34 | + "application/vnd.jupyter.widget-view+json": { |
| 35 | + "model_id": "901546cd31e04580810d8358cbf46d72", |
| 36 | + "version_major": 2, |
| 37 | + "version_minor": 0 |
| 38 | + }, |
| 39 | + "text/plain": [ |
| 40 | + "LayoutWidget(Layout(ContextProvider(<function context at 0x7fb48b0a3600>)))" |
| 41 | + ] |
| 42 | + }, |
| 43 | + "execution_count": 1, |
| 44 | + "metadata": {}, |
| 45 | + "output_type": "execute_result" |
| 46 | + } |
| 47 | + ], |
32 | 48 | "source": [
|
33 | 49 | "from reactpy import component, html\n",
|
34 | 50 | "\n",
|
|
55 | 71 | },
|
56 | 72 | {
|
57 | 73 | "cell_type": "code",
|
58 |
| - "execution_count": null, |
| 74 | + "execution_count": 2, |
59 | 75 | "metadata": {
|
60 | 76 | "tags": []
|
61 | 77 | },
|
62 |
| - "outputs": [], |
| 78 | + "outputs": [ |
| 79 | + { |
| 80 | + "data": { |
| 81 | + "application/vnd.jupyter.widget-view+json": { |
| 82 | + "model_id": "ee078bce581341f7826d8578cc03f971", |
| 83 | + "version_major": 2, |
| 84 | + "version_minor": 0 |
| 85 | + }, |
| 86 | + "text/plain": [ |
| 87 | + "LayoutWidget(Layout(ContextProvider(<function context at 0x7fb48b0a3600>)))" |
| 88 | + ] |
| 89 | + }, |
| 90 | + "execution_count": 2, |
| 91 | + "metadata": {}, |
| 92 | + "output_type": "execute_result" |
| 93 | + } |
| 94 | + ], |
63 | 95 | "source": [
|
64 | 96 | "from reactpy import component, html\n",
|
65 | 97 | "\n",
|
|
109 | 141 | },
|
110 | 142 | {
|
111 | 143 | "cell_type": "code",
|
112 |
| - "execution_count": null, |
| 144 | + "execution_count": 3, |
113 | 145 | "metadata": {
|
114 | 146 | "tags": []
|
115 | 147 | },
|
116 |
| - "outputs": [], |
| 148 | + "outputs": [ |
| 149 | + { |
| 150 | + "data": { |
| 151 | + "application/vnd.jupyter.widget-view+json": { |
| 152 | + "model_id": "3e5123eaa6fe49fcb94f2527ec7665e8", |
| 153 | + "version_major": 2, |
| 154 | + "version_minor": 0 |
| 155 | + }, |
| 156 | + "text/plain": [ |
| 157 | + "LayoutWidget(Layout(ContextProvider(<function context at 0x7fb48b0a3600>)))" |
| 158 | + ] |
| 159 | + }, |
| 160 | + "execution_count": 3, |
| 161 | + "metadata": {}, |
| 162 | + "output_type": "execute_result" |
| 163 | + } |
| 164 | + ], |
117 | 165 | "source": [
|
118 | 166 | "import json\n",
|
119 | 167 | "from pathlib import Path\n",
|
|
164 | 212 | },
|
165 | 213 | {
|
166 | 214 | "cell_type": "code",
|
167 |
| - "execution_count": null, |
| 215 | + "execution_count": 4, |
168 | 216 | "metadata": {},
|
169 |
| - "outputs": [], |
| 217 | + "outputs": [ |
| 218 | + { |
| 219 | + "data": { |
| 220 | + "application/vnd.jupyter.widget-view+json": { |
| 221 | + "model_id": "cb6e7a22534d4db6b1c6b826689cf739", |
| 222 | + "version_major": 2, |
| 223 | + "version_minor": 0 |
| 224 | + }, |
| 225 | + "text/plain": [ |
| 226 | + "LayoutWidget(Layout(ContextProvider(<function context at 0x7fb48b0a3600>)))" |
| 227 | + ] |
| 228 | + }, |
| 229 | + "execution_count": 4, |
| 230 | + "metadata": {}, |
| 231 | + "output_type": "execute_result" |
| 232 | + } |
| 233 | + ], |
170 | 234 | "source": [
|
171 | 235 | "from reactpy_jupyter import from_widget\n",
|
172 | 236 | "from ipywidgets import IntSlider\n",
|
|
182 | 246 | "cell_type": "markdown",
|
183 | 247 | "metadata": {},
|
184 | 248 | "source": [
|
185 |
| - "Let's consider a ReactPy component that responds to and displays changes from an `ipywidgets.IntSlider`. The ReactPy component will need to accept an `IntSlider` instance as one of its arguments, convert it to a component with `from_widget`, declare state that will track the slider's value, and register a lister that will update that state via the slider's `IntSlider.observe()` method using an [\"effect\"](https://reactpy.dev/docs/reference/hooks-api.html#use-effect):" |
| 249 | + "Let's consider a ReactPy component that mirrors an `ipywidgets.IntSlider` - that is, it displays a slider that moves when the `IntSlider` does and when moved alters the `IntSlider`. To accomplish this, the ReactPy component will need to accept an `IntSlider` instance as one of its arguments, convert it to a component with `from_widget`, and access the attributes it expects to change or that need to be changed via a `use_trait` method on the converted widget:" |
186 | 250 | ]
|
187 | 251 | },
|
188 | 252 | {
|
189 | 253 | "cell_type": "code",
|
190 |
| - "execution_count": null, |
| 254 | + "execution_count": 10, |
191 | 255 | "metadata": {
|
192 | 256 | "tags": []
|
193 | 257 | },
|
194 | 258 | "outputs": [],
|
195 | 259 | "source": [
|
196 |
| - "from reactpy import use_effect\n", |
197 | 260 | "from reactpy_jupyter import from_widget\n",
|
198 | 261 | "\n",
|
199 | 262 | "\n",
|
200 | 263 | "@component\n",
|
201 |
| - "def SliderObserver(slider):\n", |
202 |
| - " slider_component = from_widget(slider)\n", |
203 |
| - " value, set_value = use_state(0)\n", |
204 |
| - "\n", |
205 |
| - " @use_effect\n", |
206 |
| - " def register_observer():\n", |
207 |
| - " def handle_change(change):\n", |
208 |
| - " set_value(change[\"new\"])\n", |
209 |
| - "\n", |
210 |
| - " # observe the slider's value\n", |
211 |
| - " slider.observe(handle_change, \"value\")\n", |
212 |
| - " # unobserve the slider's value if this component is no longer displayed\n", |
213 |
| - " return lambda: slider.unobserve(handle_change, \"value\")\n", |
214 |
| - "\n", |
| 264 | + "def MirrorSlider(slider_widget):\n", |
| 265 | + " slider_component = from_widget(slider_widget)\n", |
| 266 | + " value, set_value = slider_component.use_trait(\"value\")\n", |
215 | 267 | " return html.div(\n",
|
216 |
| - " slider_component, html.p(f\"ReactPy observes the value to be: \", value)\n", |
| 268 | + " html.h3(\"Jupyter Slider\"),\n", |
| 269 | + " # slider_component,\n", |
| 270 | + " html.h3(\"ReactPy Slider\"),\n", |
| 271 | + " html.input(\n", |
| 272 | + " {\n", |
| 273 | + " \"type\": \"range\",\n", |
| 274 | + " \"min\": slider_widget.min,\n", |
| 275 | + " \"max\": slider_widget.max,\n", |
| 276 | + " \"value\": value,\n", |
| 277 | + " \"on_change\": lambda event: set_value(event[\"target\"][\"value\"]),\n", |
| 278 | + " }\n", |
| 279 | + " ),\n", |
217 | 280 | " )"
|
218 | 281 | ]
|
219 | 282 | },
|
|
227 | 290 | },
|
228 | 291 | {
|
229 | 292 | "cell_type": "code",
|
230 |
| - "execution_count": null, |
| 293 | + "execution_count": 11, |
231 | 294 | "metadata": {
|
232 | 295 | "tags": []
|
233 | 296 | },
|
234 |
| - "outputs": [], |
| 297 | + "outputs": [ |
| 298 | + { |
| 299 | + "data": { |
| 300 | + "application/vnd.jupyter.widget-view+json": { |
| 301 | + "model_id": "48a4b16d9b7149fe9bbc8cbf5c20bd6c", |
| 302 | + "version_major": 2, |
| 303 | + "version_minor": 0 |
| 304 | + }, |
| 305 | + "text/plain": [ |
| 306 | + "LayoutWidget(Layout(ContextProvider(<function context at 0x7fb48b0a3600>)))" |
| 307 | + ] |
| 308 | + }, |
| 309 | + "execution_count": 11, |
| 310 | + "metadata": {}, |
| 311 | + "output_type": "execute_result" |
| 312 | + } |
| 313 | + ], |
235 | 314 | "source": [
|
236 | 315 | "from ipywidgets import IntSlider\n",
|
237 | 316 | "\n",
|
238 |
| - "SliderObserver(IntSlider(readout=False))" |
| 317 | + "MirrorSlider(IntSlider(readout=False))" |
239 | 318 | ]
|
240 | 319 | },
|
241 | 320 | {
|
|
248 | 327 | },
|
249 | 328 | {
|
250 | 329 | "cell_type": "code",
|
251 |
| - "execution_count": null, |
| 330 | + "execution_count": 9, |
252 | 331 | "metadata": {
|
253 | 332 | "tags": []
|
254 | 333 | },
|
255 |
| - "outputs": [], |
| 334 | + "outputs": [ |
| 335 | + { |
| 336 | + "data": { |
| 337 | + "application/vnd.jupyter.widget-view+json": { |
| 338 | + "model_id": "4fc27c4a9ae04351b140ca4bcb15e5be", |
| 339 | + "version_major": 2, |
| 340 | + "version_minor": 0 |
| 341 | + }, |
| 342 | + "text/plain": [ |
| 343 | + "Box(children=(LayoutWidget(Layout(ContextProvider(<function context at 0x7fb48b0a3600>))), LayoutWidget(Layout…" |
| 344 | + ] |
| 345 | + }, |
| 346 | + "execution_count": 9, |
| 347 | + "metadata": {}, |
| 348 | + "output_type": "execute_result" |
| 349 | + } |
| 350 | + ], |
256 | 351 | "source": [
|
257 | 352 | "from ipywidgets import Box\n",
|
258 | 353 | "from reactpy_jupyter import to_widget\n",
|
259 | 354 | "\n",
|
260 | 355 | "slider = IntSlider(readout=False)\n",
|
261 |
| - "slider_observer_widget = to_widget(SliderObserver(slider))\n", |
| 356 | + "slider_observer_widget = to_widget(MirrorSlider(slider))\n", |
262 | 357 | "\n",
|
263 |
| - "Box([slider, slider_observer_widget])" |
| 358 | + "Box([slider_observer_widget, slider_observer_widget])" |
264 | 359 | ]
|
265 | 360 | },
|
266 | 361 | {
|
|
0 commit comments