Commit graph

116 commits

Author SHA1 Message Date
Lu Wilson
3e2f2e0884
Add tsdocs to Editor methods (#1581)
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>
2023-06-14 06:40:10 +00:00
Steve Ruiz
ce1cf82029
Add optional generic to updateShapes / createShapes (#1579)
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`
2023-06-13 18:02:17 +00:00
Steve Ruiz
e3b00e7c11
[fix] embeds (#1578)
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
2023-06-13 12:45:43 +00:00
Steve Ruiz
b65aef5cf2
[improvement] Embed shape cleanup (#1569)
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
2023-06-13 08:27:54 +00:00
Mitja Bezenšek
439a2ed3bc
Move the loading of assets to the TldrawEditorWithReadyStore so that all code paths load the assets. (#1561)
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).
2023-06-13 08:22:38 +00:00
Steve Ruiz
34a880dcbd
[improvement] bookmark shape logic (#1568)
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
2023-06-12 19:15:58 +00:00
alex
7b03ef9d0c
shapes folder, move tools into shape defs (#1574)
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
2023-06-12 15:39:50 +00:00
Brian Hung
8d409462c0
offset drop point by editor client rect (#1564)
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.
2023-06-12 15:23:15 +00:00
alex
1927f88041
mini defineShape API (#1563)
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]
2023-06-12 14:04:14 +00:00
Judicael
d6be4bf26a
use the right TLEventHandlers (#1486)
### 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>
2023-06-09 13:57:31 +00:00
Steve Ruiz
d71d15124c
yjs example (#1560)
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
2023-06-09 12:15:06 +00:00
Mitja Bezenšek
bacb307bad
Asset improvements (#1557)
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
2023-06-09 11:43:01 +00:00
David Sheldrick
707ddc876f
More misc sync fixes (#1559)
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
2023-06-09 10:17:14 +00:00
Steve Ruiz
0cc91eec62
ExternalContentManager for handling external content (files, images, etc) (#1550)
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`
2023-06-08 14:53:11 +00:00
David Sheldrick
938bc32259
Misc sync fixes (#1555)
I've been doing some fuzz testing for the socket robustness work. This
PR pulls in the bublic fixes. It also fixes #1511

### 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
- [ ] `minor` — New Feature
- [ ] `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. Create a frame in a multiplayer room
2. create two boxes inside the frame
3. draw an arrow connecting the two boxes
4. delete the frame
5. hit undo
6. the frame and boxes and arrows should reappear as they were before

### Release Notes

- Fixes a handful of state management bugs that manifest in multiplayer
rooms
2023-06-08 10:16:39 +00:00
Lu Wilson
9d87ee9dd8
[Docs] Change some editor properties to methods (#1553)
This PR changes some App properties into methods, to make them
consistent with everything else.

Closes #1544

Is there any reason why we can't change any of these?

eg:

![image](https://github.com/tldraw/tldraw/assets/15892272/24ef843d-9677-4eca-a756-84fc2188ef17)

### Change Type

- [x] `documentation` — Changes to the documentation only (will not
publish a new version)

### Release Notes

- [docs] Fixed some methods that were incorrectly marked as properties.
2023-06-08 10:14:44 +00:00
Lu Wilson
b86c751b03
[Docs] Change some internal methods to public (#1554)
This PR changes some Editor methods from internal to public, so that
they appear on the docs site.

Closes #1545 

### Change Type

- [x] `documentation` — Changes to the documentation only (will not
publish a new version)

### Release Notes

- [docs] Changed some Editor methods from internal to public.
2023-06-08 10:09:33 +00:00
Mitja Bezenšek
21cefc77f5
Use unpkg as a default for serving assets. (#1548)
Use unpkg to host our assets and use that as a default. This will smooth
out the first run experience.

The way this works for different use cases:
- It doesn't change the asset loading for VS Code extension and
tldraw.com
- When running our examples (and our local development) [we still
override the
urls](4a9ef5044c/apps/examples/src/index.tsx (L32-L34))
to use the assets from the filesystem. This allows the assets to still
update when you change them.
- When you use our `Tldraw` component and when just copying the examples
code we will now serve the assets from unpkg by default.

I guess it's a breaking change since we will now use unpkg by default.

### Change Type

- [x] `major` — Breaking Change

### Release Notes

- Use unpkg asset hosting as a default.
2023-06-07 21:01:38 +00:00
Steve Ruiz
1531bfa81c
update editor tests (#1547)
This PR renames our test files for tools.

### Change Type

- [x] `tests` — Changes to any testing-related code only (will not
publish a new version)
2023-06-07 07:31:00 +00:00
alex
f2d8fae6ea
hoist opacity out of props (#1526)
This change hoists opacity out of props and changes it to a number
instead of an enum.

The change to a number is to make tldraw more flexible for library
consumers who might want more expressivity with opacity than our 5
possible values allow. the tldraw editor will now happily respect any
opacity between 0 and 1. The limit to our supported values is enforced
only in the UI. I think this is limited enough that it's a reasonable
tradeoff between in-app simplicity and giving external developers the
flexibility they need.

There's a new `opacityForNextShape` property on the instance. This works
exactly the same way as propsForNextShape does, except... it's just for
opacity. With this, there should be no user-facing changes to how
opacity works in tldraw. There are also new `opacity`/`setOpacity` APIs
in the editor that work with it/selections similar to how props do.

@ds300 do you mind reviewing the migrations here?

### Change Type

- [x] `major` — Breaking Change

### Test Plan

- [x] Unit Tests
- [ ] Webdriver tests

### Release Notes

[internal only for now]
2023-06-06 16:15:12 +00:00
Steve Ruiz
355ed1de72
rename app folder to editor (#1528)
Turns out there was one last terrible renaming PR to make. This PR
renames the `@tldraw.editor`'s `app` folder to `editor`. It should not
effect exports but it will be a gnarly diff.

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)
2023-06-06 16:01:54 +00:00
Lu Wilson
5d826c926d
Fix arrows with weird bends crashing (#1540)
This PR prevents a crash when you try to curve an arrow that is pointing
a very small distance.

Fixes #1533

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

1. Draw a line.
2. Draw an arrow from one point on the line to another point on the
line.
3. It might look weird or flicker (that's ok - that's a *different*
issue - we can fix it another time).
4. Move the middle handle of the arrow.
5. It should curve the arrow.

---

1. Open this snapshot link:
https://www.tldraw.com/s/v2_c_LtB3kVSYEyWuR-aCCrrUn
2. Copy its contents onto your own tldraw.
3. Click on the frog.
4. Drag the handle that's on the frog's face.
5. It shouldn't crash the app.

- [ ] Unit Tests
- [ ] Webdriver tests

### Release Notes

- Fixed a rare crash that could happen when you try to curve an arrow
with zero distance.
2023-06-06 13:30:50 +00:00
Steve Ruiz
1753190f5c
[feature] add vertical align to note shape (#1539)
This PR adds vertical align to the note shape.

### Change Type

- [x] `minor` — New Feature

### Test Plan

1. Try the vertical align prop on note shapes

### Release Notes

- Adds vertical align prop to note shapes
2023-06-06 13:27:32 +00:00
Steve Ruiz
b89612bdb7
[fix] Shift key code / nudge (#1537)
Fix key code when pressing Shift, which fixes nudging.

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

1. use the shift key to nudge things

### Release Notes

- Fix shift key nudging
2023-06-06 11:49:17 +00:00
alex
66b3de4a03
scale exported canvases when they reach the browsers max size (#1536)
Uses https://github.com/jhildenbiddle/canvas-size to determine the max
supported canvas size of the current browser, then scales exports
accordingly.

### 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


### Test Plan

Tested locally across a few browsers

### Release Notes

- Fix a bug where sometimes exports would fail when they were too big
for your browser. Now, they're scaled down to the max supported size.
2023-06-06 11:44:21 +00:00
Steve Ruiz
6f8533df5d
[fix] control click on mac (#1535)
This PR fixes control click for right click on Mac.

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

1. On a PC, ensure that control clicking does not select the thing under
your cursor
2. On a mac, ensure that control clicking does select the thing under
your cursor before the context menu opens

### Release Notes

- Fix control click to open menu on Mac
2023-06-06 11:30:52 +00:00
Lu Wilson
7039c3772e
Fix being able to undo following (#1531)
This PR fixes a bug where you could undo following/unfollowing.

Fixes #1532

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

1. In two browser sessions...
2. In a shared project...
3. Follow the other tab's user.
4. Draw something.
5. Unfollow them.
6. Close the people menu!
7. Undo as far as you can go.
8. Check that you don't start following them again at any point.

- [ ] Unit Tests
- [ ] Webdriver tests

### Release Notes

- Fixed a bug where you could undo viewport-following and
viewport-unfollowing.
2023-06-06 11:25:14 +00:00
alex
d9548556cb
highlighter fixes (#1530)
Fixes the following issues with highlighter:
* Exported highlighter has much larger stroke width than in-app
highlighter
* Selecting two highlighter shapes with different sizes would hide the
size option from the styles panel
* Highlighter lines drawn on ipad look noise-y

### 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
- [ ] `minor` — New Feature
- [ ] `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

-

### Release Notes

[aq bug fixes]
2023-06-06 11:06:28 +00:00
Steve Ruiz
3be19ad53e
ensure that fixed points stay fixed (#1523)
This PR fixes points on resize as well as on create. This should help
with file size for large resizes.

### Change Type
- [x] `patch` — Bug Fix

### Test Plan

- [ ] Unit Tests
2023-06-05 18:04:13 +00:00
David Sheldrick
a4fff303bf update lazyrepo 2023-06-05 18:32:32 +01:00
Steve Ruiz
1f0a20cc94
Simplify static cursors (#1520)
This PR simplifies the static cursors.

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)

### Test Plan

1. Use cursors throughout app.

### Release Notes

- (editor) Simplifies the cursors in our CSS.
2023-06-05 14:49:44 +00:00
David Sheldrick
f15a8797f0
Independent instance state persistence (#1493)
This PR 

- Removes UserDocumentRecordType
  - moving isSnapMode to user preferences
  - moving isGridMode and isPenMode to InstanceRecordType
  - deleting the other properties which are no longer needed.
 
- Creates a separate pipeline for persisting instance state.
  
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.

There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
  
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.

- Undoes the assumption that we might have more than one instance's
state in the store.

- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.

Tests to do

- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back


### Change Type

- [x] `major` — Breaking Change


### 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.
2023-06-05 14:11:07 +00:00
Steve Ruiz
0f89309604
Renaming types, shape utils, tools (#1513)
This PR renames all exported types to include the `TL` prefix. It also
removes the `TL` prefix from things that are not types, including:
- shape utils (e.g. `TLArrowUtil` becomes `ArrowShapeUtil`)
- tools (e.g. `TLArrowTool` becomes `ArrowShapeTool`, `TLSelectTool`
becomes `SelectTool`)

### Change Type

- [x] `major` — Breaking Change

### Release Notes

- Renaming of types, shape utils, tools
2023-06-04 10:38:53 +00:00
Steve Ruiz
4b6383ed90
tlschema cleanup (#1509)
This PR cleans up the file names and imports for @tldraw/tlschema.

It also:
- renames some erroneously named validators / migrators (e.g.
`pageTypeValidator` -> `pageValidator`)
- removes the duplicated `languages.ts` and makes `tlschema` the source
of truth for languages
- renames ID to RecordId

### Change Type

- [x] `major` — Breaking Change

### Release Notes

- [editor] Remove `app.createShapeId`
- [tlschema] Cleans up exports
2023-06-03 20:46:53 +00:00
Steve Ruiz
c1b84bf246
Rename tlstore to store (#1507)
This PR renames the `@tldraw/tlstore` package to `@tldraw/store`, mainly
to avoid confusion between `TLStore`. Will be doing the same with other
packages.

### Change Type

- [x] `major` — Breaking Change

### Release Notes

- Replace @tldraw/tlstore with @tldraw/store
2023-06-03 08:59:04 +00:00
Steve Ruiz
7307282f1f
Rename tlvalidate to validate (#1508)
This PR renames the @tldraw/tlvalidate package to @tldraw/validate. 

### Change Type

- [x] `major` — Breaking Change

### Release Notes

- Rename tlvalidate to validate
2023-06-03 08:27:44 +00:00
Steve Ruiz
735f1c41b7
rename app to editor (#1503)
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`.
2023-06-02 15:21:45 +00:00
Steve Ruiz
da35e0da27
move v1 migration code into file-format (#1499)
Move v1 migration code out of editor

### Change Type

- [x] `minor` — New Feature
2023-06-02 09:38:13 +00:00
Lu Wilson
3bc72cb822
Add support for project names (#1340)
This PR adds some things that we need for the Project Name feature on
tldraw.com.
It should be reviewed alongside
https://github.com/tldraw/tldraw-lite/pull/1814


## Name Property
This PR adds a `name` property to `TLDocument`. We use this to store a
project's name.

<img width="454" alt="Screenshot 2023-05-09 at 15 47 26"
src="https://github.com/tldraw/tldraw/assets/15892272/f3be438e-aa0f-4dec-8f51-8dfd9f9d0ced">

## Top Zone
This PR adds a `topZone` area of the UI that we can add stuff to,
similar to how `shareZone` works.
It also adds an example to show where the `topZone` and `shareZone` are:

<img width="1511" alt="Screenshot 2023-05-12 at 10 57 40"
src="https://github.com/tldraw/tldraw/assets/15892272/f5e1cd33-017e-4aaf-bfee-4d85119e2974">

## Breakpoints
This PR change's the UI's breakpoints a little bit.
It moves the action bar to the bottom a little bit earlier.
(This gives us more space at the top for the project name).

![2023-05-12 at 11 08 26 - Fuchsia
Bison](https://github.com/tldraw/tldraw/assets/15892272/34563cea-b1d1-47be-ac5e-5650ee0ba02d)

![2023-05-12 at 13 45 04 - Tan
Mole](https://github.com/tldraw/tldraw/assets/15892272/ab190bd3-51d4-4a8b-88de-c72ab14bcba6)

## Input Blur
This PR adds an `onBlur` parameter to `Input`.
This was needed because 'clicking off' the input wasn't firing
`onComplete` or `onCancel`.

<img width="620" alt="Screenshot 2023-05-09 at 16 12 58"
src="https://github.com/tldraw/tldraw/assets/15892272/3b28da74-0a74-4063-8053-e59e47027caf">

## Create Project Name
This PR adds an internal `createProjectName` property to
`TldrawEditorConfig`.
Similar to `derivePresenceState`, you can pass a custom function to it.
It lets you control what gets used as the default project name. We use
it to set different names in our local projects compared to shared
projects.

In the future, when we add more advanced project features, we could
handle this better within the UI.

<img width="454" alt="Screenshot 2023-05-09 at 15 47 26"
src="https://github.com/tldraw/tldraw/assets/15892272/da9a4699-ac32-40d9-a97c-6c682acfac41">

### Test Plan

1. Gradually reduce the width of the browser window.
2. Check that the actions menu jumps to the bottom before the style
panel moves to the bottom.

---

1. In the examples app, open the `/zones` example.
2. Check that there's a 'top zone' at the top.

- [ ] Unit Tests
- [ ] Webdriver tests

### Release Note

- [dev] Added a `topZone` area where you can put stuff.
- [dev] Added a `name` property to `TLDocument` - and `app` methods for
it.
- [dev] Added an internal `createProjectName` config property for
controlling the default project name.
- [dev] Added an `onBlur` parameter to `Input`.
- Moved the actions bar to the bottom on medium-sized screens.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2023-06-01 18:46:26 +00:00
Mitja Bezenšek
d738c28c19
Add support for locking shapes (#1447)
Add support for locking shapes. 

How it works right now:
- You can lock / unlock shapes from the context menu.
- You can also lock shapes with `⇧⌘L` keyboard shortcut.
- You cannot select locked shapes: clicking on the shape, double click
to edit, select all, brush select,... should not work.
- You cannot change props of locked shapes.
- You cannot delete locked shapes.
- If a shape is grouped or within the frame the same rules apply.
- If you delete a group, that contains locked shape it will also delete
those shapes. This seems to be what other apps use as well.

Solves #1445 

### Change Type

- [x] `minor` — New Feature

### Test Plan

1. Insert a shape
2. Right click on it and lock it.
3. Test that you cannot select it, change its properties, delete it.
4. Do the same with locked groups.
5. Do the same with locked frames.

- [x] Unit Tests
- [ ] Webdriver tests

### Release Notes

- Add support for locking shapes.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2023-06-01 18:13:38 +00:00
Steve Ruiz
0c4174c0b8
[refactor] User-facing APIs (#1478)
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
2023-06-01 15:47:34 +00:00
alex
d6085e4ea6
[3/3] Highlighter styling (#1490)
This PR finalises the highlighter shape with new colors, sizing, and
perfect freehand options.

The colors are based on our existing colour palette, but take advantage
of wide-gamut displays to make the highlighter highlightier. I used my
[oklch color palette tool to pick the
palette](https://alex.dytry.ch/toys/palette/?palette=%7B%22families%22:%5B%22black%22,%22grey%22,%22white%22,%22green%22,%22light-green%22,%22blue%22,%22light-blue%22,%22violet%22,%22light-violet%22,%22red%22,%22light-red%22,%22orange%22,%22yellow%22%5D,%22shades%22:%5B%22light-mode%22,%22dark-mode%22,%22hl-light%22,%22hl-dark%22%5D,%22colors%22:%5B%5B%5B0.2308,0,null%5D,%5B0.9097,0,null%5D,%5B0.2308,0,null%5D,%5B0.2308,0,null%5D%5D,%5B%5B0.7692,0.0145,248.02%5D,%5B0.6778,0.0118,256.72%5D,%5B0.7692,0.0145,248.02%5D,%5B0.7692,0.0145,248.02%5D%5D,%5B%5B1,0,null%5D,%5B0.2308,0,null%5D,%5B1,0,null%5D,%5B1,0,null%5D%5D,%5B%5B0.5851,0.1227,164.1%5D,%5B0.5319,0.0811,162.23%5D,%5B0.8729,0.2083,173.3%5D,%5B0.5851,0.152,173.3%5D%5D,%5B%5B0.7146,0.1835,146.44%5D,%5B0.6384,0.1262,143.36%5D,%5B0.8603,0.2438,140.11%5D,%5B0.6082,0.2286,140.11%5D%5D,%5B%5B0.5566,0.2082,268.35%5D,%5B0.4961,0.1644,270.65%5D,%5B0.7158,0.173,243.85%5D,%5B0.5573,0.178,243.85%5D%5D,%5B%5B0.718,0.1422,246.06%5D,%5B0.6366,0.1055,250.98%5D,%5B0.8615,0.1896,200.03%5D,%5B0.707,0.161,200.03%5D%5D,%5B%5B0.5783,0.2186,319.15%5D,%5B0.5043,0.1647,315.37%5D,%5B0.728,0.2001,307.45%5D,%5B0.5433,0.2927,307.45%5D%5D,%5B%5B0.7904,0.1516,319.77%5D,%5B0.6841,0.1139,315.99%5D,%5B0.812,0.21,327.8%5D,%5B0.5668,0.281,327.8%5D%5D,%5B%5B0.5928,0.2106,26.53%5D,%5B0.5112,0.1455,26.18%5D,%5B0.7326,0.21,20.59%5D,%5B0.554,0.2461,20.59%5D%5D,%5B%5B0.7563,0.146,21.1%5D,%5B0.6561,0.0982,20.86%5D,%5B0.7749,0.178,6.8%5D,%5B0.5565,0.2454,6.8%5D%5D,%5B%5B0.6851,0.1954,44.57%5D,%5B0.5958,0.1366,46.6%5D,%5B0.8207,0.175,68.62%5D,%5B0.6567,0.164,68.61%5D%5D,%5B%5B0.8503,0.1149,68.95%5D,%5B0.7404,0.0813,72.25%5D,%5B0.8939,0.2137,100.36%5D,%5B0.7776,0.186,100.36%5D%5D%5D%7D&selected=3).
I'm not sure happy about these colors as they are right now - in
particular, i think dark mode looks a bit rubbish and there are a few
colors where the highlight and original version are much too similar
(light-violet & light-red). Black uses yellow (like note shape) and grey
uses light-blue. Exports are forced into srgb color space rather than P3
for maximum compatibility.


![image](https://github.com/tldraw/tldraw/assets/1489520/e3de762b-6ef7-4d17-87db-3e2b71dd8de1)


![image](https://github.com/tldraw/tldraw/assets/1489520/3bd90aa9-bdbc-4a2b-9e56-e3a83a2a877b)



The size of a highlighter stroke is now based on the text size which
works nicely for making the highlighter play well with text:


![image](https://github.com/tldraw/tldraw/assets/1489520/dd3184fc-decd-4db5-90ce-e9cc75edd3d6)


Perfect freehands settings are very similar to the draw tool, but with
the thinning turned way down. There is still some, but it's pretty
minimal.

### The plan
1. initial highlighter shape/tool #1401 
2. sandwich rendering for highlighter shapes #1418
3. shape styling - new colours and sizes, lightweight perfect freehand
changes #1490 **>you are here<**

### Change Type
- [x] `minor` — New Feature

### Test Plan

1. You can find the highlighter tool in the extended toolbar
2. You can activate the highlighter tool by pressing shift-D
3. Highlighter draws nice and vibrantly when over the page background or
frame background
4. Highlighter is less vibrant but still visible when drawn over images
/ other fills
5. Highlighter size should nicely match the corresponding unscaled text
size
6. Exports with highlighter look as expected

### Release Notes

Highlighter pen is here! 🎉🎉🎉

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2023-06-01 15:34:59 +00:00
alex
a11a741de4
[2/3] renderer changes to support "sandwich mode" highlighting (#1418)
This diff modifies our canvas/rendering code to support shapes rendering
into a "background layer". The background layer isn't a layer in the
sense of our own html/svg/indicator layers, but is instead part of the
HTML canvas layer and is created by allocating z-indexes to shapes below
all others.

For most shapes, the background starts at the canvas. If a shape is in a
frame, then the frame is treated as the background.

![Kapture 2023-05-19 at 11 38
12](https://github.com/tldraw/tldraw/assets/1489520/3ab6e0c0-f71e-4bfd-a996-c5411be28a71)

Exports now use the `renderingShapes` algorithm which fixed a small bug
with exports where opacity wouldn't get correctly propagated down
through child shapes.

### The plan
1. initial highlighter shape/tool #1401 
2. sandwich rendering for highlighter shapes #1418  **>you are here<**
3. shape styling - new colours and sizes, lightweight perfect freehand
changes

### Change Type

- [x] `minor` — New Feature


### Test Plan

not yet!

- [x] Unit Tests

### Release Notes

[not yet!]
2023-06-01 15:22:47 +00:00
alex
674a829d1f
[1/3] initial highlighter shape/tool (#1401)
This diff adds an initial version of the highlighter shape. At this
stage, it's a complete copy of the draw tool minus the following
features:
* Fills
* Stroke types
* Closed shapes

I've created a new shape util (a copy-paste of the draw one with stuff
renamed/deleted) but reused the state chart nodes for the draw shape.
Currently this new tool looks exactly like the draw tool, but that'll be
changing soon!

![Kapture 2023-05-17 at 15 37
33](https://github.com/tldraw/tldraw/assets/1489520/982e78f4-6495-4a68-aa51-c8f7b5bcdd01)

The UI here is extremely WIP. The highlighter tool is behind a feature
flag, but once enabled is accessible through the tool bar. There's a
first-draft highlighter icon (i didn't spend much time on this, it's not
super legible on non-retina displays yet imo), and the tool is bound to
the `i` key (any better suggestions? `h` is taken by the hand tool)

### The plan
1. initial highlighter shape/tool #1401 **>you are here<**
2. sandwich rendering for highlighter shapes #1418  
3. shape styling - new colours and sizes, lightweight perfect freehand
changes

### Change Type
- [x] `minor` — New Feature

### Test Plan
(not yet)

### Release Notes

[internal only change layout ground work for highlighter]
2023-06-01 12:46:13 +00:00
Steve Ruiz
2992ad85d9
[chore] remove benchmark (#1489)
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)
2023-05-30 15:43:28 +00:00
Steve Ruiz
a220b2eff1
[feature] reduce motion (#1485)
This PR adds a user preference to reduce motion. When enabled the app
will not animate the camera (and perhaps skip other animations in the
future). It's actual implementation is as an `animateSpeed` property, so
we can also use it to speed up or slow down our animations if that's
something we want to do!

### Change Type

- [x] `minor` — New Feature

### Test Plan

1. Turn on reduce motion
2. Use minimap / camera features to zoom in / out / etc

- [x] Unit Tests

### Release Notes

- [editor] Add `reduceMotion` user preference
- Add reduce motion option to preferences
2023-05-30 15:22:49 +00:00
Steve Ruiz
e3cf05f408
Add playwright tests (#1484)
This PR replaces our webdriver end to end tests with playwright tests.

It:
- replaces our webdriver workflow with a new e2e workflow based on
playwright
- removes the webdriver project
- adds e2e tests to our examples app
- replaces all `data-wd` attributes with `data-testid`

### Coverage

Most of the tests from our previous e2e tests are reproduced here,
though there are some related to our gestures that will need to be done
in a different way—or not at all. I've also added a handful of new
tests, too.

### Where are they

The tests are now part of our examples app rather than being in its own
different app. This should help us test our different examples too. As
far as I can tell there are no downsides here in terms of the regular
developer experience, though they might complicate any CodeSandbox
projects that are hooked into the examples app.

### Change Type

- [x] `tests` — Changes to any testing-related code only (will not
publish a new version)
2023-05-30 15:28:56 +01:00
alex
e3dec58499
Add DSL to make writing shape-layout test cases much easier (#1413)
As part of my highlighter work, I've been writing a few test cases
around rendering with different combinations of nested frames and
groups. Writing these test cases using `createShapes` is really hard,
and reading them is even harder. I wanted to see if there was an easier
way for us to define shapes for test cases, and turns out... there is!

This diff introduces a JSX-based DSL for defining test cases. It looks
something like this:
```tsx
// create some shapes
const ids = app.createShapesFromJsx([
	<TL.geo ref="A" x={100} y={100} w={100} h={100} />,
	<TL.frame ref="B" x={200} y={200} w={300} h={300}>
		<TL.geo ref="C" x={200} y={200} w={50} h={50} />
		<TL.text ref="D" x={1000} y={1000} text="Hello, world!" align="end" />
	</TL.frame>,
])

// refer to shape IDs according to their `ref`
app.select(ids.C)
```

It's probably not worth trying to migrate everything possible to this,
but i picked a few random tests to convert over to show how it works
(and because i wanted this diff to end up red overall)

In the future, I'd like to use this with visual regression testing to
test rendering/exports on some complex combinations of shapes too.

### Change Type
- [x] `tests` — Changes to any testing-related code only (will not
publish a new version)

### Release Notes

[internal only change]
2023-05-30 13:27:26 +00:00
alex
4048064e78
Feature flags rework (#1474)
This diff tweaks our `debugFlags` framework to support setting different
default value for different environments, makes it easier to define
feature flags, and makes feature flags show up in the debug menu by
default. With this change, feature flags will default to being enabled
in dev and preview environments, but disabled in production.

Specify a feature flag like this:
```ts
const featureFlags = {
      myCoolNewFeature: createFeatureFlag('myCoolNewFeature')
}
```

optionally, pass a second value to control its defaults:
```ts
const featureFlags = {
    featureEnabledInProduction: createFeatureFlag('someFeature', { all: true }),
    customEnabled: createFeatureFlag('otherFeature', {development: true, staging: false, production: false}),
}
```

In code, the value can be read using `featureFlags.myFeature.value`.
Remember to wrap reading it in a reactive context!

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

-

### Release Notes

[internal only change]
2023-05-30 13:06:15 +00:00
Steve Ruiz
7578fff2b1
[tiny] add isPageId (#1482)
This PR adds an `isPageId` helper.

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package (will not publish a new version)

### Release Notes

- [tlschema] Add `isPageId`
2023-05-27 17:53:18 +00:00