When same handler is used for both a shortcut and button click, pressing Ctrl+Enter unexpectedly triggers a ClickEvent instead of TextareaShortcutEvent.
This is confusing because the handler's expected event type (TextareaShortcutEvent) is overwritten by ClickEvent from later registration.
To Reproduce
Steps to reproduce the behavior:
Run this code:
import mesop as me
@me.stateclass
class State:
event_type: str = ""
def submit(e: me.TextareaShortcutEvent):
state = me.state(State)
state.event_type = str(type(e))
# Cannot access e.value with ClickEvent
@me.page(path="/page1")
def page1():
state = me.state(State)
me.textarea(
placeholder="Ctrl+Enter to submit",
shortcuts={
me.Shortcut(ctrl=True, key="Enter"): submit,
},
)
me.text(state.event_type)
# => <class 'mesop.components.input.input.TextareaShortcutEvent'>
@me.page(path="/page2")
def page2():
state = me.state(State)
me.textarea(
placeholder="Ctrl+Enter to submit",
shortcuts={
me.Shortcut(ctrl=True, key="Enter"): submit,
},
)
me.button("submit", on_click=submit)
me.text(state.event_type)
# => <class 'mesop.events.events.ClickEvent'>
Access /page1 and focus on the textarea and press Ctrl+Enter (works fine)
Access /page2 and focus on the textarea and press Ctrl+Enter (unexpectedly triggers ClickEvent)
Expected behavior
When pressing Ctrl+Enter: Handler should receive TextareaShortcutEvent
When clicking button: Handler should receive ClickEvent
Each input should trigger its appropriate event type.
Screenshots
When focusing on the textarea and press Ctrl+Enter:
I understand that defining separate handlers for keyboard and mouse events is the correct solution, since event types should naturally correspond to their components.
This is confusing because event types should be determined by the component (button → ClickEvent, shortcut → TextareaShortcutEvent), but instead they are determined by handler registration order.
Having event types determined by registration order or handler assignment makes the behavior unpredictable and breaks the natural component-event relationship.
This happens because register_event_handler function overwrites event type mappings.
I think this is pretty difficult to fix implementation-wise and something fairly rare, please feel free to send a PR to improve the docs / add warnings. Thanks.
Describe the bug
When same handler is used for both a shortcut and button click, pressing Ctrl+Enter unexpectedly triggers a ClickEvent instead of TextareaShortcutEvent.
This is confusing because the handler's expected event type (
TextareaShortcutEvent
) is overwritten byClickEvent
from later registration.To Reproduce Steps to reproduce the behavior:
/page1
and focus on the textarea and press Ctrl+Enter (works fine)/page2
and focus on the textarea and press Ctrl+Enter (unexpectedly triggers ClickEvent)Expected behavior
Screenshots
When focusing on the textarea and press Ctrl+Enter:
Desktop System Info
Additional context
I understand that defining separate handlers for keyboard and mouse events is the correct solution, since event types should naturally correspond to their components.
This is confusing because event types should be determined by the component (
button
→ClickEvent
,shortcut
→TextareaShortcutEvent
), but instead they are determined by handler registration order.Having event types determined by registration order or handler assignment makes the behavior unpredictable and breaks the natural component-event relationship.
This happens because
register_event_handler
function overwrites event type mappings.https://github.com/google/mesop/blob/69148c9ccd21346005d87b0bdac5429d136f1f65/mesop/component_helpers/helper.py#L374-L382
If it's difficult to fix this issue directly in the implementation, I would like to propose the following: