Commit graph

2931 commits

Author SHA1 Message Date
Lu Wilson
a8ca235eaf
Fix some menu issues on mobile (#2906)
This PR fixes some issues with menus on mobile.

- Adds the missing submenu button on the pages menu.
- Re-adds the min-width for the main menu. Looks like it was
accidentally copy-pasted over?

### Change Type

- [x] `patch` — Bug fix

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. On mobile...
2. In an empty board...
3. Open the Edit menu.
4. Make sure the buttons are not tenny tiny.
5. Open the pages menu.
6. Press the pencil button in the pages menu.
7. Make sure you can see the submenu button on each page (icon is three
dots).

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

### Release Notes

- Add a brief release note for your PR here.
2024-02-21 15:18:53 +00:00
alex
1850602ea7
fix invite others (#2904)
"Invite others" button in the people menu looked off - icon was in the
wrong place and it was messing up the layout.

### Change Type

- [x] `patch` — Bug fix
2024-02-21 15:16:06 +00:00
David Sheldrick
987a576423
Check tsconfig "references" arrays (#2891)
Closes #2800

This PR makes it so that `check-scripts` will error out if you forget to
add a "references" entry to a tsconfig file when adding an internal
dependency in our monorepo.

If these project references are missed it can prevent TS from
building/rebuilding things when they need to be built/rebuilt.

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package[^2]
2024-02-21 13:07:53 +00:00
Mitja Bezenšek
5fd6b4dca7
Fix object validator (#2897)
Make sure we check if we have the optional function before calling it

### Change Type

- [x] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
2024-02-21 12:15:51 +00:00
Mime Čuvalo
f5f9da4f64
[experiment] paste: show little puff when pasting to denote something happened (#2787)
@steveruizok go ahead and take a look at the animation css and tweak as
you like.
@SomeHats and @steveruizok this is an experiment in that this is prbly
the wrong way to approach it? But I'd be curious to learn if there was a
more proper route here


https://github.com/tldraw/tldraw/assets/469604/40a7029c-f4e8-4f2a-914e-8e6f264be4c7

### Change Type

- [x] `patch` — Bug fix

### Release Notes

- UI: add a little 'puff' when something is pasted to tell that
something has happened.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-02-21 10:46:57 +00:00
alex
fd4b5c6291
Add line IDs & fractional indexes (#2890)
In #2856, we moved changed line handles into an array of points. This
introduced an issue where some concurrent operations wouldn't work
because they array indexes change. We need some sort of stable way of
referring to these points. Our existing fractional indexing system is a
good fit.

In this version, instead of making the points be a map from index to
x/y, we make the points be a map from id (the index) to
x/y/index/id(also index). This is "kinda silly" (steve's words) but
might be more familiar to devs who are expecting maps to be keyed on IDs
rather than anything else.

### Change Type

- [x] `major` — Breaking change
2024-02-21 10:06:14 +00:00
Lu Wilson
dac814fd39
Fix custom keyboard shortcut dialog example (#2876)
This PR fixes the custom keyboard shortcut dialog example.

Previously, the custom menu item wasn't appearing in the menu because it
didn't have a shortcut associated with it. (we filter out any actions
without one).

I fixed it by adding a smiley face. I tried adding a real shortcut, but
I think it made the example too complicated. So I decided on a fake
smiley face instead! After all, the example is demonstrating how to
customise the UI, not how to add an action.


![image](https://github.com/tldraw/tldraw/assets/15892272/e521c603-9978-439b-8f51-684c2e2d3f97)


### Change Type

- [x] `documentation` — Changes to the documentation only[^2]
- [x] `internal` — Any other changes that don't affect the published
package[^2]

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Open the custom keyboard shortcuts dialog example.
2. Open the keyboard shortcuts menu.
3. Check that it says "Like my posts" in the dialog.

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

### Release Notes

- Docs: Fixed custom keyboard shortcut dialog example.
2024-02-21 09:41:54 +00:00
Lu Wilson
59285690d2
Sentence case all example titles (#2889)
This PR converts all example titles and categories to sentence case, to
make them consistent with our UI and the other examples.

### Change Type

- [x] `documentation` — Changes to the documentation only[^2]

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Look at the examples app.
2. Check that all the titles of examples make you feel calm and good
inside.

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

### Release Notes

- Docs: Made the examples titles sentence case.
2024-02-20 18:13:50 +00:00
David Sheldrick
3e12b27728
Fix 'style panel doesn't always disappear if you switch to the hand/laser tools' (#2886)
We had some bad logic in `useRelevantStyles` explicitly allowing an
opacity-slider to be rendered at all times when there is at least one
shape selected.

This shouldn't be the case when the editor is in non-shape-focused tools
like the move tool and the laser pointer tool. I refactored the hook
slightly to make it easier to express the correct logic. See the comment
for a more detailed description.

### Change Type

- [x] `patch` — Bug fix


[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version


### Release Notes

- Fixes an bug causing the opacity slider to show up in the move tool
and laser pointer tool.
2024-02-20 15:09:45 +00:00
Mime Čuvalo
9b65b0e20f
docs: fix scroll position and theming issue for code snippets (#2883)
- scrolling to a section was hiding the header under the top layout when
clicking on the sidebar
- dark mode wasn't hydrating correctly and we only render on client, for
now

### Change Type

- [x] `documentation` — Changes to the documentation only[^2]
2024-02-20 14:24:54 +00:00
David Sheldrick
d372010ad3
remove stray 'console' (#2881)
tiny cleanup, closes #2839

### Change Type

- [x] `patch` — Bug fix
2024-02-20 13:41:58 +00:00
David Sheldrick
4a2040f92c
Faster validations + record reference stability at the same time (#2848)
This PR adds a validation mode whereby previous known-to-be-valid values
can be used to speed up the validation process itself. At the same time
it enables us to do fine-grained equality checking on records much more
quickly than by using something like lodash isEqual, and using that we
can prevent triggering effects for record updates that don't actually
alter any values in the store.

Here's some preliminary perf testing of average time spent in
`store.put()` during some common interactions

| task | before (ms) | after (ms) |
| ---- | ---- | ---- |
| drawing lines | 0.0403 | 0.0214 |
| drawing boxes | 0.0408 | 0.0348 |
| translating lines | 0.0352 | 0.0042 |
| translating boxes | 0.0051 | 0.0032 |
| rotating lines | 0.0312 | 0.0065 |
| rotating boxes | 0.0053 | 0.0035 |
| brush selecting boxes | 0.0200 | 0.0232 |
| traversal with shapes | 0.0130 | 0.0108 |
| traversal without shapes | 0.0201 | 0.0173 |

**traversal** means moving the camera and pointer around the canvas

#### Discussion

At the scale of hundredths of a millisecond these .put operations are so
fast that even if they became literally instantaneous the change would
not be human perceptible. That said, there is an overall marked
improvement here. Especially for dealing with draw shapes.

These figures are also mostly in line with expectations, aside from a
couple of things:

- I don't understand why the `brush selecting boxes` task got slower
after the change.
- I don't understand why the `traversal` tasks are slower than the
`translating boxes` task, both before and after. I would expect that
.putting shape records would be much slower than .putting pointer/camera
records (since the latter have fewer and simpler properties)

### Change Type

- [x] `patch` — Bug fix

### 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-02-20 12:35:25 +00:00
alex
50f77fe75c
[Snapping 6/6] Self-snapping API (#2869)
This diff adds a self-snapping API for handles. Self-snapping is used
when a shape's handles want to snap to the shape itself. By default,
this isn't allowed because moving the handle might move the snap point,
which creates a janky user experience.

Now, shapes can return customised versions of their normal handle
snapping geometry in these cases. As a bonus, line shapes now snap to
other handles on their own line!

### Change Type

- [x] `minor` — New feature

### Test Plan

1. Line handles should snap to other handles on the same line when
holding command

- [x] Unit Tests

### Release Notes

- Line handles now snap to other handles on the same line when holding
command

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-02-19 17:27:29 +00:00
Steve Ruiz
31ce1c1a89
[handles] Line shape handles -> points (#2856)
This PR replaces the line shape's `handles` prop with `points`, an array
of `VecModel`s.

### Change Type

- [x] `minor` — New feature

### Test Plan

- [x] Unit Tests
- [ ] End to end tests
2024-02-19 17:10:31 +00:00
Lu Wilson
b1b821e529
Update Hungarian and Korean (#2871)
This PR pulls over updated translations of Hungarian and Korean from
Lokalise.
2024-02-19 16:31:03 +00:00
Taha
d1151a7af5
Editable shape example (#2853)
This PR adds an example for an editable shape. I wanted to show the
onEditEnd method so I just made the shape do a little wiggle.

Closes #2592 

### Change Type

- [x] `documentation` — Changes to the documentation only[^2]
### Release Notes

- Adds an editable shape example
2024-02-19 16:00:37 +00:00
Lu Wilson
8b390dddb1
Fix dialog title styles (#2873)
This PR fixes default dialog styles being wrong.


![image](https://github.com/tldraw/tldraw/assets/15892272/0f541111-f9b1-4ae4-9019-aaf725ab2cd2)


### Change Type

- [x] `patch` — Bug fix
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

Try opening the following dialogs to check their titles look correct:
1. Keyboard shortcuts.
2. Edit link.
3. Insert embed.

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

### Release Notes

- Unreleased bug: Fixed dialog titles appearance.
2024-02-19 15:58:07 +00:00
Lu Wilson
c57f81fdc9
Fix some incorrect translation keys (#2870)
This PR fixes some cases where translation keys became wrong. They
slipped in with the composable UI changes.

(side-note: the styling of those titles looks wrong right? that wasnt an
intentional change right?)


![image](https://github.com/tldraw/tldraw/assets/15892272/187d5256-3820-491f-a946-1affca2a6161)


![image](https://github.com/tldraw/tldraw/assets/15892272/cfb809c1-c0e3-45b6-b27c-1b5d1829550e)


To validate for yourself, you can:
- Change the typing of `msg` in `useTranslation` to accept only
translation keys. (no strings)
- Run `yarn lint`.
- Look for any errors where we're passing in a string literal. There
should be none now!

---

In the future, I'd love to add a tiny eslint rule that enforces this for
string literals. We accept strings in `msg` because it makes it easier
for consumers (and us) to add custom labels, etc.

Or... if @mimecuvalo does some bigger work on translations, we might
have a better solution.

### Change Type

- [x] `patch` — Bug fix

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

To validate for yourself, you can:
- Change the typing of `msg` in `useTranslation` to accept only
translation keys. (no strings)
- Run `yarn lint`.
- Look for any errors where we're passing in a string literal. There
should be none now!

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

### Release Notes

- Unreleased issue. Fixed some translation keys being wrong.
2024-02-19 14:54:39 +00:00
Steve Ruiz
9fc5f4459f
Roundup fixes (#2862)
This one is a roundup of superficial changes, apologies for having them
in a single PR.

This PR:
- does some chair re-arranging for one of our hotter paths related to
updating shapes
- changes our type exports for editor components
- adds shape indicator to editor components
- moves canvas to be an editor component
- fixes a CSS bug with hinted buttons
- fixes CSS bugs with the menus
- fixes bad imports in examples

### Change Type

- [x] `major`
2024-02-19 14:52:43 +00:00
Mitja Bezenšek
b3d6af4454
Allow users to set document name and use it for exporting / saving (#2685)
Adds the ability to change document names in the top center part of the
UI. This mostly brings back the functionality we already had in the
past.

This is basically a port of what @SomeHats did a while back. I changed
the dropdown options and removed some of the things (we are not dealing
with network requests directly so some of that logic did not apply any
longer). We did have autosave back then, not sure if we want to bring
that back?

Changes the `exportAs` api, thus braking.

### Change Type

- [ ] `patch` — Bug fix
- [ ] `minor` — New feature
- [x] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Top center should now show a new UI element. It has a dropdown with a
few actions.
2. Double clicking the name should also start editing it.
3. The name should also be respected when exporting things. Not if you
select some shapes or a frame. In that case we still use the old names.
But if you don't have anything selected and then export / save a project
it should have the document name.

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

### Release Notes

- Allow users to name their documents.
2024-02-19 12:30:26 +00:00
Rokixy
1e7af3a3e0
Fix some problem under Windows OS development enviroment (#2722)
1. language.ts will be changed in every commit when commiting with a
'zh-cn' OS language setting. Fix it by specifying the locale 'en' when
sorting languages with localeCompare().

2. The parameter of glob.sync() must in posix path form. In Win32 system
the path separator '\\' considered as a escape char by node-glob, Fix it
by replace '\\' with '/'.

3. build-api with child_process.execFile() will cause "Error: spawn yarn
ENOENT" in Win32. Replace it with child_process.exec().
### Change Type

- [ ] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [x] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Release Notes

- stablize language.ts when running under different OS language.
- add isWin32() and posixPath() to format the parameter of glob.sync().
- use child_process.exec() instead of child_process.execFile() for win32
platform.
2024-02-19 11:14:33 +00:00
Rokixy
a3bce9ecb4
doc: fix typo in examples (#2859)
fix typo in examples

### Change Type

- [ ] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [x] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Release Notes

- fix typo in examples
2024-02-19 07:59:19 +00:00
Steve Ruiz
3e41c3acd7
[fix] grid, other insets (#2858)
Fix the grid and other insets, a few CSS cleanups.

### Change Type

- [x] `patch` — Bug fix

### Test Plan

1. Turn on the grid.

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

### Release Notes

- Fixes a bug with the grid not appearing.
2024-02-18 23:01:00 +00:00
Taha
7e673b5e37
E2e tests for the toolbar (#2709)
This PR adds some e2e tests for the toolbar.

Fixtures have been set up for the toolbar and style panel, and are
fairly barebones at the moment. Eventually each menu should have a
fixture associated with it, and all tests will use the class defined in
the fixtures file.

### Change Type

- [x] `tests` — Changes to any test code only[^2]

### Release Notes

- Add e2e tests for the toolbar
2024-02-16 14:15:00 +00:00
Taha
c039d44f72
fix frame style panel (#2851)
Opacity slider was squished when frame tool was selected. I think it's
because this PR #2847 got rid of the tlui-style-panel div. Putting it
back seems to fix it.

### Change Type

- [x] `patch` — Bug fix



### Release Notes

- Fixes an issue with the opacity slider getting squished.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-02-16 13:56:21 +00:00
Lu Wilson
212eb88480
Add component for viewing an image of a snapshot (#2804)
This PR adds the `TldrawImage` component that displays a tldraw snapshot
as an SVG image.

![2024-02-15 at 12 29 52 - Coral
Cod](https://github.com/tldraw/tldraw/assets/15892272/14140e9e-7d6d-4dd3-88a3-86a6786325c5)

## Why

We've seen requests for this kind of thing from users. eg: GitBook, and
on discord:

<img width="710" alt="image"
src="https://github.com/tldraw/tldraw/assets/15892272/3d3a3e9d-66b9-42e7-81de-a70aa7165bdc">

The component provides a way to do that.
This PR also untangles various bits of editor state from image
exporting, which makes it easier for library users to export images more
agnostically. (ie: they can now export any shapes on any page in any
theme. previously, they had to change the user's state to do that).

## What else

- This PR also adds an **Image snapshot** example to demonstrate the new
component.
- We now pass an `isDarkMode` property to the `toSvg` method (inside the
`ctx` argument). This means that `toSvg` doesn't have to rely on editor
state anymore. I updated all our `toSvg` methods to use it.
- See code comments for more info.

## Any issues?

When you toggle to editing mode in the new example, text measurements
are initially wrong (until you edit the size of a text shape). Click on
the text shape to see how its indicator is wrong. Not sure why this is,
or if it's even related. Does it ring a bell with anyone? If not, I'll
take a closer look. (fixed, see comments --steve)

## Future work

Now that we've untangled image exporting from editor state, we could
expose some more helpful helpers for making this easier.

Fixes tld-2122

### Change Type

- [x] `minor` — New feature

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Open the **Image snapshot** example.
2. Try editing the image, saving the image, and making sure the image
updates.

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

### Release Notes

- Dev: Added the `TldrawImage` component.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-02-16 13:54:48 +00:00
Steve Ruiz
dd67577fea
[fix] pointer capture logging when debug flag is off (#2850)
This PR fixes a bug where pointer capture would log when the debug flag
was off.

### Change Type

- [x] `patch` — Bug fix
2024-02-16 10:41:27 +00:00
pocari
ba47cd08cc
fix typo(examples/hosted-images) (#2849)
### Change Type

- [ ] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [x] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

no tests

### Release Notes

- Fixed a typo in the description in the hosted-images example.
2024-02-16 09:41:38 +00:00
Steve Ruiz
7ece89a357
UI components round two (#2847)
This PR:
- replaces the `shareZone` prop with `SharePanel` component
- replaces the `topZone` prop with `TopPanel` components
- replaces the `Button` component with `TldrawUiButton` and
subcomponents
- adds `TldrawUi` prefix to our primitives
- fixes a couple of bugs with the components

### Change Type

- [x] `major` — Breaking change
2024-02-16 09:13:04 +00:00
Mime Čuvalo
5d87804a76
ui: refactor breakpoints to fit in an enum (#2843)
@SomeHats i feel like my naming sucks here. halp.

### Change Type

- [x] `patch` — Bug fix

### Release Notes

- Refactor breakpoints into an enum.
2024-02-15 17:39:17 +00:00
alex
31a2b2115f
[Snapping 5/5] Better handle snapping for geo shapes (#2845)
Currently, geo shapes have slightly janky handle-snapping: they snap to
label geometry (even though its invisible) and because they extend from
`BaseBoxShapeUtil` they snap to the corners of their bounding box (even
if that's not where the actual shape is).

With this PR, we no longer snap to labels, and we snap to the actual
vertices of the geo shape rather than its bounding points.

1. #2827
2. #2831
3. #2793
4. #2841
5. #2845 (you are here)

### Change Type

- [x] `minor` — New feature


### Test Plan
- [x] Unit Tests

### Release Notes

- You can now snap the handles of lines to the corners of rectangles,
stars, triangles, etc.
2024-02-15 15:53:28 +00:00
alex
89881397b5
[Snapping 4/5] Add handle-point snapping (#2841)
Currently, when dragging line handles they'll snap to the outlines of
other shapes, but not to their vertices. This can make it hard to snap
precisely to certain key places, like the handles of other lines, or the
corners of `geo` shapes.

This diff adds a new snap type for handles - snapping to points:

![Kapture 2024-02-14 at 16 30
41](https://github.com/tldraw/tldraw/assets/1489520/046109d3-2961-463f-bf71-9350ea1204bc)

This adds to the new snapping API so the snapping points can very easily
be customised on a shape-by-shape basis. Closes TLD-2198

This PR is part of a series - please don't merge it until the things
before it have landed!
1. #2827 
2. #2831
3. #2793 
4. #2841 (you are here)
5. #2845

### Change Type

- [x] `minor` — New feature

### Test Plan

1. create a line shape
2. drag its handles whilst holding command
3. it should snap to the outlines of other shapes, vertices of other
line shapes, and the bounding box corners/center of most 'boxy' shapes
(geo, embed, etc)

- [x] Unit Tests

### Release Notes

- Line handles
2024-02-15 15:22:48 +00:00
alex
77865d9f5e
[Snapping 3/5] Custom snapping API (#2793)
This diff adds an API for customising our existing snap types. These
are:
1. Bound snapping. When translating or resizing a shape, it'll snap to
certain key points on the bounds of particular shapes. Previously, these
were hard-coded to the corners and center of the bounding box of the
shape. Now, a shape can bring its own (e.g. a triangle may add snapping
for its 3 corners, and it's centroid rather than bounding box center.
2. Handle outline snapping. When dragging a handle, it'll snap to the
outline of other shapes geometry. Now, shapes can return different
geometry for this sort of snapping if they like.

Each of these is customised through a method on `ShapeUtil`:
`getBoundsSnapGeometry` and `getHandleSnapGeometry`. These return
interfaces describing the different geometry that can be snapped to in
both these cases. Currently, each returns an object with a single
property, but there are more types of snapping coming in follow-up PRs.
When reviewing this PR, start with the definitions of
`BoundsSnapGeometry` in `BoundsSnaps.ts` and `HandleSnapGeometry` in
`HandleSnaps.ts`

This doesn't add point snapping - i'll add that in a follow-up! It'll be
customisable with the `getHandleSnapGeometry` API.

Fixes TLD-2197

This PR is part of a series - please don't merge it until the things
before it have landed!
1. #2827 
4. #2831
5. #2793 (you are here)
6. #2841
7. #2845

### Change Type

- [x] `minor` — New feature

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

- [x] Unit Tests

### Release Notes

- Add `ShapeUtil.getSnapInfo` for customising shape snaps.
2024-02-15 15:10:04 +00:00
Steve Ruiz
ac0259a6af
Composable custom UI (#2796)
This PR refactors our menu systems and provides an interface to hide or
replace individual user interface elements.

# Background

Previously, we've had two types of overrides:
- "schema" overrides that would allow insertion or replacement of items
in the different menus
- "component" overrides that would replace components in the editor's
user interface

This PR is an attempt to unify the two and to provide for additional
cases where the "schema-based" user interface had begun to break down.

# Approach

This PR makes no attempt to change the `actions` or `tools`
overrides—the current system seems to be correct for those because they
are not reactive. The challenge with the other ui schemas is that they
_are_ reactive, and thus the overrides both need to a) be fed in from
outside of the editor as props, and b) react to changes from the editor,
which is an impossible situation.

The new approach is to use React to declare menu items. (Surprise!) 

```tsx
function CustomHelpMenuContent() {
	return (
		<>
			<DefaultHelpMenuContent />
			<TldrawUiMenuGroup id="custom stuff">
				<TldrawUiMenuItem
					id="about"
					label="Like my posts"
					icon="external-link"
					readonlyOk
					onSelect={() => {
						window.open('https://x.com/tldraw', '_blank')
					}}
				/>
			</TldrawUiMenuGroup>
		</>
	)
}

const components: TLComponents = {
	HelpMenuContent: CustomHelpMenuContent,
}

export default function CustomHelpMenuContentExample() {
	return (
		<div className="tldraw__editor">
			<Tldraw components={components} />
		</div>
	)
}
```

We use a `components` prop with the combined editor and ui components.

- [ ] Create a "layout" component?
- [ ] Make UI components more isolated? If possible, they shouldn't
depend on styles outside of themselves, so that they can be used in
other layouts. Maybe we wait on this because I'm feeling a slippery
slope toward presumptions about configurability.
- [ ] OTOH maybe we go hard and consider these things as separate
components, even packages, with their own interfaces for customizability
/ configurability, just go all the way with it, and see what that looks
like.

# Pros

Top line: you can customize tldraw's user interface in a MUCH more
granular / powerful way than before.

It solves a case where menu items could not be made stateful from
outside of the editor context, and provides the option to do things in
the menus that we couldn't allow previously with the "schema-based"
approach.

It also may (who knows) be more performant because we can locate the
state inside of the components for individual buttons and groups,
instead of all at the top level above the "schema". Because items /
groups decide their own state, we don't have to have big checks on how
many items are selected, or whether we have a flippable state. Items and
groups themselves are allowed to re-build as part of the regular React
lifecycle. Menus aren't constantly being rebuilt, if that were ever an
issue.

Menu items can be shared between different menu types. We'll are
sometimes able to re-use items between, for example, the menu and the
context menu and the actions menu.

Our overrides no longer mutate anything, so there's less weird searching
and finding.

# Cons

This approach can make customization menu contents significantly more
complex, as an end user would need to re-declare most of a menu in order
to make any change to it. Luckily a user can add things to the top or
bottom of the context menu fairly easily. (And who knows, folks may
actually want to do deep customization, and this allows for it.)

It's more code. We are shipping more react components, basically one for
each menu item / group.

Currently this PR does not export the subcomponents, i.e. menu items. If
we do want to export these, then heaven help us, it's going to be a
_lot_ of exports.

# Progress 

- [x] Context menu
- [x] Main menu
- [x] Zoom menu
- [x] Help menu
- [x] Actions menu
- [x] Keyboard shortcuts menu
- [x] Quick actions in main menu? (new)
- [x] Helper buttons? (new)
- [x] Debug Menu

And potentially
- [x] Toolbar
- [x] Style menu
- [ ] Share zone
- [x] Navigation zone
- [ ] Other zones

### Change Type

- [x] `major` — Breaking change

### Test Plan

1. use the context menu
2. use the custom context menu example
3. use cursor chat in the context menu

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

### Release Notes

- Add a brief release note for your PR here.
2024-02-15 12:10:09 +00:00
Mime Čuvalo
5faac660bc
errors: improve msg in dialog when error happens (#2844)
Right now it's hard to parse the stack trace to see what the problem is.
This just raises the msg up to a first-class position to get the gist of
the problem.

<img width="631" alt="Screenshot 2024-02-14 at 17 09 55"
src="https://github.com/tldraw/tldraw/assets/469604/d40b8bb4-e752-48d3-946d-6377c08e66fc">


### Change Type

- [x] `patch` — Bug fix

### Release Notes

- Improves error dialog messaging.
2024-02-15 11:35:42 +00:00
Mime Čuvalo
5bb60858b9
seo: take 2 (#2817)
(pending landing on: "Going to wait to land this one until the Google
SEO 'soft 404' validation finishes. I want to make sure we're testing
separate things.")

- removes Loading text
- adds sitemap to try to get Google to play nice

### Change Type

- [x] `patch` — Bug fix

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-02-15 11:28:43 +00:00
Mime Čuvalo
c621a43d19
humans.txt (#2842)
see: https://humanstxt.org/

@TodePond if you wanna help wordsmith/riff here, please do :) even after
it lands

i've added this in a bunch of places :)
https://paper.dropbox.com/humans.txt
https://www.rewiringamerica.org/humans.txt
https://www.mobilize.us/humans.txt
https://www.joingreenwork.com/humans.txt
https://nightlight.rocks/humans.txt

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package[^2]

---------

Co-authored-by: Lu Wilson <l2wilson94@gmail.com>
2024-02-15 10:57:46 +00:00
alex
4bfea7649d
[Snapping 2/5] Fix line-handle mid-point snapping (#2831)
Currently, only the end handles of the line tool snap. It should be all
of them.

Line handles work kind of weirdly at the moment: instead of just storing
the positions, we store full `TLHandle` objects complete with IDs,
`canSnap`/`canBind` properties, etc. Currently, all the handles get
written to the store with `canSnap: false`, when really it should be up
to the shape util to decide which handles are snappable.

This diff replaces the current handles map (from arbitrary ID to
`TLHandle`) with just the data we need: a map from index to x/y. The
extra information that the `Editor` needs for `TLHandle` is hydrated at
runtime (with `canSnap` set to `true` this time!)

Fixes TLD-2200

This PR is part of a series - please don't merge it until the things
before it have landed!
1. #2827 
2. #2831 (you are here)
3. #2793
4. #2841
5. #2845

### Change Type

- [x] `major` — Breaking change


[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Create a funky line shape on tldraw.com
2. Paste it into staging and make sure it comes across ok
3. Make some funky line shape in staging - make sure you use dragging,
mid-point creation, and shift-clicking

- [x] Unit Tests

### Release Notes

- Simplify the contents of `TLLineShape.props.handles`
2024-02-15 10:27:55 +00:00
alex
93c2ed615c
[Snapping 1/5] Validation & strict types for fractional indexes (#2827)
Currently, we type our fractional index keys as `string` and don't have
any validation for them. I'm touching some of this code for my work on
line handles and wanted to change that:
- fractional indexes are now `IndexKey`s, not `string`s. `IndexKey`s
have a brand property so can't be used interchangeably with strings
(like our IDs)
- There's a new `T.indexKey` validator which we can use in our
validations to make sure we don't end up with nonsense keys.

This PR is part of a series - please don't merge it until the things
before it have landed!
1. #2827 (you are here)
2. #2831
3. #2793
4. #2841
5. #2845

### Change Type

- [x] `patch` — Bug fix

### Test Plan

1. Mostly relying on unit & end to end tests here - no user facing
changes.

- [x] Unit Tests
2024-02-14 17:53:30 +00:00
Mime Čuvalo
fb00358a53
examples: rename ui events and increase priority (#2840)
### Change Type

- [x] `internal` — Any other changes that don't affect the published
package[^2]
2024-02-14 16:36:25 +00:00
Mime Čuvalo
2ad47958bb
dev: swap yarn test and test-dev for better dx (#2773)
As discussed offline, just making `yarn test` do what we expect it to.

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package[^2]
2024-02-14 16:05:59 +00:00
Taha
7caaa2fbbb
Readonly defaults to the hand tool (#2833)
#2720 
This PR makes it so that the editor defaults to the hand tool in read
only mode

### Change Type

- [x] `minor` — New feature


### Test Plan

1. Open the editor in readonly mode
2. It should default to the hand tool

### Release Notes

- Shared projects in  read only mode now default to the hand tool
2024-02-14 15:07:25 +00:00
David Sheldrick
f9f5c6afcb
Improve signia error handling (#2835)
This PR revamps how errors in signia are handled.

This was brought about by a situation that @MitjaBezensek encountered
where he added a reactor to a shape util class. During fuzz tests, that
reactor was being executed at times when the Editor was not in a usable
state (we had a minor hole in our sync rebase logic that allowed this,
fixed elsewhere) and the reactor was throwing errors because it
dereferenced a parent signal that relied on the page state
(getShapesInCurrentPage or whatever) when there were no page records in
the store.

The strange part was that even if we wrapped the body of the reactor
function in a try/catch, ignoring the error, we'd still see the error
bubble up somehow.

That was because the error was being thrown in a Computed derive
function, and those are evaluated independently (i.e. outside of the
reactor function) by signia as it traverses the dependency graph from
leaves to roots in the `haveParentsChanged()` internal function.

So the immediate fix was to make it so that `haveParentsChanged` ignores
errors somehow.

But the better fix involved completely revamping how signia handles
errors, and they work very much like how signia handles values now. i.e.

- signia still assumes that deriver functions are pure, and that if a
deriver function throws once it will throw again unless its parent
signals change value, so **it caches thrown errors for computed values**
and throws them again if .get() is called again before the parents
change
- it clears the history buffer if an error is thrown
- it does not allow errors to bubble during dirty checking i.e. inside
`haveParentsChanged` or while calculating diffs.

### Change Type

- [x] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

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

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

### Release Notes

- Add a brief release note for your PR here.
2024-02-14 13:32:15 +00:00
Steve Ruiz
27b75b2701
[fix] sticky note bug (#2836)
Fixes a bug with sticky notes.

### Change Type

- [x] `patch` — Bug fix
2024-02-14 12:41:30 +00:00
Mime Čuvalo
f096480ade
docs: tweak search kbd placement to match loupe (#2834)
### Change Type

- [x] `patch` — Bug fix
2024-02-14 10:37:03 +00:00
Lu Wilson
7ea54fe605
Lokalise: Translations update (#2830)
Adds Slovenian localization.

### Change Type

- [ ] `patch` — Bug fix
- [x] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [ ] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

---------

Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
2024-02-14 08:59:41 +00:00
David Sheldrick
9d895aab13
[docs] Fix missing Persistence page (#2828)
Fixes #2826, extracted from #2680 

The problem is that we had two different articles whose ids were being
derived as `persistence`, the `persistence.mdx` file and the
`persistence/` example.

I've

1. Made it an error for two articles to have the same id
2. Renamed the `persistence/` article to `local-storage` since that's
the API it's using.

### Change Type

- [ ] `patch` — Bug fix
- [ ] `minor` — New feature
- [ ] `major` — Breaking change
- [ ] `dependencies` — Changes to package dependencies[^1]
- [x] `documentation` — Changes to the documentation only[^2]
- [ ] `tests` — Changes to any test code only[^2]
- [ ] `internal` — Any other changes that don't affect the published
package[^2]
- [ ] I don't know

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

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

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

### Release Notes

- Add a brief release note for your PR here.
2024-02-13 16:19:17 +00:00
Steve Ruiz
ad5a61879a
Remove pointer check for arrow labels (#2824)
This PR removes a check for pointer changes over arrow labels. We don't
really have any other uses of the `pointer` in the canvas except for
buttons, so I'd rather keep the default cursor for arrow labels.

### Change Type

- [x] `minor` — New feature
2024-02-13 15:31:49 +00:00
Dan Groshev
ef90b8e231
repair Huppy's handling of LICENCE (#2821)
Huppy was expecting `LICENCE`, while the actual filename is now
`LICENCE.md`. This PR fixes the oversight.

### Change Type

- [x] `internal` — Any other changes that don't affect the published
package
2024-02-13 15:09:59 +00:00
Dan Groshev
5cf2fe9583
Revert "emojis! 🧑‍🎨 🎨 ✏️ (#2814)" (#2822)
Reverting accidental merge of #2814

### Change Type
- [x] `internal` — Any other changes that don't affect the published
package
2024-02-13 14:59:59 +00:00