Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event type changes when handler is shared #1094

Open
pokutuna opened this issue Nov 5, 2024 · 1 comment
Open

Event type changes when handler is shared #1094

pokutuna opened this issue Nov 5, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@pokutuna
Copy link

pokutuna commented Nov 5, 2024

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 by ClickEvent from later registration.

To Reproduce
Steps to reproduce the behavior:

  1. 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'>
  1. Access /page1 and focus on the textarea and press Ctrl+Enter (works fine)
  2. 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:

Image

Desktop System Info

  • OS: macOS
  • Browser: Chrome 130.0.6723.70(Official Build)(arm64)
  • Version: mesop v0.12.8

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 (buttonClickEvent, shortcutTextareaShortcutEvent), 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.

def register_event_handler(
handler_fn: Callable[..., Any], event: Type[E]
) -> str:
fn_id = compute_fn_id(handler_fn)
runtime().context().register_event_handler(
fn_id, wrap_handler_with_event(handler_fn, event)
)
return fn_id

  • When registering same function, compute_fn_id generates same ID
  • Later registration (button's click event) overwrites earlier one (shortcut event)
  • Makes code behavior unexpected and breaks event type

If it's difficult to fix this issue directly in the implementation, I would like to propose the following:

@pokutuna pokutuna added the bug Something isn't working label Nov 5, 2024
@wwwillchen
Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants