We use `children: any` in a bunch of places, but the proper type for
these is `ReactNode`. This diff fixes those.
### Change Type
- [x] `patch` — Bug fix
This PR exposes a method for getting the style for the next shape.
### Change Type
- [x] `patch` — Bug fix
### Release Notes
- Expose the API for `Editor.getStyleForNextShape`, previously marked as
internal.
This PR adds a custom selection UI example.
![Kapture 2024-03-01 at 14 02
25](https://github.com/tldraw/tldraw/assets/23072548/039cc6ab-17b9-4bc3-8c05-ad3ce788a5d3)
It also fixes a bug with pageToScreen and adds a
`getSelectionRotatedScreenBounds` method.
### 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
### Release Notes
- Adds selection UI example.
- Adds `Editor.getSelectionRotatedScreenBounds` method
- Fixes a bug with `pageToScreen`.
By default, tldraw's brushing mode will select when the box intersects
an shape's geometry. A user can hold Command / Ctrl to require that the
selection box fully contain a shape's bounds instead.
Some people really prefer the opposite. Three years! Three years I've
been saying "no no no".
This PR adds a user preference to flip the logic. When `isWrapMode` is
true, selection requires that the box completely contain a shape before
it's added to the list of selecting shapes; and ctrl flips back to
intersection instead.
### Change Type
- [x] `minor` — New feature
### Test Plan
1. Turn on wrap mode in the user preferences menu.
2. Select stuff.
3. Use the ctrl key to except the behavior back to intersection.
- [x] Unit Tests
### Release Notes
- Added `isWrapMode` to user preferences.
- Added Wrap Mode toggle to user preferences menu.
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.
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>
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`
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>
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
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.
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.
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
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>
This PR changes the way that viewport bounds are calculated by using the
canvas element as the source of truth, rather than the container. This
allows for cases where the canvas is not the same dimensions as the
component. (Given the way our UI and context works, there are cases
where this is desired, i.e. toolbars and other items overlaid on top of
the canvas area).
The editor's `getContainer` is now only used for the text measurement.
It would be good to get that out somehow.
# Pros
We can inset the canvas
# Cons
We can no longer imperatively call `updateScreenBounds`, as we need to
provide those bounds externally.
### Change Type
- [x] `major` — Breaking change
### Test Plan
1. Use the examples, including the new inset canvas example.
- [x] Unit Tests
### Release Notes
- Changes the source of truth for the viewport page bounds to be the
canvas instead.
`Geometry2d.isSnappable` isn't used. There's some intended behaviour
here around making it so you can't snap handles to text labels, but it's
not actually working.
This is a breaking change, but given this property doesn't do anything I
don't think it's likely to be heavily depended upon
### Change Type
- [x] `major` — Breaking change
This would happen when trying to translate a zero-width bound arrow.
### Change Type
- [x] `patch` — Bug fix
### Release Notes
- Fixes zero-width arrow NaN computation when moving the label.
Taking the opportunity for some last-minute low-consequence breaking
changes before 2.0, this diff does some prep work for adding a new
snapping API by making the distinction between the two types of snapping
a bit clearer and cleaning up some naming.
- `SnapManager` has had most of the actual snapping logic moved into two
properties: `shapeBounds` (for snapping shape bounds on translate and
resize) and `handles` (for snapping handles)
- `SnapLine`s are renamed to `SnapIndicator`s. The 'line' name was a bit
confusing because not all of these indicators are lines (the new vertex
snap type will be a single point)
I'm not too worried about this being a breaking change as it touches an
area of the API that I'd be very surprised if more than a couple of
people were using.
### Change Type
- [x] `major` — Breaking change
### Test Plan
- No user-facing changes.
### Release Notes
- `SnapLine`s are now called `SnapIndicator`s
- Snapping methods moved from `editor.snaps` to
`editor.snaps.shapeBounds` and `editor.snaps.handles` depending on the
type of snapping you're trying to do.
This is a followup on the arrows work.
- allow labels to go to the ends if no arrowhead is present
- avoid using / overloading TLHandle and use a new PointingLabel state
to specifically address label movement
- removes the feature flag to launch this feature!
### Change Type
- [x] `patch` — Bug fix
### Release Notes
- Arrow labels: provide more polish on label placement
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Adds an FPS counter to detect when there's a UI slowdown.
(btw, drive-by typo fix for a file)
https://github.com/tldraw/tldraw/assets/469604/b83d4b10-35d9-4584-af46-c63b5cc107ac
### 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
### Test Plan
1.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Adds FPS counter to debug panel.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This adds the ability to drag the label on an arrow to a different
location within the line segment/arc.
https://github.com/tldraw/tldraw/assets/469604/dbd2ee35-bebc-48d6-b8ee-fcf12ce91fa5
- A lot of the complexity lay in ensuring a fixed distance from the ends
of the arrowheads.
- I added a new type of handle `text-adjust` that makes the text box the
very handle itself.
- I added a `ARROW_HANDLES` enum - we should use more enums!
- The bulk of the changes are in ArrowShapeUtil — check that out in
particular obviously :)
Along the way, I tried to improve a couple spots as I touched them:
- added some more documentation to Vec.ts because some of the functions
in there were obscure/new to me. (at least the naming, hah)
- added `getPointOnCircle` which was being done in a couple places
independently and refactored those places.
### Questions
- the `getPointOnCircle` API changed. Is this considered breaking and/or
should I leave the signature the same? Wasn't sure if it was a big deal
or not.
- I made `labelPosition` in the schema always but I guess it could have
been optional? Lemme know if there's a preference.
- Any feedback on tests? Happy to expand those if necessary.
### 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
### Test Plan
1. For arrow in [straightArrow, curvedArrow] test the following:
a. Label in the middle
b. Label at both ends of the arrow
c. Test arrows in different directions
d. Rotating the endpoints and seeing that the label stays at the end of
the arrow at a fixed width.
e. Test different stroke widths.
f. Test with different arrowheads.
2. Also, test arcs that are more circle like than arc-like.
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
- Adds ability to change label position on arrows.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Co-authored-by: alex <alex@dytry.ch>
This PR adds the docs app back into the tldraw monorepo.
## Deploying
We'll want to update our deploy script to update the SOURCE_SHA to the
newest release sha... and then deploy the docs pulling api.json files
from that release. We _could_ update the docs on every push to main, but
we don't have to unless something has changed. Right now there's no
automated deployments from this repo.
## Side effects
To make this one work, I needed to update the lock file. This might be
ok (new year new lock file), and everything builds as expected, though
we may want to spend some time with our scripts to be sure that things
are all good.
I also updated our prettier installation, which decided to add trailing
commas to every generic type. Which is, I suppose, [correct
behavior](https://github.com/prettier/prettier-vscode/issues/955)? But
that caused diffs in every file, which is unfortunate.
### Change Type
- [x] `internal` — Any other changes that don't affect the published
package[^2]
Fixes https://github.com/tldraw/tldraw/issues/2357
This PR fixes not being able to close the context menu by clicking
- your selected shape
- the ui
It seems like the Radix's `modal` setting causes trouble for us. I think
we're better off turning it off.
We now show an indicator on hovered shapes when the context menu. This
is consistent with how our other menus currently work.
![2023-12-19 at 14 19 14 - Cyan
Bovid](https://github.com/tldraw/tldraw/assets/15892272/88b492c2-8f3b-40bc-9dec-744fe72cda3b)
![2023-12-19 at 14 21 36 - Amaranth
Vulture](https://github.com/tldraw/tldraw/assets/15892272/1f19751d-499b-40c3-9b28-9f41a2f27ab2)
### 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.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Fix not being able to close the context menu by clicking on the UI or
your selected shape.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
I standardized the definition of the `useEditor hook` by changing it
from an `arrow function` to a `regular function`, in line with other
editor-related hooks.
### 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
1. Add a step-by-step description of how to test your PR here.
2.
- [x] Unit Tests
- [x] End to end tests
### Release Notes
- Add a brief release note for your PR here.
Finally removing all these deprecated getters ahead of the full release.
### Change Type
- [x] `major` — Breaking change
### Release Notes
- (Breaking) Removed deprecated getters.
This pull request was initiated by Lokalise (user Lu) at 2023-12-19
10:48:13
## Release Notes
Added Czech translations.
Updated translations for German, Korean, Russian, Ukrainian, Traditional
Chinese.
Start scrolling when we get close to the edges of the window. This works
for brush selecting, translating, and resizing.
https://github.com/tldraw/tldraw/assets/2523721/4a5effc8-5445-411b-b317-36097233d36c
### 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
### Test Plan
1. Select a shape.
2. Move it towards the edge of the window. The camera position should
change.
3. Also try resizing, brush selecting.
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
- Adds the logic to change the camera position when you get close to the
edges of the window. This allows you to drag, resize, brush select past
the edges of the current viewport.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Adds Fit to content option for frames. This resizes the frames so that
the whole content fits. It also adds 50px padding on all sides so that
the content does not touch the frame's borders.
https://github.com/tldraw/tldraw/assets/2523721/b2f86e31-7dfb-495f-ac31-f1e0125e0af1https://github.com/tldraw/tldraw/assets/2523721/e0a73d25-ac9f-4a35-a1fd-4aed7a5b151cFixes#1407
### 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
### Test Plan
1. Add some shapes.
2. Add a frame that encloses those shapes.
3. Right click on the frame and choose `Fit to content`
4. The frame should resize to fit all the children with some padding on
all sides of the frame.
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
- Add Fit to content option to the context menu for frames. This resizes
the frames to correctly fit all their content.
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This is an attempt at #1989. The big issue there is when `shapeUtils`
change when you're relying on tldraw to provide you with the store
instead of providing your own. Our `useTLStore` component had a bug
where it would rely on effects & a ref to detect when its options had
changed whilst still scheduling updates. Fresh opts would come in, but
they'd be different from the ones in the ref, so we'd schedule an
update, so the opts would come in again, but they'd still be different
as we hadn't run effects yet, and we'd schedule an update again (and so
on).
This diff fixes that by storing the previous opts in state instead of a
ref, so they're updating in lockstep with the store itself. this
prevents the update loop.
There are still situations where we can get into loops if the developer
is passing in custom tools, shapeUtils, or components but not memoising
them or defining them outside of react. As a DX improvement, we do some
auto-memoisation of these values using shallow equality to help with
this issue.
### Change Type
- [x] `patch` — Bug fix
### Test Plan
- [x] Unit Tests
### Release Notes
- Fixes a bug that could cause crashes due to a re-render loop with HMR
#1989
- Add simple frame removing - it just drops the frame and parent
children to frames parent.
- Select children after removing the frame.
- Add children to the frame if we resize the frame so that it encloses
them.
Describe what your pull request does. If appropriate, add GIFs or images
showing the before and after.
### 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
### 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: Steve Ruiz <steveruizok@gmail.com>
Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
follow up to #2189
adds runtime warnings for deprecated fields. cleans up remaining fields
and usages. Adds a lint rule to prevent access to deprecated fields.
Adds a lint rule to prevent using getters.
### Change Type
- [x] `patch` — Bug fix
This PR adds a custom tool example, the `Screenshot Tool`.
It demonstrates how a user can create a custom tool together with custom
tool UI.
### Change Type
- [x] `minor` — New feature
### Test Plan
1. Use the screenshot example
### Release Notes
- adds ScreenshotTool custom tool example
- improvements and new exports related to copying and exporting images /
files
- loosens up types around icons and translations
- moving `StateNode.isActive` into an atom
- adding `Editor.path`
This PR extracts some improvements from #2198 into a separate PR.
### Release Notes
- adds computed `StateNode.getPath`
- adds computed StateNode.getCurrent`
- adds computed StateNode.getIsActive`
- adds computed `Editor.getPath()`
- makes transition's second property optional
### Change Type
- [x] `minor` — New feature
### Test Plan
- [x] Unit Tests
- [x] End to end tests
Follow up to #2189 and #2202
### Change Type
- [x] `patch` — Bug fix
[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version
This PR replaces the `.value` getter for the atom with `.get()`
### Change Type
- [x] `major` — Breaking change
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
This improves how zooming works when we zoom in an inactive window. With
this change you should zoom towards the pointer position, while before
it zoomed towards the last known pointer position before the window
became inactive.
Fixes#2165
Before
https://github.com/tldraw/tldraw/assets/2523721/50018782-533a-43bb-88a5-21fc4419b723
After
https://github.com/tldraw/tldraw/assets/2523721/c3859f84-ef56-4db8-96b9-50a2de060507
### 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. Open the tldraw editor.
2. Click away from the browser window so that it's not longer active.
3. Hover over the browser window and start zooming.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Improves zooming for inactive windows.
This PR adds two new component overrides to the editor's `components`
slot. They are:
- `<OnTheCanvas/>`, which renders inside of the html layer that scales
and translates with the camera
- `<InFrontOfTheCanvas/>`, which renders in front of the canvas but
behind any UI elements, and which does not scale / pan with the camera.
![Kapture 2023-11-06 at 12 19
15](https://github.com/tldraw/tldraw/assets/23072548/51c0421d-8b39-48b5-9b8a-c717253c3423)
### Change Type
- [x] `minor` — New feature
### Test Plan
1. See the "on the canvas" example.
### Release Notes
- [editor] Adds two new components, `OnTheCanvas` and
`InFrontOfTheCanvas`.