tldraw/tldraw
UI system
Active contributors: Steve Ruiz, Mime Čuvalo, Mitja Bezenšek, Lu Wilson
Purpose
How the tldraw UI is composed and how to customize it without forking. The default UI ships in packages/tldraw/src/lib/ui/, controlled by the <TldrawUi /> component.
The shell
graph TD
Tldraw["<Tldraw />"] -->|wraps| TldrawUi["<TldrawUi />"]
TldrawUi --> Toolbar
TldrawUi --> StylePanel
TldrawUi --> MainMenu
TldrawUi --> PageMenu
TldrawUi --> SharePanel
TldrawUi --> ContextMenu
TldrawUi --> NavigationPanel
TldrawUi --> Toasts
TldrawUi --> Dialogs
TldrawUi --> KeyboardShortcuts
TldrawUi --> MinimapTldrawUi (packages/tldraw/src/lib/ui/TldrawUi.tsx) is the shell. It composes the default panels and exposes them as named slots that the override system can replace.
Components
Under packages/tldraw/src/lib/ui/components/:
| Folder | Component |
|---|---|
Toolbar/ |
Bottom toolbar with tool selectors. |
StylePanel/ |
Color, dash, fill, font, size pickers. |
MainMenu/ |
Top-left main menu. |
PageMenu/ |
Page list and management. |
ContextMenu/ |
Right-click menu. |
ZoomMenu/ |
Zoom controls. |
HelpMenu/ |
Help/keyboard shortcuts. |
ActionsMenu/ |
Per-selection actions. |
DebugMenu/ |
Developer-only debug toggles. |
SharePanel/ |
Multiplayer share UI. |
KeyboardShortcutsDialog/ |
Shortcuts cheat sheet. |
Minimap/ |
Minimap of the page. |
NavigationPanel/ |
Top-right navigation. |
OfflineIndicator/ |
Connection status indicator. |
QuickActions/ |
Floating quick action buttons. |
HelperButtons/ |
Floating helper buttons (e.g., next/prev page). |
TopPanel/ |
Top center panel. |
Dialogs.tsx |
Dialog stack. |
Toasts.tsx |
Toast notifications. |
The single largest piece is menu-items.tsx (~20 KB), which declares every menu item with its label, shortcut, and action. It is the canonical place to look for "where is this menu item registered?".
Style props
Style props (color, dash, fill, font, size) are defined in packages/tlschema/src/styles/ and rendered by the style panel. Adding a custom style prop is a schema-level change: define it, register it on your shape util, and the style panel picks it up automatically.
Overrides
packages/tldraw/src/lib/ui/overrides.ts defines the override system. It is the canonical way to customize the UI without forking:
import { Tldraw } from 'tldraw'
const overrides = {
actions(editor, actions) {
actions['my-action'] = {
id: 'my-action',
label: 'My action',
kbd: 'shift+m',
onSelect() {
editor.createShape({ type: 'note', x: 0, y: 0 })
},
}
return actions
},
toolbar(editor, schema, helpers) {
schema.push(helpers.menuItem(actions['my-action']))
return schema
},
}
return <Tldraw overrides={overrides} />Helpers live in packages/tldraw/src/lib/ui/hooks/menuHelpers.ts. The dotcom client uses overrides extensively (search for overrides under apps/dotcom/client/src/).
Localization
Translation strings live in packages/assets/translations/ (generated) and source under assets/translations/. The UI looks up strings by id via the i18n hook in packages/tldraw/src/lib/ui/hooks/. New strings: add to the source JSON, run yarn build-i18n, and use intl.formatMessage({ id }) in code.
Theming
packages/editor/src/lib/editor/managers/ThemeManager/ resolves the active theme. The CSS in packages/tldraw/src/lib/ui.css (47 KB) uses CSS custom properties driven by the resolved theme, so light/dark/custom themes swap without re-rendering.
CSS conventions
- One large
ui.cssfor the SDK's default UI. - Editor-only CSS in
packages/editor/editor.css. - Class names follow
tlui-<component>andtl-<editor-element>conventions. tldraw.cssis a meta-import that pulls botheditor.cssandui.css.
Related
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.