tldraw 4.3.0-next.a10a6b62725c → 4.3.0-next.bad71ed2ab6a

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 +14 -5
  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 +1 -0
  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 +1 -4
  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 +11 -1
  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 +1 -2
  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 +8 -0
  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 +14 -5
  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 +1 -0
  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 +1 -4
  85. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  86. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +1 -4
  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 +1 -4
  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 +11 -1
  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 +1 -4
  105. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  106. package/dist-esm/lib/ui/context/actions.mjs +1 -2
  107. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  108. package/dist-esm/lib/ui/hooks/menu-hooks.mjs +1 -4
  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 +8 -0
  115. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  116. package/dist-esm/lib/utils/export/exportAs.mjs +1 -3
  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 +4 -9
  123. package/src/lib/defaultExternalContentHandlers.ts +3 -4
  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 +10 -2
  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 +2 -1
  141. package/src/lib/shapes/note/noteHelpers.ts +2 -2
  142. package/src/lib/shapes/shared/PlainTextLabel.tsx +2 -1
  143. package/src/lib/shapes/shared/RichTextLabel.tsx +2 -1
  144. package/src/lib/shapes/shared/crop.ts +1 -0
  145. package/src/lib/shapes/shared/useEditablePlainText.ts +7 -3
  146. package/src/lib/shapes/shared/useEditableRichText.ts +7 -3
  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 +3 -5
  150. package/src/lib/tools/EraserTool/childStates/Pointing.ts +3 -16
  151. package/src/lib/tools/SelectTool/DragAndDropManager.ts +2 -4
  152. package/src/lib/tools/SelectTool/childStates/Brushing.ts +2 -6
  153. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +2 -3
  154. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +4 -7
  155. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +2 -4
  156. package/src/lib/tools/SelectTool/childStates/Idle.ts +6 -10
  157. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +1 -1
  158. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +4 -12
  159. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +2 -2
  160. package/src/lib/tools/SelectTool/childStates/Resizing.ts +2 -4
  161. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +2 -4
  162. package/src/lib/tools/SelectTool/childStates/Translating.ts +1 -3
  163. package/src/lib/ui/components/EditLinkDialog.tsx +16 -6
  164. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -2
  165. package/src/lib/ui/components/menu-items.tsx +6 -14
  166. package/src/lib/ui/context/actions.tsx +9 -13
  167. package/src/lib/ui/hooks/menu-hooks.ts +9 -19
  168. package/src/lib/ui/hooks/useFlatten.ts +1 -2
  169. package/src/lib/ui/hooks/useTools.tsx +1 -2
  170. package/src/lib/ui/version.ts +3 -3
  171. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +8 -0
  172. package/src/lib/utils/export/exportAs.ts +2 -9
  173. package/src/lib/utils/frames/frames.ts +1 -1
  174. package/src/lib/utils/tldr/buildFromV1Document.ts +12 -17
  175. package/src/test/Editor.test.tsx +38 -12
  176. package/src/test/SelectTool.test.ts +11 -19
  177. package/src/test/TestEditor.ts +1 -4
  178. package/src/test/TldrawEditor.test.tsx +18 -16
  179. package/src/test/bindings.test.tsx +29 -25
  180. package/src/test/bindingsIndex.test.tsx +4 -4
  181. package/src/test/commands/createShape.test.ts +64 -0
  182. package/src/test/commands/createShapes.test.ts +15 -1
  183. package/src/test/commands/getSvgString.test.ts +2 -2
  184. package/src/test/commands/isShapeOfType.test.ts +44 -0
  185. package/src/test/commands/putContent.test.ts +1 -0
  186. package/src/test/commands/updateShape.test.ts +67 -0
  187. package/src/test/commands/updateShapes.test.ts +21 -5
  188. package/src/test/custom-clipping.test.ts +36 -35
  189. package/src/test/customSnapping.test.tsx +77 -62
  190. package/src/test/duplicate.test.ts +1 -1
  191. package/src/test/frames.test.ts +2 -2
  192. package/src/test/getCulledShapes.test.tsx +11 -3
  193. package/src/test/getShapeAtPoint.test.ts +2 -2
  194. package/src/test/groups.test.tsx +6 -3
  195. package/src/test/resizing.test.ts +9 -13
  196. package/src/test/selection-omnibus.test.ts +11 -11
  197. package/src/test/shapeutils.test.ts +1 -1
  198. package/src/test/styles2.test.tsx +1 -1
  199. package/src/test/styles3.test.ts +5 -5
  200. package/src/test/test-jsx.tsx +69 -57
  201. package/src/test/text.test.ts +15 -17
  202. package/src/test/translating.test.ts +6 -8
