tldraw 4.3.0-canary.fd6b7f2a8adc → 4.3.0-next.2b3bfbba757b

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 (202) hide show
  1. package/dist-cjs/index.d.ts +5 -14
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  5. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  6. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  7. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  9. package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/shared.js.map +2 -2
  11. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  12. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  13. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
  14. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
  16. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  17. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  18. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  19. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  20. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  21. package/dist-cjs/lib/shapes/shared/crop.js +0 -1
  22. package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
  23. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  24. package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
  25. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  26. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  27. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  28. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +4 -1
  29. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  30. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  31. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  32. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +1 -1
  33. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  34. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  35. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  36. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  37. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  38. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  39. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  40. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
  41. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  42. package/dist-cjs/lib/ui/components/EditLinkDialog.js +1 -11
  43. package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
  44. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  45. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  46. package/dist-cjs/lib/ui/context/actions.js +2 -1
  47. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  48. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  49. package/dist-cjs/lib/ui/hooks/useFlatten.js.map +2 -2
  50. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  51. package/dist-cjs/lib/ui/version.js +3 -3
  52. package/dist-cjs/lib/ui/version.js.map +1 -1
  53. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +0 -8
  54. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  55. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  56. package/dist-cjs/lib/utils/frames/frames.js.map +2 -2
  57. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  58. package/dist-esm/index.d.mts +5 -14
  59. package/dist-esm/index.mjs +1 -1
  60. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  61. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  62. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  63. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  64. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  65. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  66. package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +2 -2
  67. package/dist-esm/lib/shapes/arrow/shared.mjs.map +2 -2
  68. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  69. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  70. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
  71. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  72. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
  73. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  74. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  75. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  76. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  77. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  78. package/dist-esm/lib/shapes/shared/crop.mjs +0 -1
  79. package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
  80. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  81. package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
  82. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  83. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  84. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +4 -1
  85. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  86. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +4 -1
  87. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  88. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  89. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  90. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +1 -1
  91. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  92. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  93. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  94. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  95. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +4 -1
  96. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  97. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  98. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  99. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
  100. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  101. package/dist-esm/lib/ui/components/EditLinkDialog.mjs +1 -11
  102. package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
  103. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  104. package/dist-esm/lib/ui/components/menu-items.mjs +4 -1
  105. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  106. package/dist-esm/lib/ui/context/actions.mjs +2 -1
  107. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  108. package/dist-esm/lib/ui/hooks/menu-hooks.mjs +4 -1
  109. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  110. package/dist-esm/lib/ui/hooks/useFlatten.mjs.map +2 -2
  111. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  112. package/dist-esm/lib/ui/version.mjs +3 -3
  113. package/dist-esm/lib/ui/version.mjs.map +1 -1
  114. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +0 -8
  115. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  116. package/dist-esm/lib/utils/export/exportAs.mjs +3 -1
  117. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  118. package/dist-esm/lib/utils/frames/frames.mjs.map +2 -2
  119. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  120. package/package.json +10 -10
  121. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +1 -1
  122. package/src/lib/canvas/TldrawSelectionForeground.tsx +9 -4
  123. package/src/lib/defaultExternalContentHandlers.ts +4 -3
  124. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +2 -2
  125. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +1 -1
  126. package/src/lib/shapes/arrow/arrowLabel.ts +1 -1
  127. package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
  128. package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +3 -3
  129. package/src/lib/shapes/arrow/shared.ts +4 -4
  130. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +1 -1
  131. package/src/lib/shapes/bookmark/bookmarks.ts +3 -3
  132. package/src/lib/shapes/draw/toolStates/Drawing.ts +4 -4
  133. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  134. package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
  135. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +2 -10
  136. package/src/lib/shapes/geo/toolStates/Pointing.ts +3 -3
  137. package/src/lib/shapes/line/LineShapeTool.test.ts +6 -6
  138. package/src/lib/shapes/line/LineShapeUtil.test.tsx +5 -5
  139. package/src/lib/shapes/line/toolStates/Pointing.ts +1 -1
  140. package/src/lib/shapes/note/NoteShapeTool.test.ts +1 -2
  141. package/src/lib/shapes/note/noteHelpers.ts +2 -2
  142. package/src/lib/shapes/shared/PlainTextLabel.tsx +1 -2
  143. package/src/lib/shapes/shared/RichTextLabel.tsx +1 -2
  144. package/src/lib/shapes/shared/crop.ts +0 -1
  145. package/src/lib/shapes/shared/useEditablePlainText.ts +3 -7
  146. package/src/lib/shapes/shared/useEditableRichText.ts +3 -7
  147. package/src/lib/shapes/text/TextShapeTool.test.ts +4 -4
  148. package/src/lib/shapes/text/toolStates/Pointing.ts +1 -1
  149. package/src/lib/tools/EraserTool/childStates/Erasing.ts +5 -3
  150. package/src/lib/tools/EraserTool/childStates/Pointing.ts +16 -3
  151. package/src/lib/tools/SelectTool/DragAndDropManager.ts +4 -2
  152. package/src/lib/tools/SelectTool/childStates/Brushing.ts +6 -2
  153. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +3 -2
  154. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +7 -4
  155. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +4 -2
  156. package/src/lib/tools/SelectTool/childStates/Idle.ts +10 -6
  157. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +1 -1
  158. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +12 -4
  159. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +2 -2
  160. package/src/lib/tools/SelectTool/childStates/Resizing.ts +4 -2
  161. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +4 -2
  162. package/src/lib/tools/SelectTool/childStates/Translating.ts +3 -1
  163. package/src/lib/ui/components/EditLinkDialog.tsx +6 -16
  164. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -2
  165. package/src/lib/ui/components/menu-items.tsx +14 -6
  166. package/src/lib/ui/context/actions.tsx +13 -9
  167. package/src/lib/ui/hooks/menu-hooks.ts +19 -9
  168. package/src/lib/ui/hooks/useFlatten.ts +2 -1
  169. package/src/lib/ui/hooks/useTools.tsx +2 -1
  170. package/src/lib/ui/version.ts +3 -3
  171. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +0 -8
  172. package/src/lib/utils/export/exportAs.ts +9 -2
  173. package/src/lib/utils/frames/frames.ts +1 -1
  174. package/src/lib/utils/tldr/buildFromV1Document.ts +17 -12
  175. package/src/test/Editor.test.tsx +12 -38
  176. package/src/test/SelectTool.test.ts +19 -11
  177. package/src/test/TestEditor.ts +4 -1
  178. package/src/test/TldrawEditor.test.tsx +16 -18
  179. package/src/test/bindings.test.tsx +25 -29
  180. package/src/test/bindingsIndex.test.tsx +4 -4
  181. package/src/test/commands/createShapes.test.ts +1 -15
  182. package/src/test/commands/getSvgString.test.ts +2 -2
  183. package/src/test/commands/putContent.test.ts +0 -1
  184. package/src/test/commands/updateShapes.test.ts +5 -21
  185. package/src/test/custom-clipping.test.ts +35 -36
  186. package/src/test/customSnapping.test.tsx +62 -77
  187. package/src/test/duplicate.test.ts +1 -1
  188. package/src/test/frames.test.ts +2 -2
  189. package/src/test/getCulledShapes.test.tsx +3 -11
  190. package/src/test/getShapeAtPoint.test.ts +2 -2
  191. package/src/test/groups.test.tsx +3 -6
  192. package/src/test/resizing.test.ts +13 -9
  193. package/src/test/selection-omnibus.test.ts +11 -11
  194. package/src/test/shapeutils.test.ts +1 -1
  195. package/src/test/styles2.test.tsx +1 -1
  196. package/src/test/styles3.test.ts +5 -5
  197. package/src/test/test-jsx.tsx +57 -69
  198. package/src/test/text.test.ts +17 -15
  199. package/src/test/translating.test.ts +8 -6
  200. package/src/test/commands/createShape.test.ts +0 -64
  201. package/src/test/commands/isShapeOfType.test.ts +0 -44
  202. package/src/test/commands/updateShape.test.ts +0 -67
