Open paddymul opened 9 months ago
The code of
class ButtonElement(reacton.core.Element):
def _add_widget_event_listener(self, widget: widgets.Widget, name: str, callback: Callable):
if name == "on_click":
callback_exception_safe = _event_handler_exception_wrapper(callback)
def on_click(change):
callback_exception_safe()
key = (widget.model_id, name, callback)
self._callback_wrappers[key] = on_click
widget.on_click(on_click)
else:
super()._add_widget_event_listener(widget, name, callback)
def _remove_widget_event_listener(self, widget: widgets.Widget, name: str, callback: Callable):
if name == "on_click":
key = (widget.model_id, name, callback)
on_click = self._callback_wrappers[key]
del self._callback_wrappers[key]
widget.on_click(on_click, remove=True)
else:
super()._remove_widget_event_listener(widget, name, callback)
if __name__ == "__main__":
from . import generate
class CodeGen(generate.CodeGen):
element_classes = {ipywidgets.Button: ButtonElement}
def get_extra_argument(self, cls):
return {ipywidgets.Button: [("on_click", None, typing.Callable[[], Any])]}.get(cls, [])
current_module = __import__(__name__)
CodeGen([widgets, ipywidgets.widgets.widget_description, ipywidgets.widgets.widget_int]).generate(__file__)
when run through CodeGen
becomes
def _Button(
button_style: str = "",
description: str = "",
disabled: bool = False,
icon: str = "",
layout: Union[Dict[str, Any], Element[ipywidgets.widgets.widget_layout.Layout]] = {},
style: Union[Dict[str, Any], Element[ipywidgets.widgets.widget_button.ButtonStyle]] = {},
tooltip: str = "",
on_button_style: typing.Callable[[str], Any] = None,
on_description: typing.Callable[[str], Any] = None,
on_disabled: typing.Callable[[bool], Any] = None,
on_icon: typing.Callable[[str], Any] = None,
on_layout: typing.Callable[[Union[Dict[str, Any], Element[ipywidgets.widgets.widget_layout.Layout]]], Any] = None,
on_style: typing.Callable[[Union[Dict[str, Any], Element[ipywidgets.widgets.widget_button.ButtonStyle]]], Any] = None,
on_tooltip: typing.Callable[[str], Any] = None,
on_click: typing.Callable[[], typing.Any] = None,
) -> Element[ipywidgets.widgets.widget_button.Button]:
"""Button widget.
This widget has an `on_click` method that allows you to listen for the
user clicking on the button. The click event itself is stateless.
Parameters
----------
description: str
description displayed next to the button
tooltip: str
tooltip caption of the toggle button
icon: str
font-awesome icon name
disabled: bool
whether user interaction is enabled
:param button_style: Use a predefined styling for the button.
:param description: Button label.
:param disabled: Enable or disable user changes.
:param icon: Font-awesome icon name, without the 'fa-' prefix.
:param tooltip: Tooltip caption of the button.
"""
...
@implements(_Button)
def Button(**kwargs):
if isinstance(kwargs.get("layout"), dict):
kwargs["layout"] = Layout(**kwargs["layout"])
if isinstance(kwargs.get("style"), dict):
kwargs["style"] = ButtonStyle(**kwargs["style"])
widget_cls = ipywidgets.widgets.widget_button.Button
comp = reacton.core.ComponentWidget(widget=widget_cls)
return ButtonElement(comp, kwargs=kwargs)
del _Button
Ok, I got this to work.
My own codegen
import reacton
from buckaroo.buckaroo_widget import BuckarooWidget
def reacton_buckaroo(**kwargs):
widget_cls = BuckarooWidget
comp = reacton.core.ComponentWidget(widget=widget_cls)
return reacton.core.Element(comp, kwargs=kwargs)
then invoking it in a simple solara app
import pandas as pd
import solara
df = pd.DataFrame({'a':[10,20]})
@solara.component
def Page():
bw = reacton_buckaroo(df=df)
Page()
I am the creator of Buckaroo a full featured dataframe viewer that wraps ag-grid. I am trying to figure out how to expose buckaroo as a component for Solara apps.
A couple of points:
DFViewer
component that takes a serialized dataframe and Buckaroo styling config. There is also extra UI that swaps clientside styling configs, and sets properties on the parent widget that communicates back with the python widget (which transform function to apply, some other things)It might be easier and more straightforward to integrate just the
DFViewer
frontend component. I don't have this as a separate DOMWidget, but I could work on it. This would probably be easier for solara users since it is less opinionated than the full BuckarooWidget.Where I'm getting stuck
I am having trouble understanding the wrapping stage. I'm a bit lost as to how to make Buckaroo work there. I looked at the other examples (IPYWidgets, BQPlot, IPYVeutify).
The codegen in particular is confusing. what is the generated code accomplishing?
Are you inserting actual python code into an existing file in site-packages? are you only using it to run mypy on the generated code? are you using it to get completions in an IDE?
Ahhh after looking at the code in my sitepackages, I see that you are indeed writing to the file.
Documenting this would help.