-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a use_trait hook attached to widget wrapper
- Loading branch information
Showing
7 changed files
with
219 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from typing import Any | ||
|
||
from reactpy import use_effect, use_state | ||
from reactpy.types import State | ||
from traitlets import HasTraits | ||
|
||
|
||
def use_trait(obj: HasTraits, name: str) -> State[Any]: | ||
"""Hook to use the attribute of a HasTraits object as a state variable | ||
This works on Jupyter Widgets, for example. | ||
""" | ||
value, set_value = use_state(lambda: getattr(obj, name)) | ||
|
||
@use_effect | ||
def register_observer(): | ||
def handle_change(change): | ||
set_value(change["new"]) | ||
|
||
# observe the slider's value | ||
obj.observe(handle_change, "value") | ||
# unobserve the slider's value if this component is no longer displayed | ||
return lambda: obj.unobserve(handle_change, "value") | ||
|
||
def set_trait(new_value: Any) -> None: | ||
setattr(obj, name, new_value) | ||
|
||
return State(value, set_trait) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,8 @@ | ||
from typing import Any | ||
from weakref import finalize | ||
|
||
from reactpy.core.component import Component | ||
|
||
from reactpy_jupyter.layout_widget import to_widget | ||
|
||
# we can't track the widgets by adding them as a hidden attribute to the component | ||
# because Component has __slots__ defined | ||
LIVE_WIDGETS: dict[int, Any] = {} | ||
from reactpy_jupyter.widget_component import WidgetComponent | ||
|
||
|
||
def execute_patch() -> None: | ||
"""Monkey patch ReactPy's Component class to display as a Jupyter widget""" | ||
|
||
def _repr_mimebundle_(self: Component, *a, **kw) -> None: | ||
self_id = id(self) | ||
if self_id not in LIVE_WIDGETS: | ||
widget = LIVE_WIDGETS[self_id] = to_widget(self) | ||
finalize(self, lambda: LIVE_WIDGETS.pop(self_id, None)) | ||
else: | ||
widget = LIVE_WIDGETS[self_id] | ||
return widget._repr_mimebundle_(*a, **kw) | ||
|
||
Component._repr_mimebundle_ = _repr_mimebundle_ | ||
Component._repr_mimebundle_ = WidgetComponent._repr_mimebundle_ |
Oops, something went wrong.