#9500·tldraw

Add an InteractionShape that emits configurable events for hit areas and interaction zones

Author: steveruizokCreated Jul 5, 2026Updated Sep 28, 2026
Labelsfeaturesdkmaybe

️: Add an InteractionShape that emits events when the user interacts with it, with optional props to help condition the event name, e.g. "name": "prevButton" might cause the app to emit { type: "custom-event", name: "prevButton:pointerDown" } or something. The InteractionShape should also be highly configurable via props to determine whether it can drag, hover, rotate, be clicked, and so on, and should emit events during all of those interactions. This would be used to create "hit areas" or other arbitrary interaction zones. An AI agent designing a tldraw canvas would take advantage of this shape.


A new default InteractionShape shipped in the SDK that acts as a configurable, invisible interaction zone or "hit area." It renders nothing; its purpose is to detect interactions and emit events describing them. It emits across the full set of interactions — pointer down/up, click, double-click, hover enter/leave, drag start/move/end, and rotate. A name prop lets the app condition on which zone fired (event name along the lines of "prevButton:pointerDown"), and the emitted event also carries the shape id so consumers can identify the exact instance. Additional props toggle which interactions are enabled; when a given interaction is disabled the shape stays inert for that gesture (no event, no default canvas behavior). Apps consume the events by attaching a standard editor event listener, rather than through a callback prop or store side-effect. The shape is designed to be created and positioned programmatically — the motivating use case is an AI agent composing a tldraw canvas and wiring up arbitrary interactive regions in code.

Open questions

  1. Should this ship as a default shape in the SDK, or as an example showing how to build a custom InteractionShape? Ship it as a default shape in the SDK.
  2. How should apps receive the emitted events — the editor event bus, a callback prop on the component, a store side-effect subscription, or something else? Through a standard editor event listener; the shape emits onto the editor's event bus.
  3. Which interactions should be toggleable and emit events — is the full set pointer down/up, click, double-click, hover enter/leave, drag start/move/end, and rotate, or a smaller set? The full set.
  4. What should the shape look like — an invisible hit area by default, or does it render something (fill, border, label), and is appearance configurable? It renders nothing; it should be invisible.
  5. When an interaction is disabled (e.g. canDrag: false), should the shape stay fully inert for that gesture, or still emit the event while suppressing the default canvas behavior? Inert for that gesture — no event, no default behavior.
  6. What should the emitted event payload look like — is type always "custom-event" with the interaction encoded in name as "<name>:<interaction>", or should the payload carry structured fields (e.g. name, interaction, shapeId, pointer info)? Not fully decided — a name:interaction event name is likely the better shape, but the shape id must also be present on the event. Implementer has latitude on the exact structure.
  7. Since the shape is invisible and can be inert to gestures, how should an author create, select, resize, and position it — is there an authoring affordance in the editor, or is it purely programmatic (props-driven) for the AI-agent use case? Purely programmatic — the shape is designed to be written by code, so no in-editor authoring affordance is required.

Confidence: 88%, ready to get started.