No description
Find a file
Lu Wilson f745781056
[hot take] remove tool from shape definition (#1691)
This PR removes the `tool` parameter from the `defineShape` function.
It's an opinionated change that I think we should at the very least
consider.

## What's the context?

Currently, you can add **tools** (aka state nodes) to your state chart
in two different ways:

1. Passing them to the `<Tldraw>` component with the `tools` attribute.
2. As part of a shape definition's `tool` property, which you then pass
to the `<Tldraw>` component with the `shapes` attribute.

This is what (1) looks like:

```jsx
import { MyTool } from "./MyTool"

function Example() {
  return <Tldraw tools={[MyTool]} />
}
```

This is what (2) looks like:

```jsx
import { MyTool } from "./MyTool"
import { MyShapeUtil, myShapeProps } from "./MyShape"

const MyShapeDefinition = defineShape("my-shape", {
  util: MyShapeUtil,
  props: myShapeProps,
  tool: MyTool,
})

function Example() {
  return <Tldraw shapes={[MyShapeDefinition]} />
}
```

Clearly, (1) is better for when you want to add *just a tool*, that
doesn't have an associated shape.
And (2) is better for when you want to add *both* a tool and an
associated shape.

## Why change it?

I think we should remove method (2). Because I think that it adds a few
complications.


#### Does it help?

I don't think that it helps to streamline the process of coupling shapes
and tools. You still need to remember to add your tool.

Seeing as `tool` is optional on the shape definition (rightly so), it
doesn't prompt you to do it.

#### What's easier to explain?

I think it's easier to just have to explain _one method_. It would take
longer to explain two methods, and it complicates the concepts involved.

Seeing as there's not a big benefit to one method over the other, the
added explanation wouldn't be a good trade-off.

#### What happens if I use both?

It's unclear to the user what would happen if they use both methods. Do
we know what the intended behaviour of this would be? I think this will
happen often.

```jsx
import { MyTool } from "./MyTool"
import { MyShapeUtil, myShapeProps } from "./MyShape"

const MyShapeDefinition = defineShape("my-shape", {
  util: MyShapeUtil,
  props: myShapeProps,
  tool: MyTool,
})

function Example() {
  return <Tldraw tools={[MyTool]} shapes={[MyShapeDefinition]} />
}
```

#### Does it fit my shape/tool?

Many shapes are coupled closely with one tool. But some shapes would
involve multiple tools. And some tools would involve multiple shapes.

For example, you might first add a tool and a shape that go nicely
together, so you use method (2). But two months later, you decide that
you want another tool to be able to make this shape too. Now you've
inserted your related tools in two different places, unless you
refactor.

Alternatively, you might want to add some more functionality to your
tool, so that it can make multiple types of shapes. Instead of
refactoring the existing shape, you want to create an entirely new
shape, to keep your new code separate. Should you add the `tool`
property to the new shape as well? What would happen if you did/didn't?
What happens if you later disable the original shape? Would you need to
move the `tool` property from there to the newer shape?

It would be a lot simpler to just have the tool in your list of tools,
instead of having them tangled up with shapes.

#### Plugins?

We've been considering moving towards some sort of 'plugins' system in
the future, that could collect together shapes, tools, and other stuff.

I think that a more complete concept of a 'plugin' would be the best
place to collect together shapes, and tools — not on the shape itself.

### Change Type

- [x] `major` — Breaking change

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

### Test Plan

1. Try using all of the app's tools, making sure they still work.

- [ ] Unit Tests
- [ ] End to end tests

### Release Notes

- [dev] Removed the `tool` property from `defineShape`
2023-07-07 11:44:57 +00:00
.github [infra] use huppy token for publish-new (#1687) 2023-06-30 16:00:04 +00:00
.husky Fix VS Code commits failing on bublic? (#1680) 2023-06-30 12:25:16 +00:00
.yarn Styles API (#1580) 2023-06-16 10:33:47 +00:00
apps [hot take] remove tool from shape definition (#1691) 2023-07-07 11:44:57 +00:00
assets Lokalise: Translations update (#1694) 2023-07-04 10:10:57 +00:00
config Revert "Update dependencies (#1613)" (#1617) 2023-06-19 09:49:44 +00:00
docs Add API links to all docs pages (#1661) 2023-07-06 14:01:11 +00:00
packages [hot take] remove tool from shape definition (#1691) 2023-07-07 11:44:57 +00:00
scripts [fix] remove docs scripts (#1651) 2023-06-27 08:34:26 +00:00
.eslintignore untrack generated files (#1646) 2023-06-24 08:22:42 +00:00
.eslintplugin.js transfer-out: transfer out 2023-04-25 12:01:25 +01:00
.eslintrc.js replace console.log with nicelog (#1496) 2023-06-01 18:01:49 +00:00
.gitignore untrack generated files (#1646) 2023-06-24 08:22:42 +00:00
.ignore untrack generated files (#1646) 2023-06-24 08:22:42 +00:00
.prettierignore untrack generated files (#1646) 2023-06-24 08:22:42 +00:00
.prettierrc Revert "Update dependencies (#1613)" (#1617) 2023-06-19 09:49:44 +00:00
.yarnrc.yml lite: tweak lockfile name 2023-04-25 12:01:38 +01:00
CHANGELOG.md Update CHANGELOG.md [skip ci] 2023-07-04 14:21:37 +00:00
CODE_OF_CONDUCT.md transfer-out: transfer out 2023-04-25 12:01:25 +01:00
CONTRIBUTING.md Add contributor license agreement. (#1556) 2023-06-08 12:45:44 +00:00
lazy.config.ts untrack generated files (#1646) 2023-06-24 08:22:42 +00:00
lerna.json Update CHANGELOG.md [skip ci] 2023-07-04 14:21:37 +00:00
LICENSE transfer-out: transfer out 2023-04-25 12:01:25 +01:00
package.json untrack generated files (#1646) 2023-06-24 08:22:42 +00:00
public-yarn.lock [improvemnet] drop crc, Buffer dependency (#1673) 2023-06-29 14:14:43 +00:00
README.md Update readme (#1686) 2023-07-04 10:07:05 +00:00

tldraw

tldraw

Welcome to the public monorepo for tldraw.

What is tldraw?

tldraw is a collaborative digital whiteboard available at tldraw.com. Its editor, user interface, and other underlying libraries are open source and available in this repository. They are also distributed on npm. You can use tldraw to create a drop-in whiteboard for your product or as the foundation on which to build your own infinite canvas applications.

Learn more at tldraw.dev.

Note

This repo contains source code for the current version of tldraw. You can find the source for the original version here.

Installation & Usage

To learn more about using tldraw in your React application, follow our guide here or see the examples sandbox.

import { Tldraw } from '@tldraw/tldraw'
import '@tldraw/tldraw/tldraw.css'

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

Local development

To run the local development server, first clone this repo.

Install dependencies:

yarn

Start the local development server:

yarn dev

Open the example project at localhost:5420.

Examples

Our development server contains several examples that demonstrates different ways that you can customize tldraw or use its APIs. Each example is found in the apps/examples folder.

  • eg: localhost:5420 for the basic example.
  • eg: localhost:5420/api for the API example.

To learn more about using tldraw, visit our docs.

About this repository

Top-level layout

This repository's contents is divided across four primary sections:

  • /apps contains the source for our applications
  • /packages contains the source for our public packages
  • /scripts contains scripts used for building and publishing
  • /assets contains icons and translations relied on by the app
  • /docs contains the content for our docs site at tldraw.dev

Applications

Packages

  • assets: a library for working with tldraw's fonts and translations
  • editor: the tldraw editor
  • file-format: a library for working with tldraw's .tldr file format
  • indices: a library for working with tldraw's indices
  • polyfills: a collection of polyfills used by tldraw
  • primitives: low-level primitives for working with vectors and geometry
  • state: a signals library, also known as signia
  • store: an in-memory reactive database
  • tldraw: the main tldraw package containing both the editor and the UI
  • tlschema: shape definitions and migrations
  • ui: the editor's user interface
  • utils: low-level data utilities shared by other libraries
  • validate: a validation library used for run-time validation

Community

Have questions, comments or feedback? Join our discord or start a discussion.

Distributions

You can find tldraw on npm here.

At the moment the tldraw package is in alpha. We also ship a canary version which is always up to date with the main branch of this repo.

License

The source code for various apps and packages in this repository (as well as our 2.0+ distributions and releases) are currently licensed under Apache-2.0. These licenses are subject to change in our upcoming 2.0 release. If you are planning to use tldraw in a commercial product, please reach out at hello@tldraw.com.

Contribution

Please see our contributing guide. Found a bug? Please submit an issue.

Contact

Find us on Twitter at @tldraw or email hello@tldraw.com. You can also join our discord for quick help and support.