CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-html--core

Compose Web HTML library for building reactive web user interfaces using Kotlin with type-safe HTML DSL, CSS styling, and event handling

Pending
Overview
Eval results
Files

event-handling.mddocs/

Event Handling

Comprehensive event system with synthetic events that wrap native browser events while providing type safety and consistent APIs across different event types.

Capabilities

Event System Overview

All events in Compose Web are synthetic events that wrap native DOM events with additional type safety and consistent behavior.

/**
 * Base synthetic event interface
 * @param T Native event type
 */
interface SyntheticEvent<T : Event> {
    val nativeEvent: T
    val target: EventTarget?
    val currentTarget: EventTarget?
    fun preventDefault()
    fun stopPropagation()
}

Mouse Events

Mouse interaction events for clicks, movements, and button states.

/**
 * Mouse event interface extending SyntheticEvent
 */
interface SyntheticMouseEvent : SyntheticEvent<MouseEvent> {
    val clientX: Int
    val clientY: Int
    val button: Short
    val buttons: Short
    val altKey: Boolean
    val ctrlKey: Boolean
    val metaKey: Boolean
    val shiftKey: Boolean
}

/**
 * Mouse event listeners (available in EventsListenerScope)
 */
fun EventsListenerScope.onClick(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onDoubleClick(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseDown(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseUp(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseEnter(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseLeave(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseMove(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseOut(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onMouseOver(listener: (SyntheticMouseEvent) -> Unit)
fun EventsListenerScope.onWheel(listener: (SyntheticWheelEvent) -> Unit)

Keyboard Events

Keyboard input events for key presses and releases.

/**
 * Keyboard event interface
 */
interface SyntheticKeyboardEvent : SyntheticEvent<KeyboardEvent> {
    val key: String
    val code: String
    val keyCode: Int
    val altKey: Boolean
    val ctrlKey: Boolean
    val metaKey: Boolean
    val shiftKey: Boolean
    val repeat: Boolean
}

/**
 * Keyboard event listeners
 */
fun EventsListenerScope.onKeyDown(listener: (SyntheticKeyboardEvent) -> Unit)
fun EventsListenerScope.onKeyUp(listener: (SyntheticKeyboardEvent) -> Unit)

Focus Events

Focus and blur events for element focus state changes.

/**
 * Focus event interface
 */
interface SyntheticFocusEvent : SyntheticEvent<FocusEvent> {
    val relatedTarget: EventTarget?
}

/**
 * Focus event listeners
 */
fun EventsListenerScope.onFocus(listener: (SyntheticFocusEvent) -> Unit)
fun EventsListenerScope.onBlur(listener: (SyntheticFocusEvent) -> Unit)
fun EventsListenerScope.onFocusIn(listener: (SyntheticFocusEvent) -> Unit)
fun EventsListenerScope.onFocusOut(listener: (SyntheticFocusEvent) -> Unit)

Input Events

Input value change events for form elements.

/**
 * Input event interface for value changes
 */
interface SyntheticInputEvent : SyntheticEvent<InputEvent> {
    val data: String?
    val inputType: String
}

/**
 * Change event interface for form controls
 */
interface SyntheticChangeEvent : SyntheticEvent<Event> {
    val target: EventTarget?
}

/**
 * Text selection event interface
 */
interface SyntheticSelectEvent : SyntheticEvent<Event>

/**
 * Input event listeners
 */
fun EventsListenerScope.onInput(listener: (SyntheticInputEvent) -> Unit)
fun EventsListenerScope.onChange(listener: (SyntheticChangeEvent) -> Unit)
fun EventsListenerScope.onSelect(listener: (SyntheticSelectEvent) -> Unit)

Form Events

Form submission and reset events.

/**
 * Form submission event interface
 */
interface SyntheticSubmitEvent : SyntheticEvent<SubmitEvent>

/**
 * Form event listeners
 */
fun EventsListenerScope.onSubmit(listener: (SyntheticSubmitEvent) -> Unit)
fun EventsListenerScope.onReset(listener: (SyntheticEvent<Event>) -> Unit)

Touch Events

Touch interaction events for mobile and touch-enabled devices.

/**
 * Touch event interface
 */
interface SyntheticTouchEvent : SyntheticEvent<TouchEvent> {
    val touches: TouchList
    val targetTouches: TouchList
    val changedTouches: TouchList
    val altKey: Boolean
    val ctrlKey: Boolean
    val metaKey: Boolean
    val shiftKey: Boolean
}

/**
 * Touch event listeners
 */
fun EventsListenerScope.onTouchStart(listener: (SyntheticTouchEvent) -> Unit)
fun EventsListenerScope.onTouchEnd(listener: (SyntheticTouchEvent) -> Unit)
fun EventsListenerScope.onTouchMove(listener: (SyntheticTouchEvent) -> Unit)
fun EventsListenerScope.onTouchCancel(listener: (SyntheticTouchEvent) -> Unit)

Animation Events

CSS animation lifecycle events.

/**
 * Animation event interface for CSS animations
 */
interface SyntheticAnimationEvent : SyntheticEvent<AnimationEvent> {
    val animationName: String
    val elapsedTime: Double
    val pseudoElement: String
}

/**
 * Animation event listeners
 */
fun EventsListenerScope.onAnimationStart(listener: (SyntheticAnimationEvent) -> Unit)
fun EventsListenerScope.onAnimationEnd(listener: (SyntheticAnimationEvent) -> Unit)
fun EventsListenerScope.onAnimationIteration(listener: (SyntheticAnimationEvent) -> Unit)

Clipboard Events

Clipboard operation events for copy, cut, and paste operations.

/**
 * Clipboard event interface
 */
interface SyntheticClipboardEvent : SyntheticEvent<ClipboardEvent> {
    val clipboardData: DataTransfer?
}

/**
 * Clipboard event listeners
 */
fun EventsListenerScope.onCopy(listener: (SyntheticClipboardEvent) -> Unit)
fun EventsListenerScope.onCut(listener: (SyntheticClipboardEvent) -> Unit)
fun EventsListenerScope.onPaste(listener: (SyntheticClipboardEvent) -> Unit)

Event Handler Context

Event listeners are used within the attrs builder context of HTML elements.

/**
 * Event listener scope available within attrs builders
 */
interface EventsListenerScope

/**
 * Attributes scope that includes event listener scope
 */
interface AttrsScope<out TElement : Element> : EventsListenerScope

Usage Examples:

import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.events.*

// Mouse events
Button({
    onClick { event ->
        console.log("Button clicked at (${event.clientX}, ${event.clientY})")
        if (event.ctrlKey) {
            console.log("Ctrl key was held")
        }
    }
    
    onDoubleClick { event ->
        console.log("Button double-clicked")
        event.preventDefault()
    }
}) {
    Text("Click Me")
}

// Keyboard events
TextInput(value = "", {
    onKeyDown { event ->
        when (event.key) {
            "Enter" -> {
                console.log("Enter key pressed")
                // Handle form submission
            }
            "Escape" -> {
                console.log("Escape key pressed")
                // Clear input or close dialog
            }
            else -> {
                console.log("Key pressed: ${event.key}")
            }
        }
    }
    
    onKeyUp { event ->
        if (event.ctrlKey && event.key == "z") {
            console.log("Undo shortcut detected")
        }
    }
})

// Focus events
TextInput(value = "", {
    onFocus { event ->
        console.log("Input focused")
        // Show help text or highlight field
    }
    
    onBlur { event ->
        console.log("Input lost focus")
        // Validate input or hide help text
    }
})

// Input events for reactive updates
var inputValue by remember { mutableStateOf("") }

TextInput(value = inputValue, {
    onInput { event ->
        // Update state on every character typed
        inputValue = (event.target as HTMLInputElement).value
        console.log("Input value: $inputValue")
    }
    
    onChange { event ->
        // Fires on blur, useful for validation
        val value = (event.target as HTMLInputElement).value
        console.log("Final value: $value")
    }
})

// Form events
Form({
    onSubmit { event ->
        event.preventDefault() // Prevent default form submission
        console.log("Form submitted")
        
        // Handle form data
        val formData = FormData(event.target as HTMLFormElement)
        // Process form data...
    }
    
    onReset { event ->
        console.log("Form reset")
        // Clear custom state if needed
    }
}) {
    TextInput(name = "username")
    PasswordInput(name = "password")
    SubmitInput()
}

// Touch events for mobile
Div({
    onTouchStart { event ->
        console.log("Touch started with ${event.touches.length} fingers")
    }
    
    onTouchMove { event ->
        event.preventDefault() // Prevent scrolling
        val touch = event.touches[0]
        console.log("Touch moved to (${touch.clientX}, ${touch.clientY})")
    }
    
    onTouchEnd { event ->
        console.log("Touch ended")
    }
}) {
    Text("Touch-enabled area")
}

// Animation events
Div({
    classes("animated-element")
    
    onAnimationStart { event ->
        console.log("Animation '${event.animationName}' started")
    }
    
    onAnimationEnd { event ->
        console.log("Animation '${event.animationName}' completed after ${event.elapsedTime}s")
    }
    
    onAnimationIteration { event ->
        console.log("Animation '${event.animationName}' iteration completed")
    }
}) {
    Text("Animated content")
}

// Clipboard events
TextArea({
    onCopy { event ->
        console.log("Text copied to clipboard")
        val selectedText = window.getSelection()?.toString()
        console.log("Copied text: $selectedText")
    }
    
    onPaste { event ->
        val pastedData = event.clipboardData?.getData("text/plain")
        console.log("Pasted text: $pastedData")
        
        // Optionally prevent default and handle custom paste logic
        // event.preventDefault()
    }
})

// Event delegation example
Div({
    onClick { event ->
        // This will catch clicks from child elements due to event bubbling
        val clickedElement = event.target as? Element
        console.log("Clicked element: ${clickedElement?.tagName}")
        
        // Stop propagation if needed
        if (clickedElement?.classList?.contains("no-bubble") == true) {
            event.stopPropagation()
        }
    }
}) {
    Button { Text("Child Button 1") }
    Button({ classes("no-bubble") }) { Text("Child Button 2 (no bubble)") }
    P { Text("Clickable paragraph") }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-html--core

docs

css-styling.md

event-handling.md

forms-inputs.md

html-elements.md

index.md

svg-support.md

tile.json