tldraw 5.5.0 → 5.6.0-canary.07d34be92012

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/DOCS.md +43 -37
  2. package/RELEASE_NOTES.md +122 -71
  3. package/dist-cjs/index.d.ts +4 -5
  4. package/dist-cjs/index.js +1 -1
  5. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +1 -1
  6. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +2 -2
  7. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js +24 -16
  8. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js.map +2 -2
  9. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +3 -6
  10. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  11. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +2 -8
  12. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  13. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js +1 -3
  14. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  15. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js +2 -2
  16. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  17. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +29 -61
  18. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +3 -3
  19. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js +0 -4
  20. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  21. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +18 -20
  22. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  23. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +0 -1
  24. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  25. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +1 -2
  26. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  27. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +0 -2
  28. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  29. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js.map +2 -2
  30. package/dist-cjs/lib/ui/version.js +3 -3
  31. package/dist-cjs/lib/ui/version.js.map +1 -1
  32. package/dist-esm/index.d.mts +4 -5
  33. package/dist-esm/index.mjs +1 -1
  34. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +1 -1
  35. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +2 -2
  36. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs +24 -16
  37. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs.map +2 -2
  38. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +3 -6
  39. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  40. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +2 -8
  41. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  42. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs +1 -3
  43. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  44. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs +2 -2
  45. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  46. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +29 -61
  47. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +3 -3
  48. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs +0 -4
  49. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  50. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +18 -20
  51. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  52. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +0 -1
  53. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  54. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +1 -2
  55. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  56. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +0 -2
  57. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  58. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs.map +2 -2
  59. package/dist-esm/lib/ui/version.mjs +3 -3
  60. package/dist-esm/lib/ui/version.mjs.map +1 -1
  61. package/package.json +17 -23
  62. package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +1 -1
  63. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +43 -0
  64. package/src/lib/shapes/arrow/toolStates/Idle.tsx +29 -17
  65. package/src/lib/tools/EraserTool/childStates/Erasing.ts +3 -8
  66. package/src/lib/tools/SelectTool/DragAndDropManager.ts +2 -9
  67. package/src/lib/tools/SelectTool/childStates/Brushing.ts +2 -4
  68. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +2 -2
  69. package/src/lib/tools/SelectTool/childStates/Idle.ts +31 -62
  70. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +0 -8
  71. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +21 -25
  72. package/src/lib/tools/SelectTool/childStates/Resizing.ts +0 -4
  73. package/src/lib/tools/SelectTool/childStates/Rotating.ts +1 -4
  74. package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -2
  75. package/src/lib/tools/selection-logic/updateHoveredShapeId.ts +2 -5
  76. package/src/lib/ui/version.ts +3 -3
  77. package/src/test/EraserTool.test.ts +42 -1
  78. package/src/test/commands/duplicatePage.test.ts +41 -1
  79. package/src/test/resizeBox.test.ts +25 -0
  80. package/src/test/resizing.test.ts +71 -0
  81. package/src/test/shapeutils.test.ts +58 -1
  82. package/src/test/testutils/renderTldrawComponent.tsx +3 -3
  83. package/tldraw.css +0 -4
package/DOCS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # tldraw Documentation
2
2
 
3
- Version: `5.5.0`
3
+ Version: `5.6.0-canary.07d34be92012`
4
4
 
5
5
  This file is generated during package publishing from the tldraw docs content for this exact package version.
6
6
 
@@ -383,6 +383,7 @@ We ship an experimental `tldraw-migrate` agent skill that helps a coding agent u
383
383
 
384
384
  #### v5.x
385
385
 