@@ -1,8 +1,6 @@
1
1
  import {
2
2
  Geometry2d,
3
3
  StateNode,
4
- TLFrameShape,
5
- TLGroupShape,
6
4
  TLShape,
7
5
  TLShapeId,
8
6
  Vec,
@@ -104,7 +102,7 @@ export class ScribbleBrushing extends StateNode {
104
102
 
105
103
  // If the shape is a group or is already selected or locked, don't select it
106
104
  if (
107
- editor.isShapeOfType<TLGroupShape>(shape, 'group') ||
105
+ editor.isShapeOfType(shape, 'group') ||
108
106
  newlySelectedShapeIds.has(shape.id) ||
109
107
  editor.isShapeOrAncestorLocked(shape)
110
108
  ) {
@@ -115,7 +113,7 @@ export class ScribbleBrushing extends StateNode {
115
113
 
116
114
  // If the scribble started inside of the frame, don't select it
117
115
  if (
118
- editor.isShapeOfType<TLFrameShape>(shape, 'frame') &&
116
+ editor.isShapeOfType(shape, 'frame') &&
119
117
  geometry.bounds.containsPoint(editor.getPointInShapeSpace(shape, originPagePoint))
120
118
  ) {
121
119
  continue
@@ -407,9 +407,7 @@ function getTranslatingSnapshot(editor: Editor) {
407
407
  const { originPagePoint } = editor.inputs
408
408
 
409
409
  const allHoveredNotes = shapeSnapshots.filter(
410
- (s) =>
411
- editor.isShapeOfType<TLNoteShape>(s.shape, 'note') &&
412
- editor.isPointInShape(s.shape, originPagePoint)
410
+ (s) => editor.isShapeOfType(s.shape, 'note') && editor.isPointInShape(s.shape, originPagePoint)
413
411
  ) as (MovingShapeSnapshot & { shape: TLNoteShape })[]
414
412
 
415
413
  if (allHoveredNotes.length === 0) {
@@ -1,4 +1,4 @@
1
- import { T, TLBaseShape, track, useEditor } from '@tldraw/editor'
1
+ import { ExtractShapeByProps, T, TLShape, track, useEditor } from '@tldraw/editor'
2
2
  import { useCallback, useEffect, useRef, useState } from 'react'
3
3
  import { TLUiDialogProps } from '../context/dialogs'
4
4
  import { useTranslation } from '../hooks/useTranslation/useTranslation'
@@ -25,20 +25,28 @@ function validateUrl(url: string) {
25
25
  return { isValid: false, hasProtocol: false }
26
26
  }
27
27
 
28
- type ShapeWithUrl = TLBaseShape<string, { url: string }>
28
+ type ShapeWithUrl = ExtractShapeByProps<{ url: string }>
29
+
30
+ function isShapeWithUrl(shape: TLShape | null | undefined): shape is ShapeWithUrl {
31
+ return !!(shape && 'url' in shape.props && typeof shape.props.url === 'string')
32
+ }
33
+
34
+ function assertShapeWithUrl(shape: TLShape | null | undefined): asserts shape is ShapeWithUrl {
35
+ if (!isShapeWithUrl(shape)) {
36
+ throw new Error('Shape is not a valid ShapeWithUrl')
37
+ }
38
+ }
29
39
 
30
40
  export const EditLinkDialog = track(function EditLinkDialog({ onClose }: TLUiDialogProps) {
31
41
  const editor = useEditor()
32
42
 
33
43
  const selectedShape = editor.getOnlySelectedShape()
34
44
 
35
- if (
36
- !(selectedShape && 'url' in selectedShape.props && typeof selectedShape.props.url === 'string')
37
- ) {
45
+ if (!isShapeWithUrl(selectedShape)) {
38
46
  return null
39
47
  }
40
48
 
41
- return <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape as ShapeWithUrl} />
49
+ return <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape} />
42
50
  })
43
51
 
44
52
  export const EditLinkDialogInner = track(function EditLinkDialogInner({
@@ -98,6 +106,7 @@ export const EditLinkDialogInner = track(function EditLinkDialogInner({
98
106
  const handleClear = useCallback(() => {
99
107
  const onlySelectedShape = editor.getOnlySelectedShape()
100
108
  if (!onlySelectedShape) return
109
+ assertShapeWithUrl(onlySelectedShape)
101
110
  editor.updateShapes([
102
111
  { id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: '' } },
103
112
  ])
@@ -108,6 +117,7 @@ export const EditLinkDialogInner = track(function EditLinkDialogInner({
108
117
  const onlySelectedShape = editor.getOnlySelectedShape()
109
118
 
110
119
  if (!onlySelectedShape) return
120
+ assertShapeWithUrl(onlySelectedShape)
111
121
 
112
122
  // ? URL is a magic value
113
123
  if (onlySelectedShape && 'url' in onlySelectedShape.props) {
@@ -1,4 +1,4 @@
1
- import { preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'
1
+ import { ExtractShapeByProps, preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'
2
2
  import { useCallback, useEffect, useRef, useState } from 'react'
3
3
  import { useUiEvents } from '../../context/events'
4
4
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
@@ -31,7 +31,7 @@ export function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps)
31
31
 
32
32
  const handleComplete = () => {
33
33
  trackEvent('set-alt-text', { source })
34
- const shape = editor.getShape<TLShape & { props: { altText: string } }>(shapeId)
34
+ const shape = editor.getShape<ExtractShapeByProps<{ altText: string }>>(shapeId)
35
35
  if (!shape) return
36
36
  editor.updateShapes([
37
37
  {
@@ -1,12 +1,4 @@
1
- import {
2
- TLBookmarkShape,
3
- TLEmbedShape,
4
- TLFrameShape,
5
- TLImageShape,
6
- TLPageId,
7
- useEditor,
8
- useValue,
9
- } from '@tldraw/editor'
1
+ import { TLPageId, useEditor, useValue } from '@tldraw/editor'
10
2
  import { supportsDownloadingOriginal } from '../context/actions'
11
3
  import { useUiEvents } from '../context/events'
12
4
  import { useToasts } from '../context/toasts'
@@ -64,7 +56,7 @@ export function FlattenMenuItem() {
64
56
  const selectedShapeIds = editor.getSelectedShapeIds()
65
57
  if (selectedShapeIds.length === 0) return false
66
58
  const onlySelectedShape = editor.getOnlySelectedShape()
67
- if (onlySelectedShape && editor.isShapeOfType<TLImageShape>(onlySelectedShape, 'image')) {
59
+ if (onlySelectedShape && editor.isShapeOfType(onlySelectedShape, 'image')) {
68
60
  return false
69
61
  }
70
62
  return true
@@ -117,7 +109,7 @@ export function RemoveFrameMenuItem() {
117
109
  () => {
118
110
  const selectedShapes = editor.getSelectedShapes()
119
111
  if (selectedShapes.length === 0) return false
120
- return selectedShapes.every((shape) => editor.isShapeOfType<TLFrameShape>(shape, 'frame'))
112
+ return selectedShapes.every((shape) => editor.isShapeOfType(shape, 'frame'))
121
113
  },
122
114
  [editor]
123
115
  )
@@ -135,7 +127,7 @@ export function FitFrameToContentMenuItem() {
135
127
  const onlySelectedShape = editor.getOnlySelectedShape()
136
128
  if (!onlySelectedShape) return false
137
129
  return (
138
- editor.isShapeOfType<TLFrameShape>(onlySelectedShape, 'frame') &&
130
+ editor.isShapeOfType(onlySelectedShape, 'frame') &&
139
131
  editor.getSortedChildIdsForParent(onlySelectedShape).length > 0
140
132
  )
141
133
  },
@@ -518,7 +510,7 @@ export function ConvertToBookmarkMenuItem() {
518
510
  const onlySelectedShape = editor.getOnlySelectedShape()
519
511
  if (!onlySelectedShape) return false
520
512
  return !!(
521
- editor.isShapeOfType<TLEmbedShape>(onlySelectedShape, 'embed') &&
513
+ editor.isShapeOfType(onlySelectedShape, 'embed') &&
522
514
  onlySelectedShape.props.url &&
523
515
  !editor.isShapeOrAncestorLocked(onlySelectedShape)
524
516
  )
@@ -542,7 +534,7 @@ export function ConvertToEmbedMenuItem() {
542
534
  const onlySelectedShape = editor.getOnlySelectedShape()
543
535
  if (!onlySelectedShape) return false
544
536
  return !!(
545
- editor.isShapeOfType<TLBookmarkShape>(onlySelectedShape, 'bookmark') &&
537
+ editor.isShapeOfType(onlySelectedShape, 'bookmark') &&
546
538
  onlySelectedShape.props.url &&
547
539
  getEmbedDefinition(onlySelectedShape.props.url) &&
548
540
  !editor.isShapeOrAncestorLocked(onlySelectedShape)
@@ -6,10 +6,7 @@ import {
6
6
  HALF_PI,
7
7
  PageRecordType,
8
8
  Result,
9
- TLBookmarkShape,
10
9
  TLEmbedShape,
11
- TLFrameShape,
12
- TLGroupShape,
13
10
  TLImageShape,
14
11
  TLShape,
15
12
  TLShapeId,
@@ -327,7 +324,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
327
324
  .getSelectedShapes()
328
325
  .filter(
329
326
  (shape): shape is TLTextShape =>
330
- editor.isShapeOfType<TLTextShape>(shape, 'text') && shape.props.autoSize === false
327
+ editor.isShapeOfType(shape, 'text') && shape.props.autoSize === false
331
328
  )
332
329
  editor.updateShapes(
333
330
  shapes.map((shape) => {
@@ -362,7 +359,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
362
359
  return
363
360
  }
364
361
  const shape = editor.getShape(ids[0])
365
- if (!shape || !editor.isShapeOfType<TLEmbedShape>(shape, 'embed')) {
362
+ if (!shape || !editor.isShapeOfType(shape, 'embed')) {
366
363
  console.error(warnMsg)
367
364
  return
368
365
  }
@@ -401,8 +398,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
401
398
  const creationPromises: Promise<Result<any, any>>[] = []
402
399
 
403
400
  for (const shape of shapes) {
404
- if (!shape || !editor.isShapeOfType<TLEmbedShape>(shape, 'embed') || !shape.props.url)
405
- continue
401
+ if (!shape || !editor.isShapeOfType(shape, 'embed') || !shape.props.url) continue
406
402
 
407
403
  const center = editor.getShapePageBounds(shape)?.center
408
404
 
@@ -441,7 +437,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
441
437
  const createList: TLShapePartial[] = []
442
438
  const deleteList: TLShapeId[] = []
443
439
  for (const shape of shapes) {
444
- if (!editor.isShapeOfType<TLBookmarkShape>(shape, 'bookmark')) continue
440
+ if (!editor.isShapeOfType(shape, 'bookmark')) continue
445
441
 
446
442
  const { url } = shape.props
447
443
 
@@ -552,7 +548,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
552
548
 
553
549
  trackEvent('group-shapes', { source })
554
550
  const onlySelectedShape = editor.getOnlySelectedShape()
555
- if (onlySelectedShape && editor.isShapeOfType<TLGroupShape>(onlySelectedShape, 'group')) {
551
+ if (onlySelectedShape && editor.isShapeOfType(onlySelectedShape, 'group')) {
556
552
  editor.markHistoryStoppingPoint('ungroup')
557
553
  editor.ungroupShapes(editor.getSelectedShapeIds())
558
554
  } else {
@@ -572,7 +568,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
572
568
  const selectedShapes = editor.getSelectedShapes()
573
569
  if (
574
570
  selectedShapes.length > 0 &&
575
- selectedShapes.every((shape) => editor.isShapeOfType<TLFrameShape>(shape, 'frame'))
571
+ selectedShapes.every((shape) => editor.isShapeOfType(shape, 'frame'))
576
572
  ) {
577
573
  editor.markHistoryStoppingPoint('remove-frame')
578
574
  removeFrame(
@@ -590,7 +586,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
590
586
 
591
587
  trackEvent('fit-frame-to-content', { source })
592
588
  const onlySelectedShape = editor.getOnlySelectedShape()
593
- if (onlySelectedShape && editor.isShapeOfType<TLFrameShape>(onlySelectedShape, 'frame')) {
589
+ if (onlySelectedShape && editor.isShapeOfType(onlySelectedShape, 'frame')) {
594
590
  editor.markHistoryStoppingPoint('fit-frame-to-content')
595
591
  fitFrameToContent(editor, onlySelectedShape.id)
596
592
  }
@@ -1599,8 +1595,8 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
1599
1595
  const onlySelectedShape = editor.getOnlySelectedShape()
1600
1596
  if (
1601
1597
  onlySelectedShape &&
1602
- (editor.isShapeOfType<TLImageShape>(onlySelectedShape, 'image') ||
1603
- editor.isShapeOfType<TLVideoShape>(onlySelectedShape, 'video'))
1598
+ (editor.isShapeOfType(onlySelectedShape, 'image') ||
1599
+ editor.isShapeOfType(onlySelectedShape, 'video'))
1604
1600
  ) {
1605
1601
  const firstToolbarButton = editor
1606
1602
  .getContainer()
@@ -1,14 +1,4 @@
1
- import {
2
- Editor,
3
- TLArrowShape,
4
- TLDrawShape,
5
- TLGroupShape,
6
- TLImageShape,
7
- TLLineShape,
8
- TLTextShape,
9
- useEditor,
10
- useValue,
11
- } from '@tldraw/editor'
1
+ import { Editor, useEditor, useValue } from '@tldraw/editor'
12
2
  import { getArrowBindings } from '../../shapes/arrow/shared'
13
3
 
14
4
  function shapesWithUnboundArrows(editor: Editor) {
@@ -19,7 +9,7 @@ function shapesWithUnboundArrows(editor: Editor) {
19
9
 
20
10
  return selectedShapes.filter((shape) => {
21
11
  if (!shape) return false
22
- if (editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {
12
+ if (editor.isShapeOfType(shape, 'arrow')) {
23
13
  const bindings = getArrowBindings(editor, shape)
24
14
  if (bindings.start || bindings.end) return false
25
15
  }
@@ -52,7 +42,7 @@ export const useAllowGroup = () => {
52
42
  if (selectedShapes.length < 2) return false
53
43
 
54
44
  for (const shape of selectedShapes) {
55
- if (editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {
45
+ if (editor.isShapeOfType(shape, 'arrow')) {
56
46
  const bindings = getArrowBindings(editor, shape)
57
47
  if (bindings.start) {
58
48
  // if the other shape is not among the selected shapes...
@@ -163,7 +153,7 @@ export function useShowAutoSizeToggle() {
163
153
  const selectedShapes = editor.getSelectedShapes()
164
154
  return (
165
155
  selectedShapes.length === 1 &&
166
- editor.isShapeOfType<TLTextShape>(selectedShapes[0], 'text') &&
156
+ editor.isShapeOfType(selectedShapes[0], 'text') &&
167
157
  selectedShapes[0].props.autoSize === false
168
158
  )
169
159
  },
@@ -196,11 +186,11 @@ export function useOnlyFlippableShape() {
196
186
  const shape = editor.getOnlySelectedShape()
197
187
  return (
198
188
  shape &&
199
- (editor.isShapeOfType<TLGroupShape>(shape, 'group') ||
200
- editor.isShapeOfType<TLImageShape>(shape, 'image') ||
201
- editor.isShapeOfType<TLArrowShape>(shape, 'arrow') ||
202
- editor.isShapeOfType<TLLineShape>(shape, 'line') ||
203
- editor.isShapeOfType<TLDrawShape>(shape, 'draw'))
189
+ (editor.isShapeOfType(shape, 'group') ||
190
+ editor.isShapeOfType(shape, 'image') ||
191
+ editor.isShapeOfType(shape, 'arrow') ||
192
+ editor.isShapeOfType(shape, 'line') ||
193
+ editor.isShapeOfType(shape, 'draw'))
204
194
  )
205
195
  },
206
196
  [editor]
@@ -3,7 +3,6 @@ import {
3
3
  Editor,
4
4
  IndexKey,
5
5
  TLImageAsset,
6
- TLImageShape,
7
6
  TLShape,
8
7
  TLShapeId,
9
8
  Vec,
@@ -166,7 +165,7 @@ export async function flattenShapesToImages(
166
165
  const shapeId = createShapeId()
167
166
 
168
167
  // create an image shape in the same place as the shapes
169
- editor.createShape<TLImageShape>({
168
+ editor.createShape({
170
169
  id: shapeId,
171
170
  type: 'image',
172
171
  index,
@@ -4,7 +4,6 @@ import {
4
4
  Editor,
5
5
  GeoShapeGeoStyle,
6
6
  getIndicesBetween,
7
- TLLineShape,
8
7
  TLPointerEventInfo,
9
8
  TLShapeId,
10
9
  toRichText,
@@ -195,7 +194,7 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
195
194
  onDragFromToolbarToCreateShape(editor, info, {
196
195
  createShape: (id) => {
197
196
  const [start, end] = getIndicesBetween(null, null, 2)
198
- editor.createShape<TLLineShape>({
197
+ editor.createShape({
199
198
  id,
200
199
  type: 'line',
201
200
  props: {
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '4.3.0-next.a10a6b62725c'
4
+ export const version = '4.3.0-next.bad71ed2ab6a'
5
5
  export const publishDates = {
6
6
  major: '2025-09-18T14:39:22.803Z',
7
- minor: '2025-11-19T17:01:11.304Z',
8
- patch: '2025-11-19T17:01:11.304Z',
7
+ minor: '2025-11-28T07:50:37.384Z',
8
+ patch: '2025-11-28T07:50:37.384Z',
9
9
  }
@@ -133,6 +133,7 @@ export async function putExcalidrawContent(
133
133
  ...base,
134
134
  type: 'geo',
135
135
  props: {
136
+ ...editor.getShapeUtil('geo').getDefaultProps(),
136
137
  geo: element.type,
137
138
  url: element.link ?? '',
138
139
  w: element.width,
@@ -152,6 +153,7 @@ export async function putExcalidrawContent(
152
153
  ...base,
153
154
  type: 'draw',
154
155
  props: {
156
+ ...editor.getShapeUtil('draw').getDefaultProps(),
155
157
  dash: getDash(element),
156
158
  size: strokeWidthsToSizes[element.strokeWidth],
157
159
  color: colorsToColors[element.strokeColor] ?? 'black',
@@ -180,6 +182,7 @@ export async function putExcalidrawContent(
180
182
  ...base,
181
183
  type: 'line',
182
184
  props: {
185
+ ...editor.getShapeUtil('line').getDefaultProps(),
183
186
  dash: getDash(element),
184
187
  size: strokeWidthsToSizes[element.strokeWidth],
185
188
  color: colorsToColors[element.strokeColor] ?? 'black',
@@ -221,6 +224,7 @@ export async function putExcalidrawContent(
221
224
  ...base,
222
225
  type: 'arrow',
223
226
  props: {
227
+ ...editor.getShapeUtil('arrow').getDefaultProps(),
224
228
  richText: toRichText(text),
225
229
  kind: element.elbowed ? 'elbow' : 'arc',
226
230
  bend: getBend(element, start, end),
@@ -243,6 +247,7 @@ export async function putExcalidrawContent(
243
247
  toId: startTargetId,
244
248
  props: {
245
249
  terminal: 'start',
250
+ snap: 'none',
246
251
  normalizedAnchor: { x: 0.5, y: 0.5 },
247
252
  isPrecise: false,
248
253
  isExact: false,
@@ -259,6 +264,7 @@ export async function putExcalidrawContent(
259
264
  toId: endTargetId,
260
265
  props: {
261
266
  terminal: 'end',
267
+ snap: 'none',
262
268
  normalizedAnchor: { x: 0.5, y: 0.5 },
263
269
  isPrecise: false,
264
270
  isExact: false,
@@ -275,6 +281,7 @@ export async function putExcalidrawContent(
275
281
  ...base,
276
282
  type: 'text',
277
283
  props: {
284
+ ...editor.getShapeUtil('text').getDefaultProps(),
278
285
  size,
279
286
  scale,
280
287
  font: fontFamilyToFontType[element.fontFamily] ?? 'draw',
@@ -310,6 +317,7 @@ export async function putExcalidrawContent(
310
317
  ...base,
311
318
  type: 'image',
312
319
  props: {
320
+ ...editor.getShapeUtil('image').getDefaultProps(),
313
321
  w: element.width,
314
322
  h: element.height,
315
323
  assetId,
@@ -1,11 +1,4 @@
1
- import {
2
- Editor,
3
- sanitizeId,
4
- TLExportType,
5
- TLFrameShape,
6
- TLImageExportOptions,
7
- TLShapeId,
8
- } from '@tldraw/editor'
1
+ import { Editor, sanitizeId, TLExportType, TLImageExportOptions, TLShapeId } from '@tldraw/editor'
9
2
 
10
3
  /** @public */
11
4
  export interface ExportAsOptions extends TLImageExportOptions {
@@ -35,7 +28,7 @@ export async function exportAs(
35
28
  name = `shapes at ${getTimestamp()}`
36
29
  if (ids.length === 1) {
37
30
  const first = editor.getShape(ids[0])!
38
- if (editor.isShapeOfType<TLFrameShape>(first, 'frame')) {
31
+ if (editor.isShapeOfType(first, 'frame')) {
39
32
  name = first.props.name || 'frame'
40
33
  } else {
41
34
  name = `${sanitizeId(first.id)} at ${getTimestamp()}`
@@ -22,7 +22,7 @@ export function removeFrame(editor: Editor, ids: TLShapeId[]) {
22
22
  const frames = compact(
23
23
  ids
24
24
  .map((id) => editor.getShape<TLFrameShape>(id))
25
- .filter((f) => f && editor.isShapeOfType<TLFrameShape>(f, 'frame'))
25
+ .filter((f) => f && editor.isShapeOfType(f, 'frame'))
26
26
  )
27
27
  if (!frames.length) return
28
28
 
@@ -12,14 +12,9 @@ import {
12
12
  TLDefaultHorizontalAlignStyle,
13
13
  TLDefaultSizeStyle,
14
14
  TLDefaultTextAlignStyle,
15
- TLDrawShape,
16
15
  TLGeoShape,
17
- TLImageShape,
18
- TLNoteShape,
19
16
  TLPageId,
20
17
  TLShapeId,
21
- TLTextShape,
22
- TLVideoShape,
23
18
  Vec,
24
19
  VecModel,
25
20
  clamp,
@@ -187,7 +182,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
187
182
 
188
183
  switch (v1Shape.type) {
189
184
  case TLV1ShapeType.Sticky: {
190
- editor.createShapes<TLNoteShape>([
185
+ editor.createShapes([
191
186
  {
192
187
  ...inCommon,
193
188
  type: 'note',
@@ -203,7 +198,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
203
198
  break
204
199
  }
205
200
  case TLV1ShapeType.Rectangle: {
206
- editor.createShapes<TLGeoShape>([
201
+ editor.createShapes([
207
202
  {
208
203
  ...inCommon,
209
204
  type: 'geo',
@@ -225,7 +220,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
225
220
 
226
221
  const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id)!
227
222
 
228
- editor.updateShapes<TLGeoShape>([
223
+ editor.updateShapes([
229
224
  {
230
225
  id: inCommon.id,
231
226
  type: 'geo',
@@ -259,7 +254,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
259
254
  break
260
255
  }
261
256
  case TLV1ShapeType.Triangle: {
262
- editor.createShapes<TLGeoShape>([
257
+ editor.createShapes([
263
258
  {
264
259
  ...inCommon,
265
260
  type: 'geo',
@@ -280,7 +275,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
280
275
 
281
276
  const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id)!
282
277
 
283
- editor.updateShapes<TLGeoShape>([
278
+ editor.updateShapes([
284
279
  {
285
280
  id: inCommon.id,
286
281
  type: 'geo',
@@ -314,7 +309,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
314
309
  break
315
310
  }
316
311
  case TLV1ShapeType.Ellipse: {
317
- editor.createShapes<TLGeoShape>([
312
+ editor.createShapes([
318
313
  {
319
314
  ...inCommon,
320
315
  type: 'geo',
@@ -335,7 +330,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
335
330
 
336
331
  const pageBoundsBeforeLabel = editor.getShapePageBounds(inCommon.id)!
337
332
 
338
- editor.updateShapes<TLGeoShape>([
333
+ editor.updateShapes([
339
334
  {
340
335
  id: inCommon.id,
341
336
  type: 'geo',
@@ -375,7 +370,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
375
370
  break
376
371
  }
377
372
 
378
- editor.createShapes<TLDrawShape>([
373
+ editor.createShapes([
379
374
  {
380
375
  ...inCommon,
381
376
  type: 'draw',
@@ -400,7 +395,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
400
395
  const v2Bend = (dist * -v1Bend) / 2
401
396
 
402
397
  // Could also be a line... but we'll use it as an arrow anyway
403
- editor.createShapes<TLArrowShape>([
398
+ editor.createShapes([
404
399
  {
405
400
  ...inCommon,
406
401
  type: 'arrow',
@@ -429,7 +424,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
429
424
  break
430
425
  }
431
426
  case TLV1ShapeType.Text: {
432
- editor.createShapes<TLTextShape>([
427
+ editor.createShapes([
433
428
  {
434
429
  ...inCommon,
435
430
  type: 'text',
@@ -453,7 +448,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
453
448
  return
454
449
  }
455
450
 
456
- editor.createShapes<TLImageShape>([
451
+ editor.createShapes([
457
452
  {
458
453
  ...inCommon,
459
454
  type: 'image',
@@ -474,7 +469,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
474
469
  return
475
470
  }
476
471
 
477
- editor.createShapes<TLVideoShape>([
472
+ editor.createShapes([
478
473
  {
479
474
  ...inCommon,
480
475
  type: 'video',
@@ -472,12 +472,20 @@ describe('isFocused', () => {
472
472
  })
473
473
  })
474
474
 
475
+ const BLORG_TYPE = 'blorg'
476
+
477
+ declare module '@tldraw/tlschema' {
478
+ export interface TLGlobalShapePropsMap {
479
+ [BLORG_TYPE]: { w: number; h: number }
480
+ }
481
+ }
482
+
475
483
  describe('getShapeUtil', () => {
476
484
  let myUtil: any
477
485
 
478
486
  beforeEach(() => {
479
487
  class _MyFakeShapeUtil extends BaseBoxShapeUtil<any> {
480
- static override type = 'blorg'
488
+ static override type = BLORG_TYPE
481
489
 
482
490
  getDefaultProps() {
483
491
  return {
@@ -519,16 +527,22 @@ describe('getShapeUtil', () => {
519
527
  })
520
528
 
521
529
  it('throws if that shape type isnt registered', () => {
522
- const myMissingShape = { type: 'missing' } as TLShape
523
- expect(() => editor.getShapeUtil(myMissingShape)).toThrowErrorMatchingInlineSnapshot(
524
- `[Error: No shape util found for type "missing"]`
525
- )
530
+ const myMissingShape = { type: 'missing' }
531
+ expect(() =>
532
+ editor.getShapeUtil(
533
+ // @ts-expect-error
534
+ myMissingShape
535
+ )
536
+ ).toThrowErrorMatchingInlineSnapshot(`[Error: No shape util found for type "missing"]`)
526
537
  })
527
538
 
528
539
  it('throws if that type isnt registered', () => {
529
- expect(() => editor.getShapeUtil('missing')).toThrowErrorMatchingInlineSnapshot(
530
- `[Error: No shape util found for type "missing"]`
531
- )
540
+ expect(() =>
541
+ editor.getShapeUtil(
542
+ // @ts-expect-error
543
+ 'missing'
544
+ )
545
+ ).toThrowErrorMatchingInlineSnapshot(`[Error: No shape util found for type "missing"]`)
532
546
  })
533
547
  })
534
548
 
@@ -866,9 +880,19 @@ describe('instance.isReadonly', () => {
866
880
  })
867
881
  })
868
882
 
883
+ const MY_CUSTOM_SHAPE_TYPE = 'myCustomShape'
884
+
885
+ type MyCustomShape = TLShape<typeof MY_CUSTOM_SHAPE_TYPE>
886
+
887
+ declare module '@tldraw/tlschema' {
888
+ export interface TLGlobalShapePropsMap {
889
+ [MY_CUSTOM_SHAPE_TYPE]: { w: number; h: number }
890
+ }
891
+ }
892
+
869
893
  describe('the geometry cache', () => {
870
- class CustomShapeUtil extends BaseBoxShapeUtil<any> {
871
- static override type = 'custom'
894
+ class CustomShapeUtil extends BaseBoxShapeUtil<MyCustomShape> {
895
+ static override type = MY_CUSTOM_SHAPE_TYPE
872
896
 
873
897
  getDefaultProps() {
874
898
  return {
@@ -894,9 +918,11 @@ describe('the geometry cache', () => {
894
918
  editor = new TestEditor({
895
919
  shapeUtils: [CustomShapeUtil],
896
920
  })
897
- const { A } = editor.createShapesFromJsx([<TL.custom ref="A" x={0} y={0} w={100} h={100} />])
921
+ const { A } = editor.createShapesFromJsx([
922
+ <TL.myCustomShape ref="A" x={0} y={0} w={100} h={100} />,
923
+ ])
898
924
  expect(editor.getShapePageBounds(A)!.width).toBe(100)
899
- editor.updateShape({ id: A, type: 'custom', meta: { double: true } })
925
+ editor.updateShape({ id: A, type: 'myCustomShape', meta: { double: true } })
900
926
  expect(editor.getShapePageBounds(A)!.width).toBe(200)
901
927
  })
902
928
  })