widgetti / reacton Goto Github PK
View Code? Open in Web Editor NEWA pure Python port of React for ipywidgets
Home Page: https://reacton.solara.dev/
License: MIT License
A pure Python port of React for ipywidgets
Home Page: https://reacton.solara.dev/
License: MIT License
First congrats on this work, really amazing to see this. Have you looked at integrating ipydatagrid? What would that take?
The example from https://github.com/widgetti/reacton#markdown-component-example does not work with myst_parser>=0.18
since the to_html
function has been removed from the python api (see https://github.com/executablebooks/MyST-Parser/blob/28725fceb8e1e117cb247b06a267f82c501ce527/CHANGELOG.md#breaking-changes)
One solution:
@reacton.component
def Markdown(md: str):
from markdown_it.renderer import RendererHTML
from myst_parser.config.main import MdParserConfig
from myst_parser.parsers.mdit import create_md_parser
md_parser = create_md_parser(MdParserConfig(), RendererHTML)
html = md_parser.render(md)
return w.HTML(value=html)
BR, Alex
In some cases when changing the options of a SelectionRangeSlider, the options list is not updated. For this to occur, you must have both continuous_update set to True, and an index specified. I've seen similar behavior in react_ipywidgets 0.11 (ipywidgets 0.7) with the SelectMultiple widget. I believe it's some kind of race condition in the SelectionRangeSlider's JavaScript view, but I haven't been able to reproduce this issue with ipywidgets directly.
Test Case:
Click Update, and then try and adjust the slider range. The range remains 1-3, instead of updating to 1-10.
Set continuous_update to False, or remove the index, and the problem does not occur.
import reacton as react
import reacton.ipywidgets as w
@react.component()
def Test():
options, setOptions = react.use_state(['1', '2', '3'])
firstIndex = 0
lastIndex = max(0, len(options)-1)
def onClicked():
setOptions([str(i) for i in range(1, 11)])
print("what")
print(options)
with w.VBox() as vbox:
w.Button(description="Update", on_click=onClicked)
w.SelectionRangeSlider(
description="Options",
options=options,
index=(firstIndex, lastIndex),
continuous_update=True
)
return vbox
Test()
Software Versions:
python 3.10.9
ipywidgets 8.0.4
reacton 1.2.2
The DatetimePicker ist not currently covered by https://github.com/widgetti/reacton/blob/master/reacton/ipywidgets.py
Hi, I feel this project should really help me but I am struggling to get how it would be beneficial compared to a class type structure. Also, would there be a benefit to using Reacton within a class structure? I couldn't get that to work. I would very much appreciate your thoughts on the following button click examples below. In particular, how can Reacton work in classes? and would that structure typically be used in large Jupyter widget web-app projects?
import ipywidgets as widgets
clicks = 0 # issue 3
def on_click(button):
global clicks # issue 3
clicks += 1
button.description = f"Clicked {clicks} times"
button = widgets.Button(description="Clicked 0 times")
button.on_click(on_click) #
button
import reacton
@reacton.component
def ButtonClick():
# first render, this return 0, after that, the last argument
# of set_clicks
clicks, set_clicks = reacton.use_state(0)
def my_click_handler():
# trigger a new render with a new value for clicks
set_clicks(clicks+1)
button = w.Button(description=f"Clicked {clicks} times",
on_click=my_click_handler)
return button
ButtonClick()
The method I currently use for large projects.
import ipywidgets as widgets
class ButtonClick:
def __init__(self):
self.clicks = -1 # issue 3
self.button = widgets.Button()
self.button.on_click(self.on_click)
self.on_click(_)
def on_click(self,_):
self.clicks += 1
self.button.description = f"Clicked {self.clicks} times"
ButtonClick().button
Is this even needed? I'm not sure. It would be nice to incorporate Reacton in existing code within a class based structure.
class ButtonClick_r:
def __init__(self):
self.ButtonClick()
self.clicks= 0
self.button = w.Button(description=f"Clicked {self.clicks} times",
on_click=self.my_click_handler)
@reacton.component
def ButtonClick(self):
# first render, this return 0, after that, the last argument
# of set_clicks
self.clicks, set_clicks = reacton.use_state(0)
def my_click_handler(self):
# trigger a new render with a new value for clicks
set_clicks(self.clicks+1)
ButtonClick_r().button
I am trying to implement this very simple example with reacton.ipvuetify.VuetifyTemplate. The implementation if templates in reacton is a method instead of a class and I am unsure as to how you pass methods to the function (in this example the vue_btn_click
).
import traitlets
import ipyvuetify
class TestWidget(ipyvuetify.VuetifyTemplate):
template = traitlets.Unicode('''
<template>
<v-btn @click="btn_click">
Button
</v-btn>
</template>
''').tag(sync=True)
def vue_btn_click(self, data):
print(1)
test = TestWidget()
test
Started exploring the project, no react knowledge, I like the pure python approach.
Just a minor thing:
In the getting-started.md the example says:
el = ButtonClick
display(el)
I guess this was meant "()":
el = ButtonClick()
display(el)
Thanks a ton.
When using an ipywidgets.Output widget in a reacton component, plots are not displayed in notebook. I've tested this with the ipympl and inline backends. It works fine when using ipywidgets directly, and used to work with react-ipywdgets 0.11.
Here's an example that shows both the working case (with ipywidgeds) and the non-working case (reacton).
import matplotlib.pyplot as plt
import reacton as react
import reacton.ipywidgets as w
import ipywidgets as widgets
#%matplotlib inline
%matplotlib ipympl
def plot(outputWidget):
with plt.ioff():
fig, ax = plt.subplots()
fruits = ['apple', 'blueberry', 'cherry', 'orange']
counts = [40, 100, 30, 55]
bar_labels = ['red', 'blue', '_red', 'orange']
bar_colors = ['tab:red', 'tab:blue', 'tab:red', 'tab:orange']
ax.bar(fruits, counts, label=bar_labels, color=bar_colors)
ax.set_ylabel('fruit supply')
ax.set_title('Fruit supply by kind and color')
ax.legend(title='Fruit color')
with outputWidget:
print("Displaying")
plt.show()
# Reacton Test Case
@react.component()
def Test():
render, setRender = react.use_state(False)
def displayReacton():
if render == False:
return
outputWidget = react.get_widget(output)
plot(outputWidget)
with w.VBox() as vbox:
w.Button(description="Render", on_click=lambda: setRender(True))
output = w.Output()
react.use_effect(displayReacton, [render])
return vbox
Test()
# Ipywidgets test case
outputWidget = widgets.Output()
button = widgets.Button(description="Render")
def displayIpywidgets(_):
plot(outputWidget)
button.on_click(displayIpywidgets)
widgets.VBox([
button,
outputWidget
])
Software Versions:
python 3.10.9
matplotlib-base 3.7.1
ipympl 0.9.3
reacton 1.2.2
Like many other people, I want to write good-looking apps with React-style (Model-View-Update, The Elm Architecture) in 100% Python.
Congratulations on implementing Hooks in Python; I believe you’re the first person to do that.
https://maartenbreddels.medium.com/advance-your-ipywidget-app-development-with-reacton-6734a5607d69
Once a common library for rendering/reconciliation exists, the same procedure can be repeated for Qt
It sure would be nice if we could write PySide6 apps with Reacton. Here’s an issue for talking about that.
I got following warning when running pytest:
reacton\core.py:362: DeprecationWarning: Widget.widgets is deprecated.
before = set(widgets.Widget.widgets)
reacton\core.py:1936: DeprecationWarning: Widget.widgets is deprecated.
orphan_widgets = set([widgets.Widget.widgets[k] for k in orphan_ids])
All occurrences of referencing Widget.widgets throw DeprecationWarning.
In ipywidgets(8.0.6), it states:
# Because this is a static attribute, it will be accessed when initializing this class. In that case, since a user
# did not explicitly try to use this attribute, we do not want to throw a deprecation warning.
# So we check if the thing calling this static property is one of the known initialization functions in traitlets.
Anyway to avoid?
P.S.
What's the difference between render()
and render_fixed()
? I do see render add another container around elements. Any explanations about when to choose which?
Thanks a lot.
We could try to support this, or give a better error message.
Hi I am trying to create a DataTable with single row select as well as dropdown (Select) menus in one of the columns. My current issue is that changing the value of one dropdown changes the value of every dropdown (probably because they share a v_model). In the end I need to be able to pull the values of the dropdown out of the table.
import reacton.ipyvuetify as v
data = [
{"name": "John", "age": 15, "city": "New York"},
{"name": "Jane", "age": 23, "city": "London"},
{"name": "Peter", "age": 32, "city": "Paris"},
{"name": "Kate", "age": 21, "city": "Berlin"},
{"name": "Mary", "age": 29, "city": "Mumbai"},
]
v.DataTable(
headers=[
{"text": "Name", "value": "name"},
{"text": "Age", "value": "age"},
{"text": "City", "value": "city"},
{"text": "Selector", "value": "selector"},
],
items=data,
class_="elevation-1",
single_select=True,
show_select=True,
v_slots=[
{
"name": "item.selector",
"variable": "item",
"children": v.Select(
items=["Yes", "No"],
v_model="item.selector",
),
}
],
)
I was trying to execute the calculator demo
https://reacton.solara.dev/en/latest/_output/lab/
and from import reacton
I got the following error.
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
/tmp/xpython_42/3272763547.py in <cell line: 1>()
----> 1 import reacton
2 import reacton.ipywidgets as w
3
4
5 @reacton.component
ModuleNotFoundError: No module named 'reacton'
Reacton does appear in this jupyterlite config file (I think)
https://github.com/widgetti/reacton/blob/master/docs/xeus-python-environment.yml
This project has already saved me a bunch of time building complex Jupyter UIs. I just wanted to say thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.