(2/2) Add content to Tools docs page. (#1721)

This PR adds some tools docs. There's more to come (eventually), but
this is what's finished so far.

This PR relies on this brivate one landing first:
https://github.com/tldraw/brivate/pull/2223

### Change Type

- [x] `documentation` — Changes to the documentation only[^2]

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Release Notes

- Tools docs.
This commit is contained in:
Lu Wilson 2023-07-10 09:43:58 +01:00 committed by GitHub
parent eeb41d4e69
commit 30b0a4d736
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 10 deletions

View file

@ -16,7 +16,7 @@ keywords:
- [Introduction](#introduction)
- [State](#state)
- [Events and Tools](#events-and-tools)
- [Events](#events)
- [Inputs](#inputs)
- [Common things to do with the editor](#common-things-to-do-with-the-editor)
@ -124,17 +124,17 @@ editor.duplicateShapes(editor.selectedIds)
editor.bailToMark("first") // will to A
```
## Events and Tools
## Events
The [`Editor`](/gen/editor/Editor) class receives events from the user interface via 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.
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.
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 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.
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.

View file

@ -10,6 +10,59 @@ keywords:
- state
---
Coming soon.
##### Table of Contents
See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to create custom tools in tldraw.
- [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,7 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"packages": [
"packages/*"
],
"packages": ["packages/*"],
"version": "2.0.0-alpha.14"
}