Back to Tldraw

Note shape

apps/docs/content/sdk-features/note-shape.mdx

5.4.07.5 KB
Original Source

The note shape is a sticky note: a colored square with text. Notes are built for brainstorming: you can spawn new notes next to existing ones with clone handles or keyboard shortcuts, and they snap into a grid beside their neighbors. See NoteShapeUtil and TLNoteShape.

tsx
import { toRichText } from 'tldraw'

editor.createShape({
	type: 'note',
	x: 100,
	y: 100,
	props: {
		color: 'yellow',
		labelColor: 'black',
		richText: toRichText('My note'),
		size: 'm',
		font: 'draw',
		align: 'middle',
		verticalAlign: 'middle',
	},
})

Sizing behavior

Notes have a fixed base width of 200 pixels (the noteWidth display value). Unlike most shapes, you can't manually resize a note by default. Instead, notes grow vertically to fit their text. The growY property tracks how much extra height the note needs beyond its base size.

When text is too wide, the note shrinks the font size (down to a minimum of 14px) before allowing text to wrap. This keeps notes compact without hiding content.

Clone handles

Notes display clone handles on their edges—small plus buttons at the top, right, bottom, and left sides. These handles let you quickly create adjacent notes.

Click a clone handle to create a new note in that direction. If a note already exists there, tldraw selects it and starts editing instead. Drag a clone handle to create a new note and immediately start moving it; when you release, the new note enters edit mode.

Clone handles only appear when the note is selected and the effective zoom (zoom × note scale) is high enough. Below 25% they're hidden entirely, and between 25% and 50% only the bottom handle appears. Touch input never shows clone handles.

The handles come from ShapeUtil#getHandles: each has type: 'clone' and an id of top, right, bottom, or left.

Adjacent snapping

When you create a note with the note tool (N key) or drag an existing note, tldraw checks whether you're near an "adjacent position": an empty slot next to another note. If you're within 10 screen pixels of a slot, the note snaps into place with consistent spacing.

Snapping only considers notes with the same scale. New notes created with the tool only snap next to unrotated notes; dragged notes snap next to notes with matching rotation. The spacing comes from editor.options.adjacentShapeMargin (10 pixels by default; see TldrawOptions).

Keyboard navigation

When editing a note, you can use keyboard shortcuts to create adjacent notes:

ShortcutAction
TabCreate or select note right
Shift+TabCreate or select note left
Cmd/Ctrl+EnterCreate or select note below
Shift+Cmd/Ctrl+EnterCreate or select note above

These shortcuts respect the current note's rotation. They also handle right-to-left text: in RTL content, Tab moves left instead of right. When the cursor is inside a list, Tab indents the list item instead of creating a note.

When moving down, the keyboard shortcut accounts for the current note's growY. This keeps notes from overlapping when one note has grown taller than the base size.

Visual appearance

Notes render with a subtle drop shadow seeded from the shape's ID, so each note has slightly different lift and opacity. The shadow responds to the note's rotation on the canvas. Below 25% effective zoom (adjusted for the note's scale) the shadow is replaced with a plain bottom border to keep rendering cheap.

The note's text color is determined by its labelColor property. When set to 'black' (the default), the note uses a color that contrasts well with the background. Other label colors override this automatic selection.

Properties

PropertyTypeDescription
colorTLDefaultColorStyleBackground color of the note
labelColorTLDefaultColorStyleText color (independent of background)
richTextTLRichTextNote content with formatting
sizeTLDefaultSizeStyleSize preset (s, m, l, xl) affecting base font
fontTLDefaultFontStyleFont family (draw, sans, serif, mono)
alignTLDefaultHorizontalAlignStyleHorizontal text alignment
verticalAlignTLDefaultVerticalAlignStyleVertical text alignment
fontSizeAdjustmentnumber | nullRatio applied to the base font size when text shrinks to fit (set automatically)
growYnumberAdditional height beyond the base 200px (set automatically)
urlstringOptional hyperlink URL
scalenumberScale factor applied to the shape
textLastEditedBystring | nullID of the user who last edited the note's text (set automatically)

Configuration

Notes support the following configuration options:

OptionTypeDefaultDescription
resizeMode'none' | 'scale''none'How the note resizes. Set to 'scale' for manual resize handles.

By default, notes can't be manually resized—they only grow based on text content. To allow user resizing with locked aspect ratio:

tsx
import { Tldraw, NoteShapeUtil } from 'tldraw'
import 'tldraw/tldraw.css'

const ConfiguredNoteUtil = NoteShapeUtil.configure({
	resizeMode: 'scale',
})

export default function App() {
	return (
		<div style={{ position: 'fixed', inset: 0 }}>
			<Tldraw shapeUtils={[ConfiguredNoteUtil]} />
		</div>
	)
}

See the note resizing example for a working demo. Other display values, such as noteWidth, noteHeight, and colors, can be customized through the display value hooks on NoteShapeUtil options; see Themes.

Dynamic resize mode

When editor.user.getIsDynamicResizeMode() is true, new notes are created at a scale inversely proportional to the current zoom level, so they stay visually consistent regardless of zoom. Editor#getResizeScaleFactor returns that scale. See Text shape for details.

  • Attribution — How notes display who last edited them in multiplayer sessions
  • Default shapes — Overview of all built-in shapes
  • Rich text — Working with formatted text content
  • Styles — Working with shape styles like color and size