This PR fixes pen mode.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. On iPad, use the pencil to enter pen mode
2. Select the draw tool
3. touch the screen
- [x] Unit Tests (sort of)
### Release Notes
- [fix] pen mode
This PR adds some more nuance to collaborator cursors.
Rather than being timed out or not timed out, a collaborator can now be
`active`, `idle` or `inactive`.
We calculate this based on the difference between the time that has
elapsed since the user's last activity timestamp.
After 3 seconds of inactivity, they go `idle`.
After sixty seconds of inactivity, they are `inactive`.
After any activity, they become `active` again.
When a user is `active`, we always show their cursor.
When a user is `idle`, we hide their cursor if they're following us,
unless they're highlighted
When a user is `inactive`, we hide their cursor unless they're
highlighted.
### Change Type
- [x] `minor`
### Test Plan
1. Find a friend and experiment with inactive times
2. Join a room that includes an inactive cursors; they should be hidden
on load
3. Have people follow you; do their timeouts feel natural?
### Release Notes
- Improve cursor timeouts and hiding logic.
This PR fixes some issues in our `useDocumentEvents`. It closes
https://github.com/tldraw/tldraw/issues/1667 (I think).
### Change Type
- [x] `patch`
### Release Notes
- [@tldraw/editor] Bug fixes on document events.
This PR incorporates a crc method from
https://github.com/alexgorbatchev/crc into the library, removing a peer
dependency on `buffer`. This was causing build errors in apps that did
not include the buffer library. (Our codebase included buffer because of
vsce.)
### Change Type
- [x] `patch`
### Release Notes
- [@tldraw/editor] Remove peer dependency on buffer.
This PR adds the `ScribbleManager` to the exports from `@tldraw/editor`.
### Change Type
- [x] `minor` — New feature
### Release Notes
- [@tldraw/tldraw] Export `ScribbleManager`
This PR fixes shape rendering logic. Remember! memo's 2nd argument
returns "when should we NOT render" not "when should we render"
### Change Type
- [x] `patch`
### Test Plan
1. Use the draw tool
This PR adds a `meta` property to shapes and other records.
It adds it to:
- asset
- camera
- document
- instance
- instancePageState
- instancePresence
- page
- pointer
- rootShape
## Setting meta
This data can generally be added wherever you would normally update the
corresponding record.
An exception exists for shapes, which can be updated using a partial of
the `meta` in the same way that we update shapes with a partial of
`props`.
```ts
this.updateShapes([{
id: myShape.id,
type: "geo",
meta: {
nemesis: "steve",
special: true
}
])
```
## `Editor.getInitialMetaForShape`
The `Editor.getInitialMetaForShape` method is kind of a hack to set the
initial meta property for newly created shapes. You can set it
externally. Escape hatch!
### Change Type
- [x] `minor` — New feature
### Test Plan
todo
- [ ] Unit Tests (todo)
### Release Notes
- todo
This PR fixes a crash when rotating a deleted shapes, and adds a unit
test for it.
It also updates the docs of an editor method to communicate a current
limitation that we left a 'todo' for. See code comments for more info.
### Change Type
- [x] `patch` — Bug fix
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
### Test Plan
1. Get two devices out for this! (or write a little console script to do
it for you)
2. Rotate a shape on one device.
3. While rotating it, delete it on the other device.
4. Make sure the page doesn't crash!
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
- Fixed a crash when trying to rotate a deleted shape.
This PR fixes an import in the custom shapes example. It also tweaks the
example to show how buttons and other interactive content should work.
### Change Type
- [x] `documentation`
This PR improves the types for the Store.
- renames `StoreSnapshot` to `SerializedStore`, which is the return type
of `Store.serialize`
- creates `StoreSnapshot` as a type for the return type of
`Store.getSnapshot` / the argument type for `Store.loadSnapshot`
- creates `TLStoreSnapshot` as the type used for the `TLStore`.
This came out of a session I had with a user. This should prevent
needing to import types from `@tldraw/store` directly.
### Change Type
- [x] `major` — Breaking change
### Test Plan
- [x] Unit Tests
### Release Notes
- [dev] Rename `StoreSnapshot` to `SerializedStore`
- [dev] Create new `StoreSnapshot` as type related to
`getSnapshot`/`loadSnapshot`
This PR fixes an issue (cough feature cough) where three touches would
exit pen mode.
### Change Type
- [x] `patch` — Bug fix
### Release Notes
- Removes three touches to cancel pen mode feature.
This PR fixes text shapes always being black.
It also fixes Note shapes not having the correct text colour.
<img width="759" alt="Screenshot 2023-06-26 at 11 26 45"
src="https://github.com/tldraw/tldraw/assets/15892272/a68ae0d1-69ba-43de-9e21-87c483ffd2dc">
### Change Type
- [x] `patch` — Bug fix
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
### Test Plan
1. Make a text shape.
2. Make sure you can change its colour.
3. Make a note shape.
4. Make sure its text label stays black when you change the note's
colour.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- None: Fixes an unreleased bug.
Adds some basic API docs for the new styles API.
### Change Type
- [x] `documentation` — Changes to the documentation only[^2]
### Test Plan
--
### Release Notes
--
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
tldraw-zero themed follow-ups to the styles API added in #1580.
- Removed style related helpers from `ShapeUtil`
- `editor.css` no longer includes the tldraw default color palette.
Instead, a global `DefaultColorPalette` is defined as part of the color
style. If developers wish to cusomise the colors, they can mutate that
global.
- `ShapeUtil.toSvg` no longer takes font/color. Instead, it takes an
"svg export context" that can be used to add `<defs>` to the exported
SVG element. Converting e.g. fonts to inlined data urls is now the
responsibility of the shapes that use them rather than the Editor.
- `usePattern` is not longer a core part of the editor. Instead,
`ShapeUtil` has a `getCanvasSvgDefs` method for returning react
components representing anything a shape needs included in `<defs>` for
the canvas.
- The shape-specific cleanup logic in `setStyle` has been deleted. It
turned out that none of that logic has been running anyway, and instead
the relevant logic lives in shape `onBeforeChange` callbacks already.
### Change Type
- [x] `minor` — New feature
### Test Plan
- [x] Unit Tests
- [x] End to end tests
### Release Notes
--
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR fixes a few components that were updating too often. It changes
the format of our error boundaries in order to avoid re-rendering them
as changed props.
### Change Type
- [x] `major` — Breaking change
It tried to get out but we're dragging it back in.
This PR brings [signia](https://github.com/tldraw/signia) back into
tldraw as @tldraw/state.
### Change Type
- [x] major
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
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 PR removes the `onDropOverride` prop from the canvas, which was a
bit of a hack.
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [editor] Remove `onDropOverride`
This PR changes `resizeBox` to be a regular function rather than an
arrow function.
### Change Type
- [x] `minor` — New feature
### Release Notes
- [editor] Change `resizeBox` to be a regular function.
This PR:
- updates the yjs example to include user presence
- tweaks the `createPresenceStateDerivation` API
- fix a "double update" bug caused by re-syncing local changes
- fix connection bugs
### Change Type
- [x] `minor` — New feature
This PR restores camera culling behavior and includes a 500ms forced
render while the camera is moving to prevent weird long pan behavior.
It:
- removes `CameraManager`
- adds `cameraState` to editor
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [editor] Adds `Editor.cameraState`
- Adds smart culling to make panning and zooming more smooth
This PR is intended to do some housecleaning ahead of our developer
release.
It:
- co-locates code in the `Editor` class, i.e. moving shape-related
methods next to other shape-related methods
- renames `cullingBounds` and other culling-related names to
`renderingBounds`
- renames `Editor.getParentPageId` to `Editor.getAncestorPageId`
- renames `Editor.shapeIds` to `Editor.currentPageShapeIds`
### Change Type
- [x] `major` — api changes
Removes `propsForNextShape` and replaces it with the new styles API.
Changes in here:
- New custom style example
- `setProp` is now `setStyle` and takes a `StyleProp` instead of a
string
- `Editor.props` and `Editor.opacity` are now `Editor.sharedStyles` and
`Editor.sharedOpacity`
- They return an object that flags mixed vs shared types instead of
using null to signal mixed types
- `Editor.styles` returns a `SharedStyleMap` - keyed on `StyleProp`
instead of `string`
- `StateNode.shapeType` is now the shape util rather than just a string.
This lets us pull the styles from the shape type directly.
- `color` is no longer a core part of the editor set on the shape
parent. Individual child shapes have to use color directly.
- `propsForNextShape` is now `stylesForNextShape`
- `InstanceRecordType` is created at runtime in the same way
`ShapeRecordType` is. This is so it can pull style validators out of
shape defs for `stylesForNextShape`
- Shape type are now defined by their props rather than having separate
validators & type defs
### Change Type
- [x] `major` — Breaking change
### Test Plan
1. Big time regression testing around styles!
2. Check UI works as intended for all shape/style/tool combos
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
-
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR adds a timeout to collaborator cursors.
It's part 1 of two PRs. The second one is smaller:
https://github.com/tldraw/brivate/pull/2053
# What is this?
After three seconds of inactivity, collaborator cursors disappear.
![2023-06-08 at 10 42 43 - Moccasin
Flamingo](https://github.com/tldraw/tldraw/assets/15892272/93e463aa-0329-4ecb-ada1-4c38b36a655b)
If you're following someone, you can always see their cursor.
![2023-06-08 at 10 45 42 - Olive
Crayfish](https://github.com/tldraw/tldraw/assets/15892272/11e8d85a-18a8-4976-85c5-d14f3841c296)
# Is there anything else?
The PR also adds support for the brivate PR:
https://github.com/tldraw/brivate/pull/2053
# Admin
### Change Type
- [x] `minor` — New Feature
### Test Plan
You probably need to test this locally, as we don't do multiplayer
previews on this repo yet.
1. Open the same shared project in two browser sessions.
2. Move around the cursor in one session, while able to see it from the
other.
3. Stop moving the cursor.
4. Make sure that the cursor disappears on the other session after 3
seconds.
5. Move the cursor again, and make sure it reappears it.
6. Make sure that viewport-following the user makes the cursor show
permanently.
### Release Notes
- Brought back cursor timeouts. Collaborator cursors now disappear after
3 seconds of inactivity.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR adds support for seeing **another user**'s chat messages.
It's part 1 of two PRs relating to Cursor Chat.
And it's needed for the much bigger part 2:
https://github.com/tldraw/brivate/pull/1981
# Presence
You can see another person's chat messages!
![2023-06-02 at 17 42 33 - Blush
Capybara](https://github.com/tldraw/tldraw/assets/15892272/8f3efb5f-9c05-459c-aa7e-24842be75e58)
If they have a name, it gets popped on top.
![2023-06-02 at 17 45 34 - Sapphire
Meerkat](https://github.com/tldraw/tldraw/assets/15892272/749bd924-c1f5-419b-a028-1fafe1b61292)
That's it!
With this PR, there's no way of actually *typing* your chat messages.
That comes with the [next
one](https://github.com/tldraw/brivate/pull/1981)!
# Admin
### To-do
- [x] Store chat message
- [x] Allow overflowing chat
- [x] Presence for chat message
- [x] Display chat message to others
### Change Type
- [x] `minor` — New Feature
### Test Plan
To test this, I recommend checking out both `lu/cursor-chat` branches,
and opening two browser sessions in the same shared project.
1. In one session, type some cursor chat by pressing the Enter key while
on the canvas (and typing).
2. On the other session, check that you can see the chat message appear.
3. Repeat this while being both named, and unnamed.
I recommend just focusing on the visible presense in this PR.
The [other PR](https://github.com/tldraw/brivate/pull/1981) is where we
can focus about how we _input_ the cursor chat.
### Release Notes
- [dev] Added support for cursor chat presence.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR adds shape type checks that use the shape util, e.g.
`this.editor.isShapeOfType(shape, FrameShapeUtil)`. In part this is
designed to help us track down where dependencies exist between the
editor and our default shapes.
### Change Type
- [x] `internal` — Any other changes that don't affect the published
package
This PR is a refactor / tidy up of some snapping logic.
- Fix a bug where the recursive call to `findAdjacentGaps` could lead to
a maximum call stack error
- Fixed an issue that caused handle snapping to expensively recompute
- Fixed a dependency from the snap manager to the line shape
### Change Type
- [x] `patch`
### Test Plan
Our snap tests are pretty thorough, they should work here.
### Release Notes
- [editor] fix bug in snapping
Removes the cached (but not really needed) local transform for shapes.
We almost never get the local transform except when getting the page
transform.
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [editor] Remove `ShapeUtil.transform`
We load the user preferences a bit earlier, so that we can make sure
that the `LoadingScreen` and `ErrorScreen` also use the correct color
and background color based on the dark mode setting.
There's still a brief flash of white screen, but that's before any of
our components load, not sure if we can avoid that one.
Solves https://github.com/tldraw/tldraw/issues/1248
### Change Type
- [x] `patch` — Bug Fix
### Test Plan
1. Probably best if you throttle your network speed.
2. Reload the page.
3. The asset loading screen should use take your dark mode setting into
account.
4. Change the dark mode and try again.
### Release Notes
- Make sure our loading and error screens take dark mode setting into
account.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR updates exports related to user presence, in order to enable
external sync solutions that use user presence.
### Change Type
- [x] `patch` — Bug fix
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
This PR removes the default SVG export for groups.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
1. Create a group
2. Export it to SVG
### Release Notes
- Fix image exports for groups
This PR does a first-pass of adding tsdocs to the methods of the Editor
class.
It's a minimal start — just descriptions of them, and their parameters.
It makes the Editor docs page a lot more fleshed out though, and easier
to quickly scan.
There's still a lot more to do!
### Change Type
- [x] `documentation` — Changes to the documentation only[^2]
### Release Notes
- [dev] Added initial documentation for the Editor class.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR adds a generic that we can use with `updateShapes` and
`createShapes` in order to type the partials being passed into those
methods. By default, the partials are typed as `TLUnknownShape`, which
accepts any props.
### Change Type
- [x] `minor` — New feature
### Test Plan
- [x] Unit Tests
### Release Notes
- [editor] adds an optional shape generic to `updateShapes` and
`createShapes`
This PR fixes embeds to remove the `doesResize` prop when creating
embeds / converting between bookmarks and embeds.
### Change Type
- [x] `patch` — Bug fix
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
### Test Plan
1. Create an embed
2. Convert between bookmark and embed
This PR does some cleanup around our Embed Shape.
It:
- removes used `doesResize` and `overridePermissions` props
- removes the no-longer-needed `tmpOldUrl` prop
- adds a `canUnmount` property to embed definitions, so that some embeds
can unmount when desired
### Change Type
- [x] `patch` — Bug Fix
### Test Plan
1. Create embed shapes
2. Migrate old data that includes embed shapes?
- [x] Unit Tests
### Release Notes
- [editor] Remove unused props for `TLEditorShape`
- [editor] Adds `canUnmount` property to embed definitions
Move the preloading of assets to `TldrawEditorWithReadyStore` which
makes it sure that all codepaths preload assets. Before that didn't
happen for cases where we passed in an existing store - snapshots.
### Change Type
- [x] `patch` — Bug Fix
### Release notes
- Fix a problem where assets were not loading in some cases (snapshots).
This PR extracts some logic from the EditUrlDialog into the bookmark
shape util, removing the dependency between the two.
### Change Type
- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
### Test Plan
1. Create a bookmark shape
2. Set its URL to an empty string
- [x] Unit Tests
This diff adds a new property to `defineShape`: `tool`.
The tool prop allows shapes to bring a tool along with them as part of
their definition. E.g. the draw shape isn't much use without the draw
tool, so adding the draw shape to your app gives you the draw tool tool.
As part of this, i renamed the `shapeutils` folder to just `shapes`, and
moved a bunch of shape-specific tools from the tools folder into the
shapes folder. This more closely reflects how things will be once we
move our default shapes out of core for tldraw-zero.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
Tested locally
### Release Notes
n/a
In my app, I have a sidebar and noticed that dropped shapes were being
created at an offset by the sidebar's width. This is because the current
point given to `putExternalContent` does not offset by the editor's
client rect.
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]
### Change Type
Change the `TLEventHandlers` of `onPointerLeave` to use `onPointerLeave`
- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
### Test Plan
I don't think we need to test something here because it's just a small
change that doesn't affect anything; just a type IMO
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR adds a yjs example to the examples app.
### Change Type
- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
### Release Notes
- [editor] Adds yjs example project
This PR does the following:
- Add `selfHosted.js`, which is a great option for users that wish to
self host the assets. Works well for both self hosting from the public
folder or via a CDN.
- Updates the docs for assets. We now have a dedicated page for assets
where all the options are more clearly explained. I also removed the
assets explanation from the main docs as the unpkg option should work
out of the box and setting up the assets is no longer necessary.
- Cleaned up the `refresh-assets` script. We now use common `types.d.ts`
file to define our types. All the other options then reuse them.
- Pulled out the `formatAssetUrl` into it's own file. It's now static an
no longer generated.
- `urls.d.ts`, `import.d.ts`, and newly added `selfhosted.d.ts` are now
also no longer generated as we can import the types from `types.d.ts`.
- You can now pass a subset of `assetUrls` to `<Tldraw />` and it will
override the default option with the passed in overrides. This makes it
easy to only customizes certain assets (only change the draw font as an
example).
### Change Type
- [x] `patch` — Bug Fix
Follow-up to #1555, taking care of a few more rare edge cases found
during fuzz testing.
### 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] -->
- [x] `patch` — Bug Fix