CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-reactpy

Reactive user interfaces with pure Python

Pending
Overview
Eval results
Files

events.mddocs/

Event Handling

Event system for handling user interactions with proper event delegation and prevention. ReactPy provides a decorator-based approach to event handling that works seamlessly with HTML elements.

Capabilities

Event Decorator

The @event decorator creates event handlers with optional event behavior control:

@event(prevent_default: bool = False, stop_propagation: bool = False)
def event_handler(event_data: dict) -> None: ...

Parameters:

  • prevent_default: Whether to prevent the default browser action
  • stop_propagation: Whether to stop event bubbling

Returns: EventHandler instance

EventHandler Class

The EventHandler class wraps event functions with metadata:

class EventHandler:
    function: Callable[[dict], None]
    prevent_default: bool
    stop_propagation: bool

Basic Event Handling

from reactpy import component, html, event

@component
def ClickableButton():
    @event
    def handle_click(event_data):
        print(f"Button clicked! Event: {event_data}")
    
    return html.button(
        {"onClick": handle_click},
        "Click Me"
    )

Event Prevention

@component
def FormWithValidation():
    @event(prevent_default=True)  # Prevent form submission
    def handle_submit(event_data):
        # Custom validation logic
        if not validate_form():
            print("Form invalid!")
            return
        # Process form submission
        submit_form()
    
    return html.form(
        {"onSubmit": handle_submit},
        html.input({"type": "text", "required": True}),
        html.button({"type": "submit"}, "Submit")
    )

Event Propagation Control

@component
def NestedClickHandlers():
    @event
    def outer_click(event_data):
        print("Outer clicked")
    
    @event(stop_propagation=True)  # Stop bubbling
    def inner_click(event_data):
        print("Inner clicked - won't bubble")
    
    return html.div(
        {"onClick": outer_click, "style": {"padding": "20px", "border": "1px solid"}},
        "Outer div",
        html.button(
            {"onClick": inner_click},
            "Inner button"
        )
    )

Common Event Types

ReactPy supports all standard DOM events:

@component
def EventExamples():
    @event
    def handle_input(event_data):
        value = event_data.get("target", {}).get("value", "")
        print(f"Input value: {value}")
    
    @event
    def handle_focus(event_data):
        print("Input focused")
    
    @event
    def handle_blur(event_data):
        print("Input blurred")
    
    @event
    def handle_keydown(event_data):
        key = event_data.get("key", "")
        if key == "Enter":
            print("Enter key pressed")
    
    return html.div(
        html.input({
            "onInput": handle_input,
            "onFocus": handle_focus,
            "onBlur": handle_blur,
            "onKeyDown": handle_keydown,
            "placeholder": "Type here..."
        })
    )

Event Data Structure

Event data contains standard DOM event properties:

@component
def EventDataExample():
    @event
    def handle_mouse_event(event_data):
        # Common properties available in event_data:
        event_type = event_data.get("type")  # "click", "mousedown", etc.
        
        # Mouse events
        x = event_data.get("clientX")
        y = event_data.get("clientY")
        button = event_data.get("button")  # 0=left, 1=middle, 2=right
        
        # Keyboard events
        key = event_data.get("key")
        alt_key = event_data.get("altKey")
        ctrl_key = event_data.get("ctrlKey")
        shift_key = event_data.get("shiftKey")
        
        # Target element
        target = event_data.get("target", {})
        value = target.get("value")  # For input elements
        tag_name = target.get("tagName")
        
        print(f"Event: {event_type} at ({x}, {y})")
    
    return html.div(
        {"onMouseDown": handle_mouse_event},
        "Click me to see event data"
    )

State Updates in Event Handlers

Event handlers commonly update component state:

@component
def Counter():
    count, set_count = use_state(0)
    
    @event
    def increment(event_data):
        set_count(count + 1)
    
    @event
    def decrement(event_data):
        set_count(count - 1)
    
    @event
    def reset(event_data):
        set_count(0)
    
    return html.div(
        html.h2(f"Count: {count}"),
        html.button({"onClick": increment}, "+"),
        html.button({"onClick": decrement}, "-"),
        html.button({"onClick": reset}, "Reset")
    )

Form Event Handling

Special patterns for form events:

@component
def ContactForm():
    form_data, set_form_data = use_state({"name": "", "email": ""})
    
    @event
    def handle_input_change(event_data):
        field_name = event_data["target"]["name"]
        field_value = event_data["target"]["value"]
        set_form_data({
            **form_data,
            field_name: field_value
        })
    
    @event(prevent_default=True)
    def handle_submit(event_data):
        print(f"Submitting: {form_data}")
        # Process form submission
    
    return html.form(
        {"onSubmit": handle_submit},
        html.input({
            "name": "name",
            "value": form_data["name"],
            "onInput": handle_input_change,
            "placeholder": "Name"
        }),
        html.input({
            "name": "email",
            "type": "email",
            "value": form_data["email"],
            "onInput": handle_input_change,
            "placeholder": "Email"
        }),
        html.button({"type": "submit"}, "Submit")
    )

Install with Tessl CLI

npx tessl i tessl/pypi-reactpy

docs

backend.md

components.md

configuration.md

events.md

hooks.md

html-elements.md

index.md

svg-elements.md

testing.md

vdom.md

web-modules.md

widgets.md

tile.json