Remove docs source. (#2030)

The docs source is going back to the brivate secret sauce repo!

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package[^2]
This commit is contained in:
Steve Ruiz 2023-10-06 14:44:15 +01:00 committed by GitHub
parent 53a8fd6c69
commit 68c52f0bfa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 0 additions and 875 deletions

View file

View file

@ -1,14 +0,0 @@
{
"steveruizok": {
"name": "Steve Ruiz",
"email": "steve@tldraw.com",
"twitter": "steveruizok",
"image": "steve_ruiz.jpg"
},
"api": {
"name": "API",
"email": "hello@tldraw.com",
"twitter": "tldraw",
"image": "api.jpg"
}
}

View file

@ -1,15 +0,0 @@
---
title: Contributing
status: published
author: steveruizok
date: 3/22/2023
order: 0
---
Interested in contributing to the open source project?
You can find tldraw on GitHub at [github.com/tldraw/tldraw](https://github.com/tldraw/tldraw). You can [create an issue](https://github.com/tldraw/tldraw/issues/new/choose) and submit pull requests for our review.
Please see our [Contributing guide](https://github.com/tldraw/tldraw/blob/main/CONTRIBUTING.md) for more information.
Please also see our [Code of Conduct](https://github.com/tldraw/tldraw/blob/main/CODE_OF_CONDUCT.md) for our expectations around contributor culture.

View file

@ -1,11 +0,0 @@
---
title: Translations
status: published
author: steveruizok
date: 3/22/2023
order: 1
---
The tldraw user interface (in [@tldraw/ui](/docs/user-interface)) is currently translated into over thirty different languages, with twenty languages at above 70% completion. Where a key's translation is missing in the user's current language language, the default (English) translation will be used instead.
We manage our translations through [Lokalise](https://www.lokalise.com), a long-time tldraw sponsor. If you would like to help by translating or reviewing translations, please let us know on [Discord](https://discord.gg/sKNgCZyrrf) so that we can add you to the project.

View file

@ -1,69 +0,0 @@
---
title: Assets
status: published
author: steveruizok
date: 6/9/2023
order: 9
---
In order to use the [`<Tldraw/>`](/gen/tldraw/Tldraw) component, the app must be able to find certain assets. These are contained in the `embed-icons`, `fonts`, `icons`, and `translations` folders. We offer a few different ways of making these assets available to your app.
### 1. Using a public CDN
By default we serve these assets from a [public CDN called unpkg](https://unpkg.com/browse/@tldraw/assets@2.0.0-alpha.12/), so everything should work out of the box and is a good way to get started.
If you would like to customize some of the assets you can pass the customizations to our [`<Tldraw/>`](/gen/tldraw/Tldraw) component. For example, to use a custom icon for the `hand` tool you can do the following:
```javascript
const assetUrls = {
icons: {
'tool-hand': './custom-tool-hand.svg',
},
}
<Tldraw assetUrls={assetUrls} />
```
This will use the custom icon for the `hand` tool and the default assets for everything else.
### 2. Hosting the assets yourself
If you want more flexibility you can also host these assets yourself:
1. Download the `embed-icons`, `fonts`, `icons`, and `translations` folders from the [assets folder](https://github.com/tldraw/tldraw/tree/main/assets) of the tldraw repository.
2. Place the folders in your project's public path.
3. Pass `assetUrls` prop to our `<Tldraw/>` component to let the component know where the assets live.
You can use our `getAssetUrls` helper function from the `@tldraw/assets` package to generate these urls for you.
```javascript
import { getAssetUrls } from '@tldraw/assets/selfHosted'
const assetUrls = getAssetUrls()
<Tldraw assetUrls={assetUrls} />
```
While these files must be available, you can overwrite the individual files: for example, by placing different icons under the same name or modifying / adding translations.
If you use a CDN for hosting these files you can specify the base url of your assets. To recreate the above option of serving the assets from unpkg you would do the following:
```javascript
const assetUrls = getAssetUrls({
baseUrl: 'https://unpkg.com/@tldraw/assets@2.0.0-alpha.12/',
})
```
### 3. Using a bundler
If you're using a bundler like webpack or rollup, you can import the assets directly from the `@tldraw/assets` package. Here you can use `getAssetUrlsByMetaUrl` helper function:
```javascript
import { getAssetUrlsByMetaUrl } from '@tldraw/assets/urls'
const assetUrls = getAssetUrlsByMetaUrl()
<Tldraw assetUrls={assetUrls} />
```
### Adding custom assets
We have plans to offer more rich asset customizations in the future (e.g. custom cursors, custom fonts, translations for other languages etc).

View file

@ -1,11 +0,0 @@
---
title: Collaboration
status: published
author: steveruizok
date: 3/22/2023
order: 7
---
Coming soon.
See the [tldraw-yjs example](https://github.com/tldraw/tldraw-yjs-example) for an example of how to use yjs with the `@tldraw/tldraw` library.

View file

@ -1,250 +0,0 @@
---
title: Editor
status: published
author: steveruizok
date: 3/22/2023
order: 3
keywords:
- ui
- app
- editor
- control
- select
---
##### Table of Contents
- [Introduction](#introduction)
- [Store](#store)
- [Events and Tools](#events-and-tools)
- [Inputs](#inputs)
- [Common things to do with the editor](#common-things-to-do-with-the-editor)
## Introduction
The [`Editor`](/gen/editor/Editor) class is the main way of controlling tldraw's editor. You can use it to manage the editor's internal state, make changes to the document, or respond to changes that have occurred.
By design, the [`Editor`](/gen/editor/Editor)'s surface area is very large. Almost everything is available through it. Need to create some shapes? Use [`editor.createShapes()`](/gen/editor/Editor#createShapes). Need to delete them? Use [`editor.deleteShapes(editor.selectedShapeIds)`](/gen/editor/Editor#deleteShapes). Need a sorted array of every shape on the current page? Use [`editor.currentPageShapesSorted`](/gen/editor/Editor#currentPageShapesSorted).
This page gives a broad idea of how the [`Editor`](/gen/editor/Editor) class is organized and some of the architectural concepts involved. The full reference is available in the [Editor API](/gen/editor/Editor).
## Store
The editor holds the raw state of the document in its [`store`](/gen/editor/Editor#store) property. Data is kept here as a table of JSON serializable records.
For example, the store contains a `page` record for each page in the current document, as well as an `instancePageState` record for each page that stores information about the editor's state for that page, and a single `instanceState` for each editor instance which stores the id of the user's current page.
The editor also exposes many _computed_ values which are derived from other records in the store. For example, [`editor.selectedShapeIds`](/gen/editor/Editor#selectedShapeIds) is a computed property that will return the editor's current selected shape ids for its current page.
You can use these properties directly or you can use them in signals.
```tsx
import { track, useEditor } from "@tldraw/tldraw"
export const SelectedShapeIdsCount = track(() => {
const editor = useEditor()
return (
<div>{editor.selectedShapeIds.length}</div>
)
})
```
### Changing the state
The [`Editor`](/gen/editor/Editor) class has many methods for updating its state. For example, you can change the current page's selection using [`editor.setSelectedShapes`](/gen/editor/Editor#setSelectedShapes). You can also use other convenience methods, such as [`editor.select`](/gen/editor/Editor#), [`editor.deselect`](/gen/editor/Editor#deselect), [`editor.selectAll`](/gen/editor/Editor#selectAll), or [`editor.selectNone`](/gen/editor/Editor#selectNone).
```ts
editor.selectNone()
editor.select(myShapeId, myOtherShapeId)
editor.selectedShapeIds // [myShapeId, myOtherShapeId]
```
Each change to the state happens within a transaction. You can batch changes into a single transaction using the [`editor.batch`](/gen/editor/Editor#batch) method. It's a good idea to batch wherever possible, as this reduces the overhead for persisting or distributing those changes.
### Listening for changes
You can subscribe to changes using [`editor.store.listen`](/gen/store/Store#listen). Each time a transaction completes, the editor will call the callback with a history entry. This entry contains information about the records that were added, changed, or deleted, as well as whether the change was caused by the user or from a remote change.
```ts
editor.store.listen(entry => {
entry // { changes, source }
})
```
### Remote changes
By default, changes to the editor's store are assumed to have come from the editor itself. You can use [`editor.store.mergeRemoteChanges`](/gen/store/Store#mergeRemoteChanges) to make changes in the store that will be emitted via [`store.listen`](/gen/store/Store#listen) with the `source` property as `'remote'`.
If you're setting up some kind of multiplayer backend, you would want to send only the `'user'` changes to the server and merge the changes from the server using [`editor.store.mergeRemoteChanges`](/gen/store/Store#mergeRemoteChanges).
### Undo and redo
The history stack in tldraw contains two types of data: "marks" and "commands". Commands have their own `undo` and `redo` methods that describe how the state should change when the command is undone or redone.
You can call [`editor.mark(id)`](/gen/editor/Editor#mark) to add a mark to the history stack with the given `id`.
When you call [`editor.undo()`](/gen/editor/Editor#undo), the editor will undo each command until it finds either a mark or the start of the stack. When you call [`editor.redo()`](/gen/editor/Editor#redo), the editor will redo each command until it finds either a mark or the end of the stack.
```ts
// A
editor.mark("duplicate everything")
editor.selectAll()
editor.duplicateShapes(editor.selectedShapeIds)
// B
editor.undo() // will return to A
editor.redo() // will return to B
```
You can call [`editor.bail()`](/gen/editor/Editor#bail) to undo and delete all commands in the stack until the first mark.
```ts
// A
editor.mark("duplicate everything")
editor.selectAll()
editor.duplicateShapes(editor.selectedShapeIds)
// B
editor.bail() // will return to A
editor.redo() // will do nothing
```
You can use [`editor.bailToMark(id)`](/gen/editor/Editor#bailToMark) to undo and delete all commands and marks until you reach a mark with the given `id`.
```ts
// A
editor.mark("first")
editor.selectAll()
// B
editor.mark("second")
editor.duplicateShapes(editor.selectedShapeIds)
// C
editor.bailToMark("first") // will return to A
```
## Events
The [`Editor`](/gen/editor/Editor) class receives events from its [`dispatch`](/gen/editor/Editor#dispatch) method. When the [`Editor`](/gen/editor/Editor) receives an event, it is first handled internally to update [`editor.inputs`](/gen/editor/Editor#inputs) and other state before, and then sent into to the editor's state chart.
You shouldn't need to use the [`dispatch`](/gen/editor/Editor#dispatch) method directly, however you may write code in the state chart that responds to these events. See the [Tools page](tools) to learn how to do that, or read below for a more detailed information about the state chart itself.
### State Chart
The [`Editor`](/gen/editor/Editor) class has a "state chart", or a tree of [`StateNode`](/gen/editor/StateNode) instances, that contain the logic for the editor's tools such as the select tool or the draw tool. User interactions such as moving the cursor will produce different changes to the state depending on which nodes are active.
Each node can be active or inactive. Each state node may also have zero or more children. When a state is active, and if the state has children, one (and only one) of its children must also be active. When a state node receives an event from its parent, it has the opportunity to handle the event before passing the event to its active child. The node can handle an event in any way: it can ignore the event, update records in the store, or run a _transition_ that changes which states nodes are active.
When a user interaction is sent to the editor via its [`dispatch`](/gen/editor/Editor#dispatch) method, this event is sent to the editor's root state node (`editor.root`) and passed then down through the chart's active states until either it reaches a leaf node or until one of those nodes produces a transaction.
<Image title="Events" src="/images/api/events.png" alt="A diagram showing an event being sent to the editor and handled in the state chart." title="The editor passes an event into the state start where it is handled by each active state in order."/>
### Path
You can get the editor's current "path" of active states via `editor.root.path`. In the above example, the value would be `"root.select.idle"`.
You can check whether a path is active via [`editor.isIn`](/gen/editor/Editor#isIn), or else check whether multiple paths are active via [`editor.isInAny`](/gen/editor/Editor#isInAny).
```ts
editor.store.path // 'root.select.idle'
editor.isIn('root.select') // true
editor.isIn('root.select.idle') // true
editor.isIn('root.select.pointing_shape') // false
editor.isInAny('editor.select.idle', 'editor.select.pointing_shape') // true
```
Note that the paths you pass to [`isIn`](/gen/editor/Editor#isIn) or [`isInAny`](/gen/editor/Editor#isInAny) can be the full path or a partial of the start of the path. For example, if the full path is `root.select.idle`, then [`isIn`](/gen/editor/isIn) would return true for the paths `root`, `root.select`, or `root.select.idle`.
> If all you're interested in is the state below `root`, there is a convenience property, [`editor.currentToolId`](/gen/editor/Editor#currentToolId), that can help with the editor's currently selected tool.
```tsx
import { track, useEditor } from "@tldraw/tldraw"
export const CreatingBubbleToolUi = track(() => {
const editor = useEditor()
const isSelected = editor.isIn('root.bubble.creating')
if (!editor.currentToolId === 'bubble') return
return (
<div data-isSelected={isSelected}>Creating Bubble</div>
)
})
```
## Inputs
The editor's [`inputs`](/gen/editor/Editor#inputs) object holds information about the user's current input state, including their cursor position (in page space _and_ screen space), which keys are pressed, what their multi-click state is, and whether they are dragging, pointing, pinching, and so on.
Note that the modifier keys include a short delay after being released in order to prevent certain errors when modeling interactions. For example, when a user releases the "Shift" key, [`editor.inputs.shiftKey`](/gen/editor/Editor#inputs) will remain `true` for another 100 milliseconds or so.
This property is stored as regular data. It is not reactive.
## Common things to do with the editor
### Create shapes
```ts
editor.createShapes([
{
id,
type: 'geo',
x: 0,
y: 0,
props: {
geo: 'rectangle',
w: 100,
h: 100,
dash: 'draw',
color: 'blue',
size: 'm',
},
},
])
```
### Update shapes
```ts
const shape = editor.selectedShapes[0]
editor.updateShapes([
{
id: shape.id, // required
type: shape.type, // required
x: 100,
y: 100,
props: {
w: 200,
},
},
])
```
### Delete shapes
```ts
const shape = editor.selectedShapes[0]
editor.deleteShapes([shape.id])
```
### Get a shape by its id
```ts
editor.getShape(myShapeId)
```
### Move the camera
```ts
editor.setCamera(0, 0, 1)
```
---
See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to use tldraw's Editor API to control the editor.

View file

@ -1,18 +0,0 @@
---
title: Persistence
status: published
author: steveruizok
date: 3/22/2023
order: 6
keywords:
- data
- sync
- persistence
- database
- indexeddb
- localstorage
---
Coming soon.
See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to use persistence with the `@tldraw/tldraw` or `@tldraw/editor` libraries.

View file

@ -1,234 +0,0 @@
---
title: Shapes
status: published
author: steveruizok
date: 3/22/2023
order: 4
keywords:
- custom
- shapes
- shapeutils
- utils
---
##### Table of Contents
- [Introduction](#introduction)
- [Types of shape](#types-of-shape)
- [Inside a shape](#inside-a-shape)
- [Shape util](#shape-util)
- [Custom shapes](#custom-shapes)
- [Meta information](#meta-information)
## Introduction
In tldraw, a **shape** is something that can exist on the page, like an arrow, an image, or some text.
This article is about shapes: what they are, how they work, and how to create your own shapes. If you'd prefer to see an example, see the tldraw repository's [examples app](https://github.com/tldraw/tldraw/tree/main/apps/examples) for examples of how to create custom shapes in tldraw.
## Types of shape
The editor comes with some built-in [**core shapes**](/gen/editor/coreShapes), like the [text shape](/gen/tlschema/TLTextShape), the [group shape](/gen/tlschema/TLGroupShape) and more. These are required for the editor to work, so they can't be removed.
There are also some [**default shapes**](/gen/editor/defaultShapes) available, like the [arrow shape](/gen/tlschema/TLArrowShape), the [draw shape](/gen/tlschema/TLDrawShape), and more. The [`<Tldraw>`](/gen/editor/Editor) component provides access to these shapes automatically.
You can also create your own **custom shapes**. Find more information about that [below](#custom-shapes).
## Inside a shape
Shapes are just JSON objects that sit in the [store](/docs/editor#store).
Every shape contains some **base information**. These include the shape's type, position, rotation, opacity, and more. You can find the full list of base properties [here](/gen/tlschema/TLBaseShape).
```js
const shape = editor.getShape('some-shape-id')
if (shape) {
shape.type // The shape's type
shape.opacity // The shape's opacity
}
```
Every shape also contains some **shape-specific information**. We call these `props`. For example, the text shape has a [text prop](/gen/tlschema/textShapeProps), the arrow shape has a [start and end prop](/gen/tlschema/arrowShapeProps), and so on.
```js
const textShape = editor.getShape('some-text-shape-id')
if (textShape) {
textShape.props.text // The shape's text
textShape.props.font // The shape's font
}
```
## Shape util
While tldraw's shapes themselves are simple JSON objects, we use [`ShapeUtil`](/gen/editor/ShapeUtil) classes to answer questions about shapes. For example, when the editor needs to know the bounding box of a text shape, it will find the [`TextShapeUtil`](/gen/editor/TextShapeUtil) and call its [`getBounds`](/gen/editor/ShapeUtil#getBounds) method, passing in the text shape object as an argument.
```JavaScript
const util = this.getShapeUtil(myShape)
if (util) {
const bounds = util.getBounds(myShape)
bounds) // The shape's bounding box
}
```
## Custom shapes
You can create your own **custom shapes**. As an example, let's create a custom "card" shape. It'll be a simple rectangle with some text inside.
### Shape type
In tldraw's data model, each shape is represented by a JSON object. Let's first create a type that describes what this object will look like.
```ts
import { TLBaseShape } from '@tldraw/tldraw'
type CardShape = TLBaseShape<
'card',
{ w: number, h: number }
>
```
With the [`TLBaseShape`](/gen/editor/TLBaseShape) helper, we define the shape's `type` property (`card`) and the shape's `props` property (`{ w: number, h: number }`). The type can be any string but the props must be a regular [JSON-serializable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) JavaScript object.
The [`TLBaseShape`](/gen/editor/TLBaseShape) helper adds the other base properties of a shape, such as `x`, `y`, `rotation`, and `opacity`.
### Shape Util
While tldraw's shapes themselves are simple JSON objects, we use [`ShapeUtil`](/gen/editor/ShapeUtil) classes to answer questions about shapes.
Let's create a [`ShapeUtil`](/gen/editor/ShapeUtil) class for the shape.
```tsx
import { ShapeUtil, HTMLContainer, Box2d } from '@tldraw/tldraw'
class CardShapeUtil extends ShapeUtil<CardShape> {
static type = 'card' as const
getDefaultProps(): CardShape['props'] {
return {
w: 100,
h: 100,
}
}
getBounds(shape: CardShape) {
return new Box2d(0, 0, shape.props.w, shape.props.h)
}
component(shape: CardShape) {
return (
<HTMLContainer>Hello</HTMLContainer>
)
}
indicator(shape: CardShape) {
return (
<rect width={shape.props.w} height={shape.props.h}/>
)
}
}
```
This is a minimal [`ShapeUtil`](/gen/editor/ShapeUtil). We've given it a static property `type` that matches the type of our shape, we've provided implementations for the abstract methods [`getDefaultProps`](/gen/editor/ShapeUtil#getDefaultProps), [`getBounds`](/gen/editor/ShapeUtil#getBounds), [`component`](/gen/editor/ShapeUtil#component), and [`indicator`](/gen/editor/ShapeUtil#indicator).
We still have work to do on the `CardShapeUtil` class, but we'll come back to it later. For now, let's put the shape onto the canvas by passing it to the [`<Tldraw>`](/gen/tldraw/Tldraw) component.
### Defining the shape
Before we pass the shape down, we need to package it up in a way using the [`defineShape`](/gen/editor/defineShape) function. We can then pass an array of our defined shapes into the [`<Tldraw>`](/gen/tldraw/Tldraw) component's `shapes` prop.
```tsx
import { Tldraw } from '@tldraw/tldraw'
import '@tldraw/tldraw/tldraw.css'
const MyCardShape = defineShape('card', { util: CardShapeUtil })
const MyCustomShapes = [MyCardShape]
export default function () {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw shapeUtils={MyCustomShapes}/>
</div>
)
}
```
Let's create a card shape using the [`Editor`](/gen/editor/Editor) API. We'll do this by setting the `onMount` prop of the [`<Tldraw>`](/gen/tldraw/Tldraw) component.
```tsx
export default function () {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw shapeUtils={MyCustomShapes} onMount={editor => {
editor.createShapes([{ type: "card" }])
}}/>
</div>
)
}
```
Once the page refreshes, we should now have our custom shape on the canvas.
## Meta information
Shapes also have a [`meta`](/gen/tlschema/TLBaseShape#meta) property that you can fill with your own data. This should feel like a bit of a hack, however it's intended to be an escape hatch for applications where you want to use tldraw's existing shapes but also want to attach a bit of extra data to the shape.
Note that tldraw's regular shape definitions have an unknown object for the shape's `meta` property. To type your shape's meta, use a union like this:
```ts
type MyShapeWithMeta = TLGeoShape & { meta: { createdBy: string } }
const shape = editor.getShape<MyShapeWithMeta>(myGeoShape.id)
```
You can update a shape's `meta` property in the same way you would update its props, using [`Editor.updateShapes`](/gen/editor/Editor#updateShapes).
```ts
editor.updateShapes<MyShapeWithMeta>([{
id: myGeoShape.id,
type: "geo",
meta: {
createdBy: "Steve"
}
}])
```
Like [`props`](/gen/tlschema/TLBaseShape#props), the data in a shape's `meta` object must be JSON serializable.
In addition to setting meta properties this way, you can also set the default meta data for shapes using the Editor's [`getInitialMetaForShape`](/gen/editor/Editor#getInitialMetaForShape) method.
```tsx
editor.getInitialMetaForShape = (shape: TLShape) => {
if (shape.type === 'text') {
return { createdBy: currentUser.id, lastModified: Date.now() }
} else {
return { createdBy: currentUser.id }
}
}
```
Whenever new shapes are created using the [`createShapes`](/gen/editor/Editor#createShapes) method, the shape's meta property will be set using the [`getInitialMetaForShape`](/gen/editor/Editor#getInitialMetaForShape) method. By default this method returns an empty object.
## Using starter shapes
You can use "starter" shape utils like [`BaseBoxShapeUtil`](/gen/editor/BaseBoxShapeUtil) to get regular rectangular shape behavior.
> todo
## Flags
You can use flags like [`hideRotateHandle`](/gen/editor/ShapeUtil#hideRotateHandle) to hide different parts of the UI when the shape is selected, or else to control different behaviors of the shape.
> todo
## Interaction
You can turn on `pointer-events` to allow users to interact inside of the shape.
> todo
## Editing
You can make shapes "editable" to help decide when they're interactive or not.
> todo

View file

@ -1,68 +0,0 @@
---
title: Tools
status: published
author: steveruizok
date: 3/22/2023
order: 5
keywords:
- custom
- tools
- state
---
##### Table of Contents
- [Introduction](#introduction)
- [Types of tool](#types-of-tool)
- [Inside a tool](#inside-a-tool)
- [Handling events](#handling-events)
## Introduction
In tldraw, a **tool** is what we call any top-level state in our state chart. For example, the select tool, the draw tool, and the arrow tool are all top-level states that the user can be in.
<Image title="Tools" src="/images/api/tools.png" alt="A diagram showing the state chart of tldraw. The top row of states (apart from the Root state) are annotated as tools." title="The first level of states in the start chart are known as tools."/>
For more detailed information about the state chart, and how it works, go to the [Editor page](editor). Or read below for more information about tools, and how to make your own.
## Types of tool
The tldraw editor comes with some in-built **core tools**: the [select tool](/gen/editor/SelectTool), the [zoom tool](/gen/editor/ZoomTool), and the [text tool](/gen/editor/TextTool). These are always added to the state chart.
There are also some **default tools** available, like the [draw tool](/gen/editor/DrawShapeTool), the [hand tool](/gen/editor/HandTool), the [arrow tool](/gen/editor/ArrowTool), and more. The `<Tldraw>` component automatically adds these tools to the state chart.
You can also create your own **custom tools**. You can add them to the state chart by passing an array of them to the [`<Tldraw>`](/gen/editor/Tldraw) component's `tools` prop.
Note: You might also want to add a tool to the user interface in various ways, such as the toolbar. That isn't documented here yet, but you can see how it's done in our [examples folder](https://github.com/tldraw/tldraw/tree/main/apps/examples/src/3-custom-config).
## Inside a tool
Every tool has an **id**. This is used to identify it in the state chart.
```ts
class MyTool extends StateNode {
static override id = 'my-tool'
}
```
Tools can contain **children**. For example, the [hand tool](/gen/editor/HandTool) has three children, `Idle`, `Pointing` and `Dragging`. If a state has children, it must also have an `initial` state, so that it knows which state to start in.
```ts
class MyIdleState extends StateNode {
static override id = 'my-idle-state'
}
class MyPointingState extends StateNode {
static override id = 'my-pointing-state'
}
class MyTool extends StateNode {
static override id = 'my-tool'
static override initial = 'my-idle-state'
static override children = [MyIdleState, MyPointingState]
}
```
### Handling events
Coming soon...

View file

@ -1,38 +0,0 @@
---
title: User Interface
status: published
author: steveruizok
date: 3/22/2023
order: 8
keywords:
- ui
- interface
- tools
- shapes
- custom
- button
- toolbar
- styles
---
## Events
The [`<Tldraw>`](/gen/tldraw/Tldraw) component has a prop, `onUiEvent`, that the user interface will call when certain events occur.
```tsx
function Example() {
function handleEvent(name, data) {
// do something with the event
}
return (
<Tldraw onUiEvent={handleEvent}/>
)
}
```
The `onUiEvent` callback is called with the name of the event as a string and an object with information about the event's source (e.g. `menu` or `context-menu`) and possibly other data specific to each event, such as the direction in an `align-shapes` event.
Note that `onUiEvent` is only called when interacting with the user interface. It is not called when running commands manually against the app, e.g. [`editor.alignShapes()`](/gen/editor/Editor#alignShapes) will not call `onUiEvent`.
See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to customize tldraw's user interface.

View file

@ -1,29 +0,0 @@
---
title: Installation
status: published
author: steveruizok
date: 3/22/2023
order: 1
---
At the moment the `@tldraw/tldraw` package is in alpha. We also ship a canary version which is always up to date with the main branch of tldraw [repository](https://github.com/tldraw/tldraw).
## Alpha
First, install the `@tldraw/tldraw` package using `@alpha` for the latest.
```bash
yarn add @tldraw/tldraw@alpha
# or
npm install @tldraw/tldraw@alpha
```
## Canary
To get the very latest version, use the [latest canary release](https://www.npmjs.com/package/@tldraw/tldraw?activeTab=versions). Docs for the very latest version are also available at [canary.tldraw.dev](https://canary.tldraw.dev).
```bash
yarn add @tldraw/tldraw@canary
# or
npm install @tldraw/tldraw@canary
```

View file

@ -1,50 +0,0 @@
---
title: Introduction
status: published
author: steveruizok
date: 3/22/2023
order: 0
---
Welcome to the tldraw developer docs.
Here at tldraw, we make two things: a very good multiplayer whiteboard (at [tldraw.com](https://tldraw.com)), and the [open source library](https://github.com/tldraw/tldraw) that powers it. This page provides documentation and reference for that open source library.
```tsx
import { Tldraw } from '@tldraw/tldraw'
import '@tldraw/tldraw/tldraw.css'
export default function () {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw />
</div>
)
}
```
You can use the [`<Tldraw>`](/gen/tldraw/Tldraw) React component to build on top of the default tldraw experience. It's easy to use and easy to extend with your own [custom shapes](/docs/shapes), [custom tools](/docs/tools), and [user interface](/docs/user-interface) overrides.
You can also use the [Editor API](/docs/editor) to create, update, and delete shapes, control the camera, or do just about anything else.
If you want to go even deeper, you can use the [`<TldrawEditor>`](/gen/editor/TldrawEditor) component as a more minimal engine without the default tldraw shapes or user interface.
Best of all, you can easily plug tldraw into the [collaboration backend](/docs/collaboration) of your choice.
- Want to explore the code? Visit the [GitHub repo](https://github.com/tldraw/tldraw).
- Want to try it out? Visit the [examples sandbox](https://stackblitz.com/github/tldraw/tldraw/tree/examples?file=src%2F1-basic%2FBasicExample.tsx).
Otherwise, continue on to the [installation](/docs/installation) and [usage](/docs/usage) guides.
## Community
Found a bug or want to request a feature? Create an issue [here](https://github.com/tldraw/tldraw/issues). To connect with the team and other users, join us on our [Discord](https://discord.gg/JMbeb96jsh).
If you spot an issue with these docs, please use the links at the bottom of each page to suggest a change.
## License
Our open source libraries are licensed and distributed under Apache-2.0.
Our plan is to keep these libraries permissively licensed while we develop a commercial offering for teams who want more from tldraw. If you're planning to use use tldraw in a commercial product, please reach out at [hello@tldraw.com](mailto://hello@tldraw.com).

View file

@ -1,48 +0,0 @@
---
title: Usage
status: published
author: steveruizok
date: 3/22/2023
order: 2
---
The [`<Tldraw>`](/gen/tldraw/Tldraw) component is the easiest way to get started. To use it, create a file like this one:
```tsx
import { Tldraw } from '@tldraw/tldraw'
import '@tldraw/tldraw/tldraw.css'
export default function () {
return (
<div style={{ position: 'fixed', inset: 0 }} >
<Tldraw />
</div>
)
}
```
### CSS
In order to use the [`<Tldraw>`](/gen/tldraw/Tldraw) component, you should also import the `tldraw.css` file from the `@tldraw/tldraw` package. You can alternatively import this file inside of another CSS file using the `@import` syntax.
You can overwrite these files with other CSS or copy the contents into a different file and import that instead.
### HTML
If you're using the [`<Tldraw>`](/gen/tldraw/Tldraw) component in a full-screen app, you probably also want to update your `index.html`'s meta viewport element as shown below.
```html
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
```
This may not be critical to [`<Tldraw>`](/gen/tldraw/Tldraw) performing correctly, however some features (such as safe area positioning) will only work correctly if these viewport options are set.
## Using in Next.js, Create React App, Vite, etc.
Check the [examples repository](https://github.com/tldraw/examples) to see examples of tldraw being used in various frameworks.
By the way, the [`<Tldraw>`](/gen/tldraw/Tldraw) component can't be server-rendered. If you're using the component in a server-rendered framework (such as Next.js) then you need to import it dynamically.
## Going deeper
The [`<Tldraw>`](/gen/tldraw/Tldraw) component combines two lower-level components: [`<TldrawEditor>`](/gen/editor/TldrawEditor) and [`<TldrawUi>`](gen/ui/TldrawUi). If you want to have more granular control, you can use those lower-level components directly. See [this example](https://github.com/tldraw/tldraw/blob/main/apps/examples/src/examples/ExplodedExample.tsx) for reference.

View file

@ -1,20 +0,0 @@
[
{
"id": "getting-started",
"title": "",
"description": "",
"categories": []
},
{
"id": "docs",
"title": "Documentation",
"description": "Developer documentation for tldraw.",
"categories": []
},
{
"id": "community",
"title": "Community",
"description": "Guides for contributing to tldraw's open source project.",
"categories": []
}
]