This PR shrinks the commands API surface and adds a manager
(`CleanupManager`) for side effects.
### Change Type
- [x] `major` — Breaking change
### Test Plan
Use the app! Especially undo and redo. Our tests are passing but I've
found more cases where our coverage fails to catch issues.
### Release Notes
- tbd
This PR fixes the extra outlines on text shapes when not editing those
shapes.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. Create two text shapes
2. Edit one of them
3. The outline on the second shape should not be shown
This PR exports the `UiEventsProvider` component (and renames
`useEvents` to `useUiEvents`). It also changes the `useUiEvents` hook to
work outside of the context. When used outside of the context, the hook
will no longer throw an error—though it will also have no effect.
### Change Type
- [x] `minor`
### Release Notes
- [@tldraw/tldraw] export ui events, so that UI hooks can work without
context
These shapes no longer use perfect freehand for their rendering, so we
can drop the effect of `useForceSolid` for them.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. Zoom out
2. Draw style draw shapes should not change
### Release Notes
- Remove the force solid switching for geo / line shapes
This PR fixes a bug that was introduced (by me) in #1751, where:
- the `commonBoundsOfAllShapesOnCurrentPage` would mutate the first
bounding box
- the render reactor would fire too often
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. Use the minimap
This PR removes `Editor.selectionPageCenter` and moves its
implementation inline where used (in two places).
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [dev] Removes `Editor.selectionPageCenter`
This PR fixes a bug introduced with #1751 where pointing the bounds of
rotated selections would not correctly hit the bounds background.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. Create a rotated selection.
2. Point into the bounds background
- [x] Unit Tests
This PR fixes some GREP-introduced errors to the old structure of legacy
v1 documents.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. Open a V1 document.
This PR is a significant rewrite of our selection / hit testing logic.
It
- replaces our current geometric helpers (`getBounds`, `getOutline`,
`hitTestPoint`, and `hitTestLineSegment`) with a new geometry API
- moves our hit testing entirely to JS using geometry
- improves selection logic, especially around editing shapes, groups and
frames
- fixes many minor selection bugs (e.g. shapes behind frames)
- removes hit-testing DOM elements from ShapeFill etc.
- adds many new tests around selection
- adds new tests around selection
- makes several superficial changes to surface editor APIs
This PR is hard to evaluate. The `selection-omnibus` test suite is
intended to describe all of the selection behavior, however all existing
tests are also either here preserved and passing or (in a few cases
around editing shapes) are modified to reflect the new behavior.
## Geometry
All `ShapeUtils` implement `getGeometry`, which returns a single
geometry primitive (`Geometry2d`). For example:
```ts
class BoxyShapeUtil {
getGeometry(shape: BoxyShape) {
return new Rectangle2d({
width: shape.props.width,
height: shape.props.height,
isFilled: true,
margin: shape.props.strokeWidth
})
}
}
```
This geometric primitive is used for all bounds calculation, hit
testing, intersection with arrows, etc.
There are several geometric primitives that extend `Geometry2d`:
- `Arc2d`
- `Circle2d`
- `CubicBezier2d`
- `CubicSpline2d`
- `Edge2d`
- `Ellipse2d`
- `Group2d`
- `Polygon2d`
- `Rectangle2d`
- `Stadium2d`
For shapes that have more complicated geometric representations, such as
an arrow with a label, the `Group2d` can accept other primitives as its
children.
## Hit testing
Previously, we did all hit testing via events set on shapes and other
elements. In this PR, I've replaced those hit tests with our own
calculation for hit tests in JavaScript. This removed the need for many
DOM elements, such as hit test area borders and fills which only existed
to trigger pointer events.
## Selection
We now support selecting "hollow" shapes by clicking inside of them.
This involves a lot of new logic but it should work intuitively. See
`Editor.getShapeAtPoint` for the (thoroughly commented) implementation.
![Kapture 2023-07-23 at 23 27
27](https://github.com/tldraw/tldraw/assets/23072548/a743275c-acdb-42d9-a3fe-b3e20dce86b6)
every sunset is actually the sun hiding in fear and respect of tldraw's
quality of interactions
This PR also fixes several bugs with scribble selection, in particular
around the shift key modifier.
![Kapture 2023-07-24 at 23 34
07](https://github.com/tldraw/tldraw/assets/23072548/871d67d0-8d06-42ae-a2b2-021effba37c5)
...as well as issues with labels and editing.
There are **over 100 new tests** for selection covering groups, frames,
brushing, scribbling, hovering, and editing. I'll add a few more before
I feel comfortable merging this PR.
## Arrow binding
Using the same "hollow shape" logic as selection, arrow binding is
significantly improved.
![Kapture 2023-07-22 at 07 46
25](https://github.com/tldraw/tldraw/assets/23072548/5aa724b3-b57d-4fb7-92d0-80e34246753c)
a thousand wise men could not improve on this
## Moving focus between editing shapes
Previously, this was handled in the `editing_shapes` state. This is
moved to `useEditableText`, and should generally be considered an
advanced implementation detail on a shape-by-shape basis. This addresses
a bug that I'd never noticed before, but which can be reproduced by
selecting an shape—but not focusing its input—while editing a different
shape. Previously, the new shape became the editing shape but its input
did not focus.
![Kapture 2023-07-23 at 23 19
09](https://github.com/tldraw/tldraw/assets/23072548/a5e157fb-24a8-42bd-a692-04ce769b1a9c)
In this PR, you can select a shape by clicking on its edge or body, or
select its input to transfer editing / focus.
![Kapture 2023-07-23 at 23 22
21](https://github.com/tldraw/tldraw/assets/23072548/7384e7ea-9777-4e1a-8f63-15de2166a53a)
tldraw, glorious tldraw
### Change Type
- [x] `major` — Breaking change
### Test Plan
1. Erase shapes
2. Select shapes
3. Calculate their bounding boxes
- [ ] Unit Tests // todo
- [ ] End to end tests // todo
### Release Notes
- [editor] Remove `ShapeUtil.getBounds`, `ShapeUtil.getOutline`,
`ShapeUtil.hitTestPoint`, `ShapeUtil.hitTestLineSegment`
- [editor] Add `ShapeUtil.getGeometry`
- [editor] Add `Editor.getShapeGeometry`
<img width="1372" alt="image"
src="https://github.com/tldraw/tldraw/assets/7578559/5d5f29fa-a3d7-488b-a4fe-25673d94134e">
This should be tldraw version instead of react version, the typo
happened here:
b7d9c8684c (diff-feb0a5bdada68de6bf60ae3fd8b83915d234dc78f56cae91f33e5c209ad3bf0a).
### Change Type
- [x] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
### Release Notes
- Fixed asset urls
This PR fixes snapping for arrow shapes. Previously, the middle handle
of an arrow was marked as a vertex, causing the arrow to have to
segments (one of which would be snapped to). In this PR we make the
second handle a "virtual" handle and tweak how we display handles to
preserve the same appearance.
### Change Type
- [x] `minor` — New feature
### Test Plan
1. Drag an arrow while snapping.
### Release Notes
- [fix] arrow snapping
This PR fixes a bug where dark mode would not immediately cause shapes
to update their colors. Previously, we got the current theme during
render but not in a way that hooked into the change. In this update, we
hook into the change. We also pass the change down to shape fills as
props rather than getting the theme from deeper down.
### Change Type
- [x] `patch`
### Test Plan
1. Use dark mode.
2. Switch colors
### Release Notes
- [fix] dark mode colors not updating
This PR is another grab bag:
- renames `readOnly` to `readonly` throughout editor
- fixes a regression related to focus and keyboard shortcuts
- adds a small outline for focused editors
### Change Type
- [x] `major`
### Test Plan
- [x] End to end tests
Fix minor typo error in shapeType declaration
**Change Type**
- [x] `patch`
**Test Plan**
- [x] Unit Tests
- [ ] End to end tests
**Release Notes**
Fix typo
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR removes several extraneous computed values from the editor. It
adds some silly instance state onto the instance state record and
unifies a few methods which were inconsistent. This is fit and finish
work 🧽
## Computed Values
In general, where once we had a getter and setter for `isBlahMode`,
which really masked either an `_isBlahMode` atom on the editor or
`instanceState.isBlahMode`, these are merged into `instanceState`; they
can be accessed / updated via `editor.instanceState` /
`editor.updateInstanceState`.
## tldraw select tool specific things
This PR also removes some tldraw specific state checks and creates new
component overrides to allow us to include them in tldraw/tldraw.
### Change Type
- [x] `major` — Breaking change
### Test Plan
- [x] Unit Tests
- [x] End to end tests
### Release Notes
- [tldraw] rename `useReadonly` to `useReadOnly`
- [editor] remove `Editor.isDarkMode`
- [editor] remove `Editor.isChangingStyle`
- [editor] remove `Editor.isCoarsePointer`
- [editor] remove `Editor.isDarkMode`
- [editor] remove `Editor.isFocused`
- [editor] remove `Editor.isGridMode`
- [editor] remove `Editor.isPenMode`
- [editor] remove `Editor.isReadOnly`
- [editor] remove `Editor.isSnapMode`
- [editor] remove `Editor.isToolLocked`
- [editor] remove `Editor.locale`
- [editor] rename `Editor.pageState` to `Editor.currentPageState`
- [editor] add `Editor.pageStates`
- [editor] add `Editor.setErasingIds`
- [editor] add `Editor.setEditingId`
- [editor] add several new component overrides
Escape the eraser tool on pressing the escape key.
(note that the same bug exists for the laser tool, i'm not sure if the
escape key behaviour should be the same for it too)
![licecap-output](https://github.com/tldraw/tldraw/assets/5616556/14bcb1f3-325c-4d28-ad39-a6a7205bd011)
Fixes#1731
### Change Type
- [x] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
### Test Plan
1. Select eraser tool
2. Press [escape], you should be back in the select tool
3. Select eraser tool, and start dragging around and press [escape], the
behaviour should be same as before
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- escape eraser tool on escape
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR fixes the issue where the arrow label was black in dark mode
instead of white.
light mode (normal):
<img width="600" alt="Screenshot 2023-07-12 at 00 21 35"
src="https://github.com/tldraw/tldraw/assets/5616556/2ac5e951-7777-4e96-9dde-a410a754aa01">
dark mode (before):
<img width="600" alt="Screenshot 2023-07-12 at 00 21 52"
src="https://github.com/tldraw/tldraw/assets/5616556/c67c3309-2847-4499-b4ef-6ba686e1382e">
dark mode (after):
<img width="600" alt="Screenshot 2023-07-12 at 00 21 44"
src="https://github.com/tldraw/tldraw/assets/5616556/244987c0-4570-410b-8975-43db47b786fa">
Fixes#1716
### Change Type
- [x] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
### Test Plan
1. Add an arrow with label
2. Switch between dark and light mode and notice that the label color
adapts correctly
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- fixed arrow label dark mode color
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR moves code between our packages so that:
- @tldraw/editor is a “core” library with the engine and canvas but no
shapes, tools, or other things
- @tldraw/tldraw contains everything particular to the experience we’ve
built for tldraw
At first look, this might seem like a step away from customization and
configuration, however I believe it greatly increases the configuration
potential of the @tldraw/editor while also providing a more accurate
reflection of what configuration options actually exist for
@tldraw/tldraw.
## Library changes
@tldraw/editor re-exports its dependencies and @tldraw/tldraw re-exports
@tldraw/editor.
- users of @tldraw/editor WITHOUT @tldraw/tldraw should almost always
only import things from @tldraw/editor.
- users of @tldraw/tldraw should almost always only import things from
@tldraw/tldraw.
- @tldraw/polyfills is merged into @tldraw/editor
- @tldraw/indices is merged into @tldraw/editor
- @tldraw/primitives is merged mostly into @tldraw/editor, partially
into @tldraw/tldraw
- @tldraw/file-format is merged into @tldraw/tldraw
- @tldraw/ui is merged into @tldraw/tldraw
Many (many) utils and other code is moved from the editor to tldraw. For
example, embeds now are entirely an feature of @tldraw/tldraw. The only
big chunk of code left in core is related to arrow handling.
## API Changes
The editor can now be used without tldraw's assets. We load them in
@tldraw/tldraw instead, so feel free to use whatever fonts or images or
whatever that you like with the editor.
All tools and shapes (except for the `Group` shape) are moved to
@tldraw/tldraw. This includes the `select` tool.
You should use the editor with at least one tool, however, so you now
also need to send in an `initialState` prop to the Editor /
<TldrawEditor> component indicating which state the editor should begin
in.
The `components` prop now also accepts `SelectionForeground`.
The complex selection component that we use for tldraw is moved to
@tldraw/tldraw. The default component is quite basic but can easily be
replaced via the `components` prop. We pass down our tldraw-flavored
SelectionFg via `components`.
Likewise with the `Scribble` component: the `DefaultScribble` no longer
uses our freehand tech and is a simple path instead. We pass down the
tldraw-flavored scribble via `components`.
The `ExternalContentManager` (`Editor.externalContentManager`) is
removed and replaced with a mapping of types to handlers.
- Register new content handlers with
`Editor.registerExternalContentHandler`.
- Register new asset creation handlers (for files and URLs) with
`Editor.registerExternalAssetHandler`
### Change Type
- [x] `major` — Breaking change
### Test Plan
- [x] Unit Tests
- [x] End to end tests
### Release Notes
- [@tldraw/editor] lots, wip
- [@tldraw/ui] gone, merged to tldraw/tldraw
- [@tldraw/polyfills] gone, merged to tldraw/editor
- [@tldraw/primitives] gone, merged to tldraw/editor / tldraw/tldraw
- [@tldraw/indices] gone, merged to tldraw/editor
- [@tldraw/file-format] gone, merged to tldraw/tldraw
---------
Co-authored-by: alex <alex@dytry.ch>
This PR improves the ergonomics of `ShapeUtil` classes.
### Cached methods
First, I've remove the cached methods (such as `bounds`) from the
`ShapeUtil` class and lifted this to the `Editor` class.
Previously, calling `ShapeUtil.getBounds` would return the un-cached
bounds of a shape, while calling `ShapeUtil.bounds` would return the
cached bounds of a shape. We also had `Editor.getBounds`, which would
call `ShapeUtil.bounds`. It was confusing. The cached methods like
`outline` were also marked with "please don't override", which suggested
the architecture was just wrong.
The only weirdness from this is that utils sometimes reach out to the
editor for cached versions of data rather than calling their own cached
methods. It's still an easier story to tell than what we had before.
### More defaults
We now have three and only three `abstract` methods for a `ShapeUtil`:
- `getDefaultProps` (renamed from `defaultProps`)
- `getBounds`,
- `component`
- `indicator`
Previously, we also had `getCenter` as an abstract method, though this
was usually just the middle of the bounds anyway.
### Editing bounds
This PR removes the concept of editingBounds. The viewport will no
longer animate to editing shapes.
### Active area manager
This PR also removes the active area manager, which was not being used
in the way we expected it to be.
### Dpr manager
This PR removes the dpr manager and uses a hook instead to update it
from React. This is one less runtime browser dependency in the app, one
less thing to document.
### Moving things around
This PR also continues to try to organize related methods and properties
in the editor.
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [editor] renames `defaultProps` to `getDefaultProps`
- [editor] removes `outline`, `outlineSegments`, `handles`, `bounds`
- [editor] renames `renderBackground` to `backgroundComponent`
This reverts commit b6716a3750.
Not sure why, but this introduced a `/// <references />` comment in the
tldraw/tldraw api-report.md file that doesn't show up when you build
from brivate. Reverting for now.
### Change Type
- [x] `dependencies` — Changes to package dependencies[^1]
### Test Plan
-
### Release Notes
-
This PR introduces `@tldraw/tldraw/tldraw.css`, an exported CSS file
that replaces the `editor.css` and `ui.css` that were previously copied
from the editor and ui packages. Instead, these files are combined into
the `tldraw.css` file, simplifying the import story when using
`@tldraw/tldraw`.
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [tldraw] Removes `editor.css` and `ui.css` exports, replaces with
`tldraw.css`
Based on #1549, but with a lot of code-structure related changes backed
out. Shape schemas are still defined in tlschemas with this diff.
Couple differences between this and #1549:
- This tightens up the relationship between store schemas and editor
schemas a bit
- Reduces the number of places we need to remember to include core
shapes
- Only `<TLdrawEditor />` sets default shapes by default. If you're
doing something funky with lower-level APIs, you need to specify
`defaultShapes` manually
- Replaces `validator` with `props` for shapes
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [x] Unit Tests
- [ ] Webdriver tests
### Release Notes
[dev-facing, notes to come]
This PR improves the editor's APIs around creating assets and files.
This allows end user developers to replace behavior that might occur,
for example, when pasting images or dragging files onto the canvas.
Here, we:
- remove `onCreateAssetFromFile` prop
- remove `onCreateBookmarkFromUrl` prop
- introduce `onEditorReady` prop
- introduce `onEditorWillDispose` prop
- introduce `ExternalContentManager`
The `ExternalContentManager` (ECM) is used in circumstances where we're
turning external content (text, images, urls, etc) into assets or
shapes. It is designed to allow certain methods to be overwritten by
other developers as a kind of weakly supported hack.
For example, when a user drags an image onto the canvas, the event
handler passes a `TLExternalContent` object to the editor's
`putExternalContent` method. This method runs the ECM's handler for this
content type. That handler may in turn run other methods, such as
`createAssetFromFile` or `createShapesForAssets`, which will lead to the
image being created on the canvas.
If a developer wanted to change the way that assets are created from
files, then they could overwrite that method at runtime.
```ts
const handleEditorReady = (editor: Editor) => {
editor.externalContentManager.createAssetFromFile = myHandler
}
function Example() {
return <Tldraw onEditorReady={handleEditorReady}/>
}
```
If you wanted to go even deeper, you could override the editor's
`putExternalContent` method.
```ts
const handleEditorReady = (editor: Editor) => {
const handleExternalContent = (info: TLExternalContent): Promise<void> => {
if (info.type === 'files') {
// do something here
} else {
// do the normal thing
editor.externalContentManager.handleContent(info)
}
}
```
### Change Type
- [x] `major`
### Test Plan
1. Drag images, urls, etc. onto the canvas
2. Use copy and paste for single and multiple files
3. Use bookmark / embed shapes and convert between eachother
### Release Notes
- [editor] add `ExternalContentManager` for plopping content onto the
canvas
- [editor] remove `onCreateAssetFromFile` prop
- [editor] remove `onCreateBookmarkFromUrl` prop
- [editor] introduce `onEditorReady` prop
- [editor] introduce `onEditorWillDispose` prop
- [editor] introduce `ExternalContentManager`
This PR renames `App`, `app` and all appy names to `Editor`, `editor`,
and editorry names.
### Change Type
- [x] `major` — Breaking Change
### Release Notes
- Rename `App` to `Editor` and many other things that reference `app` to
`editor`.
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
This PR removes unused scripts related to benchmarking, and some other
unused dependencies.
### Change Type
- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
- Remove TLUser, TLUserPresence
- Add first-class support for user preferences that persists across
rooms and tabs
### Change Type
<!-- 💡 Indicate the type of change your pull request is. -->
<!-- 🤷♀️ If you're not sure, don't select anything -->
<!-- ✂️ Feel free to delete unselected options -->
<!-- To select one, put an x in the box: [x] -->
- [ ] `patch` — Bug Fix
- [ ] `minor` — New Feature
- [x] `major` — Breaking Change
- [ ] `dependencies` — Dependency Update (publishes a `patch` release,
for devDependencies use `internal`)
- [ ] `documentation` — Changes to the documentation only (will not
publish a new version)
- [ ] `tests` — Changes to any testing-related code only (will not
publish a new version)
- [ ] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
This PR restores `createTLSchema`.
It also:
- removes `TldrawEditorConfig.default`
- makes `config` a required property of `<TldrawEditor>`, though it's
created automatically in `<Tldraw>`.
- makes `config` a required property of `App`
- removes `TLShapeType` and replaces the rare usage with
`TLShape["type"]`
- adds `TLDefaultShape` for a union of our default shapes
- makes `TLShape` a union of `TLDefaultShape` and `TLUnknownShape`
### Change Type
- [x] `major` — Breaking Change
### Release Notes
- [editor] Simplifies custom shape definition
- [tldraw] Updates props for <TldrawEditor> component to require a
`TldrawEditorConfig`.
We had a few issues with lazy race conditions failing CI. This came from
scripts configured to invoke lazy again, rather than through expressing
dependencies between scripts.
This diff reconfigures lazy to articulate these sorts of things as
dependencies instead of through self-invocation. Instead of having lots
of separate `build-package`, `build-docs`, etc commands, we now just
have a build command with package overrides to express more specific
options
### Change Type
- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
### Release Notes
[internal only]
Right now this examples app looks exactly the same as our old examples
app, but there are a couple of tiny differences:
- We use `vite` instead of our own esbuild setup for development and
bundling
- We use `@tldraw/assets` for smart asset hashing instead of copying the
assets to a public folder
You can use `@tldraw/assets` with vite with a bunch of extra config, but
it (plus a bunch of other bundlers) also support a special syntax for
specifying asset urls: `new URL('./my/asset.svg',
import.meta.url).href`. This approach is more standards-complient, but
doesn't work with every bundler just yet. This diff also adds a
url-based version of `@tldraw/assets`, although I'd like to tweak the
entry point - right now you need to import from
`@tldraw/assets/lib/urls`, but i'd like to find a way to get this to
`@tldraw/assets/urls` or something at some point.
There are a couple other extra fixes in here:
- vscode builds were broken, they're fixed now!
- there's also a little tweak to the `getBundlerAssetUrls` API to allow
passing in a function instead of an object for URL formatting
- there are new internal-only functions for injecting asset urls
globally instead of passing them in via react props. this means we can
get the benefits of cacheable URLs without having to clutter our
examples by passing them in
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.