Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tldraw/tldraw/llms.txt
Use this file to discover all available pages before exploring further.
BindingUtil is an abstract base class for creating custom binding types in tldraw. Bindings represent relationships between shapes (like an arrow pointing to a shape) and define how those relationships behave throughout their lifecycle.
Constructor
constructor(editor: Editor)
The editor instance that this binding util is associated with.
Static properties
The type identifier for this binding util. Must match the binding’s type.
props
RecordProps<TLUnknownBinding>
Validations for this binding’s props.
Migrations for this binding’s props, used when upgrading binding data between schema versions.
Instance properties
The editor instance passed to the constructor.
Abstract methods
getDefaultProps()
abstract getDefaultProps(): Partial<Binding['props']>
Returns the default props for a binding of this type.
Returns: Partial<Binding['props']> - Default properties for the binding.
Lifecycle methods
onBeforeCreate()
onBeforeCreate?(options: BindingOnCreateOptions<Binding>): Binding | void
Called when a binding is about to be created. Optionally return a new binding to replace the one being created (e.g., to set different initial props).
options
BindingOnCreateOptions<Binding>
required
The binding being created.
Returns: Binding | void - Optionally return a modified binding.
onAfterCreate()
onAfterCreate?(options: BindingOnCreateOptions<Binding>): void
Called after a binding has been created.
options
BindingOnCreateOptions<Binding>
required
The binding that was created.
onBeforeChange()
onBeforeChange?(options: BindingOnChangeOptions<Binding>): Binding | void
Called when a binding is about to be changed. Note that this only fires when the binding record itself is changing, not when the associated shapes change (use onAfterChangeFromShape and onAfterChangeToShape for that).
Optionally return a new binding to replace the one being changed (e.g., to enforce constraints on the binding’s props).
options
BindingOnChangeOptions<Binding>
required
The binding record before the change.
The binding record after the change.
Returns: Binding | void - Optionally return a modified binding.
onAfterChange()
onAfterChange?(options: BindingOnChangeOptions<Binding>): void
Called after a binding has been changed. Note that this only fires when the binding record itself is changing, not when the associated shapes change.
options
BindingOnChangeOptions<Binding>
required
The binding record before the change.
The binding record after the change.
onBeforeDelete()
onBeforeDelete?(options: BindingOnDeleteOptions<Binding>): void
Called when a binding is about to be deleted.
options
BindingOnDeleteOptions<Binding>
required
The binding being deleted.
onAfterDelete()
onAfterDelete?(options: BindingOnDeleteOptions<Binding>): void
Called after a binding has been deleted.
options
BindingOnDeleteOptions<Binding>
required
The binding that was deleted.
Shape change methods
onAfterChangeFromShape()
onAfterChangeFromShape?(options: BindingOnShapeChangeOptions<Binding>): void
Called after the shape referenced in a binding’s fromId is changed. Use this to propagate changes to the binding itself or the other shape as needed.
options
BindingOnShapeChangeOptions<Binding>
required
The binding record linking these two shapes.
The shape record before the change.
The shape record after the change.
Why did this shape change? 'self' means the shape itself changed, 'ancestry' means the shape’s ancestry changed but the shape itself may not have.
onAfterChangeToShape()
onAfterChangeToShape?(options: BindingOnShapeChangeOptions<Binding>): void
Called after the shape referenced in a binding’s toId is changed. Use this to propagate changes to the binding itself or the other shape as needed.
options
BindingOnShapeChangeOptions<Binding>
required
The binding record linking these two shapes.
The shape record before the change.
The shape record after the change.
Why did this shape change? 'self' means the shape itself changed, 'ancestry' means the shape’s ancestry changed but the shape itself may not have.
Shape deletion methods
onBeforeDeleteFromShape()
onBeforeDeleteFromShape?(options: BindingOnShapeDeleteOptions<Binding>): void
Called before the shape referenced in a binding’s fromId is about to be deleted. Use with care - you may want to use onBeforeIsolateFromShape instead.
options
BindingOnShapeDeleteOptions<Binding>
required
The binding record that refers to the shape.
The shape that is about to be deleted.
onBeforeDeleteToShape()
onBeforeDeleteToShape?(options: BindingOnShapeDeleteOptions<Binding>): void
Called before the shape referenced in a binding’s toId is about to be deleted. Use with care - you may want to use onBeforeIsolateToShape instead.
options
BindingOnShapeDeleteOptions<Binding>
required
The binding record that refers to the shape.
The shape that is about to be deleted.
Shape isolation methods
onBeforeIsolateFromShape()
onBeforeIsolateFromShape?(options: BindingOnShapeIsolateOptions<Binding>): void
Called before the shape referenced in a binding’s fromId is about to be isolated from the shape referenced in toId.
Isolation happens whenever two bound shapes are separated:
- One is deleted, but the other is not
- One is copied, but the other is not
- One is duplicated, but the other is not
If the remaining shape depends on the binding for its rendering, it may now be in an inconsistent state. For example, an arrow shape depends on the binding to know where the end of the arrow is. If the binding is removed, the arrow would suddenly point to the wrong location. Use isolation callbacks to update the shape based on the binding that’s about to be removed.
options
BindingOnShapeIsolateOptions<Binding>
required
The binding record that refers to the shape.
The shape being removed. For deletion, this is the deleted shape. For copy/duplicate, this is the shape that isn’t being copied/duplicated and is getting left behind.
onBeforeIsolateToShape()
onBeforeIsolateToShape?(options: BindingOnShapeIsolateOptions<Binding>): void
Called before the shape referenced in a binding’s toId is about to be isolated from the shape referenced in fromId. See onBeforeIsolateFromShape for details about isolation.
options
BindingOnShapeIsolateOptions<Binding>
required
The binding record that refers to the shape.
The shape being removed. For deletion, this is the deleted shape. For copy/duplicate, this is the shape that isn’t being copied/duplicated and is getting left behind.
Other methods
onOperationComplete()
onOperationComplete?(): void
Called whenever a store operation involving this binding type has completed. This is useful for working with networks of related bindings that may need to update together.
Example
import { BindingUtil, TLBinding } from '@tldraw/editor'
// Define a custom binding type
interface StickerBinding extends TLBinding {
type: 'sticker'
props: {
position: { x: number; y: number }
}
}
// Create a binding util for the sticker binding
class StickerBindingUtil extends BindingUtil<StickerBinding> {
static override type = 'sticker'
override getDefaultProps() {
return {
position: { x: 0.5, y: 0.5 }
}
}
override onAfterChangeToShape({ binding, shapeAfter }) {
// Update the sticker position when the bound shape moves
const sticker = this.editor.getShape(binding.fromId)
if (!sticker) return
// Custom logic to reposition the sticker
// ...
}
override onBeforeDeleteToShape({ binding }) {
// Remove the sticker when the bound shape is deleted
this.editor.deleteShapes([binding.fromId])
}
}