interface / @typed/template/EventHandler

EventHandler

Represents a DOM event handler that returns an Effect.

It encapsulates the event handler logic and any options (like preventDefault, once, etc.) that should be applied when the event is triggered.

Package version
1.0.0-beta.7
Category
Event handlers
Since
1.0.0

Import

import { EventHandler } from "@typed/template/EventHandler";

Signatures

export interface EventHandler<Ev extends Event = Event, E = never, R = never> extends Pipeable {
    readonly [EventHandlerTypeId]: EventHandlerTypeId;
    readonly handler: (event: Ev) => Effect.Effect<unknown, E, R>;
    readonly options: (AddEventListenerOptions & EventOptions) | undefined;
}

Why

EventHandler connects browser event behavior to an Effect program. When installed through EventSource, the callback receives a Proxy over the native event: properties and bound methods forward to the browser event while currentTarget is overridden with the delegated target. The wrapper is not pooled, but it is not object-identical to the native event.

Ownership and lifetime

make only describes the handler. A rendered template installs the listener within its Effect Scope and removes it when that rendered part is finalized. Any Effect returned by the callback keeps its error and required-service channels in the EventHandler<Ev, E, R> type.

Event options

Native AddEventListenerOptions are passed through. Typed’s convenience flags call the forwarded native methods before the handler; they do not introduce a separate propagation or default-action system.

Property: [[computed:[EventHandlerTypeId]]]

Nominal evidence used by isEventHandler.

Property: [[computed:[EventHandlerTypeId]]]: Why

The key prevents arbitrary callback-shaped objects from becoming handlers.

Property: [[computed:[EventHandlerTypeId]]]: Ownership and lifetime

This field is immutable metadata for the handler description.

Property: handler

The Effect program invoked with the supplied event or delegated event proxy.

Property: handler: Why

The callback preserves typed failures and services while retaining browser event behavior through the delegated proxy.

Property: handler: Ownership and lifetime

The mounted EventSource runs each Effect in a fiber owned by its Scope.

Property: options

Native listener options plus Typed’s pre-handler event controls.

Property: options: Why

Browser capture, passive, signal, propagation, and default behavior stay explicit.

Property: options: Ownership and lifetime

EventSource reads this immutable record when attaching the listener.

Examples

import { Effect } from "effect"
import * as EventHandler from "@typed/template/EventHandler"
import { html } from "@typed/template"

// Simple event handler
const handleClick = EventHandler.make((event: MouseEvent) => {
  console.log("Clicked!", event)
})

// Event handler with Effect
const handleSubmit = EventHandler.make((event: SubmitEvent) =>
  Effect.gen(function* () {
    event.preventDefault()
    yield* Effect.sync(() => console.log("Form submitted"))
  })
)

// Use in template
const template = html`<button onclick=${handleClick}>Click me</button>`

Other public imports

These import paths expose the same declaration. Each page retains its own public name and signature.

Source