Custom double-click behavior
This example shows how to customize the double-click behavior on canvas by overriding the SelectTool's Idle state's handleDoubleClickOnCanvas
method from the onMount
callback.
The example demonstrates runtime method replacement, which is a powerful technique for customizing built-in tool behavior without creating entirely new tools. In this simplified version, double-clicking on the canvas shows an alert instead of creating a text shape, demonstrating the basic pattern for method override.
This pattern is useful when you want to extend existing tool behavior, add conditional logic, or customize built-in interactions without forking the entire tool.
import { StateNode, TLClickEventInfo, Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
// There's a guide at the bottom of this file!
export default function CustomDoubleClickBehaviorExample() {
return (
<div className="tldraw__editor">
<Tldraw
// [1]
onMount={(editor) => {
// [2]
type IdleStateNode = StateNode & {
handleDoubleClickOnCanvas(info: TLClickEventInfo): void
}
// [3]
const selectIdleState = editor.getStateDescendant<IdleStateNode>('select.idle')
if (!selectIdleState) throw Error('SelectTool Idle state not found')
// [4]
function customDoubleClickOnCanvasHandler(_info: TLClickEventInfo) {
// Your custom behavior goes here...
window.alert('double clicked on the canvas')
}
// [5]
selectIdleState.handleDoubleClickOnCanvas =
customDoubleClickOnCanvasHandler.bind(selectIdleState)
}}
/>
</div>
)
}
/*
This example demonstrates how to customize the double-click behavior on canvas
by overriding the SelectTool's Idle state's handleDoubleClickOnCanvas method.
Key concepts:
[1] onMount callback:
The onMount callback gives us access to the editor instance after it's
fully initialized. This is where we can access and modify built-in tools.
[2] Type definition for IdleStateNode:
We create a type that extends StateNode and includes the handleDoubleClickOnCanvas
method. This gives us proper TypeScript support when accessing the method.
[3] Getting the SelectTool's Idle state:
We use `editor.getStateDescendant<IdleStateNode>('select.idle')` to get a
reference to the Idle state of the SelectTool. The path 'select.idle'
refers to the SelectTool's 'idle' child state.
[4] Custom handler function:
We define our custom behavior in a separate function. This keeps the code
clean and makes it easy to test or reuse the handler logic.
[5] Method replacement with binding:
We replace the original handleDoubleClickOnCanvas method with our custom
implementation, binding it to the selectIdleState context so that `this`
refers to the correct state node when the function is called. This
completely overrides the default behavior.
The handleDoubleClickOnCanvas method is called when the user double-clicks on
the canvas (not on a shape). By overriding this method, we can customize what
happens when the user double-clicks on empty space.
Note: This approach completely replaces the original method. If you want to
preserve the original behavior and add to it, you should store a reference
to the original method before replacing it, then call it from your custom
implementation when appropriate.
*/
Is this page helpful?
Prev
Before delete shapeNext
After create/update shape