Prevent multi-shape selection

Limit the selection to a single shape by rewriting selection changes in a before-change handler.

import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'

export default function PreventMultiShapeSelectionExample() {
	return (
		<div className="tldraw__editor">
			<Tldraw
				onMount={(editor) => {
					// Rewriting to the last id (rather than rejecting) keeps brushing and select-all usable.
					editor.sideEffects.registerBeforeChangeHandler('instance_page_state', (prev, next) => {
						if (
							prev.selectedShapeIds !== next.selectedShapeIds &&
							next.selectedShapeIds.length > 1
						) {
							return {
								...next,
								selectedShapeIds: [next.selectedShapeIds[next.selectedShapeIds.length - 1]],
							}
						}
						return next
					})
				}}
			/>
		</div>
	)
}

The current selection is stored on the instance_page_state record as selectedShapeIds. This example registers a registerBeforeChangeHandler for that record and, whenever an incoming change would select more than one shape, returns a copy with only the last id. Since every selection method writes to the same record, one handler covers shift-click, brush selection, select all, and editor.select() calls from your own code.

Try creating a few shapes and shift-clicking or dragging a selection box over them: only one ends up selected. Rewriting the change instead of rejecting it (by returning prev) means the user's action still does something sensible.

Is this page helpful?
Prev
Prevent shape changes
Next
Before create/update shape