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
@@ -4,10 +4,10 @@ import {
4
4
  Polyline2d,
5
5
  ShapeUtil,
6
6
  TLAnyShapeUtilConstructor,
7
+ TLBaseShape,
7
8
  TLHandle,
8
9
  TLHandleDragInfo,
9
10
  TLLineShape,
10
- TLShape,
11
11
  TLShapeId,
12
12
  Vec,
13
13
  VecModel,
@@ -16,19 +16,13 @@ import {
16
16
  import { TestEditor } from './TestEditor'
17
17
  import { TL } from './test-jsx'
18
18
 
19
- const TEST1_TYPE = 'test1'
20
-
21
- declare module '@tldraw/tlschema' {
22
- export interface TLGlobalShapePropsMap {
23
- [TEST1_TYPE]: { w: number; h: number; boundsSnapPoints: VecModel[] | null }
24
- }
25
- }
26
-
27
- type Test1Shape = TLShape<typeof TEST1_TYPE>
28
-
29
19
  describe('custom shape bounds snapping - translate', () => {
30
- class TestShapeUtil extends BaseBoxShapeUtil<Test1Shape> {
31
- static override type = TEST1_TYPE
20
+ type TestShape = TLBaseShape<
21
+ 'test',
22
+ { w: number; h: number; boundsSnapPoints: VecModel[] | null }
23
+ >
24
+ class TestShapeUtil extends BaseBoxShapeUtil<TestShape> {
25
+ static override type = 'test'
32
26
  override getDefaultProps() {
33
27
  return { w: 100, h: 100, boundsSnapPoints: null }
34
28
  }
@@ -38,7 +32,7 @@ describe('custom shape bounds snapping - translate', () => {
38
32
  override indicator() {
39
33
  throw new Error('Method not implemented.')
40
34
  }
41
- override getBoundsSnapGeometry(shape: Test1Shape) {
35
+ override getBoundsSnapGeometry(shape: TestShape) {
42
36
  return {
43
37
  points: shape.props.boundsSnapPoints ?? undefined,
44
38
  }
@@ -52,14 +46,14 @@ describe('custom shape bounds snapping - translate', () => {
52
46
  editor = new TestEditor({ shapeUtils })
53
47
  ids = editor.createShapesFromJsx([
54
48
  <TL.geo ref="box" x={0} y={0} w={100} h={100} />,
55
- <TL.test1 ref="test1" x={200} y={200} w={100} h={100} boundsSnapPoints={null} />,
49
+ <TL.test ref="test" x={200} y={200} w={100} h={100} boundsSnapPoints={null} />,
56
50
  ])
57
51
  })
58
52
 
59
53
  describe('with default boundSnapPoints', () => {
60
54
  test('normal snapping works with default boundSnapPoints when moving test shape', () => {
61
55
  // start translating the test shape
62
- editor.setSelectedShapes([ids.test1]).pointerDown(250, 250)
56
+ editor.setSelectedShapes([ids.test]).pointerDown(250, 250)
63
57
 
64
58
  // move the left edge of the test shape to the right edge of the box shape - it should snap
65
59
  editor.pointerMove(155, 250, undefined, { ctrlKey: true })
@@ -90,15 +84,15 @@ describe('custom shape bounds snapping - translate', () => {
90
84
 
91
85
  describe('with only the center in boundSnapPoints', () => {
92
86
  beforeEach(() => {
93
- editor.updateShape({
94
- id: ids.test1,
95
- type: TEST1_TYPE,
87
+ editor.updateShape<TestShape>({
88
+ id: ids.test,
89
+ type: 'test',
96
90
  props: { boundsSnapPoints: [{ x: 50, y: 50 }] },
97
91
  })
98
92
  })
99
93
 
100
94
  describe('when moving the test shape', () => {
101
- beforeEach(() => editor.select(ids.test1).pointerDown(250, 250))
95
+ beforeEach(() => editor.select(ids.test).pointerDown(250, 250))
102
96
 
103
97
  test('does not snap its edges to the box edges', () => {
104
98
  editor.pointerMove(155, 250, undefined, { ctrlKey: true })
@@ -132,15 +126,15 @@ describe('custom shape bounds snapping - translate', () => {
132
126
 
133
127
  describe('with empty boundSnapPoints', () => {
134
128
  beforeEach(() => {
135
- editor.updateShape({
136
- id: ids.test1,
137
- type: TEST1_TYPE,
129
+ editor.updateShape<TestShape>({
130
+ id: ids.test,
131
+ type: 'test',
138
132
  props: { boundsSnapPoints: [] },
139
133
  })
140
134
  })
141
135
 
142
136
  test('test shape does not snap to anything', () => {
143
- editor.select(ids.test1).pointerDown(250, 250)
137
+ editor.select(ids.test).pointerDown(250, 250)
144
138
 
145
139
  // try to snap our left edge to the right edge of the box shape - it should not snap
146
140
  editor.pointerMove(155, 250, undefined, { ctrlKey: true })
@@ -169,11 +163,10 @@ describe('custom shape bounds snapping - translate', () => {
169
163
  })
170
164
  })
171
165
 
172
- const TEST2_TYPE = 'test2'
173
-
174
- declare module '@tldraw/tlschema' {
175
- export interface TLGlobalShapePropsMap {
176
- [TEST2_TYPE]: {
166
+ describe('custom handle snapping', () => {
167
+ type TestShape = TLBaseShape<
168
+ 'test',
169
+ {
177
170
  w: number
178
171
  h: number
179
172
  ownHandle: VecModel
@@ -183,15 +176,10 @@ declare module '@tldraw/tlschema' {
183
176
  selfSnapPoints: VecModel[] | 'default'
184
177
  handleSnapType?: 'point' | 'align'
185
178
  }
186
- }
187
- }
188
-
189
- type Test2Shape = TLShape<typeof TEST2_TYPE>
190
-
191
- describe('custom handle snapping', () => {
192
- class TestShapeUtil extends BaseBoxShapeUtil<Test2Shape> {
193
- static override type = TEST2_TYPE
194
- override getDefaultProps(): Test2Shape['props'] {
179
+ >
180
+ class TestShapeUtil extends BaseBoxShapeUtil<TestShape> {
181
+ static override type = 'test'
182
+ override getDefaultProps(): TestShape['props'] {
195
183
  return {
196
184
  w: 100,
197
185
  h: 100,
@@ -208,7 +196,7 @@ describe('custom handle snapping', () => {
208
196
  override indicator() {
209
197
  throw new Error('Method not implemented.')
210
198
  }
211
- override getHandleSnapGeometry(shape: Test2Shape) {
199
+ override getHandleSnapGeometry(shape: TestShape) {
212
200
  const { handleOutline, handlePoints, selfSnapOutline, selfSnapPoints } = shape.props
213
201
  return {
214
202
  outline:
@@ -226,7 +214,7 @@ describe('custom handle snapping', () => {
226
214
  getSelfSnapPoints: selfSnapPoints === 'default' ? undefined : () => selfSnapPoints,
227
215
  }
228
216
  }
229
- override getHandles(shape: Test2Shape): TLHandle[] {
217
+ override getHandles(shape: TestShape): TLHandle[] {
230
218
  const handle: TLHandle = {
231
219
  id: 'handle',
232
220
  label: 'handle',
@@ -245,7 +233,7 @@ describe('custom handle snapping', () => {
245
233
 
246
234
  return [handle]
247
235
  }
248
- override onHandleDrag(shape: Test2Shape, { handle }: TLHandleDragInfo<Test2Shape>) {
236
+ override onHandleDrag(shape: TestShape, { handle }: TLHandleDragInfo<TestShape>) {
249
237
  return { ...shape, props: { ...shape.props, ownHandle: { x: handle.x, y: handle.y } } }
250
238
  }
251
239
  }
@@ -265,7 +253,7 @@ describe('custom handle snapping', () => {
265
253
  a2: { id: 'a2', index: 'a2' as IndexKey, x: 100, y: 100 },
266
254
  }}
267
255
  />,
268
- <TL.test2 ref="test2" x={200} y={200} w={100} h={100} />,
256
+ <TL.test ref="test" x={200} y={200} w={100} h={100} boundsSnapPoints={null} />,
269
257
  ])
270
258
  })
271
259
 
@@ -308,9 +296,9 @@ describe('custom handle snapping', () => {
308
296
 
309
297
  describe('with empty handleSnapGeometry.outline', () => {
310
298
  beforeEach(() => {
311
- editor.updateShape({
312
- id: ids.test2,
313
- type: TEST2_TYPE,
299
+ editor.updateShape<TestShape>({
300
+ id: ids.test,
301
+ type: 'test',
314
302
  props: { handleOutline: null },
315
303
  })
316
304
  })
@@ -325,9 +313,9 @@ describe('custom handle snapping', () => {
325
313
 
326
314
  describe('with custom handleSnapGeometry.outline', () => {
327
315
  beforeEach(() => {
328
- editor.updateShape({
329
- id: ids.test2,
330
- type: TEST2_TYPE,
316
+ editor.updateShape<TestShape>({
317
+ id: ids.test,
318
+ type: 'test',
331
319
  props: {
332
320
  // a diagonal line from the top left to the bottom right
333
321
  handleOutline: [
@@ -372,9 +360,9 @@ describe('custom handle snapping', () => {
372
360
 
373
361
  describe('with custom handleSnapGeometry.points', () => {
374
362
  beforeEach(() => {
375
- editor.updateShape({
376
- id: ids.test2,
377
- type: TEST2_TYPE,
363
+ editor.updateShape<TestShape>({
364
+ id: ids.test,
365
+ type: 'test',
378
366
  props: {
379
367
  handlePoints: [
380
368
  { x: 30, y: 30 },
@@ -399,12 +387,12 @@ describe('custom handle snapping', () => {
399
387
 
400
388
  describe('with custom handleSnapGeometry.points along the outline', () => {
401
389
  beforeEach(() => {
402
- editor.updateShape({
403
- id: ids.test2,
404
- type: TEST2_TYPE,
390
+ editor.updateShape<TestShape>({
391
+ id: ids.test,
392
+ type: 'test',
405
393
  props: {
406
394
  handlePoints: editor
407
- .getShapeGeometry(ids.test2)
395
+ .getShapeGeometry(ids.test)
408
396
  .bounds.cornersAndCenter.map(({ x, y }) => ({ x, y })),
409
397
  },
410
398
  })
@@ -438,9 +426,9 @@ describe('custom handle snapping', () => {
438
426
  describe('self snapping', () => {
439
427
  beforeEach(() => {
440
428
  editor.deleteShape(ids.line)
441
- editor.updateShape({
442
- id: ids.test2,
443
- type: TEST2_TYPE,
429
+ editor.updateShape<TestShape>({
430
+ id: ids.test,
431
+ type: 'test',
444
432
  x: 0,
445
433
  y: 0,
446
434
  props: {
@@ -449,12 +437,12 @@ describe('custom handle snapping', () => {
449
437
  })
450
438
  })
451
439
  function startDraggingOwnHandle() {
452
- const shape = editor.select(ids.test2).getOnlySelectedShape()!
440
+ const shape = editor.select(ids.test).getOnlySelectedShape()!
453
441
  const handles = editor.getShapeHandles(shape)!
454
442
  editor.pointerDown(0, 0, { target: 'handle', shape, handle: handles[0] })
455
443
  }
456
444
  function ownHandlePosition() {
457
- const shape = editor.select(ids.test2).getOnlySelectedShape()!
445
+ const shape = editor.select(ids.test).getOnlySelectedShape()!
458
446
  const handle = editor.getShapeHandles(shape)![0]
459
447
  return { x: handle.x, y: handle.y }
460
448
  }
@@ -474,9 +462,9 @@ describe('custom handle snapping', () => {
474
462
  })
475
463
  describe('with custom self snap outline & points', () => {
476
464
  beforeEach(() => {
477
- editor.updateShape({
478
- id: ids.test2,
479
- type: TEST2_TYPE,
465
+ editor.updateShape<TestShape>({
466
+ id: ids.test,
467
+ type: 'test',
480
468
  props: {
481
469
  selfSnapOutline: [
482
470
  { x: 20, y: 50 },
@@ -518,9 +506,9 @@ describe('custom handle snapping', () => {
518
506
 
519
507
  describe('with snapType set to align', () => {
520
508
  beforeEach(() => {
521
- editor.updateShape({
522
- id: ids.test2,
523
- type: TEST2_TYPE,
509
+ editor.updateShape<TestShape>({
510
+ id: ids.test,
511
+ type: 'test',
524
512
  props: {
525
513
  selfSnapPoints: [
526
514
  { x: 20, y: 50 },
@@ -555,24 +543,19 @@ describe('custom handle snapping', () => {
555
543
  })
556
544
  })
557
545
 
558
- const BEZIER_TYPE = 'bezier'
559
-
560
- declare module '@tldraw/tlschema' {
561
- export interface TLGlobalShapePropsMap {
562
- [BEZIER_TYPE]: {
546
+ describe('custom adjacent handle for shift snapping', () => {
547
+ type BezierShape = TLBaseShape<
548
+ 'bezier',
549
+ {
563
550
  start: VecModel
564
551
  cp1: VecModel
565
552
  cp2: VecModel
566
553
  end: VecModel
567
554
  }
568
- }
569
- }
570
-
571
- type BezierShape = TLShape<typeof BEZIER_TYPE>
555
+ >
572
556
 
573
- describe('custom adjacent handle for shift snapping', () => {
574
557
  class BezierShapeUtil extends ShapeUtil<BezierShape> {
575
- static override type = BEZIER_TYPE
558
+ static override type = 'bezier'
576
559
  override getDefaultProps() {
577
560
  return {
578
561
  start: { x: 0, y: 0 },
@@ -649,6 +632,8 @@ describe('custom adjacent handle for shift snapping', () => {
649
632
  ref="bezier"
650
633
  x={0}
651
634
  y={0}
635
+ w={100}
636
+ h={100}
652
637
  start={{ x: 0, y: 0 }}
653
638
  cp1={{ x: 50, y: 0 }}
654
639
  cp2={{ x: 50, y: 100 }}
@@ -295,7 +295,7 @@ describe('When duplicating shapes that include arrows', () => {
295
295
  .select(
296
296
  ...editor
297
297
  .getCurrentPageShapes()
298
- .filter((s) => editor.isShapeOfType(s, 'arrow'))
298
+ .filter((s) => editor.isShapeOfType<TLArrowShape>(s, 'arrow'))
299
299
  .map((s) => s.id)
300
300
  )
301
301
 
@@ -1363,13 +1363,13 @@ describe('Unparenting behavior', () => {
1363
1363
 
1364
1364
  // When the shape has a fill, it should not fall out of the frame
1365
1365
  editor.undo()
1366
- editor.updateShape({ ...largeRect, props: { fill: 'solid' } })
1366
+ editor.updateShape<TLGeoShape>({ ...largeRect, props: { fill: 'solid' } })
1367
1367
  dragOntoFrame()
1368
1368
  expect(editor.getShape(largeRect.id)!.parentId).toBe(frameId)
1369
1369
 
1370
1370
  // When the shape has a label and that label is on top of the frame, it should not fall out of the frame
1371
1371
  editor.undo()
1372
- editor.updateShape({
1372
+ editor.updateShape<TLGeoShape>({
1373
1373
  ...largeRect,
1374
1374
  props: { fill: 'none', richText: toRichText('hello') },
1375
1375
  })
@@ -3,7 +3,7 @@ import {
3
3
  Box,
4
4
  RecordProps,
5
5
  T,
6
- TLShape,
6
+ TLBaseShape,
7
7
  TLShapeId,
8
8
  createShapeId,
9
9
  } from '@tldraw/editor'
@@ -11,19 +11,11 @@ import { vi } from 'vitest'
11
11
  import { TestEditor } from './TestEditor'
12
12
  import { TL } from './test-jsx'
13
13
 
14
- const UNCULLABLE_TYPE = 'uncullable'
15
-
16
- declare module '@tldraw/tlschema' {
17
- export interface TLGlobalShapePropsMap {
18
- [UNCULLABLE_TYPE]: { w: number; h: number }
19
- }
20
- }
21
-
22
14
  // Custom uncullable shape type for testing canCull override
23
- type UncullableShape = TLShape<typeof UNCULLABLE_TYPE>
15
+ type UncullableShape = TLBaseShape<'uncullable', { w: number; h: number }>
24
16
 
25
17
  class UncullableShapeUtil extends BaseBoxShapeUtil<UncullableShape> {
26
- static override type = UNCULLABLE_TYPE
18
+ static override type = 'uncullable' as const
27
19
  static override props: RecordProps<UncullableShape> = {
28
20
  w: T.number,
29
21
  h: T.number,
@@ -1,4 +1,4 @@
1
- import { TLShape, createShapeId, toRichText } from '@tldraw/editor'
1
+ import { TLGeoShape, TLShape, createShapeId, toRichText } from '@tldraw/editor'
2
2
  import { TestEditor } from './TestEditor'
3
3
 
4
4
  let editor: TestEditor
@@ -146,7 +146,7 @@ describe('with hitLabels=true', () => {
146
146
  it('hits geo shape label behind overlapping hollow shape', () => {
147
147
  // label is empty
148
148
  expect(editor.getShapeAtPoint({ x: 350, y: 350 }, opts)?.id).toBe(ids.box3)
149
- editor.updateShape({
149
+ editor.updateShape<TLGeoShape>({
150
150
  id: ids.box2,
151
151
  type: 'geo',
152
152
  props: { richText: toRichText('hello') },
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  Box,
3
- ExtractShapeByProps,
4
3
  GroupShapeUtil,
5
4
  TLArrowShape,
6
5
  TLGroupShape,
@@ -36,16 +35,14 @@ const ids = {
36
35
  groupA: createShapeId('groupA'),
37
36
  }
38
37
 
39
- type BoxShape = ExtractShapeByProps<{ fill: string }>
40
-
41
38
  const box = (
42
39
  id: TLShapeId,
43
40
  x: number,
44
41
  y: number,
45
42
  w = 10,
46
43
  h = 10,
47
- fill: BoxShape['props']['fill'] = 'solid'
48
- ): TLShapePartial<BoxShape> => ({
44
+ fill = 'solid'
45
+ ): TLShapePartial => ({
49
46
  type: 'geo',
50
47
  id,
51
48
  x,
@@ -1983,7 +1980,7 @@ describe('Group opacity', () => {
1983
1980
  editor.setOpacityForNextShapes(0.5)
1984
1981
  editor.groupShapes(editor.getSelectedShapeIds())
1985
1982
  const group = editor.getShape(onlySelectedId())!
1986
- assert(editor.isShapeOfType(group, 'group'))
1983
+ assert(editor.isShapeOfType<TLGroupShape>(group, 'group'))
1987
1984
  expect(group.opacity).toBe(1)
1988
1985
  })
1989
1986
  })
@@ -3876,8 +3876,10 @@ it('uses the cross cursor when create resizing', () => {
3876
3876
  describe('Resizing text from the right edge', () => {
3877
3877
  it('Resizes text from the right edge', () => {
3878
3878
  const id = createShapeId()
3879
- editor.createShapes([{ id, type: 'text', props: { richText: toRichText('H') } }])
3880
- editor.updateShapes([{ id, type: 'text', props: { richText: toRichText('Hello World') } }]) // auto size
3879
+ editor.createShapes<TLTextShape>([{ id, type: 'text', props: { richText: toRichText('H') } }])
3880
+ editor.updateShapes<TLTextShape>([
3881
+ { id, type: 'text', props: { richText: toRichText('Hello World') } },
3882
+ ]) // auto size
3881
3883
 
3882
3884
  editor.select(id)
3883
3885
 
@@ -3903,8 +3905,10 @@ describe('Resizing text from the right edge', () => {
3903
3905
  editor.updateInstanceState({ isCoarsePointer: true })
3904
3906
 
3905
3907
  const id = createShapeId()
3906
- editor.createShapes([{ id, type: 'text', props: { richText: toRichText('H') } }])
3907
- editor.updateShapes([{ id, type: 'text', props: { richText: toRichText('Hello World') } }]) // auto size
3908
+ editor.createShapes<TLTextShape>([{ id, type: 'text', props: { richText: toRichText('H') } }])
3909
+ editor.updateShapes<TLTextShape>([
3910
+ { id, type: 'text', props: { richText: toRichText('Hello World') } },
3911
+ ]) // auto size
3908
3912
 
3909
3913
  editor.select(id)
3910
3914
 
@@ -3950,7 +3954,7 @@ describe('When resizing near the edges of the screen', () => {
3950
3954
 
3951
3955
  describe('resizing text with autosize true', () => {
3952
3956
  it('resizes text from the right side', () => {
3953
- editor.createShape({
3957
+ editor.createShape<TLTextShape>({
3954
3958
  type: 'text',
3955
3959
  x: 0,
3956
3960
  y: 0,
@@ -3976,7 +3980,7 @@ describe('resizing text with autosize true', () => {
3976
3980
  })
3977
3981
 
3978
3982
  it('resizes text from the right side when alt key is pressed', () => {
3979
- editor.createShape({
3983
+ editor.createShape<TLTextShape>({
3980
3984
  type: 'text',
3981
3985
  x: 0,
3982
3986
  y: 0,
@@ -4003,7 +4007,7 @@ describe('resizing text with autosize true', () => {
4003
4007
  })
4004
4008
 
4005
4009
  it('resizes text from the left side', () => {
4006
- editor.createShape({
4010
+ editor.createShape<TLTextShape>({
4007
4011
  type: 'text',
4008
4012
  x: 0,
4009
4013
  y: 0,
@@ -4029,7 +4033,7 @@ describe('resizing text with autosize true', () => {
4029
4033
  })
4030
4034
 
4031
4035
  it('resizes text from the left side when alt is pressed', () => {
4032
- editor.createShape({
4036
+ editor.createShape<TLTextShape>({
4033
4037
  type: 'text',
4034
4038
  x: 0,
4035
4039
  y: 0,
@@ -4058,7 +4062,7 @@ describe('resizing text with autosize true', () => {
4058
4062
 
4059
4063
  describe('cancelling a resize operation', () => {
4060
4064
  it('undoes any changes since the start of the resize operation', () => {
4061
- editor.createShape({
4065
+ editor.createShape<TLGeoShape>({
4062
4066
  type: 'geo',
4063
4067
  x: 0,
4064
4068
  y: 0,
@@ -76,7 +76,7 @@ describe('Hovering shapes', () => {
76
76
  editor.pointerMove(50, 50)
77
77
  expect(editor.getHoveredShapeId()).toBe(null)
78
78
 
79
- editor.updateShape({
79
+ editor.updateShape<TLGeoShape>({
80
80
  id: ids.box1,
81
81
  type: 'geo',
82
82
  props: { richText: toRichText('hello') },
@@ -88,7 +88,7 @@ describe('Hovering shapes', () => {
88
88
  })
89
89
 
90
90
  it('selects a shape with a full label on pointer down', () => {
91
- editor.updateShape({
91
+ editor.updateShape<TLGeoShape>({
92
92
  id: ids.box1,
93
93
  type: 'geo',
94
94
  props: { richText: toRichText('hello') },
@@ -462,7 +462,7 @@ describe('when shape is hollow', () => {
462
462
  describe('when shape is a frame', () => {
463
463
  let frame1: TLFrameShape
464
464
  beforeEach(() => {
465
- editor.createShape({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
465
+ editor.createShape<TLFrameShape>({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
466
466
  frame1 = editor.getShape<TLFrameShape>(ids.frame1)!
467
467
  })
468
468
 
@@ -517,8 +517,8 @@ describe('when shape is a frame', () => {
517
517
  describe('When a shape is behind a frame', () => {
518
518
  beforeEach(() => {
519
519
  editor.selectAll().deleteShapes(editor.getSelectedShapeIds())
520
- editor.createShape({ id: ids.box1, type: 'geo', x: 25, y: 25 })
521
- editor.createShape({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
520
+ editor.createShape<TLGeoShape>({ id: ids.box1, type: 'geo', x: 25, y: 25 })
521
+ editor.createShape<TLFrameShape>({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
522
522
  })
523
523
 
524
524
  it('does not select the shape when clicked inside', () => {
@@ -548,8 +548,8 @@ describe('when shape is inside of a frame', () => {
548
548
  let frame1: TLFrameShape
549
549
  let box1: TLGeoShape
550
550
  beforeEach(() => {
551
- editor.createShape({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
552
- editor.createShape({
551
+ editor.createShape<TLFrameShape>({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
552
+ editor.createShape<TLGeoShape>({
553
553
  id: ids.box1,
554
554
  parentId: ids.frame1,
555
555
  type: 'geo',
@@ -703,15 +703,15 @@ describe('when a frame has multiple children', () => {
703
703
  let box2: TLGeoShape
704
704
  beforeEach(() => {
705
705
  editor
706
- .createShape({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
707
- .createShape({
706
+ .createShape<TLFrameShape>({ id: ids.frame1, type: 'frame', props: { w: 100, h: 100 } })
707
+ .createShape<TLGeoShape>({
708
708
  id: ids.box1,
709
709
  parentId: ids.frame1,
710
710
  type: 'geo',
711
711
  x: 25,
712
712
  y: 25,
713
713
  })
714
- .createShape({
714
+ .createShape<TLGeoShape>({
715
715
  id: ids.box2,
716
716
  parentId: ids.frame1,
717
717
  type: 'geo',
@@ -849,7 +849,7 @@ describe('When shapes are overlapping', () => {
849
849
  let box4: TLGeoShape
850
850
  let box5: TLGeoShape
851
851
  beforeEach(() => {
852
- editor.createShapes([
852
+ editor.createShapes<TLGeoShape>([
853
853
  {
854
854
  id: ids.box1,
855
855
  type: 'geo',
@@ -470,7 +470,7 @@ describe('When interacting with a shape...', () => {
470
470
  })
471
471
 
472
472
  it('Fires handle dragging cancel events', () => {
473
- const util = editor.getShapeUtil('line')
473
+ const util = editor.getShapeUtil<TLLineShape>('line')
474
474
 
475
475
  const calls: string[] = []
476
476
 
@@ -88,7 +88,7 @@ describe('Editor.styles', () => {
88
88
  })
89
89
 
90
90
  it('should return mixed for all mixed styles', () => {
91
- editor.updateShapes([
91
+ editor.updateShapes<TLGeoShape>([
92
92
  {
93
93
  id: defaultShapesIds.box1,
94
94
  type: 'geo',
@@ -1,4 +1,4 @@
1
- import { createShapeId, toRichText } from '@tldraw/editor'
1
+ import { TLGeoShape, createShapeId, toRichText } from '@tldraw/editor'
2
2
  import { TestEditor } from './TestEditor'
3
3
 
4
4
  let editor: TestEditor
@@ -14,7 +14,7 @@ afterEach(() => {
14
14
  it("When changing the style of a geo shape, if the text label is empty, don't measure it", () => {
15
15
  const id = createShapeId()
16
16
 
17
- editor.createShapes([
17
+ editor.createShapes<TLGeoShape>([
18
18
  {
19
19
  id,
20
20
  type: 'geo',
@@ -29,7 +29,7 @@ it("When changing the style of a geo shape, if the text label is empty, don't me
29
29
 
30
30
  const boundsBefore = editor.getShapeGeometry(id).bounds
31
31
 
32
- editor.updateShapes([
32
+ editor.updateShapes<TLGeoShape>([
33
33
  {
34
34
  id,
35
35
  type: 'geo',
@@ -43,7 +43,7 @@ it("When changing the style of a geo shape, if the text label is empty, don't me
43
43
  it('When changing the style of a geo shape, if the text label has text, measure it and possibly update the size', () => {
44
44
  const id = createShapeId()
45
45
 
46
- editor.createShapes([
46
+ editor.createShapes<TLGeoShape>([
47
47
  {
48
48
  id,
49
49
  type: 'geo',
@@ -58,7 +58,7 @@ it('When changing the style of a geo shape, if the text label has text, measure
58
58
 
59
59
  const boundsBefore = editor.getShapeGeometry(id).bounds!
60
60
 
61
- editor.updateShapes([
61
+ editor.updateShapes<TLGeoShape>([
62
62
  {
63
63
  id,
64
64
  type: 'geo',