Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 946d430

Browse filesBrowse files
committed
allow jupyter widgets to be used in reactpy components
1 parent 3900cb2 commit 946d430
Copy full SHA for 946d430

File tree

Expand file treeCollapse file tree

10 files changed

+317
-2167
lines changed
Filter options
Expand file treeCollapse file tree

10 files changed

+317
-2167
lines changed

‎notebooks/introduction.ipynb

Copy file name to clipboardExpand all lines: notebooks/introduction.ipynb
+53-21Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"# What is ReactPy?\n",
7+
"<img src=\"https://raw.githubusercontent.com/reactive-python/reactpy/main/branding/svg/reactpy-logo-landscape.svg\" alt=\"ReactPy Logo\" style=\"min-width: 300px; width: 35%\" />\n",
88
"\n",
9-
"ReactPy connects your Python web framework of choice to a ReactJS frontend, allowing you to create **interactive websites without needing JavaScript!**\n",
9+
"---\n",
1010
"\n",
11-
"Following ReactJS styling, web elements are combined into [reusable \"components\"](https://reactpy.dev/docs/guides/creating-interfaces/your-first-components/index.html#parametrizing-components). These components can utilize [hooks](https://reactpy.dev/docs/reference/hooks-api.html) and [events](https://reactpy.dev/docs/guides/adding-interactivity/responding-to-events/index.html#async-event-handlers) to create infinitely complex web pages.\n",
11+
"[ReactPy](https://reactpy.dev/) is a library for building user interfaces in Python without Javascript. ReactPy interfaces are made from components which look and behave similarly to those found in [ReactJS](https://reactjs.org/). Designed with simplicity in mind, ReactPy can be used by those without web development experience while also being powerful enough to grow with your ambitions.\n",
1212
"\n",
13-
"When needed, ReactPy can [use components directly from NPM](https://reactpy.dev/docs/guides/escape-hatches/javascript-components.html#dynamically-loaded-components). For additional flexibility, components can also be [fully developed in JavaScript](https://reactpy.dev/docs/guides/escape-hatches/javascript-components.html#custom-javascript-components).\n",
1413
"\n",
1514
"\n",
1615
"# Getting Started\n",
@@ -60,7 +59,7 @@
6059
},
6160
"outputs": [],
6261
"source": [
63-
"from reactpy import component, html, run\n",
62+
"from reactpy import component, html\n",
6463
"\n",
6564
"\n",
6665
"@component\n",
@@ -186,7 +185,29 @@
186185
"source": [
187186
"# Using ReactPy With Jupyter Widgets\n",
188187
"\n",
189-
"While you can use ReactPy components independently, it may also be useful to integrate them with the rest of the Jupyter Widget ecosystem. 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, 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):"
188+
"It's possible to use Jupyter Widgets in ReactPy components if you convert them first using `reactpy_jupyter.from_widget`."
189+
]
190+
},
191+
{
192+
"cell_type": "code",
193+
"execution_count": null,
194+
"metadata": {},
195+
"outputs": [],
196+
"source": [
197+
"from reactpy_jupyter import from_widget\n",
198+
"from ipywidgets import IntSlider\n",
199+
"\n",
200+
"slider_widget = IntSlider()\n",
201+
"slider_component = from_widget(slider_widget)\n",
202+
"\n",
203+
"slider_component"
204+
]
205+
},
206+
{
207+
"cell_type": "markdown",
208+
"metadata": {},
209+
"source": [
210+
"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):"
190211
]
191212
},
192213
{
@@ -198,10 +219,12 @@
198219
"outputs": [],
199220
"source": [
200221
"from reactpy import use_effect\n",
222+
"from reactpy_jupyter import from_widget\n",
201223
"\n",
202224
"\n",
203225
"@component\n",
204226
"def SliderObserver(slider):\n",
227+
" slider_component = from_widget(slider)\n",
205228
" value, set_value = use_state(0)\n",
206229
"\n",
207230
" @use_effect\n",
@@ -214,14 +237,14 @@
214237
" # unobserve the slider's value if this component is no longer displayed\n",
215238
" return lambda: slider.unobserve(handle_change, \"value\")\n",
216239
"\n",
217-
" return html.p(f\"ReactPy observes the value to be: \", value)"
240+
" return html.div(slider_component, html.p(f\"ReactPy observes the value to be: \", value))"
218241
]
219242
},
220243
{
221244
"cell_type": "markdown",
222245
"metadata": {},
223246
"source": [
224-
"Now you'll need to display the `SliderObserver` component as well as an `IntSlider` widget. To do this, you'll want wrap the component in a `reactpy_jupyter.LayoutWidget` instance before using it alongside other Jupyter Widgets. Specifically, you'll be displaying the `SliderObserver` and `IntSlider` in a `Box`:\n"
247+
"Now you need to pass the `SliderObserver` component an `IntSlider` widget and display it.\n"
225248
]
226249
},
227250
{
@@ -232,20 +255,16 @@
232255
},
233256
"outputs": [],
234257
"source": [
235-
"from ipywidgets import Box, IntSlider\n",
236-
"from reactpy_jupyter import LayoutWidget\n",
237-
"\n",
238-
"slider = IntSlider(readout=False)\n",
239-
"slider_observer = LayoutWidget(SliderObserver(slider))\n",
258+
"from ipywidgets import IntSlider\n",
240259
"\n",
241-
"Box([slider, slider_observer])"
260+
"SliderObserver(IntSlider(readout=False))"
242261
]
243262
},
244263
{
245264
"cell_type": "markdown",
246265
"metadata": {},
247266
"source": [
248-
"If it becomes painful to wrap every ReactPy component in a `LayoutWidget` you can create an alternate `LayoutWidget` constructor using `reactpy_jupyter.widgetize`:"
267+
"You can also include ReactPy components within Jupyter Widgets using `reactpy_jupyter.to_widget`"
249268
]
250269
},
251270
{
@@ -256,21 +275,34 @@
256275
},
257276
"outputs": [],
258277
"source": [
259-
"from reactpy_jupyter import widgetize\n",
260-
"\n",
261-
"SliderObserverWidget = widgetize(SliderObserver)\n",
278+
"from ipywidgets import Box\n",
279+
"from reactpy_jupyter import to_widget\n",
262280
"\n",
263281
"slider = IntSlider(readout=False)\n",
264-
"slider_observer = SliderObserverWidget(slider)\n",
282+
"slider_observer_widget = to_widget(SliderObserver(slider))\n",
265283
"\n",
266-
"Box([slider, slider_observer])"
284+
"Box([slider, slider_observer_widget])"
267285
]
268286
},
269287
{
270288
"cell_type": "markdown",
271289
"metadata": {},
272290
"source": [
273-
"It's worth noting that, while ReactPy can be used with Jupyter Widgets, the reverse is not true. That is, **you cannot use a Jupyter Widget inside a ReactPy component**. If this is a capability you would find useful, please [start a discussion](https://github.com/reactive-python/reactpy/discussions). The ReactPy team would be very interested to hear how allowing Jupyter Widgets to be used with ReactPy could facilitate your work."
291+
"If it becomes painful to convert every ReactPy component to a jupyter widget you can create an alternate widget constructor:"
292+
]
293+
},
294+
{
295+
"cell_type": "code",
296+
"execution_count": null,
297+
"metadata": {},
298+
"outputs": [],
299+
"source": [
300+
"slider = IntSlider(readout=False)\n",
301+
"slider_observer_constructor = to_widget(SliderObserver)\n",
302+
"observer_1 = slider_observer_constructor(slider)\n",
303+
"observer_2 = slider_observer_constructor(slider)\n",
304+
"\n",
305+
"Box([observer_1, observer_2])"
274306
]
275307
},
276308
{

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.