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>
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).
Add an option to make paste at cursor the default.
Not sure if we also want to expose this on tldraw.com? For now I did,
but happy to remove if we'd want to keep the preferences simple.
We could also add this to the `TldrawOptions`, but it felt like some
apps might actually allow this customization on a per user level.
Solves https://github.com/tldraw/tldraw/issues/4066
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Copy / pasting should still work as it works now: `⌘ + v` pastes on
top of the shape, `⌘ + ⇧ + v` pastes at cursor.
2. There's now a new option under Preferences to paste at cursor. This
just swaps the logic between the two shortcuts: `⌘ + v` then pastes at
cursor and `⌘ + ⇧ + v` pastes on top of the shape.
### Release notes
- Allow users and sdk users to make pasting at the cursor a default
instead of only being available with `⌘ + ⇧ + v`.
This PR adds a sneaky action / kbd (Alt-F) for the fill fill style.
Similar to the white action, this is not really documented and may be
removed in the future. But it's cool!!
### Change Type
- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature
### Test Plan
1. Press Alt-F.
### Release Notes
- Secretly adds a fill-fill style (Alt-F)
Allow the users to fully use the same colour scheme as their system.
Allows the users to either: force dark colour scheme, force light colour
scheme, or use the system one.
It's reactive to the system changes.
https://github.com/tldraw/tldraw/assets/2523721/6d4cef03-9ef0-4098-b299-6bf5d7513e98
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Add a brief release note for your PR here.
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
This PR adds a user preference for "dynamic size mode" where the scale
of shapes (text size, stroke width) is relative to the current zoom
level. This means that the stroke width in screen pixels (or text size
in screen pixels) is identical regardless of zoom level.
![Kapture 2024-05-27 at 05 23
21](https://github.com/tldraw/tldraw/assets/23072548/f247ecce-bfcd-4f85-b7a5-d7677b38e4d8)
- [x] Draw shape
- [x] Text shape
- [x] Highlighter shape
- [x] Geo shape
- [x] Arrow shape
- [x] Note shape
- [x] Line shape
Embed shape?
### Change Type
- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature
### Test Plan
1. Use the tools.
2. Change zoom
- [ ] Unit Tests
### Release Notes
- Adds a dynamic size user preferences.
- Removes double click to reset scale on text shapes.
- Removes double click to reset autosize on text shapes.
---------
Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com>
This PR adds some functionality for turning shapes into images.
![Kapture 2024-06-13 at 12 51
00](https://github.com/tldraw/tldraw/assets/23072548/78525e29-61b5-418f-889d-2f061f26f34d)
It adds:
- the `flattenShapesToImages`
- the `useFlatten` hook
- a `flatten-shapes-to-images` action (shift + f)
- adds `flattenImageBoundsExpand` option
- adds `flattenImageBoundsPadding` option
## Flatten shapes to images
The `flattenShapesToImages` helper method will 1) create an image for
the given shape ids, 2) add it to the canvas in the same location / size
as the source shapes, and then 3) delete the original shapes. The new
image will be placed correctly in the z index and in the correct
rotation of the root-most ancestor of the given shape ids.
![image](https://github.com/tldraw/tldraw/assets/23072548/fe888980-05a5-4369-863f-90c142f9f8b9)
It has an argument, `flattenImageBoundsExpand`, which if provided will
chunk the given shapes into images based on their overlapping (expanded)
bounding boxes.
![image](https://github.com/tldraw/tldraw/assets/23072548/c4799309-244d-4a2b-ac59-9c2fd100319c)
By default, the flatten action uses the editor's
`options.flattenImageBoundsExpand`. The `flattenImageBoundsPadding`
option is used as a value for how much larger the image should be than
the source image bounds (to account for large strokes, for example).
### Change Type
- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature
### Test Plan
1. Select shapes
2. Select context menu > edit > flatten
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Add Flatten, a new menu item to flatten shapes into images
This PR ensures that the share menu is open when navigating from the
create new shared project button.
This could be achieved by calling ```editor.addOpenMenu('share-menu')```
after ```navigate('/new')``` , but that opens the menu on the local
editor first so you get a flash of that before the multiplayer editor
loads.
Instead I've used the state prop on the Navigate component/function to
pass a property called shouldOpenShareMenu.
If the user presses the back button to return to the local editor
instance then the open state of the share menu is preserved, which is
actually something we don't want in this case. Not sure how to deal with
that without adding a ton more complexity, is it worth it?
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
### Test Plan
1. Click create new shared project from the file menu
2. Share menu should open after navigating to the new room
### Release Notes
- Open share menu when navigating from the create new shared project
button.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Right now when you hit Share/Fork on production it can take a good 5
seconds for something to happen.
In the meantime, it can feel like nothing happened when you clicked the
button. Maybe you click it again to see if that'll fix it, which doesn't
do anything. Same thing for the Copy action, sometimes we don't have an
icon to subtly show that it's been copied.
This adds some toasts and disables the Share menu while a project is
being created.
Also, has two drive-by fixes:
- the getShareUrl logic is old and needed to be superseded by the new
stuff
- the icon fix for clipboard-copied.svg from the readonly omnibus PR
(https://github.com/tldraw/tldraw/pull/3192) got overridden in a
different PR (https://github.com/tldraw/tldraw/pull/3627) - this
restores the fix
<img width="304" alt="Screenshot 2024-05-30 at 11 38 39"
src="https://github.com/tldraw/tldraw/assets/469604/f9a3b7c7-f9ea-41f0-ad00-7fc5d71da93f">
<img width="257" alt="Screenshot 2024-05-30 at 11 38 14"
src="https://github.com/tldraw/tldraw/assets/469604/c0a2d762-64c3-44da-b61e-c237133dd8cd">
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
### Release Notes
- Share menu: make sharing/fork/copy actions clearer
This PR implements a camera options API.
- [x] Initial PR
- [x] Updated unit tests
- [x] Feedback / review
- [x] New unit tests
- [x] Update use-case examples
- [x] Ship?
## Public API
A user can provide camera options to the `Tldraw` component via the
`cameraOptions` prop. The prop is also available on the `TldrawEditor`
component and the constructor parameters of the `Editor` class.
```tsx
export default function CameraOptionsExample() {
return (
<div className="tldraw__editor">
<Tldraw cameraOptions={CAMERA_OPTIONS} />
</div>
)
}
```
At runtime, a user can:
- get the current camera options with `Editor.getCameraOptions`
- update the camera options with `Editor.setCameraOptions`
Setting the camera options automatically applies them to the current
camera.
```ts
editor.setCameraOptions({...editor.getCameraOptions(), isLocked: true })
```
A user can get the "camera fit zoom" via `editor.getCameraFitZoom()`.
# Interface
The camera options themselves can look a few different ways depending on
the `type` provided.
```tsx
export type TLCameraOptions = {
/** Whether the camera is locked. */
isLocked: boolean
/** The speed of a scroll wheel / trackpad pan. Default is 1. */
panSpeed: number
/** The speed of a scroll wheel / trackpad zoom. Default is 1. */
zoomSpeed: number
/** The steps that a user can zoom between with zoom in / zoom out. The first and last value will determine the min and max zoom. */
zoomSteps: number[]
/** Controls whether the wheel pans or zooms.
*
* - `zoom`: The wheel will zoom in and out.
* - `pan`: The wheel will pan the camera.
* - `none`: The wheel will do nothing.
*/
wheelBehavior: 'zoom' | 'pan' | 'none'
/** The camera constraints. */
constraints?: {
/** The bounds (in page space) of the constrained space */
bounds: BoxModel
/** The padding inside of the viewport (in screen space) */
padding: VecLike
/** The origin for placement. Used to position the bounds within the viewport when an axis is fixed or contained and zoom is below the axis fit. */
origin: VecLike
/** The camera's initial zoom, used also when the camera is reset.
*
* - `default`: Sets the initial zoom to 100%.
* - `fit-x`: The x axis will completely fill the viewport bounds.
* - `fit-y`: The y axis will completely fill the viewport bounds.
* - `fit-min`: The smaller axis will completely fill the viewport bounds.
* - `fit-max`: The larger axis will completely fill the viewport bounds.
* - `fit-x-100`: The x axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
* - `fit-y-100`: The y axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
* - `fit-min-100`: The smaller axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
* - `fit-max-100`: The larger axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
*/
initialZoom:
| 'fit-min'
| 'fit-max'
| 'fit-x'
| 'fit-y'
| 'fit-min-100'
| 'fit-max-100'
| 'fit-x-100'
| 'fit-y-100'
| 'default'
/** The camera's base for its zoom steps.
*
* - `default`: Sets the initial zoom to 100%.
* - `fit-x`: The x axis will completely fill the viewport bounds.
* - `fit-y`: The y axis will completely fill the viewport bounds.
* - `fit-min`: The smaller axis will completely fill the viewport bounds.
* - `fit-max`: The larger axis will completely fill the viewport bounds.
* - `fit-x-100`: The x axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
* - `fit-y-100`: The y axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
* - `fit-min-100`: The smaller axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
* - `fit-max-100`: The larger axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller.
*/
baseZoom:
| 'fit-min'
| 'fit-max'
| 'fit-x'
| 'fit-y'
| 'fit-min-100'
| 'fit-max-100'
| 'fit-x-100'
| 'fit-y-100'
| 'default'
/** The behavior for the constraints for both axes or each axis individually.
*
* - `free`: The bounds are ignored when moving the camera.
* - 'fixed': The bounds will be positioned within the viewport based on the origin
* - `contain`: The 'fixed' behavior will be used when the zoom is below the zoom level at which the bounds would fill the viewport; and when above this zoom, the bounds will use the 'inside' behavior.
* - `inside`: The bounds will stay completely within the viewport.
* - `outside`: The bounds will stay touching the viewport.
*/
behavior:
| 'free'
| 'fixed'
| 'inside'
| 'outside'
| 'contain'
| {
x: 'free' | 'fixed' | 'inside' | 'outside' | 'contain'
y: 'free' | 'fixed' | 'inside' | 'outside' | 'contain'
}
}
}
```
### Change Type
- [x] `sdk` — Changes the tldraw SDK
- [x] `feature` — New feature
### Test Plan
These features combine in different ways, so we'll want to write some
more tests to find surprises.
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
### Release Notes
- SDK: Adds camera options.
---------
Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
This pull request was initiated by Lokalise (user Mitja) at 2024-04-30
15:15:53
- [x] sdk
- [x] chore
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Reworks how the readonly urls work. Till now we just used a simple
function that would scramble the slugs. Now we use a proper key value
mapping between regular and readonly slugs:
- We use two KV stores. One is for going from a slug to a readonly slug
and the other one for going the other way around. They are populated at
the same time.
- We separate preview KV stores (dev, preview, staging) from production
one. I've already created these on Cloudflare. [My understanding is
](https://developers.cloudflare.com/kv/reference/data-security/#encryption-at-rest)that
ids [can be
public](https://community.cloudflare.com/t/is-it-safe-to-keep-kv-ids-in-a-public-git-repo/517387/4)
since we can only access KV from our worker. Happy to move them to env
variables though.
- [x] Disable creating new rooms when tldraw is embedded inside iframes
on other websites (we check the referrer and if it's not the same as the
iframe's origin we don't allow it)
- [x] Fork a project when inside an iframe now opens the forked project
on tldraw.com and not inside iframe.
- [x] We allow embeding of iframes, but we now track the where they are
used via the referrer. We send this to Vercel analytics.
- [x] Improved UX of the share menu to make it less confusing. Toggle is
gone.
- [x] `/new` and `/r` routes not redirect to `/`.
- [x] This introduces a new `/ro` route for readonly rooms. Legacy rooms
still live on `/v`.
- [x] Brought back `dotcom-shared` project to share code between BE and
FE. Mostly types.
- [x] Prevent creating of rooms by entering `/r/non-existing-slug`.
- [x] Handle getting a readonly slug for old rooms. Added a comment
about it
[here](https://github.com/tldraw/tldraw/pull/3192/files#diff-c0954b3dc71bb7097c39656441175f3238ed60cf5cee64077c06e21da82182cbR17-R18).
- [x] We no longer expose editor on the window object for readonly
rooms. Prevents the users disabling readonly rooms manually.
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
### Test Plan
1. Make sure old readonly rooms still work.
2. Creating a readonly link from an existing room should still use `/v`
path.
3. Newly created rooms should use `/ro` path for readonly rooms. Make
sure these work as well.
4. `/r` room was disabled and redirects to `/`
5. `/new` should still work when not inside iframes.
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
1. This adds new functionality for readonly rooms:
- We have a new route `/ro` for newly created readonly rooms. These
rooms no longer use the scrambling logic to create readonly slugs.
Instead we now use KV storage from cloudflare to track the mapping for
slugs -> readonly slug and readonly slug -> slug.
- The old route `/v` is preserved, so that the old room still work as
they did before.
- For old rooms we will keep on generating the old readonly slugs, but
for new rooms we'll start using the new logic.
2. We no longer prevent embedding of tldraw inside iframes.
3. We do prevent generating new rooms from inside the iframes though.
`/r`, `/new`, `/r/non-existing-id` should not allow creation of new
rooms inside iframes. Only `/new` still works when not inside iframes.
4. Forking a project from inside an iframe now opens it on tldraw.com
5. Slight copy change on the sharing menu. We no longer have a toggle
between readonly and non-readonly links.
6. `editor` and `app` are no longer exposed on the window object for
readonly rooms. Prevents users from using the `updateInstanceState` to
escape readonly rooms.
---------
Co-authored-by: Mime Čuvalo <mimecuvalo@gmail.com>
This PR:
- adds the export all menu items to the main menu
- removes the export all menu items from the dotcom menus
- removes the shape menu and reverts several changes from
https://github.com/tldraw/tldraw/pull/2782. This was not properly
reviewed (I thought it was a PR about hiding / showing menu items).
- fixes a bug with exporting (exporting JSON was not working when the
user had no selected shapes)
- fixes a bug that would prevent "flip shapes" from appearing in the
menu
- prevents export / copy actions from running if there are no shapes on
the page
- allows export / copy actions to default to all shapes on the page if
no shapes are selected
These changes have not been released in the dotcom yet. There's will be
some thrash in the APIs.
# Menu philosophy
In the menu, the **edit** submenu relates to undo/redo, plus the user's
current selection.
Menu items that relate to specific to certain shapes are hidden when not
available.
Menu items that relate to all shapes are disabled when not available.
<img width="640" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/e467e6bb-d958-4a9a-ac19-1dada52dcfa6">
### Change Type
- [x] `major` — Bug fix
### Test
- Select no shapes (arrange / flip should not be visible)
- Select one geo shape (arrange / flip should not be visible)
- Select two geo shapes (arrange / flip should be visible)
- Select one draw shape (arrange / flip should not be visible)
### Release Notes
- Revert some changes in the menu.
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.
<img width="428" alt="Screenshot 2024-02-16 at 16 46 28"
src="https://github.com/tldraw/tldraw/assets/469604/334cd0db-d9d5-4993-8012-c6985173edfb">
- re-orders to be the normative New / Open / Save order — we shouldn't
be messing with this conventional ordering
- removes the "Don't ask again" from New/Open dialogs because they're
non-undoable and not what _anybody_ should ever select. we shouldn't
offer users a loaded footgun! :P
- makes File menu be part of the default menu — it's presence is
glaringly missing for regular development
- along with that, make the pieces of that menu available as lego pieces
to use - it can't just be `DefaultMainMenuContent`, all or nothing,
forcing downstream users to import everything from scratch
- finally, adds the Export menu as initially intended by this PR!
@steveruizok let's discuss if you have some notes on this and we can
talk about the shape of things here.
### Change Type
- [x] `patch` — Bug fix
### Release Notes
- Composable UI: makes File items be more granularly accessible / usable
- Menu: show Export under the File menu.
This PR just changes the ordering of our translations files.
I did this because it makes it easier for contributors to update
translations directly in those files without causing lots of
hard-to-read formatting changes each time we export from Lokalise.
I also updated our Notion doc instructions on how to export from
Lokalise:
https://www.notion.so/tldraw/How-to-make-a-PR-from-Lokalise-e63e61f6beec495bbb4c31c376e9c1a1?pvs=4
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.
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.
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>
Describe what your pull request does. If appropriate, add GIFs or images
showing the before and after.
### 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
### Release Notes
- Changed the label for the Simplified Chinese language from `Chinese -
Simplified` to `简体中文`, following the convention of other languages.
- Updated the API and relevant documentation through build scripts.
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>
- 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>
Improves the overall translation of the application into Portuguese
(pt-br), fix typos and adds new translations for new features.
### 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 workspace.
- [x] Unit Tests
- [x] End to end tests
### Release Notes
- Improves the overall translation into Portuguese (pt-br).
This pull request was initiated by Lokalise (user Lu) at 2023-11-13
13:15:02
## Release Notes
- Updated translations for Spanish, Japanese, Romanian, Russian,
Ukrainian, and Simplified Chinese.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Just add the Japanese translations.
-------
Describe what your pull request does. If appropriate, add GIFs or images
showing the before and after.
### 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
- Updated Japanese translations.
This PR adds an offline indicator to the UI package. It's not used in
the default app but we'll use it on tldraw.com, and it makes sense to
include it here as it's generally useful.
### Change Type
- [x] `minor` — New feature
### Test Plan
1. See the zones example.
### Release Notes
- [@tldraw/tldraw] add offline indicator to ui components
This PR adds an "Unlock all" action to the edit menu.
- Selecting `unlock all` sets `isLocked` to false for all shapes on the
current page
- The option is disabled if the page is empty; but we don't check
whether there are locked shapes on the page (juice < squeeze)
Closes https://github.com/tldraw/tldraw/issues/1809
### Change Type
- [x] `minor` — New feature
### Test Plan
1. Create locked shapes
2. Select menu > edit > unlock all
### Release Notes
- Adds the unlock all feature.
This PR is another grab bag:
- renames `readOnly` to `readonly` throughout editor
- fixes a regression related to focus and keyboard shortcuts
- adds a small outline for focused editors
### Change Type
- [x] `major`
### Test Plan
- [x] End to end tests
Fix cloud tool tooltip
### 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
- Add a brief release note for your PR here.
![Kapture 2023-07-04 at 16 36
31](https://github.com/tldraw/tldraw/assets/1242537/bcb19959-ac66-46fa-92ea-50fe4692a96c)
### 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. Make some cloud shapes, try different sizes, colors, fills.
2. Export cloud shapes to images.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Adds a cloud shape.