Skip to content

Commit 492acf6

Browse files
Merge pull request #59 from maartenbreddels/feat_trigger_click
feat: .click convenience function to trigger a click event
2 parents 1dd3a71 + 451e93c commit 492acf6

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

ipyvue/VueWidget.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,23 @@ def on_event(self, event_and_modifiers, callback, remove=False):
101101

102102
def fire_event(self, event, data=None):
103103
"""Manually trigger an event handler on the Python side."""
104+
# note that a click event will trigger click.stop if that particular
105+
# event+modifier is registered.
106+
event_match = [k for k in self._event_handlers_map.keys() if k.startswith(event)]
107+
if not event_match:
108+
raise ValueError(f"'{event}' not found in widget {self}")
109+
110+
self._fire_event(event_match[0], data)
111+
112+
def click(self, data=None):
113+
"""Manually triggers the event handler for the 'click' event
114+
115+
Note that this does not trigger a click event in the browser, this only
116+
invokes the Python event handlers.
117+
"""
118+
self.fire_event("click", data or {})
119+
120+
def _fire_event(self, event, data=None):
104121
dispatcher = self._event_handlers_map[event]
105122
# we don't call via the dispatcher, since that eats exceptions
106123
for callback in dispatcher.callbacks:
@@ -109,7 +126,7 @@ def fire_event(self, event, data=None):
109126
def _handle_event(self, _, content, buffers):
110127
event = content.get("event", "")
111128
data = content.get("data", {})
112-
self.fire_event(event, data)
129+
self._fire_event(event, data)
113130

114131

115132
class VueWidget(DOMWidget, Events):

tests/test_vue_widget.py

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from unittest.mock import MagicMock
2+
13
from ipyvue import VueWidget
24

35

@@ -58,3 +60,20 @@ def test_show(self):
5860
test_widget.class_list.add(self.CLASS, "d-none")
5961
test_widget.show()
6062
assert "d-none" not in test_widget.class_
63+
64+
65+
def test_event_handling():
66+
event_handler = MagicMock()
67+
button = VueWidget()
68+
button.on_event("click.stop", event_handler)
69+
button.fire_event("click.stop", {"foo": "bar"})
70+
event_handler.assert_called_once_with(button, "click.stop", {"foo": "bar"})
71+
72+
event_handler.reset_mock()
73+
button.click({"foo": "bar"})
74+
event_handler.assert_called_once_with(button, "click.stop", {"foo": "bar"})
75+
76+
# test the code path as if it's coming from the frontend
77+
event_handler.reset_mock()
78+
button._handle_event(None, dict(event="click.stop", data={"foo": "bar"}), [])
79+
event_handler.assert_called_once_with(button, "click.stop", {"foo": "bar"})

0 commit comments

Comments
 (0)