386
+ - [v5.5](https://tldraw.dev/releases/v5.5.0) - Smart typography and matched-pair wrapping in rich text, pasting links onto shapes, a replaceable note attribution badge, TipTap's extension API re-exported from tldraw, and a reliability pass across the SDK
386
387
  - [v5.4](https://tldraw.dev/releases/v5.4.0) - A center align operation, a tleditors registry of mounted editors, faster signals and store layers, and a broad reliability pass across the SDK
387
388
  - [v5.3](https://tldraw.dev/releases/v5.3.0) - Commenting with anchored threads on the canvas, new collaboration packages, geo shape flipping, crop snapping, and faster viewport culling
388
389
  - [v5.2](https://tldraw.dev/releases/v5.2.0) - Faster freehand ink, a frame selection action, SDK-wide performance improvements, and breaking changes to the collaborator user-id types and Node support
@@ -6780,6 +6781,8 @@ Mount the layer through the `InFrontOfTheCanvas` component slot so it sits above
6780
6781
 
6781
6782
  `commentToolOverrides` puts the comment tool in Quick Actions with the `C` shortcut. With the tool active, clicking empty canvas starts a thread anchored to that point, and clicking a shape anchors a comment to the shape. You can also turn on region comments, where dragging the tool out covers an area. Either way the click only opens a composer: nothing is written to the store until the comment is posted.
6782
6783
 
6784
+ To start a comment from somewhere other than the tool, such as a context menu item, call `startCommentAt(editor, point)` with a page point. It enters the comment tool and opens the composer there, anchored the same way a click would be.
6785
+
6783
6786
  Once a comment thread exists, its pin is the handle for everything else.
6784
6787
 
6785
6788
  | Input | Result |
@@ -7317,19 +7320,19 @@ This is the same question the client's [`canModifyComment`](#who-can-edit-and-de
7317
7320
 
7318
7321
  `CanvasComments` is one way to assemble the parts, and every part it uses is exported. You can rebuild it, or build something quite different, from the same pieces.
7319
7322
 
7320
- | Export | Description |
7321
- | ---------------------------------------- | ----------------------------------------------------------- |
7322
- | `CommentTool`, `commentToolOverrides` | Placement: the tool state machine and its toolbar entry. |
7323
- | `CommentPin`, `CountBadge` | The pin marker and the clustered-count badge. |
7324
- | `CommentThread`, `CommentCard`, `Byline` | A thread and its comments. |
7325
- | `CommentComposer`, `SendButton` | The composer and its send control. |
7326
- | `CommentsList`, `CommentListItem` | A list of threads and one row of it. |
7327
- | `EmptyState`, `sortSidebarRows` | The list's empty state, and the sidebar's ordering. |
7328
- | `Avatar`, `Mention`, `MentionList` | Author avatars and the mention picker. |
7329
- | `Reaction`, `Reactions` | A reaction pill and a comment's row of them. |
7330
- | `anchorPagePoint`, `shapeAnchorAt` | Anchor math: page position from an anchor, and the reverse. |
7331
- | `editComment`, `deleteComment` | The write verbs. See [Writing comments](#writing-comments). |
7332
- | `registerCommentAnchorLifecycle` | Keeps shape-anchored threads alive across shape deletion. |
7323
+ | Export | Description |
7324
+ | ------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
7325
+ | `CommentTool`, `commentToolOverrides`, `startCommentAt` | Placement: the tool state machine, its toolbar entry, and starting a comment at a point. |
7326
+ | `CommentPin`, `CountBadge` | The pin marker and the clustered-count badge. |
7327
+ | `CommentThread`, `CommentCard`, `Byline` | A thread and its comments. |
7328
+ | `CommentComposer`, `SendButton` | The composer and its send control. |
7329
+ | `CommentsList`, `CommentListItem` | A list of threads and one row of it. |
7330
+ | `EmptyState`, `sortSidebarRows` | The list's empty state, and the sidebar's ordering. |
7331
+ | `Avatar`, `Mention`, `MentionList` | Author avatars and the mention picker. |
7332
+ | `Reaction`, `Reactions` | A reaction pill and a comment's row of them. |
7333
+ | `anchorPagePoint`, `shapeAnchorAt` | Anchor math: page position from an anchor, and the reverse. |
7334
+ | `editComment`, `deleteComment` | The write verbs. See [Writing comments](#writing-comments). |
7335
+ | `registerCommentAnchorLifecycle` | Keeps shape-anchored threads alive across shape deletion. |
7333
7336
 
7334
7337
  The presentational components take plain props and know nothing about the editor. The canvas layer, the tool, and the hooks build on them. `CanvasComments` registers the anchor lifecycle for you, so call `registerCommentAnchorLifecycle` yourself only if you're replacing the layer wholesale.
7335
7338
 
@@ -7839,31 +7842,34 @@ The `type` determines the visual appearance—like `'default'`, `'grab'`, or `'n
7839
7842
 
7840
7843
  tldraw supports these cursor types:
7841
7844
 
7842
- | Type | Description |
7843
- | ------------- | ---------------------------------------------- |
7844
- | `default` | Standard pointer arrow |
7845
- | `pointer` | Hand indicating clickable element |
7846
- | `cross` | Crosshair for precise positioning |
7847
- | `comment` | Speech bubble for placing comments |
7848
- | `grab` | Open hand for draggable content |
7849
- | `grabbing` | Closed hand while dragging |
7850
- | `text` | I-beam for text editing |
7851
- | `move` | Four-way arrow for moving elements |
7852
- | `zoom-in` | Magnifying glass with plus |
7853
- | `zoom-out` | Magnifying glass with minus |
7854
- | `ew-resize` | Horizontal resize (east-west) |
7855
- | `ns-resize` | Vertical resize (north-south) |
7856
- | `nesw-resize` | Diagonal resize (northeast-southwest) |
7857
- | `nwse-resize` | Diagonal resize (northwest-southeast) |
7858
- | `nesw-rotate` | Rotation handle (northeast-southwest position) |
7859
- | `nwse-rotate` | Rotation handle (northwest-southeast position) |
7860
- | `senw-rotate` | Rotation handle (southeast-northwest position) |
7861
- | `swne-rotate` | Rotation handle (southwest-northeast position) |
7862
- | `none` | Hidden cursor |
7845
+ | Type | Description |
7846
+ | --------------- | --------------------------------------------------------- |
7847
+ | `default` | Standard pointer arrow |
7848
+ | `pointer` | Hand indicating clickable element |
7849
+ | `cross` | Crosshair for precise positioning |
7850
+ | `comment` | Speech bubble for placing comments |
7851
+ | `grab` | Open hand for draggable content |
7852
+ | `grabbing` | Closed hand while dragging |
7853
+ | `text` | I-beam for text editing |
7854
+ | `move` | Four-way arrow for moving elements |
7855
+ | `zoom-in` | Magnifying glass with plus |
7856
+ | `zoom-out` | Magnifying glass with minus |
7857
+ | `ew-resize` | Horizontal resize (east-west) |
7858
+ | `ns-resize` | Vertical resize (north-south) |
7859
+ | `nesw-resize` | Diagonal resize (northeast-southwest) |
7860
+ | `nwse-resize` | Diagonal resize (northwest-southeast) |
7861
+ | `nesw-rotate` | Rotation handle (northeast-southwest position) |
7862
+ | `nwse-rotate` | Rotation handle (northwest-southeast position) |
7863
+ | `senw-rotate` | Rotation handle (southeast-northwest position) |
7864
+ | `swne-rotate` | Rotation handle (southwest-northeast position) |
7865
+ | `none` | Hidden cursor |
7866
+ | `rotate` | Static rotation cursor (falls back to `pointer`) |
7867
+ | `resize-edge` | Static edge resize cursor (falls back to `ew-resize`) |
7868
+ | `resize-corner` | Static corner resize cursor (falls back to `nesw-resize`) |
7863
7869
 
7864
7870
  Static cursors like `default`, `pointer`, and `grab` are prerendered SVG cursors defined as CSS custom properties in tldraw's stylesheet (`--tl-cursor-default`, `--tl-cursor-grab`, and so on). Dynamic cursors like the resize and rotate types are generated at runtime as SVGs with the current rotation applied. The canvas reads the result from the `--tl-cursor` variable.
7865
7871
 
7866
- > `TLCursorType` also includes `resize-edge`, `resize-corner`, and `rotate` for schema compatibility. The default cursor rendering doesn't support them, so don't pass them to `setCursor`.
7872
+ The `rotate`, `resize-edge`, and `resize-corner` types are static too: they map to `--tl-cursor-rotate`, `--tl-cursor-resize-edge`, and `--tl-cursor-resize-corner`, which default to the browser's `pointer`, `ew-resize`, and `nesw-resize` cursors and ignore the cursor rotation. Use the direction-specific `*-resize` and `*-rotate` types when you want the rotated SVG cursors.
7867
7873
 
7868
7874
  #### Setting the cursor
7869
7875
 
@@ -20983,7 +20989,7 @@ The tldraw SDK is a product of a company. See [tldraw.dev](https://tldraw.dev/co
20983
20989
 
20984
20990
  ### Dependencies
20985
20991
 
20986
- {/* This page is generated by `yarn license-report --prod`. Do not edit it by hand. */}
20992
+ {/* This page is generated by `pnpm license-report --prod`. Do not edit it by hand. */}
20987
20993
 
20988
20994
  The tldraw SDK itself is published under the [tldraw license](https://tldraw.dev/legal/tldraw-license). It also depends on the third-party packages listed below, each under its own license.
20989
20995
 
package/RELEASE_NOTES.md CHANGED
@@ -1,83 +1,120 @@
1
1
  # Releases
2
2
 
3
- Version: `5.5.0`
3
+ Version: `5.6.0-canary.07d34be92012`
4
4
 
5
5
  This file is generated during package publishing from the tldraw release notes content for this exact package version.
6
6
 
7
7
  ## v5.5.0
8
8
 
9
- This release is a broad reliability pass over the SDK. Shapes keep changes made by other commands while they are being dragged, resized, rotated, or cropped; touch gestures no longer stick when the browser cancels a pointer; selection, draw, line, note, frame, and arrow interactions survive shapes being deleted or locked mid-interaction; SVG exports embed every resource they reference; and there are fixes across the store, signals, sync, and local persistence. `tldraw` now re-exports TipTap's extension API, so custom rich text extensions no longer need their own `@tiptap/*` install, and `Editor.setCamera` rejects non-finite values instead of quietly coercing them.
9
+ [View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v5.5.0)
10
+
11
+ This release adds smart typography to rich text, sets a shape's link when you paste a url onto it, lets you hide or replace the note shape's attribution badge, and re-exports TipTap's extension API from `tldraw`. It is also a broad reliability pass, with fixes across gestures, selection, arrows, exports, the store, sync, and local persistence, and `Editor.setCamera` now rejects non-finite values.
12
+
13
+ ### What's new
14
+
15
+ #### Smart typography and TipTap extensions in rich text ([#10767](https://github.com/tldraw/tldraw/pull/10767), [#10691](https://github.com/tldraw/tldraw/pull/10691))
16
+
17
+ Text typed on the canvas now reads like typeset text. Straight quotes curl, `--` becomes an em dash, `...` an ellipsis, and `->` an arrow. Pressing Backspace straight after a rewrite restores what you typed. The rules are TipTap's Typography extension, added as a standalone entry in `getTipTapDefaultExtensions()`, so filter it out to keep literal punctuation:
18
+
19
+ ```tsx
20
+ import { getTipTapDefaultExtensions } from 'tldraw'
21
+
22
+ const extensions = getTipTapDefaultExtensions().filter((e) => e.name !== 'typography')
23
+ ```
24
+
25
+ With text selected, typing an opening bracket or quote wraps the selection instead of replacing it: select a word and press `(` to get `(word)`. Pressing `` ` `` over a selection toggles inline code. Quotes stay straight inside code and in the mono font. The new `WrapSelectionExtension` does the wrapping, and `defaultWrappingPairs` lists the pairs it uses.
26
+
27
+ `tldraw` now also re-exports TipTap's extension API: `Node`, `Mark`, `Extension`, `mergeAttributes`, and `getSchema`, the `Extensions` and `JSONContent` types, and the `TaskList` and `TaskItem` extensions. Custom rich text extensions no longer need their own `@tiptap/*` dependency, which also rules out loading two copies of TipTap.
28
+
29
+ ```tsx
30
+ import { Mark, mergeAttributes } from 'tldraw'
31
+ ```
10
32
 
11
33
  ### API changes
12
34
 
13
35
  - 💥 **`Editor.setCamera`** now throws on a non-finite `x`, `y`, or `z` instead of silently coercing it to `0` or the current zoom level, and no longer mutates the point object passed to it. ([#9903](https://github.com/tldraw/tldraw/pull/9903))
14
- - 💥 **`store.query.filterHistory()`** now returns its own change counter rather than a value that always matches `store.history.get()`. After a rolled-back transaction it can be ahead of the store's counter, and it reports a change even for record types the transaction didn't touch. ([#10200](https://github.com/tldraw/tldraw/pull/10200))
15
- - Re-export TipTap's extension surface from `tldraw`: `Node`, `Mark`, `Extension`, `mergeAttributes`, and `getSchema`, the `Extensions` and `JSONContent` types, and the `TaskList` and `TaskItem` extensions. Custom rich text extensions no longer need their own `@tiptap/*` dependency, which also rules out loading two copies of TipTap. ([#10691](https://github.com/tldraw/tldraw/pull/10691))
36
+ - 💥 **`store.query.filterHistory()`** now returns its own change counter rather than a value that always matches `store.history.get()`. After a rolled-back transaction it can be ahead of the store's counter, and it reports a change even for record types the transaction didn't touch. This also fixes `store.query.ids()` and `store.query.index()` going permanently out of date after a transaction that read them was rolled back. ([#10200](https://github.com/tldraw/tldraw/pull/10200))
37
+ - 💥 **`debugFlags`** no longer includes the unused `reconnectOnPing` and `debugCursors` flags. This also fixes the canvas staying empty when debug mode is turned off with the **Hide shapes** debug flag still on, and stops keys that don't type a character from starting to edit a selected note. ([#10536](https://github.com/tldraw/tldraw/pull/10536))
38
+ - Add `MESSAGE_TOO_LARGE` to `TLSyncErrorCloseEventReason`. A client that sends a message over the size limit now gets this error, instead of getting stuck in a disconnect-and-reconnect loop while the server held the partial message in memory. Clients that switch on the reason to pick an error message will want a case for it. ([#10810](https://github.com/tldraw/tldraw/pull/10810))
39
+ - Add `LruCache.delete(key)` to `@tldraw/utils`. ([#10338](https://github.com/tldraw/tldraw/pull/10338))
40
+ - Add an `AttributionComponent` option to `NoteShapeUtil` to hide or replace the note's "last edited by" badge, on the canvas and in exports. Pass `null` to hide it, or a component that receives `TLNoteShapeAttributionProps`. The default is exported as `DefaultNoteShapeAttribution`. ([#9407](https://github.com/tldraw/tldraw/pull/9407))
16
41
 
17
42
  ```tsx
18
- import { Mark, mergeAttributes } from 'tldraw'
43
+ <Tldraw shapeUtils={[NoteShapeUtil.configure({ AttributionComponent: null })]} />
19
44
  ```
20
45
 
21
- - Add `MESSAGE_TOO_LARGE` to `TLSyncErrorCloseEventReason`. Clients that switch on the reason to pick an error message will want a case for it. ([#10810](https://github.com/tldraw/tldraw/pull/10810))
22
- - Add `LruCache.delete(key)` to `@tldraw/utils`. ([#10338](https://github.com/tldraw/tldraw/pull/10338))
46
+ - `EditorManager.addEditorEvent()` now returns an unsubscribe function, and managers can call the new protected `unregister()` to tear down a resource before the editor is disposed. ([#10732](https://github.com/tldraw/tldraw/pull/10732))
47
+ - `Group2d.transform` now takes the same arguments as `Geometry2d.transform`, and keeps the group's ignored children, flags such as `isInternal`, and any options you pass. ([#10603](https://github.com/tldraw/tldraw/pull/10603))
23
48
 
24
49
  ### Improvements
25
50
 
26
- - `npm create tldraw .` now scaffolds into the current directory, prompting first when the directory isn't empty. ([#10657](https://github.com/tldraw/tldraw/pull/10657))
27
- - Update the AI starter kit templates to current Claude, Gemini, and GPT model ids. ([#10058](https://github.com/tldraw/tldraw/pull/10058))
51
+ - `npm create tldraw .` now scaffolds into the current directory, prompting first when the directory isn't empty, and `create-tldraw -t <template>` no longer crashes on startup. ([#10657](https://github.com/tldraw/tldraw/pull/10657))
52
+ - Update the AI starter kit templates to current Claude, Gemini, and GPT model ids. ([#10058](https://github.com/tldraw/tldraw/pull/10058), [#10869](https://github.com/tldraw/tldraw/pull/10869))
53
+ - Paste a link with a single shape selected to set that shape's link, instead of creating a bookmark or embed. For custom handlers, `TLUrlExternalContent` gains a `shapeId` naming the target shape, which `defaultHandleExternalUrlContent` uses. ([#10765](https://github.com/tldraw/tldraw/pull/10765))
54
+ - Toggle snapping while dragging handles, and wrap mode while brush selecting, with Cmd on Mac and Ctrl elsewhere, the same key used when moving, resizing, and cropping. ([#10172](https://github.com/tldraw/tldraw/pull/10172))
55
+ - The keyboard shortcuts dialog now says when keyboard shortcuts are turned off in accessibility preferences. ([#10532](https://github.com/tldraw/tldraw/pull/10532))
28
56
 
29
57
  ### Bug fixes
30
58
 
31
59
  #### Crashes
32
60
 
33
- - Fix a crash that could replace the editor with the host app's error screen when a group's child record was removed during a transaction. Children that no longer resolve are skipped, and a group where none resolve falls back to a unit box. ([#10668](https://github.com/tldraw/tldraw/pull/10668))
34
- - Fix a crash when a shape is deleted between pointing at it and starting to drag it or one of its handles. ([#10179](https://github.com/tldraw/tldraw/pull/10179))
35
- - Fix a crash when a shape being translated, or the frame it is being dragged over, is deleted mid-drag. ([#10171](https://github.com/tldraw/tldraw/pull/10171))
36
- - Fix draw and highlight shapes created with no segments throwing in geometry and rendering. ([#10224](https://github.com/tldraw/tldraw/pull/10224))
37
- - Fix duplicating a zero-length line throwing. `LineShapeUtil.onBeforeCreate` no longer mutates the caller's points. ([#10248](https://github.com/tldraw/tldraw/pull/10248))
38
- - Fix a line shape with fewer than two points breaking hit testing for the whole page. ([#10222](https://github.com/tldraw/tldraw/pull/10222))
39
- - Fix large rooms failing to load in `InMemorySyncStorage` with a stack overflow. ([#10110](https://github.com/tldraw/tldraw/pull/10110))
61
+ - Fix a rare crash, which could replace the editor with your app's error screen, when a shape inside a group was deleted. A group whose children are all gone now behaves as a small empty box. ([#10668](https://github.com/tldraw/tldraw/pull/10668))
62
+ - Fix a crash when a shape is deleted, for example by a collaborator, between pressing on it and starting to drag it or one of its handles. ([#10179](https://github.com/tldraw/tldraw/pull/10179))
63
+ - Fix a crash when a collaborator deletes a shape you're dragging, or the frame you're dragging it into, before you release it. ([#10171](https://github.com/tldraw/tldraw/pull/10171))
64
+ - Fix `editor.createShape({ type: 'draw' })` or `{ type: 'highlight' }` without any `segments` breaking clicks on the page. The empty shape is now treated as a dot. ([#10224](https://github.com/tldraw/tldraw/pull/10224))
65
+ - Fix duplicating a line whose points are all in the same place throwing an error. `LineShapeUtil.onBeforeCreate` no longer changes the points object you pass in. ([#10248](https://github.com/tldraw/tldraw/pull/10248))
66
+ - Fix a line shape with fewer than two points, such as one created from code or loaded from a file, breaking clicks and hover across the whole page. It now renders as a dot. ([#10222](https://github.com/tldraw/tldraw/pull/10222))
40
67
 
41
68
  #### Selection and tools
42
69
 
43
- - Fix shapes losing changes made by other commands while they are being translated, resized, rotated, or cropped. Pressing the rotate shortcut mid-drag, or a remote update arriving during a gesture, is no longer overwritten by the next pointer move. ([#9215](https://github.com/tldraw/tldraw/pull/9215))
70
+ - Fix changes made during a drag, resize, rotate, or crop being undone by the next pointer move. Pressing the rotate shortcut mid-drag, or a collaborator's edit arriving mid-gesture, now sticks. ([#9215](https://github.com/tldraw/tldraw/pull/9215))
44
71
  - Fix tapping a toolbar tool with a stylus, finger, or trackpad sometimes creating a shape instead of selecting the tool. Dragging a tool out of the toolbar now requires the pointer to leave the toolbar, and sliding along the toolbar no longer starts a drag. ([#10651](https://github.com/tldraw/tldraw/pull/10651))
45
72
  - Fix touch gestures staying stuck when the browser cancels the pointer, as it does for an edge swipe, an incoming call, or palm rejection. ([#10464](https://github.com/tldraw/tldraw/pull/10464))
46
73
  - Fix Tab, Shift+Tab, and Ctrl/Cmd+arrow keyboard traversal selecting locked shapes, which clicking and select all never do. ([#10482](https://github.com/tldraw/tldraw/pull/10482))
47
74
  - Fix the right Shift key not giving the large nudge step when moving shapes with the arrow keys. ([#10477](https://github.com/tldraw/tldraw/pull/10477))
48
75
  - Fix keyboard shape navigation, and `Editor.selectAdjacentShape('prev')`, selecting the second-to-last shape instead of the last one when nothing is selected. ([#10601](https://github.com/tldraw/tldraw/pull/10601))
49
76
  - Fix Ctrl/Cmd+arrow shape navigation preferring a nearer diagonal shape over an aligned one. ([#10339](https://github.com/tldraw/tldraw/pull/10339))
50
- - Fix pointer downs inside a rotated multi-selection dragging the wrong shapes, and clicking a selected locked shape with `selectLockedShapes` selecting the shape behind it. ([#10166](https://github.com/tldraw/tldraw/pull/10166))
51
- - Fix the select tool bailing to an old history mark, or crashing, when a resize starts with nothing selected. ([#10165](https://github.com/tldraw/tldraw/pull/10165))
52
- - Fix the select tool getting stuck after pressing an arrow label in a read-only editor or on a deleted arrow. ([#10183](https://github.com/tldraw/tldraw/pull/10183))
53
- - Use Cmd (Mac) or Ctrl to toggle snapping while dragging handles and wrap mode while brush selecting, matching translate, resize, and crop. ([#10172](https://github.com/tldraw/tldraw/pull/10172))
54
- - Fix cancelling a note clone-handle drag leaving the new note behind and switching to the note tool. ([#10187](https://github.com/tldraw/tldraw/pull/10187))
55
- - Fix the toolbar losing the originating tool's highlight while zooming with Z, and the zoom tool staying on when Z was pressed straight after clicking a toolbar button. ([#10185](https://github.com/tldraw/tldraw/pull/10185))
77
+ - Fix dragging inside a rotated multi-selection sometimes grabbing only the shape under the cursor instead of moving the whole selection, and clicking an already-selected locked shape with `selectLockedShapes` on selecting the shape behind it. ([#10166](https://github.com/tldraw/tldraw/pull/10166))
78
+ - Fix a resize crashing, or undoing your previous resize and everything after it, when a collaborator deleted the shape between your press on the handle and the start of the drag. ([#10165](https://github.com/tldraw/tldraw/pull/10165))
79
+ - Fix the select tool becoming unresponsive after clicking an arrow's label in a read-only editor, or on an arrow that was deleted as you clicked. ([#10183](https://github.com/tldraw/tldraw/pull/10183))
80
+ - Fix pressing Escape while dragging a new note out of a note's clone handle leaving the new note behind and switching to the note tool. The new note is now removed and you stay in the select tool. ([#10187](https://github.com/tldraw/tldraw/pull/10187))
81
+ - Fix two glitches when holding Z to zoom: the toolbar stopped highlighting the tool you were using, and pressing Z straight after clicking a toolbar button left the zoom tool stuck on. ([#10185](https://github.com/tldraw/tldraw/pull/10185))
56
82
  - Fix the **Frame selection** action and shortcut doing nothing when a single shape is selected. Locked shapes, and arrows bound to shapes outside the new frame, are now left out of it. ([#10627](https://github.com/tldraw/tldraw/pull/10627))
57
- - Fix the enlarge and shrink shortcuts moving shapes away from the original selection's center when several shapes are selected. ([#10070](https://github.com/tldraw/tldraw/pull/10070))
58
- - Fix selecting arrows and hollow shapes larger than the viewport by clicking their edges. ([#10333](https://github.com/tldraw/tldraw/pull/10333))
59
- - Fix `Editor.animateShapes` moving locked shapes, and apply ancestor-lock semantics to delete, duplicate, group, and ungroup. ([#10334](https://github.com/tldraw/tldraw/pull/10334))
60
- - Fix `groupShapes` throwing for locked selections or orphaning shapes at the page limit, `ungroupShapes` deleting nested children, and both commands ignoring calls made outside the select tool. ([#10330](https://github.com/tldraw/tldraw/pull/10330))
83
+ - Fix the enlarge and shrink shortcuts pulling shapes apart when several shapes are selected. The selection now scales about its original center. ([#10070](https://github.com/tldraw/tldraw/pull/10070))
84
+ - Fix clicking the edge of an arrow or hollow shape that's larger than the screen not selecting it. ([#10333](https://github.com/tldraw/tldraw/pull/10333))
85
+ - Fix `Editor.animateShapes` moving locked shapes. Deleting, duplicating, grouping, and ungrouping now also skip shapes inside a locked frame or group, matching `updateShapes`. ([#10334](https://github.com/tldraw/tldraw/pull/10334))
86
+ - Fix the select tool getting stuck mid-drag when a custom tool creates a shape and hands it over for dragging without an `onCreate` callback. ([#10190](https://github.com/tldraw/tldraw/pull/10190))
87
+ - Fix quickly pressing a resize, rotate, or crop handle twice, or an image being cropped, counting as a double click instead of letting the second press drag. ([#10176](https://github.com/tldraw/tldraw/pull/10176))
88
+ - Fix the wrong cursor showing, and the select tool staying active in the background, after finishing a text edit with the text tool locked. ([#10174](https://github.com/tldraw/tldraw/pull/10174))
89
+ - Fix cropping an image inside a rotated frame or group moving the crop, and nudging it, along the wrong axis. ([#10170](https://github.com/tldraw/tldraw/pull/10170))
90
+ - Fix a handle drag sometimes switching to precise arrow binding on its own, because a timer from the previous drag was still running. ([#10164](https://github.com/tldraw/tldraw/pull/10164))
91
+ - Fix three stylus issues: in pen mode, a palm resting on the screen could disturb the pen's stroke; double clicks with a desktop graphics tablet pen weren't detected; and pressing a stylus's eraser button crashed editors that don't include the eraser tool. ([#10346](https://github.com/tldraw/tldraw/pull/10346))
92
+ - Fix shapes snapping to hidden shapes, and handles snapping to a note's text label instead of its edges. Gap snapping also now behaves the same horizontally and vertically. ([#10331](https://github.com/tldraw/tldraw/pull/10331))
93
+ - Fix several grouping bugs: grouping a selection that included locked shapes could throw, grouping at the page's shape limit made the shapes vanish, ungrouping nested groups deleted the inner group's children, and `groupShapes` and `ungroupShapes` did nothing when called while a tool other than select was active. ([#10330](https://github.com/tldraw/tldraw/pull/10330))
61
94
 
62
95
  #### Camera and viewport
63
96
 
64
97
  - Fix the camera not panning to a note created with Tab, Ctrl/Cmd+Enter, or a note's clone handle when the new note landed outside the viewport. ([#10486](https://github.com/tldraw/tldraw/pull/10486))
65
- - Fix camera coasting after a fling, and edge scrolling, running roughly twice as fast on a 120 Hz display as on a 60 Hz one. Both now scale by the elapsed tick time, so motion per second is the same at any refresh rate. ([#10501](https://github.com/tldraw/tldraw/pull/10501))
66
- - Fix a click landing during a camera animation or a fling being treated as a drag. ([#10714](https://github.com/tldraw/tldraw/pull/10714))
98
+ - Fix camera coasting after a fling, and edge scrolling, running roughly twice as fast on a 120 Hz display as on a 60 Hz one. Both now move at the same speed at any refresh rate. ([#10501](https://github.com/tldraw/tldraw/pull/10501))
99
+ - Fix a click made while the camera is moving, such as during a pan to a new note or the glide after a fling, being treated as a drag. ([#10714](https://github.com/tldraw/tldraw/pull/10714))
100
+ - Fix three camera input issues: the space bar and arrow keys still panned a locked camera, pinching a locked camera acted on the current tool, and the input device preference turned wheel input back on when `wheelBehavior` is `'none'`. ([#10348](https://github.com/tldraw/tldraw/pull/10348))
67
101
  - Fix `setCamera` resetting the zoom to 100% when called with a plain `{ x, y }` point. ([#10385](https://github.com/tldraw/tldraw/pull/10385))
68
- - Fix forced animated camera moves snapping back inside the camera constraints on their last frame. ([#10386](https://github.com/tldraw/tldraw/pull/10386))
69
- - Fix a viewport deep link with a zero-size viewport moving the camera to the page origin instead of falling back to fitting the page content. ([#10628](https://github.com/tldraw/tldraw/pull/10628))
102
+ - Fix animated camera moves made with `force: true` jumping back inside the camera constraints on their last frame. ([#10386](https://github.com/tldraw/tldraw/pull/10386))
103
+ - Fix a deep link with a zero-width or zero-height viewport moving the camera to the page's top-left corner. The link is now ignored and the editor zooms to fit the page content. ([#10628](https://github.com/tldraw/tldraw/pull/10628))
70
104
 
71
105
  #### Arrows and shapes
72
106
 
73
- - Fix arrow clusters in the stack, pack, and distribute commands depending on selection order, so an arrow selected before the shapes it binds no longer moves separately from them. ([#10382](https://github.com/tldraw/tldraw/pull/10382))
74
- - Fix arrow bindings flip-flopping while resizing a bound shape together with its arrow. ([#10197](https://github.com/tldraw/tldraw/pull/10197))
107
+ - Fix the stack, pack, and distribute commands moving an arrow separately from the shapes it connects when the arrow was selected before them. ([#10382](https://github.com/tldraw/tldraw/pull/10382))
108
+ - Fix an arrow's ends flipping back and forth when you resize it together with a shape it's bound to and drag past the opposite edge. ([#10197](https://github.com/tldraw/tldraw/pull/10197))
75
109
  - Fix rotated images jumping on the canvas when their aspect ratio or crop zoom changed, or when the image was replaced. ([#10233](https://github.com/tldraw/tldraw/pull/10233))
76
110
  - Fix image and video shapes keeping a removed asset on screen. ([#10250](https://github.com/tldraw/tldraw/pull/10250))
77
- - Fix line animations dropping points when the target line has more points than the starting one. ([#10247](https://github.com/tldraw/tldraw/pull/10247))
78
- - Fix highlight shape animations switching to the end shape's props immediately instead of interpolating from the nearer shape. ([#10246](https://github.com/tldraw/tldraw/pull/10246))
79
- - Fix draw shapes closing one update late when drawn with straight segments. ([#10242](https://github.com/tldraw/tldraw/pull/10242))
80
- - Fix the draw tool freezing the stroke after a quick Shift release during a straight segment. ([#10239](https://github.com/tldraw/tldraw/pull/10239))
111
+ - Fix the attached end of an arrow moving by the wrong amount when you drag a rotated arrow, or move an arrow with the arrow keys or from code. ([#10198](https://github.com/tldraw/tldraw/pull/10198))
112
+ - Fix short draw strokes that include straight segments, drawn by holding Shift, closing into a loop as if they were long strokes. ([#10241](https://github.com/tldraw/tldraw/pull/10241))
113
+ - Fix the opposite edge of a geo shape with a scale other than 1 moving when you resize it past the minimum size its label allows. ([#10217](https://github.com/tldraw/tldraw/pull/10217))
114
+ - Fix points disappearing partway through animating a line to one with more points. ([#10247](https://github.com/tldraw/tldraw/pull/10247))
115
+ - Fix animated highlight shapes switching to the end shape's color and size at the start of the animation instead of halfway through. ([#10246](https://github.com/tldraw/tldraw/pull/10246))
116
+ - Fix draw strokes with straight segments ignoring the newest point when checking whether the stroke has closed, so they closed one update late. ([#10242](https://github.com/tldraw/tldraw/pull/10242))
117
+ - Fix a draw stroke freezing when you release Shift quickly after starting a straight segment. ([#10239](https://github.com/tldraw/tldraw/pull/10239))
81
118
  - Fix notes created inside a rotated frame appearing off-centre from the click. ([#10235](https://github.com/tldraw/tldraw/pull/10235))
82
119
  - Fix a bookmark keeping its old preview after its url changes. ([#10208](https://github.com/tldraw/tldraw/pull/10208))
83
120
  - Fix a frame's contents jumping when double-clicking a frame edge to fit it to its children. ([#10206](https://github.com/tldraw/tldraw/pull/10206))
@@ -85,52 +122,59 @@ This release is a broad reliability pass over the SDK. Shapes keep changes made
85
122
 
86
123
  #### Editor
87
124
 
88
- - Fix keyboard shortcuts being unable to bind the `+` key (`cmd++` was silently dropped and rendered as a bare modifier) and `shift+<glyph>` shortcuts such as `shift+:` never firing when the browser reports `:` with shift held. ([#10512](https://github.com/tldraw/tldraw/pull/10512))
125
+ - Fix keyboard shortcuts that use the `+` key, such as `cmd++`, being dropped, and shortcuts that use a shifted character, such as `shift+:`, never firing. ([#10512](https://github.com/tldraw/tldraw/pull/10512))
89
126
  - Fix undo after switching pages from the page menu or with Alt+arrow also reverting the edit made before the switch. Switching pages is now its own undo step, matching the "Go back" button on the move-to-page toast. ([#10472](https://github.com/tldraw/tldraw/pull/10472))
90
- - Fix `TldrawEditor` recreating the editor when it re-renders with inline nested `camera`, `deepLinks`, `text`, or `gridSteps` options. ([#10373](https://github.com/tldraw/tldraw/pull/10373))
91
- - Fix preserve-focus mode blurring the editor on canvas clicks. ([#10374](https://github.com/tldraw/tldraw/pull/10374))
92
- - Fix double-clicking a custom shape that allows read-only editing doing nothing in a read-only editor. The gate now consults `ShapeUtil.canEditInReadonly` instead of a hard-coded list of shape types. ([#10173](https://github.com/tldraw/tldraw/pull/10173))
93
- - Fix binding and document-settings mutations going through in readonly mode, and index self-referential bindings once. ([#10340](https://github.com/tldraw/tldraw/pull/10340))
127
+ - Fix the editor being thrown away and recreated on every re-render when `TldrawEditor`'s `options` prop is written inline with nested `camera`, `deepLinks`, `text`, or `gridSteps` objects. ([#10373](https://github.com/tldraw/tldraw/pull/10373))
128
+ - Fix clicks on the canvas doing nothing in preserve-focus mode (`autoFocus` with `noAutoFocus()`), because the editor was focused and then immediately blurred. ([#10374](https://github.com/tldraw/tldraw/pull/10374))
129
+ - Fix double-clicking a custom shape that allows read-only editing doing nothing in a read-only editor. The editor now checks `ShapeUtil.canEditInReadonly` instead of a fixed list of shape types. ([#10173](https://github.com/tldraw/tldraw/pull/10173))
130
+ - Fix a read-only editor still letting code create, update, or delete bindings and change document settings. Also fix a binding from a shape to itself firing its change callbacks twice. ([#10340](https://github.com/tldraw/tldraw/pull/10340))
94
131
  - Fix selected text disappearing when a whole list is selected, such as by triple-clicking its bullet. ([#10808](https://github.com/tldraw/tldraw/pull/10808))
95
- - Fix text measurement for elements containing more than one text node. ([#10357](https://github.com/tldraw/tldraw/pull/10357))
96
- - Fix a license key that arrives after the first render being ignored, and stop watermark tracking failures surfacing as unhandled rejections. ([#10327](https://github.com/tldraw/tldraw/pull/10327))
97
- - Fix copied content dropping assets the asset store can't resolve. ([#10366](https://github.com/tldraw/tldraw/pull/10366))
98
- - Fix asset store removal errors in `deleteAssets` becoming unhandled rejections. They are now logged. ([#10368](https://github.com/tldraw/tldraw/pull/10368))
99
- - Fix geometry hit tests, nearest-point, and length calculations losing precision after a shape's SVG path data was generated. `getSvgPathData` rounded the geometry's stored points to two decimals in place, and geometries are cached per shape, so every later calculation used the rounded points. ([#10600](https://github.com/tldraw/tldraw/pull/10600))
100
- - Fix `Editor.getCurrentTheme()` returning `undefined` after `setCurrentTheme()` was called with an unregistered theme id. The call is now rejected and the current theme is kept. ([#10602](https://github.com/tldraw/tldraw/pull/10602))
101
- - Fix `Group2d.transform` dropping its ignored children, resetting the `isInternal`, `excludeFromShapeBounds`, and `isEmptyLabel` flags, and discarding its `opts` argument. It now matches the base `Geometry2d.transform` signature. ([#10603](https://github.com/tldraw/tldraw/pull/10603))
132
+ - Fix text measurement throwing, or measuring the wrong characters, in elements with more than one text node. ([#10357](https://github.com/tldraw/tldraw/pull/10357))
133
+ - Fix a license key passed after the editor first renders being ignored, and stop failures in watermark tracking showing up as unhandled promise rejections. ([#10327](https://github.com/tldraw/tldraw/pull/10327))
134
+ - Fix copying content dropping images and other assets that your asset store can't resolve. They're now copied unchanged. ([#10366](https://github.com/tldraw/tldraw/pull/10366))
135
+ - Fix an error from your asset store's `remove` method becoming an unhandled promise rejection when `deleteAssets` runs. It's now logged instead. ([#10368](https://github.com/tldraw/tldraw/pull/10368))
136
+ - Fix hit testing and distance and length calculations on a shape's geometry losing precision after `getSvgPathData` was called on it, which rounded the geometry's stored points to two decimals. ([#10600](https://github.com/tldraw/tldraw/pull/10600))
137
+ - Fix `Editor.getCurrentTheme()` returning `undefined` after `setCurrentTheme()` was called with a theme id that isn't registered. The call is now ignored and the current theme stays. ([#10602](https://github.com/tldraw/tldraw/pull/10602))
138
+ - Fix `editor.timers` holding on to the id of every timer ever set, so its memory grew for as long as the editor lived. ([#10782](https://github.com/tldraw/tldraw/pull/10782))
139
+ - Fix the debug menu's hard reset running without confirmation and stalling when another tldraw tab is open. ([#10529](https://github.com/tldraw/tldraw/pull/10529))
102
140
  - Fix embed hostname matching trusting lookalike hosts such as `tldraw.com.evil.io`, which were rendered with the matched definition's relaxed iframe permissions. A host must now be the pattern itself or a subdomain of it. ([#10196](https://github.com/tldraw/tldraw/pull/10196))
103
141
 
104
142
  #### Exports
105
143
 
106
- - Fix exports resolving with a partial image when a shape's `toSvg` throws. Exports now fail fast, custom frame-like shapes export without the default frame util, and trimming an SVG export no longer allocates an oversized measurement canvas. ([#10342](https://github.com/tldraw/tldraw/pull/10342))
107
- - Fix exports missing resources and fonts: styles with several urls, font lists, and bare `@import` rules are now all embedded, failed fetches are retried, and stylesheets that import each other no longer hang the export. ([#10338](https://github.com/tldraw/tldraw/pull/10338))
108
- - Fix a failed animated-image or video export hanging every later export of the same asset, because the rejected promise was memoized. ([#10226](https://github.com/tldraw/tldraw/pull/10226))
144
+ - Fix an export waiting until it timed out and returning an empty image when a shape's `toSvg` throws. It now fails straight away with the error. ([#10342](https://github.com/tldraw/tldraw/pull/10342))
145
+ - Fix exported SVGs and PNGs missing images and fonts referenced from CSS, such as values with several urls, font-family lists, and `@import` rules. ([#10338](https://github.com/tldraw/tldraw/pull/10338))
146
+ - Fix every export of an animated GIF or video hanging after one export of it failed, for example because the file was blocked or missing. ([#10226](https://github.com/tldraw/tldraw/pull/10226))
109
147
 
110
148
  #### Store and signals
111
149
 
112
- - Fix effects losing a dependency when a set during their first run re-triggered them. ([#10146](https://github.com/tldraw/tldraw/pull/10146))
113
- - Fix a side-effect handler being skipped when the previous handler for the same event removes itself while running. ([#10231](https://github.com/tldraw/tldraw/pull/10231))
114
- - Fix store changes made in the same frame as `dispose()` never reaching listeners. ([#10223](https://github.com/tldraw/tldraw/pull/10223))
115
- - Fix a throwing store listener stopping the other listeners from receiving the same change-set. ([#10216](https://github.com/tldraw/tldraw/pull/10216))
116
- - Fix `store.query.ids()` and `store.query.index()` staying stale after a query was read inside a transaction that then rolled back. ([#10200](https://github.com/tldraw/tldraw/pull/10200))
150
+ - Fix an effect (from `react()`, `reactor.start()`, or `useQuickReactor`) that sets a value it depends on during its first run silently stopping reacting to one of its dependencies. ([#10146](https://github.com/tldraw/tldraw/pull/10146))
151
+ - Fix a side-effect handler being skipped when the handler registered before it removes itself while running. ([#10231](https://github.com/tldraw/tldraw/pull/10231))
152
+ - Fix store changes made just before `store.dispose()` never reaching listeners. ([#10223](https://github.com/tldraw/tldraw/pull/10223))
153
+ - Fix one store listener throwing an error stopping the other listeners from hearing about the same changes. ([#10216](https://github.com/tldraw/tldraw/pull/10216))
117
154
 
118
155
  #### Persistence and sync
119
156
 
157
+ - Fix very large rooms, around 120,000 records, failing to open with `InMemorySyncStorage` because of a stack overflow. ([#10110](https://github.com/tldraw/tldraw/pull/10110))
158
+ - Fix the sync client crashing while reconnecting in browsers where the global `WebSocket` has been removed, for example by a browser extension. ([#10783](https://github.com/tldraw/tldraw/pull/10783))
120
159
  - Fix local persistence silently dropping edits: changes another tab made while this one was still loading, edits queued in the last few hundred milliseconds before unmount, and writes still in flight when the database closed. ([#10332](https://github.com/tldraw/tldraw/pull/10332))
121
- - Fix sync stalling permanently when `getUri` rejected, which in the documented `useSync` pattern is an auth-token fetch. A rejected `getUri` is now retried on the normal backoff, and a closed `ClientWebSocketAdapter` no longer notifies listeners or reconnects after disposal. ([#10107](https://github.com/tldraw/tldraw/pull/10107))
160
+ - Fix sync giving up for good when fetching the connection url failed, for example when the auth-token request in the usual `useSync` setup failed once. It now retries with the normal backoff, and a sync client that has been closed no longer tries to reconnect. ([#10107](https://github.com/tldraw/tldraw/pull/10107))
161
+ - Fix each tab's session state, such as its camera and selection, piling up in IndexedDB forever. Rows for old tabs are now cleared on load. ([#10533](https://github.com/tldraw/tldraw/pull/10533))
162
+ - Fix a rare server-side case where a client removed while it was still connecting came back as a broken session and later triggered a second `session_removed` event. ([#10121](https://github.com/tldraw/tldraw/pull/10121))
122
163
  - Fix `useSync` still reporting a previous room's error after the `uri` changed to a new, healthy room. ([#10108](https://github.com/tldraw/tldraw/pull/10108))
123
- - Fix oversized chunked sync messages being buffered indefinitely. Assembly is now bounded by a size and chunk-count limit, and a message that exceeds it fails with a `MESSAGE_TOO_LARGE` sync error instead of disconnecting the client in a loop. ([#10810](https://github.com/tldraw/tldraw/pull/10810))
124
- - Fix `TLSocketRoom.closeSession` leaving the socket open when the close reason is over 123 bytes. The reason is now truncated and ends with `... (+N bytes)`. ([#10116](https://github.com/tldraw/tldraw/pull/10116))
125
- - Fix `TLSocketRoom.updateStore` not seeing or deleting object-lane records. ([#10114](https://github.com/tldraw/tldraw/pull/10114))
126
- - Fix authorizer errors and vetoes being swallowed when `TLSocketRoom` was created without a `log` option. ([#10117](https://github.com/tldraw/tldraw/pull/10117))
127
- - Fix text arriving corrupted when a message chunk boundary split a surrogate pair, such as an emoji. ([#10119](https://github.com/tldraw/tldraw/pull/10119))
128
- - Fix `TLSyncRoom.close()` leaving per-session timers that could send into closed sockets or emit `session_removed` and `room_became_empty` on a closed room. A socket that throws on close no longer leaves the rest open. ([#10120](https://github.com/tldraw/tldraw/pull/10120))
129
- - Fix `SQLiteSyncStorage` tombstone pruning throwing from a timer after the host closed the database, and make the prune transactional so a failure part-way cannot leave the history start ahead of the surviving tombstones. ([#10112](https://github.com/tldraw/tldraw/pull/10112))
164
+ - Fix `TLSocketRoom.closeSession` failing to close the socket when the close reason is longer than 123 bytes, the WebSocket limit. The reason is now shortened to fit. ([#10116](https://github.com/tldraw/tldraw/pull/10116))
165
+ - Fix `TLSocketRoom.updateStore` not being able to read or delete records served through the room's object-store lane, such as comments. ([#10114](https://github.com/tldraw/tldraw/pull/10114))
166
+ - Fix errors and rejections from your `TLSocketRoom` authorizer being silently swallowed when the room was created without a `log` option. They're now logged to the console. ([#10117](https://github.com/tldraw/tldraw/pull/10117))
167
+ - Fix emoji and some other characters arriving corrupted when a large sync message was split into chunks in the middle of one. ([#10119](https://github.com/tldraw/tldraw/pull/10119))
168
+ - Fix a closed `TLSyncRoom` still firing `session_removed` and `room_became_empty` events, and throwing from timers as it tried to send to closed sockets. One socket failing to close no longer leaves the others open. ([#10120](https://github.com/tldraw/tldraw/pull/10120))
169
+ - Fix `SQLiteSyncStorage` throwing an uncaught error when the database was closed right after a delete. Pruning tombstones, the markers left by deleted records, is now all-or-nothing, so a failure part-way can't leave the room's history inconsistent. ([#10112](https://github.com/tldraw/tldraw/pull/10112))
130
170
 
131
171
  #### Mermaid conversion
132
172
 
133
173
  - Fix converted sequence diagrams crowding tall notes, fragment titles, and participants that are created and destroyed close together. Rows are now placed where mermaid drew them rather than on an even grid. ([#10817](https://github.com/tldraw/tldraw/pull/10817))
174
+ - Fix sequence diagrams with a created or destroyed participant being drawn much taller than they should be. ([#10822](https://github.com/tldraw/tldraw/pull/10822))
175
+ - Fix long participant names and notes in sequence diagrams wrapping or breaking mid-word. ([#10806](https://github.com/tldraw/tldraw/pull/10806))
176
+ - Fix several edges between the same two nodes swapping each other's curves. ([#10826](https://github.com/tldraw/tldraw/pull/10826))
177
+ - Fix flowchart and state diagram edge labels rendering a size smaller than node labels. ([#10804](https://github.com/tldraw/tldraw/pull/10804))
134
178
  - Fix sequence diagram participant boxes being dropped, along with their labels and colors, on conversion. ([#10813](https://github.com/tldraw/tldraw/pull/10813))
135
179
  - Fix sequence diagrams dropping a participant's bottom box, and tilting their arrows, when the source uses `destroy`. ([#10750](https://github.com/tldraw/tldraw/pull/10750))
136
180
  - Fix self-loops in flowcharts and state diagrams drawing their label on top of the node. ([#10773](https://github.com/tldraw/tldraw/pull/10773))
@@ -140,7 +184,6 @@ This release is a broad reliability pass over the SDK. Shapes keep changes made
140
184
  #### CLI
141
185
 
142
186
  - Fix `create-tldraw --no-telemetry` being ignored. ([#10789](https://github.com/tldraw/tldraw/pull/10789))
143
- - Fix `create-tldraw -t <template>` crashing on startup. ([#10657](https://github.com/tldraw/tldraw/pull/10657))
144
187
 
145
188
  ## v5.4.0
146
189
 
@@ -325,6 +368,12 @@ This release adds a `center` operation to `Editor.alignShapes`, a `tleditors` re
325
368
 
326
369
  [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v5.4.1)
327
370
 
371
+ #### v5.4.2
372
+
373
+ - Declare the MIT license in the `@tldraw/utils` and `@tldraw/validate` package metadata. ([#10738](https://github.com/tldraw/tldraw/pull/10738))
374
+
375
+ [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v5.4.2)
376
+
328
377
  ## v5.3.0
329
378
 
330
379
  [View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v5.3.0)
@@ -913,7 +962,7 @@ Note shapes now track and display a "first edited by" attribution label in the b
913
962
  <details>
914
963
  <summary>Migration guide</summary>
915
964
 
916
- **`useTldrawUser` has been removed.** Previously it bundled user *preferences* (color, color scheme) and user *identity* (id, name) into a single object. These are now separate concerns:
965
+ **`useTldrawUser` has been removed.** Previously it bundled user _preferences_ (color, color scheme) and user _identity_ (id, name) into a single object. These are now separate concerns:
917
966
 
918
967
  - **Preferences** (color, color scheme, snap mode, etc.) are managed via `TLUserPreferences`. Set them with the editor's user-preferences API directly.
919
968
  - **Identity** for attribution comes from a `TLUserStore` provider passed to the new `users` prop on `<Tldraw>`.
@@ -1549,7 +1598,7 @@ See the [Custom Shapes Guide](https://tldraw.dev/docs/shapes#Custom-shapes) and
1549
1598
  **Use `as const` on the static `type` field.** TypeScript may widen `static override type = 'my-shape'` to `string`, which fails the new constraint. Add `as const` to keep it a string literal:
1550
1599
 
1551
1600
  ```ts
1552
- class MyShapeUtil extends ShapeUtil`<MyShape>` {
1601
+ class MyShapeUtil extends (ShapeUtil`<MyShape>`) {
1553
1602
  static override type = 'my-shape' as const
1554
1603
  // ...
1555
1604
  }
@@ -1791,9 +1840,9 @@ We've upgraded TipTap from v2 to v3. If you've done any customization to our sta
1791
1840
  <details>
1792
1841
  <summary>Migration guide</summary>
1793
1842
 
1794
- Starting in v4.2, tldraw bundles TipTap v3 as a transitive dependency. If your project pins `@tiptap/*` v2 packages directly, upgrade them to v3 *before* trying to fix any code-level errors — leaving v2 in place produces a dual install that surfaces as confusing type errors.
1843
+ Starting in v4.2, tldraw bundles TipTap v3 as a transitive dependency. If your project pins `@tiptap/*` v2 packages directly, upgrade them to v3 _before_ trying to fix any code-level errors — leaving v2 in place produces a dual install that surfaces as confusing type errors.
1795
1844
 
1796
- **Dual-install symptom.** Deeply-nested errors like *"Property 'getCharacterCount' is missing in type 'Editor' but required in type 'Editor'"*, with the two `Editor` types resolving to different paths (one under `node_modules/@tiptap/core`, the other under `node_modules/@tldraw/editor/node_modules/@tiptap/core`), are not API changes — they are the v2/v3 dual install. The `Editor` classes are structurally similar but nominally different. Finishing the v3 upgrade collapses the duplicate and these errors disappear without code changes.
1845
+ **Dual-install symptom.** Deeply-nested errors like _"Property 'getCharacterCount' is missing in type 'Editor' but required in type 'Editor'"_, with the two `Editor` types resolving to different paths (one under `node_modules/@tiptap/core`, the other under `node_modules/@tldraw/editor/node_modules/@tiptap/core`), are not API changes — they are the v2/v3 dual install. The `Editor` classes are structurally similar but nominally different. Finishing the v3 upgrade collapses the duplicate and these errors disappear without code changes.
1797
1846
 
1798
1847
  **Code-level changes that affect tldraw users:**
1799
1848
 
@@ -1814,7 +1863,9 @@ Starting in v4.2, tldraw bundles TipTap v3 as a transitive dependency. If your p
1814
1863
  ```ts
1815
1864
  import { EditorEvents } from '@tiptap/core'
1816
1865
  // ...
1817
- onTransaction: (props: EditorEvents['transaction']) => { /* ... */ }
1866
+ onTransaction: (props: EditorEvents['transaction']) => {
1867
+ /* ... */
1868
+ }
1818
1869
  ```
1819
1870
 
1820
1871
  - **Custom chained commands** still register via `declare module '@tiptap/core'` augmentation in v3 — the augmentation target is the same.
@@ -26,10 +26,9 @@ import { getSchema } from '@tiptap/core';
26
26
  import { Group2d } from '@tldraw/editor';
27
27
  import { HandleSnapGeometry } from '@tldraw/editor';
28
28
  import { HTMLAttributes } from 'react';
29
- import { IndexKey } from '@tldraw/utils';
30
- import { IndexKey as IndexKey_2 } from '@tldraw/editor';
29
+ import { IndexKey } from '@tldraw/editor';
31
30
  import { JSONContent } from '@tiptap/core';
32
- import { JsonObject } from '@tldraw/utils';
31
+ import { JsonObject } from '@tldraw/editor';
33
32
  import { JSX } from 'react/jsx-runtime';
34
33
  import { JSXElementConstructor } from 'react';
35
34
  import { LANGUAGES } from '@tldraw/editor';
@@ -174,7 +173,7 @@ import { TLUserId } from '@tldraw/editor';
174
173
  import { TLVideoAsset } from '@tldraw/editor';
175
174
  import { TLVideoShape } from '@tldraw/editor';
176
175
  import { UnknownRecord } from '@tldraw/editor';
177
- import { Validator } from '@tldraw/validate';
176
+ import { Validator } from '@tldraw/editor';
178
177
  import { Vec } from '@tldraw/editor';
179
178
  import { VecLike } from '@tldraw/editor';
180
179
  import { VecModel } from '@tldraw/editor';
@@ -3065,7 +3064,7 @@ export declare class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
3065
3064
  toSvg(shape: TLNoteShape, ctx: SvgExportContext): JSX.Element;
3066
3065
  onBeforeCreate(next: TLNoteShape): {
3067
3066
  id: TLShapeId;
3068
- index: IndexKey_2;
3067
+ index: IndexKey;
3069
3068
  isLocked: boolean;
3070
3069
  meta: JsonObject;
3071
3070
  opacity: TLOpacityType;
package/dist-cjs/index.js CHANGED
@@ -666,7 +666,7 @@ var import_buildFromV1Document = require("./lib/utils/tldr/buildFromV1Document")
666
666
  var import_file = require("./lib/utils/tldr/file");
667
667
  (0, import_editor.registerTldrawLibraryVersion)(
668
668
  "tldraw",
669
- "5.5.0",
669
+ "5.6.0-canary.07d34be92012",
670
670
  "cjs"
671
671
  );
672
672
  //# sourceMappingURL=index.js.map
@@ -25,7 +25,7 @@ var import_editor = require("@tldraw/editor");
25
25
  var import_state = require("@tldraw/state");
26
26
  class ShapeIndicatorOverlayUtil extends import_editor.OverlayUtil {
27
27
  static type = "shape_indicator";
28
- options = { zIndex: 50, lineWidth: 1.5, hintedLineWidth: 2.5 };
28
+ options = { zIndex: 50, lineWidth: 1.5, hintedLineWidth: 2 };
29
29
  // Narrow projection of instance state. Reading the full record would
30
30
  // re-fire getOverlays on every cursor move / brush update; gating on these
31
31
  // three booleans means we only re-fire when one of them actually flips.