-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add reacton use_event hook in ipyvue instead of reacton
This code should go into ipyvue, not reacton, such that we can have multiple ipyvue versions with different use_event versions.
- Loading branch information
1 parent
02ac363
commit a5363d7
Showing
1 changed file
with
42 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from typing import Any, Callable, cast | ||
|
||
import ipyvue | ||
|
||
import reacton as react | ||
from reacton.core import get_render_context | ||
|
||
|
||
def use_event( | ||
el: react.core.Element, event_and_modifiers, callback: Callable[[Any], Any] | ||
): | ||
# to avoid add_event_handler having a stale reference to callback | ||
callback_ref = react.use_ref(callback) | ||
callback_ref.current = callback | ||
|
||
def add_event_handler(): | ||
vue_widget = cast(ipyvue.VueWidget, react.core.get_widget(el)) | ||
# we are basically copying the logic from | ||
# reacton.core._event_handler_exception_wrapper | ||
rc = get_render_context() | ||
context = rc.context | ||
assert context is not None | ||
|
||
def handler(*args): | ||
try: | ||
callback_ref.current(*args) | ||
except Exception as e: | ||
assert context is not None | ||
# because widgets don't have a context, but are a child of a component | ||
# we add it to exceptions_children, not exception_self | ||
# this allows a component to catch the exception of a direct child | ||
context.exceptions_children.append(e) | ||
rc.force_update() | ||
|
||
vue_widget.on_event(event_and_modifiers, handler) | ||
|
||
def cleanup(): | ||
vue_widget.on_event(event_and_modifiers, handler, remove=True) | ||
|
||
return cleanup | ||
|
||
react.use_effect(add_event_handler, [event_and_modifiers]) |