Commit graph

325 commits

Author SHA1 Message Date
Steve Ruiz
bc20b2a418
Shuffle docs order (#4183)
This PR brings updates the docs order, bringing collaboration higher up.

### Change type

- [x] `other`
2024-07-16 10:13:25 +00:00
Taha
c5b2569bfc
toSvg method example (#4124)
An example of how to use the toSvg method on custom shape.

Resolves #4057 

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- [Examples App] added an example for the toSvg method on a custom
shape.
2024-07-15 15:44:07 +00:00
Mitja Bezenšek
fe3dc0d965
Fix sticker example. (#4172)
Stickers didn't stick since they were binding to themselves.

Fixes #3982

### Change type

- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`

### Test plan

1. Use the sticker example
2. The sticker should stick 😄 

### Release notes

- Fix the sticker example.
2024-07-15 14:56:56 +00:00
Steve Ruiz
01bc73e750
Editor.run, locked shapes improvements (#4042)
This PR:
- creates `Editor.run` (previously `Editor.batch`)
- deprecates `Editor.batch`
- introduces a `ignoreShapeLock` option top the `Editor.run` method that
allows the editor to update and delete locked shapes
- fixes a bug with `updateShapes` that allowed updating locked shapes
- fixes a bug with `ungroupShapes` that allowed ungrouping locked shapes
- makes `Editor.history` private
- adds `Editor.squashToMark`
- adds `Editor.clearHistory`
- removes `History.ignore`
- removes `History.onBatchComplete`
- makes `_updateCurrentPageState` private

```ts
editor.run(() => {
  editor.updateShape({ ...myLockedShape })
  editor.deleteShape(myLockedShape)
}, { ignoreShapeLock: true })
```

It also:

## How it works

Normally `updateShape`/`updateShapes` and `deleteShape`/`deleteShapes`
do not effect locked shapes.

```ts
const myLockedShape = editor.getShape(myShapeId)!

// no change from update
editor.updateShape({ ...myLockedShape, x: 100 })
expect(editor.getShape(myShapeId)).toMatchObject(myLockedShape)

// no change from delete
editor.deleteShapes([myLockedShape])
expect(editor.getShape(myShapeId)).toMatchObject(myLockedShape)
```

The new `run` method adds the option to ignore shape lock.

```ts
const myLockedShape = editor.getShape(myShapeId)!

// update works
editor.run(() => { editor.updateShape({ ...myLockedShape, x: 100 }) }, { ignoreShapeLock: true })
expect(editor.getShape(myShapeId)).toMatchObject({ ...myLockedShape, x: 100 })

// delete works
editor.run(() => { editor.deleteShapes([myLockedShape]), { ignoreShapeLock: true })
expect(editor.getShape(myShapeId)).toBeUndefined()
```

## History changes

This is a related but not entirely related change in this PR.

Previously, we had a few ways to run code that ignored the history.

- `editor.history.ignore(() => { ... })`
- `editor.batch(() => { ... }, { history: "ignore" })`
- `editor.history.batch(() => { ... }, { history: "ignore" })`
- `editor.updateCurrentPageState(() => { ... }, { history: "ignore" })`

We now have one way to run code that ignores history:

- `editor.run(() => { ... }, { history: "ignore" })`

## Design notes

We want a user to be able to update or delete locked shapes
programmatically.

### Callback vs. method options?

We could have added a `{ force: boolean }` property to the
`updateShapes` / `deleteShapes` methods, however there are places where
those methods are called from other methods (such as
`distributeShapes`). If we wanted to make these work, we would have also
had to provide a `force` option / bag to those methods.

Using a wrapper callback allows for "regular" tldraw editor code to work
while allowing for updates and deletes.

### Interaction logic?

We don't want this change to effect any of our interaction logic.

A lot of our interaction logic depends on identifying which shapes are
locked and which shapes aren't. For example, clicking on a locked shape
will go to the `pointing_canvas` state rather than the `pointing_shape`.
This PR has no effect on that part of the library.

It only effects the updateShapes and deleteShapes methods. As an example
of this, when `_force` is set to true by default, the only tests that
should fail are in `lockedShapes.test.ts`. The "user land" experience of
locked shapes is identical to what it is now.

### Change type

- [x] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [x] `api`
- [ ] `other`

### Test plan

1. Create a shape
2. Lock it
3. From the console, update it
4. From the console, delete it

- [x] Unit tests

### Release notes

- SDK: Adds `Editor.force()` to permit updating / deleting locked shapes
- Fixed a bug that would allow locked shapes to be updated
programmatically
- Fixed a bug that would allow locked group shapes to be ungrouped
programmatically

---------

Co-authored-by: alex <alex@dytry.ch>
2024-07-15 14:10:09 +00:00
David Sheldrick
934c31574d
fix bemo url in examples app (#4156)
tiny fix to account for recent config file churn 

### Change type

- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
2024-07-12 14:39:08 +00:00
Taha
85f36639ff
State/store example (#4147)
An example of how to subscribe to values in the store and run side
effects using reactors.

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- Added an example that shows how to use track, useValue and useReactor

---------

Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
2024-07-12 13:58:09 +00:00
David Sheldrick
1c35ed27f9
[bemo] No public shared rooms in examples app (#4152)
As discussed in #4135 I'm doing a quick follow up to help me sleep at
night.

Sorry sorry sorry sorry

![Kapture 2024-07-12 at 12 47
45](https://github.com/user-attachments/assets/ee9babf0-6b7e-4ddb-a427-5aef9436f922)

i couldn't figure out the magic overlay css so I reverted to ugly static
toolbar. again so sorry

### Change type

- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- Fixed a bug with…
2024-07-12 13:07:07 +00:00
alex
64e1fac897
[5/5] Move bemo from dotcom to examples (#4135)
Move our bemo playground from dotcom to the examples app. In preparation
for more multiplayer examples, I built our a little bit of chrome around
example room IDs: if you create an example with `multiplayer: true`, the
examples app will render a little room ID picker above your example. The
room IDs are scoped to each example, and each deploy of the examples
app. By default people on the same example will be in the same room, but
the default ID changes every hour.

As I was doing this, I noticed you could get an ugly situation where the
docs site was in dark mode, tldraw was in dark mode, but the little bit
of examples chrome was in light mode. To fix this I through together an
extremely rough dark mode for the examples which switches on whenever
the tldraw instance inside is in dark mode.

### Change type

- [x] `other`

---------

Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
2024-07-12 10:36:31 +00:00
Taha
d684866f90
Geometry shape example (#4134)
An example of how to make a shape with custom geometry. It's a house.

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- Added an example for creating a shape with custom geometry
2024-07-12 07:13:25 +00:00
David Sheldrick
34eaf12bff
[bemo] allow custom shapes (#4144)
I tested this by adding a custom shape on the bemo example page, it
works 👍🏼

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- Fixed a bug with…
2024-07-11 13:48:14 +00:00
Mime Čuvalo
69a1c17b46
sdk: wires up tldraw to have licensing mechanisms (#4021)
For non-commercial usage of tldraw, this adds a watermark in the corner,
both for branding purposes and as an incentive for our enterprise
customers to purchase a license.

For commercial usage of tldraw, you add a license to the `<Tldraw
licenseKey={YOUR_LICENSE_KEY} />` component so that the watermark
doesn't show.

The license is a signed key that has various bits of information in it,
such as:
- license type
- hosts that the license is valid for
- whether it's an internal-only license
- expiry date

We check the license on load and show a watermark (or throw an error if
internal-only) if the license is not valid in a production environment.

This is a @MitjaBezensek, @Taha-Hassan-Git, @mimecuvalo joint
production! 🤜 🤛

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [x] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. We will be dogfooding on staging.tldraw.com and tldraw.com itself
before releasing this.

### Release Notes

- SDK: wires up tldraw to have licensing mechanisms.

---------

Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-07-11 11:49:18 +00:00
alex
7273eb3101
[3/5] Automatically enable multiplayer UI when using demo sync (#4119)
Adds a new `multiplayerStatus` store prop. This can either be `null`
(indicating this isn't a multiplayer store) or a signal containing
`online` or `offline` indicating that it is. We move a bunch of
previously dotcom specific UI into `tldraw` and use this new prop to
turn it on or off by default.

closes TLD-2611

### Change type

- [x] `improvement`
2024-07-10 15:46:09 +00:00
alex
965bc10997
[1/4] Blob storage in TLStore (#4068)
Reworks the store to include information about how blob assets
(images/videos) are stored/retrieved. This replaces the old
internal-only `assetOptions` prop, and supplements the existing
`registerExternalAssetHandler` API.

Previously, `registerExternalAssetHandler` had two responsibilities:
1. Extracting asset metadata
2. Uploading the asset and returning its URL

Existing `registerExternalAssetHandler` implementation will still work,
but now uploading is the responsibility of a new `editor.uploadAsset`
method which calls the new store-based upload method. Our default asset
handlers extract metadata, then call that new API. I think this is a
pretty big improvement over what we had before: overriding uploads was a
pretty common ask, but doing so meant having to copy paste our metadata
extraction which felt pretty fragile. Just in this codebase, we had a
bunch of very slightly different metadata extraction code-paths that had
been copy-pasted around then diverged over time. Now, you can change how
uploads work without having to mess with metadata extraction and
vice-versa.

As part of this we also:
1. merge the old separate asset indexeddb store with the main one.
because this warrants some pretty big migration stuff, i refactored our
indexed-db helpers to work around an instance instead of being free
functions
2. move our existing asset stuff over to the new approach
3. add a new hook in `sync-react` to create a demo store with the new
assets

### Change type

- [x] `api`

### Release notes

Introduce a new `assets` option for the store, describing how to save
and retrieve asset blobs like images & videos from e.g. a user-content
CDN. These are accessible through `editor.uploadAsset` and
`editor.resolveAssetUrl`. This supplements the existing
`registerExternalAssetHandler` API: `registerExternalAssetHandler` is
for customising metadata extraction, and should call
`editor.uploadAsset` to save assets. Existing
`registerExternalAssetHandler` calls will still work, but if you're only
using them to configure uploads and don't want to customise metadata
extraction, consider switching to the new `assets` store prop.
2024-07-10 13:00:18 +00:00
Taha
720b115a7e
Export entire canvas as an image (#4125)
This has been something we've been asked about 3-4 times on the discord
so far. So here is an example to point people towards in the future.

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- [examples app] added an example of how to export the page as an image
2024-07-10 09:53:33 +00:00
David Sheldrick
e3cdf34007
Set bemo url in examples app (#4091)
This PR just adds a thing to set the bemo URL during build. No bemo
example page yet

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`

### Test plan

1. Create a shape...
2.

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

### Release notes

- Fixed a bug with...
2024-07-08 15:37:04 +00:00
Steve Ruiz
1bf2820a3f
Add component for ShapeIndicators (#4083)
This PR adds a component for `ShapeIndicators` to the UI component
overrides. It moves the "select tool" state logic up to the new
`TldrawShapeIndicators` component.

### Change type

- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [x] `api`
- [ ] `other`

### Release notes

- Added new `ShapeIndicators` component to `components` object.
- Added new `TldrawShapeIndicators` component.
2024-07-05 10:41:03 +00:00
Steve Ruiz
a466ffe92a
indicators on the canvas example (#4071)
This PR shows how you could use an OnTheCanvas component to display
shape indicators.

### Change type

- [x] `other`
2024-07-05 09:29:42 +00:00
Steve Ruiz
cafa0f5636
Add setDefaultValue to StyleProp (#4044)
This PR adds a way to set the default value of a style property.

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`

### Release notes

- Adds a method for changing the default style of a `StyleProp`
instance.
2024-07-01 10:21:33 +00:00
Steve Ruiz
4fff8a89af
Add shape change examples (#4043)
This PR adds two new examples showing how to reject changes to shape or
instance records.

### Change type

- [x] `other`

### Release notes

- Adds shape / instance change examples.
2024-06-29 10:19:44 +00:00
Taha
978de17a12
Layout constraints example (#3996)
Adds an example of implementing layout contraints using bindings.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [x] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [x] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Adds an example of how to use bindings to create layout constraints

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-06-28 13:49:54 +00:00
Steve Ruiz
964dd82f93
Fix fog of war (#4031)
This PR fixes the fog of war example.

### Change Type


<!--  Please select a 'Type' label ️ -->

- [ ] `feature` — New feature
- [ ] `improvement` — Product improvement
- [ ] `api` — API change
- [x] `bugfix` — Bug fix
- [ ] `other` — Changes that don't affect SDK users, e.g. internal or
.com changes

---------

Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
2024-06-28 09:04:47 +00:00
Steve Ruiz
aa1c99fee3
Cleanup z-indices (#4020)
This PR:
- simplifies a lot of z-index layers

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `bugfix` — Bug fix

### Release Notes

- Cleans up z-indexes and removes some unused CSS.
2024-06-27 13:30:18 +00:00
Steve Ruiz
3d07262e20
Add fog of war example (#4025)
This PR adds a cute fog of war example.

![Kapture 2024-06-26 at 20 47
37](https://github.com/tldraw/tldraw/assets/23072548/b426776f-b027-419e-9770-29f5c7ab2563)

### Change Type

- [x] `docs` 
- [x] `improvement` 

### Release Notes

- Adds fog of war example.
2024-06-26 18:06:51 +00:00
alex
2d2a7ea76f
Fix multiple editor instances issue (#4001)
React's strict mode runs effects twice on mount, but once it's done that
it'll go forward with the state from the first effect. For example, this
component:

```tsx
let nextId = 1
function Component() {
	const [state, setState] = useState(null)
	useEffect(() => {
		const id = nextId++
		console.log('set up', id)
		setState(id)
		return () => console.log('tear down', id)
	}, [])
	if (!state) return
	console.log('render', state)
}
```

Would log something like this when mounting for the first time:
- `set up 1`
- `tear down 1`
- `set up 2`
- `render 1`

For us, this is a problem: editor 2 is the version that's still running,
but editor 1 is getting used for render. React talks a bit about this
issue here: https://github.com/reactwg/react-18/discussions/19

The fix seems to be to keep the editor in a `useRef` instead of a
`useState`. We need the state to trigger re-renders though, so we sync
the ref into the state although we don't actually use the state value.

### Change Type


- [x] `sdk` — Changes the tldraw SDK
- [x] `bugfix` — Bug fix



### Release Notes

- Fix a bug causing text shape measurement to work incorrectly when
using react strict mode
2024-06-24 12:24:24 +00:00
Taha
b60ae0f067
Add tags to examples frontmatter (#3929)
Better filtering in the examples app, see gif below.


Drive-by fixes: 
- removed a duplicate shape meta example
- Speech bubble text was overflowing and needed the width to be set
- Sticker (bindings) no longer snaps
- typos

![2024-06-12 at 17 06 17 - Jade
Woodpecker](https://github.com/tldraw/tldraw/assets/98838967/80a2ca95-582e-4f7e-b50f-5560211ef081)


### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [x] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Type a lot of text in a speech bubble shape and move the tail
2. Text should stay static

### Release Notes

- Improve filtering of examples
2024-06-18 10:47:42 +00:00
Steve Ruiz
f621f92ae2
Fix draw shape indicators for pen-drawn solid shapes (#3962)
This PR fixes the indicators for shapes that were drawn with a pen or
stylus.

<img width="1008" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/f3050ccb-08f0-4bf4-a225-51863df12464">

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `bugfix` — Bug fix

### Release Notes

- Fixes a bug with the indicator for stylus-drawn draw shapes.
2024-06-18 10:36:51 +00:00
Mitja Bezenšek
12aea7ed68
[Experiment] Allow users to use system's appearance (dark / light) mode (#3703)
Allow the users to fully use the same colour scheme as their system.
Allows the users to either: force dark colour scheme, force light colour
scheme, or use the system one.

It's reactive to the system changes.


https://github.com/tldraw/tldraw/assets/2523721/6d4cef03-9ef0-4098-b299-6bf5d7513e98


### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add a brief release note for your PR here.

---------

Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
2024-06-17 14:46:04 +00:00
Mitja Bezenšek
1bcc16d15a
Move from unpkg to our own cdn. (#3923)
Switches from unpkg to our own cdn files.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know

### Release Notes

- Start using our own cdn instead of unpkg.
2024-06-17 13:13:46 +00:00
Steve Ruiz
ac149c1014
Dynamic size mode + fill fill (#3835)
This PR adds a user preference for "dynamic size mode" where the scale
of shapes (text size, stroke width) is relative to the current zoom
level. This means that the stroke width in screen pixels (or text size
in screen pixels) is identical regardless of zoom level.

![Kapture 2024-05-27 at 05 23
21](https://github.com/tldraw/tldraw/assets/23072548/f247ecce-bfcd-4f85-b7a5-d7677b38e4d8)

- [x] Draw shape
- [x] Text shape
- [x] Highlighter shape
- [x] Geo shape
- [x] Arrow shape
- [x] Note shape
- [x] Line shape

Embed shape?

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature

### Test Plan

1. Use the tools.
2. Change zoom

- [ ] Unit Tests

### Release Notes

- Adds a dynamic size user preferences.
- Removes double click to reset scale on text shapes.
- Removes double click to reset autosize on text shapes.

---------

Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
2024-06-16 16:58:13 +00:00
Mime Čuvalo
cbf7c2c605
assets: preload fonts (#3927)
Looking at the waterfall of fonts/images/etc. we wanted the "Loading
assets..." bit to commence earlier so it's not fighting for bandwidth
with the icons loading all at the same time.

This writes to the index.html file to start preloading the fonts we
need.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [x] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Release Notes

- Perf: improve font loading timing on dotcom.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-06-16 16:02:34 +00:00
Mime Čuvalo
6c846716c3
assets: make option to transform urls dynamically / LOD (#3827)
this is take #2 of this PR https://github.com/tldraw/tldraw/pull/3764

This continues the idea kicked off in
https://github.com/tldraw/tldraw/pull/3684 to explore LOD and takes it
in a different direction.

Several things here to call out:
- our dotcom version would start to use Cloudflare's image transforms
- we don't rewrite non-image assets 
- we debounce zooming so that we're not swapping out images while
zooming (it creates jank)
- we load different images based on steps of .25 (maybe we want to make
this more, like 0.33). Feels like 0.5 might be a bit too much but we can
play around with it.
- we take into account network connection speed. if you're on 3g, for
example, we have the size of the image.
- dpr is taken into account - in our case, Cloudflare handles it. But if
it wasn't Cloudflare, we could add it to our width equation.
- we use Cloudflare's `fit=scale-down` setting to never scale _up_ an
image.
- we don't swap the image in until we've finished loading it
programatically (to avoid a blank image while it loads)

TODO
- [x] We need to enable Cloudflare's pricing on image transforms btw
@steveruizok 😉 - this won't work quite yet until we do that.


### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [x] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Test images on staging, small, medium, large, mega
2. Test videos on staging

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

### Release Notes

- Assets: make option to transform urls dynamically to provide different
sized images on demand.
2024-06-11 14:17:09 +00:00
Mime Čuvalo
3adae06d9c
security: enforce use of our fetch function and its default referrerpolicy (#3884)
followup to https://github.com/tldraw/tldraw/pull/3881 to enforce this
in the codebase

Describe what your pull request does. If appropriate, add GIFs or images
showing the before and after.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [x] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-06-11 13:59:25 +00:00
Mime Čuvalo
07296286ca
tests: ugh edit->edit still flaky, skip (#3919)
disable test

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-06-11 12:39:19 +00:00
David Sheldrick
23f8b3fd60
Bindings tests (#3800)
wip

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add a brief release note for your PR here.
2024-06-11 05:55:16 +00:00
David Sheldrick
d47fd56d82
Bindings onBeforeShapeIsolate? (#3871)
So we were kinda bending over backwards to capture the use case where we
update the arrow's terminal x,y coords when unbinding, copy-pasting, and
duplicating.

- At first we abused the `onBeforeShapeDelete` callbacks, but that was
footgunny.
- Then we created a `onBeforeUnbind` callback, which was less footgunny
but still subtly footgunny.

This PR proposes reverting the `onBeforeUnbind` stuff, taking us back to
having `onBeforeShapeDelete` stuff. But at the same time it adds
`onBeforeShapeIsolate` callbacks which are triggered at the following
times:

- When you delete the other shape in a bound shape pair
- When you copy/paste or duplicate one shape in a bound shape pair but
not the other one
- When you opt-in while deleting bindings e.g. `deleteBindings([...],
{isolateShapes: true})`

This PR also fixes the bound arrow drag interaction. We can probably
extract that out to a separate PR if needed.


![Kapture 2024-06-04 at 12 42
40](https://github.com/tldraw/tldraw/assets/1242537/95b51e14-1119-4dad-91e4-8b19fdb5e862)

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [x] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add a brief release note for your PR here.
2024-06-06 09:48:23 +00:00
David Sheldrick
5d7f368fd6
[DX] sensible defaults for createTLStore (#3886)
`createTLStore` had defaults of empty arrays for shapeUtils and
bindingUtils. this is problematic since people who already are calling
`createTLStore` manually with like `createTLStore({shapeUtils:
defaultShapeUtils})` will miss out on bindings utils when they upgrade
to the latest version, and this will probably only fail at runtime for
them.

To prevent issues we could have made `shapeUtils` and `bindingUtils`
required args but it feels better to me, long term, if we bring
`createTLStore` in line with `createTLSchema` and configure it to use
tldraw's default shapes/bindings if no custom overrides are specified.

i.e. we can do this

```diff
- const store = createTLStore({ shapeUtils: defaultShapeUtils, bindingUtils: defaultBindingUtils })
+ const store = createTLStore()
```

There's still technically potential for breaking changes by people
accidentally including the arrow binding util when they might not have
arrows in the app, but I don't think that's likely to actually cause any
bugs unless they add their own arrow binding type later on.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add a brief release note for your PR here.
2024-06-05 14:29:54 +00:00
David Sheldrick
5d58924f74
Editor.blur method (#3875)
This PR adds a `editor.blur()` method to complement the `editor.focus()`
method, and enhances both with an options param that allows to skip
dispatching a focus/blur event on the container.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [x] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add a brief release note for your PR here.
2024-06-05 12:25:41 +00:00
Mime Čuvalo
aadc0aab4d
editor: register timeouts/intervals/rafs for disposal (#3852)
We have a lot of events that fire in the editor and, technically, they
can fire after the Editor is long gone.
This adds a registry/manager to track those timeout/interval/raf IDs
(and some eslint rules to enforce it).

Some other cleanups:
- `requestAnimationFrame.polyfill.ts` looks like it's unused now (it
used to be used in a prev. revision)
- @ds300 I could use your feedback on the `EffectScheduler` tweak. in
`useReactor` we do: `() => new EffectScheduler(name, reactFn, {
scheduleEffect: (cb) => requestAnimationFrame(cb) }),`
and that looks like it doesn't currently get disposed of properly.
thoughts? happy to do that separately from this PR if you think that's a
trickier thing.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Test async operations and make sure they don't fire after disposal.

### Release Notes

- Editor: add registry of timeouts/intervals/rafs

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-06-04 08:50:40 +00:00
David Sheldrick
19d051c188
Snapshots pit of success (#3811)
Lots of people are having a bad time with loading/restoring snapshots
and there's a few reasons for that:

- It's not clear how to preserve UI state independently of document
state.
- Loading a snapshot wipes the instance state, which means we almost
always need to
  - update the viewport page bounds
  - refocus the editor
  - preserver some other sneaky properties of the `instance` record

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add a brief release note for your PR here.
2024-06-03 15:58:00 +00:00
Mime Čuvalo
aba77fd089
test: disable camera pinch test for now, too flaky (#3854)
this didn't work https://github.com/tldraw/tldraw/pull/3829
disabling this test for now

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-05-31 09:10:04 +00:00
Mime Čuvalo
749b7d4d6d
tests: fix edit→edit flakiness (#3850)
Similar to https://github.com/tldraw/tldraw/pull/3829

Trying to see if adding a small timeout helps fix this flaky test.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-05-30 13:06:40 +00:00
Mime Čuvalo
b56433aa79
tests: fix camera scroll flakiness (#3829)
There's been some flakiness on the camera e2e tests. I _think_ this
would help resolve it, theory being that it's not finished scrolling
when we take the reading.

example failure:
https://github.com/tldraw/tldraw/actions/runs/9222574205/job/25373998190?pr=3827

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-05-30 12:59:51 +00:00
alex
a457a39081
Move constants to options prop (#3799)
Another go at #3628 & #3783. This moves (most) constants into
`editor.options`, configurable by the `options` prop on the tldraw
component.

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature

### Release Notes

You can now override many options which were previously hard-coded
constants. Pass an `options` prop into the tldraw component to change
the maximum number of pages, grid steps, or other previously hard-coded
values. See `TldrawOptions` for more
2024-05-28 14:22:03 +00:00
Steve Ruiz
ef44d71ee2
Add heart geo shape (#3787)
This PR adds a heart geo shape. ❤️

It also:
- adds `toSvgPathData` to geometry2d
- uses geometry2d in places where previously we recalculated things like
perimeter of ellipse
- flattens geo shape util components

- [x] Calculate the path length for the DashStyleHeart 

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature

### Release Notes

- Adds a heart shape to the geo shape set.
2024-05-24 13:04:28 +00:00
alex
87e3d60c90
rework canBind callback (#3797)
This PR reworks the `canBind` callback to work with customizable
bindings. It now accepts an object with a the shape, the other shape
(optional - it may not exist yet), the direction, and the type of the
binding. Devs can use this to create shapes that only participate in
certain binding types, can have bindings from but not to them, etc.

If you're implementing a binding, you can see if binding two shapes is
allowed using `editor.canBindShapes(fromShape, toShape, 'my binding
type')`

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `improvement` — Improving existing features

### Release Notes

#### Breaking changes
The `canBind` flag now accepts an options object instead of just the
shape in question. If you're relying on its arguments, you need to
change from `canBind(shape) {}` to `canBind({shape}) {}`.
2024-05-23 13:32:02 +00:00
alex
f9ed1bf2c9
Force interface instead of type for better docs (#3815)
Typescript's type aliases (`type X = thing`) can refer to basically
anything, which makes it hard to write an automatic document formatter
for them. Interfaces on the other hand are only object, so they play
much nicer with docs. Currently, object-flavoured type aliases don't
really get expanded at all on our docs site, which means we have a bunch
of docs content that's not shown on the site.

This diff introduces a lint rule that forces `interface X {foo: bar}`s
instead of `type X = {foo: bar}` where possible, as it results in a much
better documentation experience:

Before:
<img width="437" alt="Screenshot 2024-05-22 at 15 24 13"
src="https://github.com/tldraw/tldraw/assets/1489520/32606fd1-6832-4a1e-aa5f-f0534d160c92">

After:
<img width="431" alt="Screenshot 2024-05-22 at 15 33 01"
src="https://github.com/tldraw/tldraw/assets/1489520/4e0d59ee-c38e-4056-b9fd-6a7f15d28f0f">


### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `docs` — Changes to the documentation, examples, or templates.
- [x] `improvement` — Improving existing features
2024-05-22 15:55:49 +00:00
Mime Čuvalo
ed33e6ab4d
build: disable flaky edit->edit focus test for now (#3803)
will fix up tomorrow to make sure the commit queue stays green

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-05-21 21:46:14 +00:00
Taha
e559a7cdbb
E2E camera tests (#3747)
This PR adds E2E tests for panning and zooming using touch gestures and
zooming using the scrollwheel input.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [x] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Adds E2E tests for the camera
2024-05-19 01:02:06 +00:00
Mime Čuvalo
9bf25c10b8
docs: smaller snapshot so it doesnt crash (#3768)
+ drive by fix for css cleanup

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [x] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [x] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
2024-05-17 13:11:52 +00:00
Mime Čuvalo
b4c1f606e1
focus: rework and untangle existing focus management logic in the sdk (#3718)
Focus management is really scattered across the codebase. There's sort
of a battle between different code paths to make the focus the correct
desired state. It seemed to grow like a knot and once I started pulling
on one thread to see if it was still needed you could see underneath
that it was accounting for another thing underneath that perhaps wasn't
needed.

The impetus for this PR came but especially during the text label
rework, now that it's much more easy to jump around from textfield to
textfield. It became apparent that we were playing whack-a-mole trying
to preserve the right focus conditions (especially on iOS, ugh).

This tries to remove as many hacks as possible, and bring together in
place the focus logic (and in the darkness, bind them).

## Places affected
- [x] `useEditableText`: was able to remove a bunch of the focus logic
here. In addition, it doesn't look like we need to save the selection
range anymore.
- lingering footgun that needed to be fixed anyway: if there are two
labels in the same shape, because we were just checking `editingShapeId
=== id`, the two text labels would have just fought each other for
control
- [x] `useFocusEvents`: nixed and refactored — we listen to the store in
`FocusManager` and then take care of autoFocus there
- [x] `useSafariFocusOutFix`: nixed. not necessary anymore because we're
not trying to refocus when blurring in `useEditableText`. original PR
for reference: https://github.com/tldraw/brivate/pull/79
- [x] `defaultSideEffects`: moved logic to `FocusManager`
- [x] `PointingShape` focus for `startTranslating`, decided to leave
this alone actually.
- [x] `TldrawUIButton`: it doesn't look like this focus bug fix is
needed anymore, original PR for reference:
https://github.com/tldraw/tldraw/pull/2630
- [x] `useDocumentEvents`: left alone its manual focus after the Escape
key is hit
- [x] `FrameHeading`: double focus/select doesn't seem necessary anymore
- [x] `useCanvasEvents`: `onPointerDown` focus logic never happened b/c
in `Editor.ts` we `clearedMenus` on pointer down
- [x] `onTouchStart`: looks like `document.body.click()` is not
necessary anymore

## Future Changes
- [ ] a11y: work on having an accessebility focus ring
- [ ] Page visibility API:
(https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API)
events when tab is back in focus vs. background, different kind of focus
- [ ] Reexamine places we manually dispatch `pointer_down` events to see
if they're necessary.
- [ ] Minor: get rid of `useContainer` maybe? Is it really necessary to
have this hook? you can just do `useEditor` → `editor.getContainer()`,
feels superfluous.

## Methodology
Looked for places where we do:
- `body.click()`
- places we do `container.focus()`
- places we do `container.blur()`
- places we do `editor.updateInstanceState({ isFocused })`
- places we do `autofocus`
- searched for `document.activeElement`

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

- [x] run test-focus.spec.ts
- [x] check MultipleExample
- [x] check EditorFocusExample
- [x] check autoFocus
- [x] check style panel usage and focus events in general
- [x] check text editing focus, lots of different devices,
mobile/desktop

### Release Notes

- Focus: rework and untangle existing focus management logic in the SDK
2024-05-17 08:53:57 +00:00