Commit graph

3184 commits

Author SHA1 Message Date
Mime Čuvalo
8aa4fd3352
asset lod: fix high-res images (#4198)
Some checks are pending
Checks / Tests & checks (push) Waiting to run
Checks / Build all projects (push) Waiting to run
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Waiting to run
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Waiting to run
End to end tests / End to end tests (push) Waiting to run
Publish Canary Packages / Publish Canary Packages (push) Waiting to run
Publish VS Code Extension / Publish VS Code Extension (push) Waiting to run
high-res images are busted currently, we weren't doing `Math.min` before
https://github.com/tldraw/tldraw/pull/4069 and now it's limited by the
natural width of the image which is actually at odds with what's been
uploaded.

## for separate PR
...actually, now that i think about it, this code isn't doing any
resizing anymore - the server has the high-res images but we're only
recording it as a smaller image:
```
if (isFinite(maxImageDimension)) {
	const resizedSize = containBoxSize(size, { w: maxImageDimension, h: maxImageDimension })
	if (size !== resizedSize && MediaHelpers.isStaticImageType(file.type)) {
		size = resizedSize
	}
}
```

### Change type

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

### Release notes

- Images LOD: fix high-res images.
2024-07-16 15:56:51 +00:00
Mime Čuvalo
1a7f5e9fb5
csp: enable image upload for dev mode (#4199)
csp fix for dev image server

### Change type

- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
2024-07-16 15:56:18 +00:00
Mime Čuvalo
9d15a05ac0
docs: fix up typo (#4194)
Describe what your pull request does. If you can, add GIFs or images
showing the before and after of your change.

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
2024-07-16 14:39:40 +00:00
Mime Čuvalo
6ba3fb0722
csp: followup fixes/dx/tweaks (#4159)
couple interesting things here as followups to the CSP work.
- first of all, again, good call on doing the report-only to start with
@SomeHats 🤘
- I combed through all the Sentry logs, looking for issues. a lot of
them were browser extensions and could be ignored.
- there were some other ones that needed fixing up though.

fixes in this PR:
- [x] CSP emulation in dev: make sure it's running in development so
that we can catch things locally. this is done via the meta tag.
- [x] `connect-src` add `blob`: this was breaking copy/export as svg/png
- [x] image testing: expand list of pasted image extensions to include
avif and some others
- [x] image pasting: this didn't really work in the first place because
typically even with CSP disabled, you'll mainly run into CORS issues. I
think it's a pretty crap user experience. So, I moved this logic to
actually be in the URL unfurling. Lemme know what you think! I don't
think we should proxy the actual image data - that sounds ... intense 😬
even though it would produce a better user experience technically.
- [x] investigated `manifest-src` errors: but it actually seems fine?
Weird thing here is that `manifest-src` isn't explicitly in the CSP so
it falls back to the `default-src` of `self` which is fine. Trying it on
tldraw.com it seems just fine with no errors but inexplicably some users
are hitting these errors. I'm guessing maybe it's an ad-blocker type
behavior maybe.
- [x] `font-src` add `data`: I'm actually unsure if this is quite
necessary but I _think_ embedded fonts in SVGs are causing the problem.
However, I can't reproduce this, I just don't mind adding this.


Before / After for pasting image URLs (not a CSP issue, to be clear, but
a CORS issue)

## Before
<img width="448" alt="Screenshot 2024-07-12 at 17 59 42"
src="https://github.com/user-attachments/assets/e8ce267b-48fd-49cd-b0f7-0fd20c0b9a1d">

## After
<img width="461" alt="Screenshot 2024-07-12 at 18 00 06"
src="https://github.com/user-attachments/assets/9956590d-fe37-4708-bc26-0c454f8151b4">

### Change type

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

### Release notes

- Security: more CSP work on dotcom
2024-07-16 14:20:38 +00:00
Mitja Bezenšek
e784d3182f
Relax the params (#4190)
Feels like we can relax what we expect? It gets passed to `loadSnapshot`
which allows for partials.

Resolves https://github.com/tldraw/tldraw/issues/3999

### Change type

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

### Release notes

- Allow passing partial `TLEditorSnapshot` to `TldrawImage` and
`useTLStore`.
2024-07-16 14:11:12 +00:00
alex
48d1f4e0d7
add version attribute (#4192)
Occasionally I come across tldraw in the wild and want to see what
version it is.

### Change type

- [x] `other`
2024-07-16 13:24:44 +00:00
alex
d85aac58b3
Explicitly type shape props and defaults (#4191)
We rely on type inference for our `defaultX` types, as well as for our
shape prop types. This works well and means we only have to list shape
props once, but has some drawbacks:
- It's unstable, which sometimes produces unintended api-report.md diffs
that need to be worked around
- It's not good for docs

This diff makes those declared explicitly

### Change type

- [x] `api`

### Release notes

- Explicitly declare type types of default shapes etc. and shape props
for better documentation
2024-07-16 13:16:39 +00:00
Steve Ruiz
62fe6561c7
Fix color scheme default (#4185)
Small follower for #4184

### Change type

- [x] `bugfix`
2024-07-16 12:39:33 +00:00
Mime Čuvalo
792de3c64e
docs: fix up prev/next for api reference (#4171)
small thing that was driving me nuts. prev/next didn't really work.

before
<img width="1237" alt="Screenshot 2024-07-15 at 12 29 45"
src="https://github.com/user-attachments/assets/bfe28ad9-40bc-4ca3-b5c9-97f08ea36c8f">

after
<img width="1343" alt="Screenshot 2024-07-15 at 12 32 31"
src="https://github.com/user-attachments/assets/ca1f3423-000d-47a8-843e-9e4a63784df3">

### Change type

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

### Release notes

- Docs: fix up prev/next.
2024-07-16 11:39:25 +00:00
alex
43811d54ba
bemo custom shape example (#4174)
Adds a custom shape bemo example. Instead of having to create a schema
ahead of time, here i've added bindingUtils/shapeUtils props to our sync
hooks to match the ones we have in the `<Tldraw />` component. Not 100%
about this though, I could easily be convinced to go with just the
schema prop.

### Change type

- [x] `other`
2024-07-16 11:24:01 +00:00
alex
c8ebe57e24
fix wrangler config (#4186)
stating -> staging


- [x] `other`
2024-07-16 10:55:34 +00:00
alex
5897d3c934
Fix watermark imports in published packages (#4180)
Different bundlers have different support for importing non-JS assets.
We can't reliably import SVGs in our public packages and rely on that to
do the right thing. When I tried installing a canary to work on a new
cloudflare template, vite was erroring out due to those imports. I had
to patch them out to get things running.

This diff replaces the file-based assets with inlined svg-in-js strings.
I haven't been able to test this though because I'm not really sure how.
@mimecuvalo could you take a look?

### Change type

- [x] `bugfix`
2024-07-16 10:41:55 +00:00
Steve Ruiz
593c51065f
Show checked theme in color scheme menu (#4184)
This PR accounts (in the UI) for a default case where the `colorScheme`
value is undefined.

### Change type

- [x] `bugfix`

### Test plan

1. Open the editor an incognito tab
2. The Menu > Preferences > Color scheme should have a ticked selection

### Release notes

- Fixed a bug where the user's color scheme was not shown in the menu by
default.
2024-07-16 10:39:37 +00:00
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
Steve Ruiz
077d42c6f9
Editor.run docs (#4182)
This PR adds a docs section for `Editor.run`.

### Change type

- [x] `other`
2024-07-16 10:00:02 +00:00
alex
348ff9f66a
publish bemo canaries (#4175)
Switch on package publishing for sync libraries so we can start building
templates on the canaries.

### Change type

- [x] `other`
2024-07-15 16:08:42 +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
Steve Ruiz
f4ceb581dd
ShapeUtil.getInterpolatedProps (#4162)
This PR adds a `getInterpolatedProps` method to the `ShapeUtil` class.
It is used in `Editor.animateShapes` to allow shapes to lerp values that
the editor doesn't specifically know about.

![Kapture 2024-07-13 at 09 12
48](https://github.com/user-attachments/assets/f9711aa0-278b-4a26-84d3-4b6bbe610b81)

### Change type

- [x] `feature`
- [x] `api`

### Test plan

1. Animate a shape's props.

```ts

const shape = editor.getOnlySelectedShape()

setInterval(() => {
	editor.animateShape(
		{
			...shape,
			x: Math.random() * 500,
			y: Math.random() * 200,
			props: { w: 200 + Math.random() * 200, h: 200 + Math.random() * 200 },
		},
		{ animation: { duration: 500 } }
	)
}, 1000)
```

- [ ] Unit tests (Could be done!)

### Release notes

- SDK: adds `ShapeUtil.getInterpolatedProps` so that shapes can better
participate in animations.

---------

Co-authored-by: alex <alex@dytry.ch>
2024-07-15 14:04:22 +00:00
David Sheldrick
7ba4040e84
Split @tldraw/state into @tldraw/state and @tldraw/state-react (#4170)
The backend code uses `@tldraw/state`, which is fine, but the package
has a peer dependency on `react`, which is not fine to impose on backend
consumers. So let's split this up again.

### Change type

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

### Test plan

1. Create a shape...
2.

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

### Release notes

- Fixed a bug with…
2024-07-15 11:18:59 +00:00
alex
719332d272
serve icons via a single merged .svg file (#4150)
We currently serve icons in the form of 141 separate svg files. This is
pretty inefficient: it results in 141 http requests each with its own
overheads and costs. Each one is generally less than 1kb of data.

This PR merges all of our icons into a single 44kb icon file. Each item
in the svg has an ID, and we use the ID in the asset url to target the
specific icon. This also fixes a lot of the icon preloading issues:
because the icon file is already loaded, there's no extra request needed
when panels open etc.

I was messing with this whilst killing time before a late meeting so
made a shitty overengineered code generator, dont at me

### Change type

- [x] `improvement`

### Release notes

- Serve icons more efficiently, and make sure they're still available if
tldraw goes offline.
2024-07-15 11:03:11 +00:00
David Sheldrick
0235f84115
[sdk] make EffectScheduler and useStateTracking public (#4155)
closes #4085 

Neither of these should be too valuable for tldraw users, but they're
also both totally stable and well documented (now) so it should be fine
to make them public?

### Change type

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

### Test plan

1. Create a shape...
2.

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

### Release notes

- Made `EffectScheduler` and `useStateTracking` public
2024-07-14 10:54:27 +00:00
Mime Čuvalo
190ea19caa
head: rm mask-icon (#4160)
"Safari formerly had a requirement of SVG monochrome icon for [pinned
tabs](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/pinnedTabs/pinnedTabs.html).
However, since Safari 12, we can use a regular favicon for pinned tabs.
Even [apple.com](https://www.apple.com/) doesn’t use the mask-icon
anymore."

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
2024-07-12 17:26:39 +00:00
Mime Čuvalo
430c48acf9
license: show on dotcom dev mode (#4158)
don't show the watermark in dev mode for dotcom

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
2024-07-12 16:53:31 +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
David Sheldrick
e4bfae4172
[bemo] allow special chars in roomId (#4153)
if people did weird room ids with non-url-safe chars like
`blah/whatever` it wouldn't work. this fixes that

### 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 14:01:34 +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
Mitja Bezenšek
bd0e9e3f43
Unify menus. Disable erroring. (#4143)
Unify the VS Code extension menus with what we have on dot com. Prevent
an error cycle.

### Change type

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

### Release notes

- Unify the VS Code extension menus (Help and Main menus) with what we
have on tldraw.com
- Prevent an onerror cycle.
2024-07-12 06:58:56 +00:00
David Sheldrick
9229d2e3c7
[bemo] add analytics to bemo worker (#4146)
Sets up worker analytics. No further grafana setup needed, just need to
start querying once this is live.

### 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 16:00:39 +00:00
David Sheldrick
70a26862c4
Fix /new alert bug, make new user data stable (#4142)
two changes in one here because I'm feeling lazy

- fix bug in staging, introduced in whichever bemo PR refactored the
sync client+indexeddb stuff
    1. go to `/`
    2. file -> new shared project
    3. oh_no.jpg 
<img width="618" alt="image"
src="https://github.com/tldraw/tldraw/assets/1242537/8bff3498-2cc5-4c71-b407-830d459d3d36">

- fix bug in production
    1. make a new room
    2. clear localstorage
    3. refresh
    4. duplicate current tab in same browser context
    6. oh_no.jpg (there should only be one person)

<img width="99" alt="image"
src="https://github.com/tldraw/tldraw/assets/1242537/f4e434ba-8455-4913-a698-71661e5074fd">

### Change type

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

### Test plan

1. Create a shape...
8.

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

### Release notes

- Fixed a bug with…
2024-07-11 14:01:15 +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
Steve Ruiz
a7fac3bcc4
Use shape scale for geo shape min size (#4140)
This PR fixes a bug where a shape created with dynamic size would
preserve the origin

### Change type

- [x] `bugfix`

### Test plan

1. Turn on dynamic size
2. Zoom in
3. Create a text shape
4. Give a label
5. Try to resize the shape to be narrow

### Release notes

- Fixed a bug with the minimum size on dynamically scaled text shapes
2024-07-11 11:14:19 +00:00
alex
ce493dcfaf
[4/5] sync -> sync-core, sync-react -> sync (#4123)
Renames `@tldraw/sync` to `@tldraw/sync-core`, and `@tldraw/sync-react`
to `@tldraw/sync`. This also adds an export * from sync-core to sync.

- [x] `other`
2024-07-10 16:09:10 +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
627c84c2af
[2/4] Rename sync hooks, add bookmarks to demo (#4094)
Adds a new `onEditorMount` callback to the store, allowing store
creators to do things like registering bookmark handlers. We use this in
the new demo hook.

This also renames `useRemoteSyncClient` to `useMultiplayerSync`, and
`useRemoteSyncDemo` to `useMultiplayerDemo`.

Closes TLD-2601

### Change type

- [x] `api`
2024-07-10 13:15:44 +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
alex
92fa5304f5
use unique IDs for grid instances (#4132)
Previously, we had a single hard-coded DOM ID for grids. This meant that
if you had multiple editors with grids on a page, they would all point
at the svg `<defs>` from the first instance. Now, each grid generates a
unique ID.

### Change type

- [x] `bugfix`

### Release notes

- Fix a bug causing multiple tldraw instances to share the same grid
background
2024-07-10 09:57:16 +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
76a5d98eeb
Fix examples URL in docs app (#4129)
Allow us to preview docs + examples changes on staging.tldraw.dev. Also
allow previewing the docs app on phones in local dev.

### Change type

- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
2024-07-10 09:07:16 +00:00
Mitja Bezenšek
89d7438ca3
Remove duplicate code (#4128)
Looks like some leftovers since we are conditionally doing the same
thing on the next line. I might be missing something though.

### Change type

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

### Release notes

- Remove some duplicate code which should make some of the exports a bit
smaller.
2024-07-10 08:58:47 +00:00
David Sheldrick
60f43e947e
Add offline icon back (#4127)
This icon went missing. I had a larger diff here that made the icon
types stricter to catch errors but I'll save it for another PR.

### Change type

- [x] `bugfix`
- [ ] `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-10 08:51:06 +00:00
David Sheldrick
922dd416b1
fix bookmark height (#4118)
fixes #4109 

### Change type

- [x] `bugfix`
- [ ] `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-09 16:00:21 +00:00
Mitja Bezenšek
adbb0e9b3b
Add a toast for file upload failures. (#4114)
Adds toasts for cases when the file type is not allowed or the file is
too big.

Resolves
https://github.com/orgs/tldraw/projects/53?pane=issue&itemId=70298205

### Change type

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

### Test plan

1. Upload a file that is either too big (over 10mb) or of incorrect file
type (pdf, docx,...).
2. You should see a toast explaining what went wrong.

### Release notes

- Show a toast when uploading an unsupported file type or a file that is
too large (more than 10mb).
2024-07-09 13:05:31 +00:00
Mitja Bezenšek
ec0ec71c69
Add a toast for missing clipboard permissions. (#4117)
Shows a toast notifying the user that pasting failed due to clipboard
permissions. Resolves
https://github.com/orgs/tldraw/projects/53?pane=issue&itemId=70294454


![image](https://github.com/tldraw/tldraw/assets/2523721/704aaca2-a087-4b5b-a0bc-dd710960a318)


### Change type

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

### Test plan

1. Open a new private window.
2. Copy some shapes and paste them. Make sure you don't allow the
clipboard access.
3. You should see the toast.

### Release notes

- Show a toast when pasting failed due to missing clipboard permissions.
2024-07-09 12:33:01 +00:00
Steve Ruiz
9a3afa2e2a
Flip images (#4113)
This PR adds the ability to flip images.

### Change type

- [x] `improvement`

### Test plan

1. Resize an image shape
2. Select an image shape and use the flip X / flip Y options in the
context menu.

- [x] Unit tests

### Release notes

- Adds the ability to flip images.
2024-07-09 11:01:03 +00:00