Commit graph

299 commits

Author SHA1 Message Date
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
David Sheldrick
48fa9018f4
[bindings] beforeUnbind/afterUnbind to replace beforeDelete/afterDelete (#3761)
Before this PR the interface for doing cleanup when shapes/bindings were
deleted was quite footgunny and inexpressive.

We were abusing the shape beforeDelete callbacks to implement
copy+paste, which doesn't work in situations where cascading deletes are
required. This caused bugs in both our pin and sticker examples, where
copy+paste was broken. I noticed the same bug in my experiment with text
labels, and I think the fact that it took us a while to notice these
bugs indicates other users are gonna fall prey to the same bugs unless
we help them out.

One suggestion to fix this was to add `onAfterDelete(From|To)Shape`
callbacks. The cascading deletes could happen in those, while keeping
the 'commit changes' kinds of updates in the `before` callbacks and
theoretically that would fix the issues with copy+paste. However,
expecting people to figure this out on their own is asking a heckuva lot
IMO, and it's a heavy bit of nuance to try to convey in the docs. It's
hard enough to convey it here. Plus I could imagine for some users it
might easily even leave the store in an inconsistent state to allow a
bound shape to exist for any length of time after the shape it was bound
to was already deleted.

It also just makes an already large and muddy API surface area even
larger and muddier and if that can be avoided let's avoid it.

This PR clears things up by making it so that there's only one callback
for when a binding is removed. The callback is given a `reason` for why
it is being called

The `reason` is one of the following:

- The 'from' is being deleted
- The 'to' shape is being deleted
- The binding is being deleted on it's own.

Technically a binding might end up being deleted when both the `from`
and `to` shapes are being deleted, but it's very hard to know for
certain when that is happening, so I decided to just ignore it for now.
I think it would only matter for perf reasons, to avoid doing useless
work.

So this PR replaces the `onBeforeDelete`, `onAfterDelete`,
`onBeforeFromShapeDelete` and `onBeforeToShapeDelete` (and the
prospective `onAfterFromShapeDelete` and `onAfterToShapeDelete`) with
just two callbacks:

- `onBeforeUnbind({binding, reason})` - called before any shapes or the
binding have been deleted.
- `onAfterUnbind({binding, reason})` - called after the binding and any
shapes have been deleted.

This still allows all the same behaviour as before, without having to
spread the logic between multiple callbacks. It's also just clearer IMO
since you only get one callback invocation per unbinding rather than
potentially two. It also fixes our copy+paste footgun since we can now
implement that by just deleting the bindings rather than invoking the
`onBeforeDelete(From|To)Shape` callbacks.

I'm not worried about losing the explicit before/after delete callbacks
for the binding record or shape records because sdk users still have the
ability to detect all those situations with full nuance in obvious ways.
The one thing that would even require extra bookkeeping is getting
access to a shape record after the shape was deleted, but that's
probably not a thing anybody would want to do 🤷🏼

### 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-05-16 13:48:36 +00:00
alex
ab807afda3
Store-level "operation end" event (#3748)
This adds a store-level "operation end" event which fires at the end of
atomic operations. It includes some other changes too:

- The `SideEffectManager` now lives in & is a property of the store as
`StoreSideEffects`. One benefit to this is that instead of overriding
methods on the store to register side effects (meaning the store can
only ever be used in one place) the store now calls directly into the
side effect manager, which is responsible for dealing with any other
callbacks
- The history manager's "batch complete" event is gone, in favour of
this new event. We were using the batch complete event for only one
thing, calling `onChildrenChange` - which meant it wasn't getting called
for undo/redo events, which aren't part of a batch. `onChildrenChange`
is now called after each atomic store operation affecting children.

I've also added a rough pin example which shows (kinda messily) how you
might use the operation complete handler to traverse a graph of bindings
and resolve constraints between them.

### Change Type

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

### Release Notes

#### Breaking changes
`editor.registerBatchCompleteHandler` has been replaced with
`editor.registerOperationCompleteHandler`
2024-05-14 09:42:41 +00:00
alex
5a15c49d63
ban using @internal items in examples (#3746)
There's been some confusion in the community as our example use a few
`@internal` methods. These things are intended for use inside the tldraw
library, but aren't a part of the public API. That means that when those
examples are copied out of the tldraw repo, those `@internal` references
produce errors.

This diff bans the use of items tagged as `@internal` inside our
examples app by adding an eslint plugin (adapted from the one we already
have that protects against deprecated types) preventing them.

### Change Type
- [x] `docs` — Changes to the documentation, examples, or templates.
- [x] `bugfix` — Bug fix
- [x] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
2024-05-14 08:49:28 +00:00
Mime Čuvalo
d2d3e582e5
assets: rework mime-type detection to be consistent/centralized; add support for webp/webm, apng, avif (#3730)
As I started working on image LOD stuff and wrapping my head around the
codebase, this was bothering me.
- there are missing popular types, especially WebP
- there are places where we're copy/pasting the same list of types but
they can get out-of-date with each other (also, one place described
supporting webm but we didn't actually do that)

This adds animated apng/avif detection as well (alongside our animated
gif detection). Furthermore, it moves the gif logic to be alongside the
png logic (they were in separate packages unnecessarily)

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

- Images: unify list of acceptable types and expand to include webp,
webm, apng, avif
2024-05-13 08:29:43 +00:00
Steve Ruiz
da415d95db
Update READMEs, add form link (#3741)
This PR updates readmes (including fixing some typos) and adds a link to
a Google Form for license inquiries.

### Change Type
- [x] `internal` — Does not affect user-facing stuff
- [x] `chore` — other boring stuff
2024-05-12 20:48:07 +00:00
alex
da35f2bd75
Bindings (#3326)
First draft of the new bindings API. We'll follow this up with some API
refinements, tests, documentation, and examples.

Bindings are a new record type for establishing relationships between
two shapes so they can update at the same time.

### Change Type

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

### Release Notes

#### Breaking changes
- The `start` and `end` properties on `TLArrowShape` no longer have
`type: point | binding`. Instead, they're always a point, which may be
out of date if a binding exists. To check for & retrieve arrow bindings,
use `getArrowBindings(editor, shape)` instead.
- `getArrowTerminalsInArrowSpace` must be passed a `TLArrowBindings` as
a third argument: `getArrowTerminalsInArrowSpace(editor, shape,
getArrowBindings(editor, shape))`
- The following types have been renamed:
    - `ShapeProps` -> `RecordProps`
    - `ShapePropsType` -> `RecordPropsType`
    - `TLShapePropsMigrations` -> `TLPropsMigrations`
    - `SchemaShapeInfo` -> `SchemaPropsInfo`

---------

Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
2024-05-08 12:37:31 +00:00
Mitja Bezenšek
2dd71f8510
Measure action durations and fps for our interactions (#3472)
Adds a feature flag `Measure performance` that allows us to:
- Measure the performance of all the actions (it wraps them into
`measureCbDuration`).
- Measure the frame rate of certain interactions like resizing,
erasing,....

Example of how it looks like:

![CleanShot 2024-04-17 at 18 04
05](https://github.com/tldraw/tldraw/assets/2523721/0fb69745-f7b2-4b55-ac01-27ea26963d9a)


### 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
- [ ] `tests` — Changes to any test code
- [x] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
=

---------

Co-authored-by: Mime Čuvalo <mimecuvalo@gmail.com>
2024-05-08 10:06:05 +00:00
Steve Ruiz
ebc892a1a6
Camera options followups (#3701)
This PR adds a slideshow example (similar to @TodePond's slides but more
on rails) as a way to put some pressure on camera controls.

Along the way, it fixes some issues I found with animations and the new
camera controls.

- forced changes will continue to force through animations
- animations no longer set unnecessary additional listeners
- animations end correctly
- updating camera options does not immediately update the camera (to
allow for animations, etc.)

It also changes the location of the "in front of the canvas" element so
that it is not hidden by the hit test blocking element.

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `improvement` — Improving existing features
2024-05-07 10:06:35 +00:00
Steve Ruiz
fabba66c0f
Camera options (#3282)
This PR implements a camera options API.

- [x] Initial PR
- [x] Updated unit tests
- [x] Feedback / review
- [x] New unit tests
- [x] Update use-case examples
- [x] Ship?

## Public API

A user can provide camera options to the `Tldraw` component via the
`cameraOptions` prop. The prop is also available on the `TldrawEditor`
component and the constructor parameters of the `Editor` class.

```tsx
export default function CameraOptionsExample() {
	return (
		<div className="tldraw__editor">
			<Tldraw cameraOptions={CAMERA_OPTIONS} />
		</div>
	)
}
```

At runtime, a user can:
-  get the current camera options with `Editor.getCameraOptions`
-  update the camera options with `Editor.setCameraOptions`

Setting the camera options automatically applies them to the current
camera.

```ts
editor.setCameraOptions({...editor.getCameraOptions(), isLocked: true })
```

A user can get the "camera fit zoom" via `editor.getCameraFitZoom()`.

# Interface

The camera options themselves can look a few different ways depending on
the `type` provided.


```tsx
export type TLCameraOptions = {
	/** Whether the camera is locked. */
	isLocked: boolean
	/** The speed of a scroll wheel / trackpad pan. Default is 1. */
	panSpeed: number
	/** The speed of a scroll wheel / trackpad zoom. Default is 1. */
	zoomSpeed: number
	/** The steps that a user can zoom between with zoom in / zoom out. The first and last value will determine the min and max zoom. */
	zoomSteps: number[]
	/** Controls whether the wheel pans or zooms.
	 *
	 * - `zoom`: The wheel will zoom in and out.
	 * - `pan`: The wheel will pan the camera.
	 * - `none`: The wheel will do nothing.
	 */
	wheelBehavior: 'zoom' | 'pan' | 'none'
	/** The camera constraints. */
	constraints?: {
		/** The bounds (in page space) of the constrained space */
		bounds: BoxModel
		/** The padding inside of the viewport (in screen space) */
		padding: VecLike
		/** The origin for placement. Used to position the bounds within the viewport when an axis is fixed or contained and zoom is below the axis fit. */
		origin: VecLike
		/** The camera's initial zoom, used also when the camera is reset.
		 *
		 * - `default`: Sets the initial zoom to 100%.
		 * - `fit-x`: The x axis will completely fill the viewport bounds.
		 * - `fit-y`: The y axis will completely fill the viewport bounds.
		 * - `fit-min`: The smaller axis will completely fill the viewport bounds.
		 * - `fit-max`: The larger axis will completely fill the viewport bounds.
		 * - `fit-x-100`: The x axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 * - `fit-y-100`: The y axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 * - `fit-min-100`: The smaller axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 * - `fit-max-100`: The larger axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 */
		initialZoom:
			| 'fit-min'
			| 'fit-max'
			| 'fit-x'
			| 'fit-y'
			| 'fit-min-100'
			| 'fit-max-100'
			| 'fit-x-100'
			| 'fit-y-100'
			| 'default'
		/** The camera's base for its zoom steps.
		 *
		 * - `default`: Sets the initial zoom to 100%.
		 * - `fit-x`: The x axis will completely fill the viewport bounds.
		 * - `fit-y`: The y axis will completely fill the viewport bounds.
		 * - `fit-min`: The smaller axis will completely fill the viewport bounds.
		 * - `fit-max`: The larger axis will completely fill the viewport bounds.
		 * - `fit-x-100`: The x axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 * - `fit-y-100`: The y axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 * - `fit-min-100`: The smaller axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 * - `fit-max-100`: The larger axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
		 */
		baseZoom:
			| 'fit-min'
			| 'fit-max'
			| 'fit-x'
			| 'fit-y'
			| 'fit-min-100'
			| 'fit-max-100'
			| 'fit-x-100'
			| 'fit-y-100'
			| 'default'
		/** The behavior for the constraints for both axes or each axis individually.
		 *
		 * - `free`: The bounds are ignored when moving the camera.
		 * - 'fixed': The bounds will be positioned within the viewport based on the origin
		 * - `contain`: The 'fixed' behavior will be used when the zoom is below the zoom level at which the bounds would fill the viewport; and when above this zoom, the bounds will use the 'inside' behavior.
		 * - `inside`: The bounds will stay completely within the viewport.
		 * - `outside`: The bounds will stay touching the viewport.
		 */
		behavior:
			| 'free'
			| 'fixed'
			| 'inside'
			| 'outside'
			| 'contain'
			| {
					x: 'free' | 'fixed' | 'inside' | 'outside' | 'contain'
					y: 'free' | 'fixed' | 'inside' | 'outside' | 'contain'
			  }
	}
}
```

### Change Type

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

### Test Plan

These features combine in different ways, so we'll want to write some
more tests to find surprises.

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

- [ ] Unit Tests

### Release Notes

- SDK: Adds camera options.

---------

Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
2024-05-04 17:39:04 +00:00
Mime Čuvalo
68bc29f103
textfields: fix RTL layout for SVG exports (#3680)
Followup to https://github.com/tldraw/tldraw/pull/3188 (although this
problem was there before that PR)

This does more work for RTL rendering in SVG context, especially since
we position each span one-by-one.

I had to do a bit of esoteric spelunking and it turns out
[`unicode-bidi:
plaintext`](https://developer.mozilla.org/en-US/docs/Web/CSS/unicode-bidi)
solves our issue even though it isn't really recommend to be used by web
developers. Fun times 🙃

Before:
<img width="369" alt="Screenshot 2024-05-02 at 11 45 44"
src="https://github.com/tldraw/tldraw/assets/469604/df55e03a-4760-4b8f-adad-ed1a8c13ad51">


After:
<img width="365" alt="Screenshot 2024-05-02 at 11 54 48"
src="https://github.com/tldraw/tldraw/assets/469604/3339bbf4-041a-4fdf-8b6e-6fa19dfb0a9e">




### 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
- [ ] `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 LTR text.
2. Test RTL text.
3. Test mixed LTR/RTL on different lines.

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

### Release Notes

- [Add a brief release note for your PR here.](textfields: fix RTL
layout for SVG exports)

---------

Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
2024-05-03 13:40:59 +00:00
Steve Ruiz
932bbf0b1e
3d example (#3647)
This PR adds a little example of using 3D transforms in tldraw.

![Kapture 2024-04-30 at 09 52
18](https://github.com/tldraw/tldraw/assets/23072548/c7620384-629b-4914-a842-5783591c9a3a)

### Change Type

- [x] `docs`
- [x] `improvement`
2024-04-30 09:24:07 +00:00
Steve Ruiz
5601d0ee22
Separate text-align property for shapes (#3627)
This PR creates a new "text align" property for text shapes. Its default
is left align.

This means that text shapes now have their own alignment prop, separate
from the vertical / horizontal alignment used in labels.

The style panel for text has no visual change:

<img width="400" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/aac80d2a-a069-4388-870b-1e0917d88eda">

The style panel for labels has consistent icons for label position:

<img width="487" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/0adf7f0e-8446-4d3e-b9ea-a61e43035207">

Both may be configured separately.

<img width="458" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/698dcfac-6eb2-4a8c-afb8-d1e5761019ef">


# Icon refresh

This PR also removes many unused icons.

It adds a special toggle icon for the context menu.

<img width="571" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/489551e6-a370-4528-9ad4-8f93e119f26b">
<img width="492" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/cd3d77c7-8bae-4369-8b53-ca4685b2fd0e">


### Change Type

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

### Test Plan

1. Load files.
2. Paste excalidraw content.
3. Load v1 files.
4. Use the app as usual.

- [x] Unit Tests

### Release Notes

- Separates the text align property for text shapes and labels.

---------

Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
2024-04-29 10:58:15 +00:00
Mime Čuvalo
608f0210a0
examples: add filter input (#3625)
This was @Taha-Hassan-Git 's idea originally but I thought it wasn't
necessary at the time (with our much shorter list of examples just a
couple months ago!). I think now that we have a plethora of examples
that @Taha-Hassan-Git 's original instinct here was correct and we
should a filter box.

<img width="255" alt="Screenshot 2024-04-26 at 15 22 08"
src="https://github.com/tldraw/tldraw/assets/469604/1eabc04e-c4d0-414d-881c-7ca965dbd6a3">


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

### Release Notes

- Examples: add a filter box.
2024-04-27 11:13:38 +00:00
alex
8151e6f586
Automatic undo/redo (#3364)
Our undo-redo system before this diff is based on commands. A command
is:
- A function that produces some data required to perform and undo a
change
- A function that actually performs the change, based on the data
- Another function that undoes the change, based on the data
- Optionally, a function to _redo_ the change, although in practice we
never use this

Each command that gets run is added to the undo/redo stack unless it
says it shouldn't be.

This diff replaces this system of commands with a new one where all
changes to the store are automatically recorded in the undo/redo stack.
You can imagine the new history manager like a tape recorder - it
automatically records everything that happens to the store in a special
diff, unless you "pause" the recording and ask it not to. Undo and redo
rewind/fast-forward the tape to certain marks.

As the command concept is gone, the things that were commands are now
just functions that manipulate the store.

One other change here is that the store's after-phase callbacks (and the
after-phase side-effects as a result) are now batched up and called at
the end of certain key operations. For example, `applyDiff` would
previously call all the `afterCreate` callbacks before making any
removals from the diff. Now, it (and anything else that uses
`store.atomic(fn)` will defer firing any after callbacks until the end
of an operation. before callbacks are still called part-way through
operations.

## Design options
Automatic recording is a fairly large big semantic change, particularly
to the standalone `store.put`/`store.remove` etc. commands. We could
instead make not-recording the default, and make recording opt-in
instead. However, I think auto-record-by-default is the right choice for
a few reasons:

1. Switching to a recording-based vs command-based undo-redo model is
fundamentally a big semantic change. In the past, `store.put` etc. were
always ignored. Now, regardless of whether we choose record-by-default
or ignore-by-default, the behaviour of `store.put` is _context_
dependant.
2. Switching to ignore-by-default means that either our commands don't
record undo/redo history any more (unless wrapped in
`editor.history.record`, a far larger semantic change) or they have to
always-record/all accept a history options bag. If we choose
always-record, we can't use commands within `history.ignore` as they'll
start recording again. If we choose the history options bag, we have to
accept those options in 10s of methods - basically the entire `Editor`
api surface.

Overall, given that some breaking semantic change here is unavoidable, I
think that record-by-default hits the right balance of tradeoffs. I
think it's a better API going forward, whilst also not being too
disruptive as the APIs it affects are very "deep" ones that we don't
typically encourage people to use.



### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `improvement` — Improving existing features
- [x] `galaxy brain` — Architectural changes

### Release Note
#### Breaking changes
##### 1. History Options
Previously, some (not all!) commands accepted a history options object
with `squashing`, `ephemeral`, and `preserveRedoStack` flags. Squashing
enabled/disabled a memory optimisation (storing individual commands vs
squashing them together). Ephemeral stopped a command from affecting the
undo/redo stack at all. Preserve redo stack stopped commands from wiping
the redo stack. These flags were never available consistently - some
commands had them and others didn't.

In this version, most of these flags have been removed. `squashing` is
gone entirely (everything squashes & does so much faster than before).
There were a couple of commands that had a special default - for
example, `updateInstanceState` used to default to being `ephemeral`.
Those maintain the defaults, but the options look a little different now
- `{ephemeral: true}` is now `{history: 'ignore'}` and
`{preserveRedoStack: true}` is now `{history:
'record-preserveRedoStack'}`.

If you were previously using these options in places where they've now
been removed, you can use wrap them with `editor.history.ignore(fn)` or
`editor.history.batch(fn, {history: 'record-preserveRedoStack'})`. For
example,
```ts
editor.nudgeShapes(..., { ephemeral: true })
```
can now be written as
```ts
editor.history.ignore(() => {
    editor.nudgeShapes(...)
})
```

##### 2. Automatic recording
Previously, only commands (e.g. `editor.updateShapes` and things that
use it) were added to the undo/redo stack. Everything else (e.g.
`editor.store.put`) wasn't. Now, _everything_ that touches the store is
recorded in the undo/redo stack (unless it's part of
`mergeRemoteChanges`). You can use `editor.history.ignore(fn)` as above
if you want to make other changes to the store that aren't recorded -
this is short for `editor.history.batch(fn, {history: 'ignore'})`

When upgrading to this version of tldraw, you shouldn't need to change
anything unless you're using `store.put`, `store.remove`, or
`store.applyDiff` outside of `store.mergeRemoteChanges`. If you are, you
can preserve the functionality of those not being recorded by wrapping
them either in `mergeRemoteChanges` (if they're multiplayer-related) or
`history.ignore` as appropriate.

##### 3. Side effects
Before this diff, any changes in side-effects weren't captured by the
undo-redo stack. This was actually the motivation for this change in the
first place! But it's a pretty big change, and if you're using side
effects we recommend you double-check how they interact with undo/redo
before/after this change. To get the old behaviour back, wrap your side
effects in `editor.history.ignore`.

##### 4. Mark options
Previously, `editor.mark(id)` accepted two additional boolean
parameters: `onUndo` and `onRedo`. If these were set to false, then when
undoing or redoing we'd skip over that mark and keep going until we
found one with those values set to true. We've removed those options -
if you're using them, let us know and we'll figure out an alternative!
2024-04-24 18:26:10 +00:00
alex
bfc8b6a901
fix migration exports (#3586)
We're missing the export for `createShapePropsMigrationIds`, so lets add
it. This also fixes some other bits that were used in examples but not
exported properly from tldraw.

### Change Type

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

### Release Notes

- Expose `createShapePropsMigrationIds`, `defaultEditorAssetUrls`,
`PORTRAIT_BREAKPOINT`, `useDefaultColorTheme`, & `getPerfectDashProps`
2024-04-24 14:36:08 +00:00
alex
cce794e04b
Expose usePreloadAssets (#3545)
Expose `usePreloadAssets` and make sure the exploded/sublibraries
examples uses it. Before this change, fonts weren't loaded correctly for
the exploded example.

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `docs` — Changes to the documentation, examples, or templates.
- [x] `bugfix` — Bug fix
2024-04-22 10:32:22 +00:00
Mime Čuvalo
34ad856873
textfields: nix disableTab option; make TextShapes have custom Tab behavior as intended (#3506)
We shouldn't be making this something you have to negate everytime you
use `useEditableText`. The TextShape can just have its custom behavior
since that's the intended usecase. (although I think that Tab there
doesn't do much anyway, but whatevs)

### 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
- [x] `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-04-17 11:11:08 +00:00
Steve Ruiz
7732e99811
Color tweaks (light and dark mode) (#3486)
This PR makes some changes to the appearance of colors in light and dark
mode. In general colors should be very slightly darker and less
saturated in light mode, creating greater contrast against the canvas,
fill, and note colors.

Before:

![image](https://github.com/tldraw/tldraw/assets/23072548/aa9a0c64-bf7a-4cde-a611-92fa6d78eabb)

After:

![image](https://github.com/tldraw/tldraw/assets/23072548/352bc688-aa68-4b50-b990-fab643cb0bef)

There are still some balancing to do on dark mode.

Before:
<img width="1393" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/d87114a1-c96e-4b77-bd29-7b44f4faa54f">

After:
<img width="1504" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/c8818afe-b961-4a1d-8852-914ff599a7f3">

### Change Type

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

### Release Notes

- Adjusts colors

---------

Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
2024-04-17 09:31:55 +00:00
Lu Wilson
413838cd3d
Add slides example (#3467)
This PR adds a slides use-case example.


https://github.com/tldraw/tldraw/assets/15892272/89fdcb56-167d-4046-bfec-f93b18a83da2


### 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
- [ ] `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.
- [x] `dunno` — I don't know


### Test Plan

1. Try out the slideshow example! (scroll to the bottom to see it).

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

### Release Notes

- Docs: Added a slideshow example

---------

Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
2024-04-17 09:27:37 +00:00
David Sheldrick
4f70a4f4e8
New migrations again (#3220)
Describe what your pull request does. If appropriate, add GIFs or images
showing the before and after.

### Change Type

- [x] `sdk` — Changes the tldraw SDK
- [x] `galaxy brain` — Architectural changes



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

#### BREAKING CHANGES

- The `Migrations` type is now called `LegacyMigrations`.
- The serialized schema format (e.g. returned by
`StoreSchema.serialize()` and `Store.getSnapshot()`) has changed. You
don't need to do anything about it unless you were reading data directly
from the schema for some reason. In which case it'd be best to avoid
that in the future! We have no plans to change the schema format again
(this time was traumatic enough) but you never know.
- `compareRecordVersions` and the `RecordVersion` type have both
disappeared. There is no replacement. These were public by mistake
anyway, so hopefully nobody had been using it.
- `compareSchemas` is a bit less useful now. Our migrations system has
become a little fuzzy to allow for simpler UX when adding/removing
custom extensions and 3rd party dependencies, and as a result we can no
longer compare serialized schemas in any rigorous manner. You can rely
on this function to return `0` if the schemas are the same. Otherwise it
will return `-1` if the schema on the right _seems_ to be newer than the
schema on the left, but it cannot guarantee that in situations where
migration sequences have been removed over time (e.g. if you remove one
of the builtin tldraw shapes).

Generally speaking, the best way to check schema compatibility now is to
call `store.schema.getMigrationsSince(persistedSchema)`. This will throw
an error if there is no upgrade path from the `persistedSchema` to the
current version.

- `defineMigrations` has been deprecated and will be removed in a future
release. For upgrade instructions see
https://tldraw.dev/docs/persistence#Updating-legacy-shape-migrations-defineMigrations

- `migrate` has been removed. Nobody should have been using this but if
you were you'll need to find an alternative. For migrating tldraw data,
you should stick to using `schema.migrateStoreSnapshot` and, if you are
building a nuanced sync engine that supports some amount of backwards
compatibility, also feel free to use `schema.migratePersistedRecord`.
- the `Migration` type has changed. If you need the old one for some
reason it has been renamed to `LegacyMigration`. It will be removed in a
future release.
- the `Migrations` type has been renamed to `LegacyMigrations` and will
be removed in a future release.
- the `SerializedSchema` type has been augmented. If you need the old
version specifically you can use `SerializedSchemaV1`

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-04-15 12:53:42 +00:00
Steve Ruiz
41601ac61e
Stickies: release candidate (#3249)
This PR is the target for the stickies PRs that are moving forward. It
should collect changes.

- [x] New icon
- [x] Improved shadows
- [x] Shadow LOD
- [x] New colors / theme options
- [x] Shrink text size to avoid word breaks on the x axis
- [x] Hide indicator whilst typing (reverted)
- [x] Adjacent note positions
  - [x] buttons / clone handles
  - [x] position helpers for creating / translating (pits)
- [x] keyboard shortcuts: (Tab, Shift+tab (RTL aware), Cmd-Enter,
Shift+Cmd+enter)
  - [x] multiple shape translating 
- [x] Text editing
  - [x] Edit on type (feature flagged)
  - [x] click goes in correct place
- [x] Notes as parents (reverted)
- [x] Update colors
- [x] Update SVG appearance

### Change Type

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

### Test Plan

Todo: fold in test plans for child PRs

### Unit tests:

- [ ] Shrink text size to avoid word breaks on the x axis
- [x] Adjacent notes
  - [x] buttons (clone handles)
  - [x] position helpers (pits)
- [x] keyboard shortcuts: (Tab, Shift+tab (RTL aware), Cmd-Enter,
Shift+Cmd+enter)
- [ ] Text editing
  - [ ] Edit on type
  - [ ] click goes in correct place

### Release Notes

- Improves sticky notes (see list)

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Mime Čuvalo <mimecuvalo@gmail.com>
Co-authored-by: alex <alex@dytry.ch>
Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Lu[ke] Wilson <l2wilson94@gmail.com>
Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
2024-04-14 18:40:02 +00:00
Steve Ruiz
3ceebc82f8
Faster selection / erasing (#3454)
This PR makes a small improvement to the way we measure distances.
(Often we measure distances multiple times per frame per shape on the
screen). In many cases, we compare a minimum distance. This makes those
checks faster by avoiding a square root.

### Change Type

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

### Release Notes

- Improve performance of minimum distance checks.
2024-04-13 13:30:30 +00:00
Mitja Bezenšek
987b1ac0b9
Perf: Incremental culled shapes calculation. (#3411)
Reworks our culling logic:
- No longer show the gray rectangles for culled shapes. 
- Don't use `renderingBoundExpanded`, instead we now use
`viewportPageBounds`. I've removed `renderingBoundsExpanded`, but we
might want to deprecate it?
- There's now a incremental computation of non visible shapes, which are
shapes outside of `viewportPageBounds` and shapes that outside of their
parents' clipping bounds.
- There's also a new `getCulledShapes` function in `Editor`, which uses
the non visible shapes computation as a part of the culled shape
computation.
- Also moved some of the `getRenderingShapes` tests to newly created
`getCullingShapes` tests.

Feels much better on my old, 2017 ipad (first tab is this PR, second is
current prod, third is staging).


https://github.com/tldraw/tldraw/assets/2523721/327a7313-9273-4350-89a0-617a30fc01a2

### 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. Regular culling shapes tests. Pan / zoom around. Use minimap. Change
pages.

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

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-04-10 10:29:11 +00:00
Mitja Bezenšek
947f7b1d76
[culling] Improve setting of display none. (#3376)
Small improvement for culling shapes. We now use reactor to do it. .

Before:

![image](https://github.com/tldraw/tldraw/assets/2523721/7f791cdd-c0e2-4b92-84d1-8b071540de10)

After:

![image](https://github.com/tldraw/tldraw/assets/2523721/ca2e2a9e-f9f6-48a8-936f-05a402c1e7a2)


### 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
- [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-04-08 11:36:12 +00:00
Taha
e8de70ec85
Examples: update kbd shortcuts, add actions overrides example (#3330)
I think the keyboard shortcuts example already teaches the concept that
the actions overrides example does. I've updated the keyboard shortcuts
example and included an action override example in case we want that
too.

### 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. Add a step-by-step description of how to test your PR here.
2.

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

### Release Notes

- Add action overrides example, update keyboard shortcuts example

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-04-05 10:04:38 +00:00
Taha
4f2cf3dee0
Tool with child states (#3074)
Adds an example of a tool with child states. I'm going over the
annotations at the moment, just wanted to validate the idea in the
meantime.
Closes tld-2114
- [x] `documentation` — Changes to the documentation only[^2]

### Release Notes

- Add an example of a tool with child states

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-04-03 11:25:07 +00:00