@@ -1,4 +1,12 @@
1
- import { IndexKey, createShapeId, toRichText } from '@tldraw/editor'
1
+ import {
2
+ IndexKey,
3
+ TLArrowShape,
4
+ TLGeoShape,
5
+ TLNoteShape,
6
+ TLTextShape,
7
+ createShapeId,
8
+ toRichText,
9
+ } from '@tldraw/editor'
2
10
  import { vi } from 'vitest'
3
11
  import { TestEditor } from './TestEditor'
4
12
 
@@ -53,7 +61,7 @@ describe('TLSelectTool.Idle', () => {
53
61
  describe.skip('Edit on type', () => {
54
62
  it('Starts editing shape on key down if shape does auto-edit on key stroke', () => {
55
63
  const id = createShapeId()
56
- editor.createShapes([
64
+ editor.createShapes<TLNoteShape>([
57
65
  {
58
66
  id,
59
67
  type: 'note',
@@ -77,7 +85,7 @@ describe.skip('Edit on type', () => {
77
85
 
78
86
  it('Does not start editing on excluded keys', () => {
79
87
  const id = createShapeId()
80
- editor.createShapes([
88
+ editor.createShapes<TLNoteShape>([
81
89
  {
82
90
  id,
83
91
  type: 'note',
@@ -94,7 +102,7 @@ describe.skip('Edit on type', () => {
94
102
 
95
103
  it('Ignores key down if altKey or ctrlKey is pressed', () => {
96
104
  const id = createShapeId()
97
- editor.createShapes([
105
+ editor.createShapes<TLNoteShape>([
98
106
  {
99
107
  id,
100
108
  type: 'note',
@@ -262,7 +270,7 @@ describe('DraggingHandle', () => {
262
270
 
263
271
  describe('PointingLabel', () => {
264
272
  it('Enters from pointing_arrow_label and exits to idle', () => {
265
- editor.createShapes([
273
+ editor.createShapes<TLArrowShape>([
266
274
  {
267
275
  id: ids.arrow1,
268
276
  type: 'arrow',
@@ -294,7 +302,7 @@ describe('PointingLabel', () => {
294
302
  })
295
303
 
296
304
  it('Bails on escape', () => {
297
- editor.createShapes([
305
+ editor.createShapes<TLArrowShape>([
298
306
  {
299
307
  id: ids.arrow1,
300
308
  type: 'arrow',
@@ -321,7 +329,7 @@ describe('PointingLabel', () => {
321
329
  })
322
330
 
323
331
  it('Doesnt go into pointing_arrow_label mode if not selecting the arrow shape', () => {
324
- editor.createShapes([
332
+ editor.createShapes<TLArrowShape>([
325
333
  {
326
334
  id: ids.arrow1,
327
335
  type: 'arrow',
@@ -398,7 +406,7 @@ describe('When double clicking the selection edge', () => {
398
406
  .selectAll()
399
407
  .deleteShapes(editor.getSelectedShapeIds())
400
408
  .selectNone()
401
- .createShapes([
409
+ .createShapes<TLTextShape>([
402
410
  {
403
411
  id,
404
412
  type: 'text',
@@ -456,7 +464,7 @@ describe('When editing shapes', () => {
456
464
  text2: createShapeId(),
457
465
  }
458
466
 
459
- editor.createShapes([
467
+ editor.createShapes<TLGeoShape | TLTextShape>([
460
468
  {
461
469
  id: ids.geo1,
462
470
  type: 'geo',
@@ -694,7 +702,7 @@ describe('when passing a function to onInteractionEnd', () => {
694
702
  },
695
703
  }
696
704
 
697
- editor.createShapes([arrow])
705
+ editor.createShapes<TLArrowShape>([arrow])
698
706
 
699
707
  editor.setCurrentTool('select.pointing_arrow_label', {
700
708
  shape: arrow,
@@ -820,7 +828,7 @@ describe('when passing a string to onInteractionEnd', () => {
820
828
  },
821
829
  }
822
830
 
823
- editor.createShapes([arrow])
831
+ editor.createShapes<TLArrowShape>([arrow])
824
832
 
825
833
  editor.setCurrentTool('select.pointing_arrow_label', {
826
834
  shape: arrow,
@@ -10,6 +10,7 @@ import {
10
10
  RequiredKeys,
11
11
  RotateCorner,
12
12
  SelectionHandle,
13
+ TLArrowBinding,
13
14
  TLArrowShape,
14
15
  TLContent,
15
16
  TLEditorOptions,
@@ -789,7 +790,9 @@ export class TestEditor extends Editor {
789
790
  }
790
791
 
791
792
  getArrowsBoundTo(shapeId: TLShapeId) {
792
- const ids = new Set(this.getBindingsToShape(shapeId, 'arrow').map((b) => b.fromId))
793
+ const ids = new Set(
794
+ this.getBindingsToShape<TLArrowBinding>(shapeId, 'arrow').map((b) => b.fromId)
795
+ )
793
796
  return compact(Array.from(ids, (id) => this.getShape<TLArrowShape>(id)))
794
797
  }
795
798
  }
@@ -4,9 +4,8 @@ import {
4
4
  BaseBoxShapeUtil,
5
5
  Editor,
6
6
  HTMLContainer,
7
- IndexKey,
8
7
  TLAssetStore,
9
- TLShape,
8
+ TLBaseShape,
10
9
  TLShapeId,
11
10
  TldrawEditor,
12
11
  createShapeId,
@@ -197,7 +196,7 @@ describe('<TldrawEditor />', () => {
197
196
  },
198
197
  { type: 'embed' as const, props: { w: 100, h: 100, url: 'https://example.com' } },
199
198
  { type: 'frame' as const, props: { w: 100, h: 100 } },
200
- { type: 'geo' as const, props: { w: 100, h: 100, geo: 'rectangle' as const } },
199
+ { type: 'geo' as const, props: { w: 100, h: 100, geo: 'rectangle' } },
201
200
  {
202
201
  type: 'highlight' as const,
203
202
  props: { segments: [{ type: 'free' as const, points: [{ x: 0, y: 0, z: 0.5 }] }] },
@@ -207,8 +206,8 @@ describe('<TldrawEditor />', () => {
207
206
  type: 'line' as const,
208
207
  props: {
209
208
  points: {
210
- a1: { id: 'a1', index: 'a1' as IndexKey, x: 0, y: 0 },
211
- a2: { id: 'a2', index: 'a2' as IndexKey, x: 100, y: 100 },
209
+ a1: { id: 'a1', index: 'a1', x: 0, y: 0 },
210
+ a2: { id: 'a2', index: 'a2', x: 100, y: 100 },
212
211
  },
213
212
  },
214
213
  },
@@ -228,9 +227,10 @@ describe('<TldrawEditor />', () => {
228
227
  editor.createShapes([
229
228
  {
230
229
  id,
231
- ...shapeConfig,
230
+ type: shapeConfig.type,
232
231
  x: i * 150, // Space them out horizontally
233
232
  y: 0,
233
+ props: shapeConfig.props,
234
234
  },
235
235
  ])
236
236
  })
@@ -456,19 +456,17 @@ describe('<TldrawEditor />', () => {
456
456
  })
457
457
  })
458
458
 
459
- const CARD_TYPE = 'card'
460
-
461
- declare module '@tldraw/tlschema' {
462
- export interface TLGlobalShapePropsMap {
463
- [CARD_TYPE]: { w: number; h: number }
464
- }
465
- }
466
-
467
- type CardShape = TLShape<typeof CARD_TYPE>
468
-
469
459
  describe('Custom shapes', () => {
460
+ type CardShape = TLBaseShape<
461
+ 'card',
462
+ {
463
+ w: number
464
+ h: number
465
+ }
466
+ >
467
+
470
468
  class CardUtil extends BaseBoxShapeUtil<CardShape> {
471
- static override type = CARD_TYPE
469
+ static override type = 'card' as const
472
470
 
473
471
  override isAspectRatioLocked(_shape: CardShape) {
474
472
  return false
@@ -510,7 +508,7 @@ describe('Custom shapes', () => {
510
508
  class CardTool extends BaseBoxShapeTool {
511
509
  static override id = 'card'
512
510
  static override initial = 'idle'
513
- override shapeType = 'card' as const
511
+ override shapeType = 'card'
514
512
  }
515
513
 
516
514
  const tools = [CardTool]
@@ -6,8 +6,8 @@ import {
6
6
  BindingOnShapeDeleteOptions,
7
7
  BindingOnShapeIsolateOptions,
8
8
  BindingUtil,
9
- TLBinding,
10
9
  TLShapeId,
10
+ TLUnknownBinding,
11
11
  createBindingId,
12
12
  createShapeId,
13
13
  } from '@tldraw/editor'
@@ -40,7 +40,7 @@ const mockOnAfterChangeToShape = vi.fn()
40
40
 
41
41
  const calls: string[] = []
42
42
 
43
- const registerCall = (method: string, binding: TLBinding) => {
43
+ const registerCall = (method: string, binding: TLUnknownBinding) => {
44
44
  calls.push(
45
45
  `${method}: ${binding.fromId.slice('shape:'.length)}->${binding.toId.slice('shape:'.length)}`
46
46
  )
@@ -60,62 +60,62 @@ class TestBindingUtil extends BindingUtil {
60
60
  mockOnOperationComplete()
61
61
  }
62
62
 
63
- override onBeforeDelete(options: BindingOnDeleteOptions): void {
63
+ override onBeforeDelete(options: BindingOnDeleteOptions<TLUnknownBinding>): void {
64
64
  registerCall('onBeforeDelete', options.binding)
65
65
  mockOnBeforeDelete(options)
66
66
  }
67
67
 
68
- override onAfterDelete(options: BindingOnDeleteOptions): void {
68
+ override onAfterDelete(options: BindingOnDeleteOptions<TLUnknownBinding>): void {
69
69
  registerCall('onAfterDelete', options.binding)
70
70
  mockOnAfterDelete(options)
71
71
  }
72
72
 
73
- override onBeforeDeleteFromShape(options: BindingOnShapeDeleteOptions): void {
73
+ override onBeforeDeleteFromShape(options: BindingOnShapeDeleteOptions<TLUnknownBinding>): void {
74
74
  registerCall('onBeforeDeleteFromShape', options.binding)
75
75
  mockOnBeforeFromShapeDelete(options)
76
76
  }
77
77
 
78
- override onBeforeDeleteToShape(options: BindingOnShapeDeleteOptions): void {
78
+ override onBeforeDeleteToShape(options: BindingOnShapeDeleteOptions<TLUnknownBinding>): void {
79
79
  registerCall('onBeforeDeleteToShape', options.binding)
80
80
  mockOnBeforeToShapeDelete(options)
81
81
  }
82
82
 
83
- override onBeforeIsolateFromShape(options: BindingOnShapeIsolateOptions): void {
83
+ override onBeforeIsolateFromShape(options: BindingOnShapeIsolateOptions<TLUnknownBinding>): void {
84
84
  registerCall('onBeforeIsolateFromShape', options.binding)
85
85
  mockOnBeforeFromShapeIsolate(options)
86
86
  }
87
87
 
88
- override onBeforeIsolateToShape(options: BindingOnShapeIsolateOptions): void {
88
+ override onBeforeIsolateToShape(options: BindingOnShapeIsolateOptions<TLUnknownBinding>): void {
89
89
  registerCall('onBeforeIsolateToShape', options.binding)
90
90
  mockOnBeforeToShapeIsolate(options)
91
91
  }
92
92
 
93
- override onBeforeCreate(options: BindingOnCreateOptions): void {
93
+ override onBeforeCreate(options: BindingOnCreateOptions<TLUnknownBinding>): void {
94
94
  registerCall('onBeforeCreate', options.binding)
95
95
  mockOnBeforeCreate(options)
96
96
  }
97
97
 
98
- override onAfterCreate(options: BindingOnCreateOptions): void {
98
+ override onAfterCreate(options: BindingOnCreateOptions<TLUnknownBinding>): void {
99
99
  registerCall('onAfterCreate', options.binding)
100
100
  mockOnAfterCreate(options)
101
101
  }
102
102
 
103
- override onBeforeChange(options: BindingOnChangeOptions): void {
103
+ override onBeforeChange(options: BindingOnChangeOptions<TLUnknownBinding>): void {
104
104
  registerCall('onBeforeChange', options.bindingAfter)
105
105
  mockOnBeforeChange(options)
106
106
  }
107
107
 
108
- override onAfterChange(options: BindingOnChangeOptions): void {
108
+ override onAfterChange(options: BindingOnChangeOptions<TLUnknownBinding>): void {
109
109
  registerCall('onAfterChange', options.bindingAfter)
110
110
  mockOnAfterChange(options)
111
111
  }
112
112
 
113
- override onAfterChangeFromShape(options: BindingOnShapeChangeOptions): void {
113
+ override onAfterChangeFromShape(options: BindingOnShapeChangeOptions<TLUnknownBinding>): void {
114
114
  registerCall('onAfterChangeFromShape', options.binding)
115
115
  mockOnAfterChangeFromShape(options)
116
116
  }
117
117
 
118
- override onAfterChangeToShape(options: BindingOnShapeChangeOptions): void {
118
+ override onAfterChangeToShape(options: BindingOnShapeChangeOptions<TLUnknownBinding>): void {
119
119
  registerCall('onAfterChangeToShape', options.binding)
120
120
  mockOnAfterChangeToShape(options)
121
121
  }
@@ -146,19 +146,11 @@ beforeEach(() => {
146
146
  mockOnAfterChangeToShape.mockReset()
147
147
  })
148
148
 
149
- const TEST_TYPE = 'test'
150
-
151
- declare module '@tldraw/tlschema' {
152
- export interface TLGlobalBindingPropsMap {
153
- [TEST_TYPE]: Record<string, never>
154
- }
155
- }
156
-
157
149
  function bindShapes(fromId: TLShapeId, toId: TLShapeId) {
158
150
  const bindingId = createBindingId()
159
151
  editor.createBinding({
160
152
  id: bindingId,
161
- type: TEST_TYPE,
153
+ type: 'test',
162
154
  fromId,
163
155
  toId,
164
156
  })
@@ -264,9 +256,11 @@ test('copying the to shape on its own does trigger the unbind operation', () =>
264
256
  })
265
257
 
266
258
  test('cascading deletes in beforeFromShapeDelete are handled correctly', () => {
267
- mockOnBeforeFromShapeDelete.mockImplementation((options: BindingOnShapeDeleteOptions) => {
268
- editor.deleteShape(options.binding.toId)
269
- })
259
+ mockOnBeforeFromShapeDelete.mockImplementation(
260
+ (options: BindingOnShapeDeleteOptions<TLUnknownBinding>) => {
261
+ editor.deleteShape(options.binding.toId)
262
+ }
263
+ )
270
264
 
271
265
  bindShapes(ids.box1, ids.box2)
272
266
  bindShapes(ids.box2, ids.box3)
@@ -307,9 +301,11 @@ test('cascading deletes in beforeFromShapeDelete are handled correctly', () => {
307
301
  })
308
302
 
309
303
  test('cascading deletes in beforeToShapeDelete are handled correctly', () => {
310
- mockOnBeforeToShapeDelete.mockImplementation((options: BindingOnShapeDeleteOptions) => {
311
- editor.deleteShape(options.binding.fromId)
312
- })
304
+ mockOnBeforeToShapeDelete.mockImplementation(
305
+ (options: BindingOnShapeDeleteOptions<TLUnknownBinding>) => {
306
+ editor.deleteShape(options.binding.fromId)
307
+ }
308
+ )
313
309
 
314
310
  bindShapes(ids.box1, ids.box2)
315
311
  bindShapes(ids.box2, ids.box3)
@@ -1,4 +1,4 @@
1
- import { TLShapeId, createShapeId } from '@tldraw/editor'
1
+ import { TLArrowBinding, TLGeoShape, TLShapeId, createShapeId } from '@tldraw/editor'
2
2
  import { TestEditor } from './TestEditor'
3
3
  import { TL } from './test-jsx'
4
4
 
@@ -219,7 +219,7 @@ describe('bindingsIndex', () => {
219
219
 
220
220
  const [box1Clone, box2Clone] = editor
221
221
  .getSelectedShapes()
222
- .filter((shape) => editor.isShapeOfType(shape, 'geo'))
222
+ .filter((shape) => editor.isShapeOfType<TLGeoShape>(shape, 'geo'))
223
223
  .sort((a, b) => a.x - b.x)
224
224
 
225
225
  expect(editor.getArrowsBoundTo(box2Clone.id)).toHaveLength(3)
@@ -248,9 +248,9 @@ describe('bindingsIndex', () => {
248
248
 
249
249
  // move arrowA end from box2 to box3
250
250
  const binding = editor
251
- .getBindingsInvolvingShape(ids.box2, 'arrow')
251
+ .getBindingsInvolvingShape<TLArrowBinding>(ids.box2, 'arrow')
252
252
  .find((b) => b.props.terminal === 'end')!
253
- editor.updateBinding({ ...binding, toId: box3 })
253
+ editor.updateBinding({ ...binding, toId: box3 } satisfies TLArrowBinding)
254
254
 
255
255
  expect(editor.getArrowsBoundTo(ids.box2)).toHaveLength(2)
256
256
  expect(editor.getArrowsBoundTo(ids.box1)).toHaveLength(3)
@@ -19,28 +19,14 @@ beforeEach(() => {
19
19
 
20
20
  it('Uses typescript generics', () => {
21
21
  expect(() => {
22
- // Yep error because we are giving the wrong props to the shape
22
+ // No error here because no generic, the editor doesn't know what this guy is
23
23
  editor.createShapes([
24
- //@ts-expect-error
25
24
  {
26
25
  id: ids.box1,
27
26
  type: 'geo',
28
27
  props: { w: 'OH NO' },
29
28
  },
30
29
  ])
31
-
32
- // Errors when creating shapes with unknown props
33
- editor.createShapes([
34
- {
35
- id: ids.box1,
36
- type: 'geo',
37
- props: {
38
- // @ts-expect-error
39
- foo: 'bar',
40
- },
41
- },
42
- ])
43
-
44
30
  // Yep error here because we are giving the wrong props to the shape
45
31
  editor.createShapes<TLGeoShape>([
46
32
  {
@@ -1,4 +1,4 @@
1
- import { DefaultDashStyle, createShapeId, toRichText } from '@tldraw/editor'
1
+ import { DefaultDashStyle, TLGeoShape, createShapeId, toRichText } from '@tldraw/editor'
2
2
  import { vi } from 'vitest'
3
3
  import { TestEditor } from '../TestEditor'
4
4
 
@@ -21,7 +21,7 @@ beforeEach(() => {
21
21
  editor = new TestEditor()
22
22
  editor.setStyleForNextShapes(DefaultDashStyle, 'solid')
23
23
  editor.setStyleForSelectedShapes(DefaultDashStyle, 'solid')
24
- editor.createShapes([
24
+ editor.createShapes<TLGeoShape>([
25
25
  {
26
26
  id: ids.boxA,
27
27
  type: 'geo',
@@ -25,7 +25,6 @@ describe('Migrations', () => {
25
25
 
26
26
  it('Throws error if any shape is invalid due to wrong type', () => {
27
27
  const withInvalidShapeType = structuredClone(clipboardContent)
28
- // @ts-expect-error
29
28
  withInvalidShapeType.shapes[0].type = 'invalid'
30
29
  expect(() => editor.putContentOntoCurrentPage(withInvalidShapeType)).toThrow()
31
30
  })
@@ -15,38 +15,22 @@ beforeEach(() => {
15
15
 
16
16
  it('Uses typescript generics', () => {
17
17
  expect(() => {
18
+ // No error here because no generic, the editor doesn't know what this guy is
18
19
  editor.updateShapes([
19
20
  {
20
21
  id: ids.box1,
21
22
  type: 'geo',
22
- props: {
23
- // @ts-expect-error
24
- w: 'OH NO',
25
- },
26
- },
27
- ])
28
-
29
- // Errors when updating shapes with unknown props
30
- editor.updateShapes([
31
- {
32
- id: ids.box1,
33
- type: 'geo',
34
- props: {
35
- // @ts-expect-error
36
- foo: 'bar',
37
- },
23
+ props: { w: 'OH NO' },
38
24
  },
39
25
  ])
40
26
 
41
- // error here because we are giving the wrong props to the shape
27
+ // Yep error here because we are giving the wrong props to the shape
42
28
  editor.updateShapes<TLGeoShape>([
43
29
  {
44
30
  id: ids.box1,
45
31
  type: 'geo',
46
- props: {
47
- // @ts-expect-error
48
- w: 'OH NO',
49
- },
32
+ //@ts-expect-error
33
+ props: { w: 'OH NO' },
50
34
  },
51
35
  ])
52
36
 
@@ -8,6 +8,7 @@ import {
8
8
  resizeBox,
9
9
  StateNode,
10
10
  T,
11
+ TLBaseShape,
11
12
  TLEventHandlers,
12
13
  TLGeoShape,
13
14
  TLResizeInfo,
@@ -18,21 +19,19 @@ import {
18
19
  } from '@tldraw/editor'
19
20
  import { TestEditor } from './TestEditor'
20
21
 
21
- const CIRCLE_CLIP_TYPE = 'circle-clip'
22
-
23
- declare module '@tldraw/tlschema' {
24
- export interface TLGlobalShapePropsMap {
25
- [CIRCLE_CLIP_TYPE]: { w: number; h: number }
26
- }
27
- }
28
-
29
22
  // Custom Circle Clip Shape Definition
30
- export type CircleClipShape = TLShape<typeof CIRCLE_CLIP_TYPE>
23
+ export type CircleClipShape = TLBaseShape<
24
+ 'circle-clip',
25
+ {
26
+ w: number
27
+ h: number
28
+ }
29
+ >
31
30
 
32
31
  export const isClippingEnabled$ = atom('isClippingEnabled', true)
33
32
 
34
33
  export class CircleClipShapeUtil extends BaseBoxShapeUtil<CircleClipShape> {
35
- static override type = CIRCLE_CLIP_TYPE
34
+ static override type = 'circle-clip' as const
36
35
  static override props: RecordProps<CircleClipShape> = {
37
36
  w: T.number,
38
37
  h: T.number,
@@ -114,8 +113,8 @@ export class CircleClipShapeTool extends StateNode {
114
113
  if (info.target === 'canvas') {
115
114
  const { originPagePoint } = this.editor.inputs
116
115
 
117
- this.editor.createShape({
118
- type: CIRCLE_CLIP_TYPE,
116
+ this.editor.createShape<CircleClipShape>({
117
+ type: 'circle-clip',
119
118
  x: originPagePoint.x - 100,
120
119
  y: originPagePoint.y - 100,
121
120
  props: {
@@ -154,9 +153,9 @@ beforeEach(() => {
154
153
  describe('CircleClipShapeUtil', () => {
155
154
  describe('shape creation and properties', () => {
156
155
  it('should create a circle clip shape with default properties', () => {
157
- editor.createShape({
156
+ editor.createShape<CircleClipShape>({
158
157
  id: ids.circleClip1,
159
- type: CIRCLE_CLIP_TYPE,
158
+ type: 'circle-clip',
160
159
  x: 100,
161
160
  y: 100,
162
161
  props: {
@@ -173,9 +172,9 @@ describe('CircleClipShapeUtil', () => {
173
172
  })
174
173
 
175
174
  it('should use default props when not specified', () => {
176
- editor.createShape({
175
+ editor.createShape<CircleClipShape>({
177
176
  id: ids.circleClip1,
178
- type: CIRCLE_CLIP_TYPE,
177
+ type: 'circle-clip',
179
178
  x: 100,
180
179
  y: 100,
181
180
  props: {},
@@ -189,9 +188,9 @@ describe('CircleClipShapeUtil', () => {
189
188
 
190
189
  describe('geometry and clipping', () => {
191
190
  it('should generate correct circle geometry', () => {
192
- editor.createShape({
191
+ editor.createShape<CircleClipShape>({
193
192
  id: ids.circleClip1,
194
- type: CIRCLE_CLIP_TYPE,
193
+ type: 'circle-clip',
195
194
  x: 100,
196
195
  y: 100,
197
196
  props: {
@@ -211,9 +210,9 @@ describe('CircleClipShapeUtil', () => {
211
210
  })
212
211
 
213
212
  it('should generate clip path for circle', () => {
214
- editor.createShape({
213
+ editor.createShape<CircleClipShape>({
215
214
  id: ids.circleClip1,
216
- type: CIRCLE_CLIP_TYPE,
215
+ type: 'circle-clip',
217
216
  x: 100,
218
217
  y: 100,
219
218
  props: {
@@ -246,9 +245,9 @@ describe('CircleClipShapeUtil', () => {
246
245
 
247
246
  describe('child clipping behavior', () => {
248
247
  it('should clip children when clipping is enabled', () => {
249
- editor.createShape({
248
+ editor.createShape<CircleClipShape>({
250
249
  id: ids.circleClip1,
251
- type: CIRCLE_CLIP_TYPE,
250
+ type: 'circle-clip',
252
251
  x: 100,
253
252
  y: 100,
254
253
  props: {
@@ -257,7 +256,7 @@ describe('CircleClipShapeUtil', () => {
257
256
  },
258
257
  })
259
258
 
260
- editor.createShape({
259
+ editor.createShape<TLTextShape>({
261
260
  id: ids.text1,
262
261
  type: 'text',
263
262
  x: 0,
@@ -280,9 +279,9 @@ describe('CircleClipShapeUtil', () => {
280
279
  it('should not clip children when clipping is disabled', () => {
281
280
  isClippingEnabled$.set(false)
282
281
 
283
- editor.createShape({
282
+ editor.createShape<CircleClipShape>({
284
283
  id: ids.circleClip1,
285
- type: CIRCLE_CLIP_TYPE,
284
+ type: 'circle-clip',
286
285
  x: 100,
287
286
  y: 100,
288
287
  props: {
@@ -291,7 +290,7 @@ describe('CircleClipShapeUtil', () => {
291
290
  },
292
291
  })
293
292
 
294
- editor.createShape({
293
+ editor.createShape<TLTextShape>({
295
294
  id: ids.text1,
296
295
  type: 'text',
297
296
  x: 0,
@@ -315,9 +314,9 @@ describe('CircleClipShapeUtil', () => {
315
314
  describe('Integration tests', () => {
316
315
  it('should create and manage circle clip shapes with children', () => {
317
316
  // Create circle clip shape
318
- editor.createShape({
317
+ editor.createShape<CircleClipShape>({
319
318
  id: ids.circleClip1,
320
- type: CIRCLE_CLIP_TYPE,
319
+ type: 'circle-clip',
321
320
  x: 100,
322
321
  y: 100,
323
322
  props: {
@@ -327,7 +326,7 @@ describe('Integration tests', () => {
327
326
  })
328
327
 
329
328
  // Add text child
330
- editor.createShape({
329
+ editor.createShape<TLTextShape>({
331
330
  id: ids.text1,
332
331
  type: 'text',
333
332
  x: 50,
@@ -339,7 +338,7 @@ describe('Integration tests', () => {
339
338
  })
340
339
 
341
340
  // Add geo child
342
- editor.createShape({
341
+ editor.createShape<TLGeoShape>({
343
342
  id: ids.geo1,
344
343
  type: 'geo',
345
344
  x: 150,
@@ -376,9 +375,9 @@ describe('Integration tests', () => {
376
375
 
377
376
  it('should handle multiple circle clip shapes independently', () => {
378
377
  // Create two circle clip shapes
379
- editor.createShape({
378
+ editor.createShape<CircleClipShape>({
380
379
  id: ids.circleClip1,
381
- type: CIRCLE_CLIP_TYPE,
380
+ type: 'circle-clip',
382
381
  x: 100,
383
382
  y: 100,
384
383
  props: {
@@ -387,9 +386,9 @@ describe('Integration tests', () => {
387
386
  },
388
387
  })
389
388
 
390
- editor.createShape({
389
+ editor.createShape<CircleClipShape>({
391
390
  id: ids.circleClip2,
392
- type: CIRCLE_CLIP_TYPE,
391
+ type: 'circle-clip',
393
392
  x: 400,
394
393
  y: 100,
395
394
  props: {
@@ -399,7 +398,7 @@ describe('Integration tests', () => {
399
398
  })
400
399
 
401
400
  // Add children to both
402
- editor.createShape({
401
+ editor.createShape<TLTextShape>({
403
402
  id: ids.text1,
404
403
  type: 'text',
405
404
  x: 0,
@@ -410,7 +409,7 @@ describe('Integration tests', () => {
410
409
  },
411
410
  })
412
411
 
413
- editor.createShape({
412
+ editor.createShape<TLTextShape>({
414
413
  id: ids.geo1,
415
414
  type: 'text',
416
415
  x: 0,