snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-23 16:12:52 +05:00
commit a774ac673a
4541 changed files with 770499 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
---
title: Note shape
created_at: 1/31/2026
updated_at: 1/31/2026
keywords:
- note
- sticky note
- note tool
- clone handles
- adjacent notes
status: published
date: 1/31/2026
---
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:
| Shortcut | Action |
| ------------------------ | --------------------------- |
| **Tab** | Create or select note right |
| **Shift+Tab** | Create or select note left |
| **Cmd/Ctrl+Enter** | Create or select note below |
| **Shift+Cmd/Ctrl+Enter** | Create 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
| Property | Type | Description |
| -------------------- | ------------------------------- | -------------------------------------------------------------------------------- |
| `color` | `TLDefaultColorStyle` | Background color of the note |
| `labelColor` | `TLDefaultColorStyle` | Text color (independent of background) |
| `richText` | `TLRichText` | Note content with formatting |
| `size` | `TLDefaultSizeStyle` | Size preset (`s`, `m`, `l`, `xl`) affecting base font |
| `font` | `TLDefaultFontStyle` | Font family (`draw`, `sans`, `serif`, `mono`) |
| `align` | `TLDefaultHorizontalAlignStyle` | Horizontal text alignment |
| `verticalAlign` | `TLDefaultVerticalAlignStyle` | Vertical text alignment |
| `fontSizeAdjustment` | `number \| null` | Ratio applied to the base font size when text shrinks to fit (set automatically) |
| `growY` | `number` | Additional height beyond the base 200px (set automatically) |
| `url` | `string` | Optional hyperlink URL |
| `scale` | `number` | Scale factor applied to the shape |
| `textLastEditedBy` | `string \| null` | ID of the user who last edited the note's text (set automatically) |
## Configuration
Notes support the following configuration options:
| Option | Type | Default | Description |
| ---------------------- | ------------------------------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| `resizeMode` | `'none'` \| `'scale'` | `'none'` | How the note resizes. Set to `'scale'` for manual resize handles. |
| `AttributionComponent` | `ComponentType<TLNoteShapeAttributionProps>` \| `null` | `DefaultNoteShapeAttribution` | Component for the attribution badge. Set to `null` to hide it, or provide your own to replace it. |
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](/examples/configuration/resize-note) 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](/sdk-features/themes).
### Attribution badge
Notes show the name of the user who last edited their text as a small badge in the corner. This badge is rendered by the `AttributionComponent` option above, which you can override or hide with `NoteShapeUtil.configure`—it applies on the canvas and in image exports. See [attribution](/sdk-features/attribution) for details.
## 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](/sdk-features/text-shape#Dynamic-resize-mode) for details.
## Related articles
- [Attribution](/sdk-features/attribution) — How notes display who last edited them in multiplayer sessions
- [Default shapes](/sdk-features/default-shapes) — Overview of all built-in shapes
- [Rich text](/sdk-features/rich-text) — Working with formatted text content
- [Styles](/sdk-features/styles) — Working with shape styles like color and size