tldraw 4.3.0-canary.d8da2a99f394 → 4.3.0-canary.e1766dd4eab3

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 (310) hide show
  1. package/dist-cjs/index.d.ts +26 -5
  2. package/dist-cjs/index.js +2 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
  5. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +2 -2
  6. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +9 -12
  9. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  11. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  13. package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +2 -2
  14. package/dist-cjs/lib/shapes/arrow/shared.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  16. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  17. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  18. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  19. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
  20. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  21. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
  22. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +1 -1
  23. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +10 -6
  25. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  26. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  27. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +1 -1
  28. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  30. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +5 -5
  31. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  33. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +2 -1
  34. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  35. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +14 -2
  36. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +3 -3
  37. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +11 -3
  38. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +3 -3
  39. package/dist-cjs/lib/shapes/shared/ShapeFill.js +2 -2
  40. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  41. package/dist-cjs/lib/shapes/shared/crop.js +1 -0
  42. package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
  43. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  44. package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
  45. package/dist-cjs/lib/shapes/shared/{useForceSolid.js → useEfficientZoomThreshold.js} +10 -7
  46. package/dist-cjs/lib/shapes/shared/useEfficientZoomThreshold.js.map +7 -0
  47. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +1 -1
  48. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  49. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +5 -2
  50. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  51. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  52. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  53. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
  54. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  55. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  56. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +1 -4
  57. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  58. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  59. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  60. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +1 -1
  61. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  62. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js +30 -10
  63. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  64. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  65. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  66. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  67. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  68. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  69. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
  70. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  71. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js +3 -9
  72. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js.map +2 -2
  73. package/dist-cjs/lib/ui/components/EditLinkDialog.js +11 -1
  74. package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
  75. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  76. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js +1 -1
  77. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js.map +2 -2
  78. package/dist-cjs/lib/ui/components/menu-items.js +3 -1
  79. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  80. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  81. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  82. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +143 -88
  83. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  84. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +1 -1
  85. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  86. package/dist-cjs/lib/ui/context/actions.js +1 -2
  87. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  88. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  89. package/dist-cjs/lib/ui/hooks/useFlatten.js.map +2 -2
  90. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  91. package/dist-cjs/lib/ui/version.js +3 -3
  92. package/dist-cjs/lib/ui/version.js.map +1 -1
  93. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +8 -0
  94. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  95. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  96. package/dist-cjs/lib/utils/frames/frames.js.map +2 -2
  97. package/dist-cjs/lib/utils/text/richText.js +7 -17
  98. package/dist-cjs/lib/utils/text/richText.js.map +3 -3
  99. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  100. package/dist-esm/index.d.mts +26 -5
  101. package/dist-esm/index.mjs +3 -1
  102. package/dist-esm/index.mjs.map +2 -2
  103. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  104. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +2 -2
  105. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  106. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  107. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +10 -14
  108. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  109. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  110. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  111. package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +2 -2
  112. package/dist-esm/lib/shapes/arrow/shared.mjs.map +2 -2
  113. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  114. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  115. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -3
  116. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  117. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
  118. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  119. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
  120. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +1 -1
  121. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  122. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +10 -6
  123. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  124. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  125. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +1 -1
  126. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  127. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  128. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -5
  129. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  130. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  131. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +3 -2
  132. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +14 -2
  134. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  135. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +11 -3
  136. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  137. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +2 -2
  138. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  139. package/dist-esm/lib/shapes/shared/crop.mjs +1 -0
  140. package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
  141. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  142. package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
  143. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs +12 -0
  144. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs.map +7 -0
  145. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +1 -1
  146. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  147. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +5 -2
  148. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  149. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  150. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +1 -1
  151. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
  152. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  153. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +1 -4
  154. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  155. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +1 -4
  156. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  157. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  158. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  159. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +1 -1
  160. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  161. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs +30 -10
  162. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  163. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  164. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  165. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +1 -4
  166. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  167. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  168. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  169. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
  170. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  171. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs +2 -8
  172. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs.map +2 -2
  173. package/dist-esm/lib/ui/components/EditLinkDialog.mjs +11 -1
  174. package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
  175. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  176. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs +1 -1
  177. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs.map +2 -2
  178. package/dist-esm/lib/ui/components/menu-items.mjs +4 -5
  179. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  180. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -2
  181. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  182. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +151 -90
  183. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  184. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -2
  185. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  186. package/dist-esm/lib/ui/context/actions.mjs +1 -2
  187. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  188. package/dist-esm/lib/ui/hooks/menu-hooks.mjs +1 -4
  189. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  190. package/dist-esm/lib/ui/hooks/useFlatten.mjs.map +2 -2
  191. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  192. package/dist-esm/lib/ui/version.mjs +3 -3
  193. package/dist-esm/lib/ui/version.mjs.map +1 -1
  194. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +8 -0
  195. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  196. package/dist-esm/lib/utils/export/exportAs.mjs +1 -3
  197. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  198. package/dist-esm/lib/utils/frames/frames.mjs.map +2 -2
  199. package/dist-esm/lib/utils/text/richText.mjs +3 -3
  200. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  201. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  202. package/package.json +10 -10
  203. package/src/index.ts +1 -0
  204. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +1 -1
  205. package/src/lib/canvas/TldrawSelectionForeground.tsx +6 -11
  206. package/src/lib/defaultExternalContentHandlers.ts +3 -4
  207. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +2 -2
  208. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +11 -13
  209. package/src/lib/shapes/arrow/arrow-types.ts +2 -0
  210. package/src/lib/shapes/arrow/arrowLabel.ts +1 -1
  211. package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
  212. package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +3 -3
  213. package/src/lib/shapes/arrow/shared.ts +4 -4
  214. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +1 -1
  215. package/src/lib/shapes/bookmark/bookmarks.ts +3 -3
  216. package/src/lib/shapes/draw/DrawShapeUtil.tsx +3 -3
  217. package/src/lib/shapes/draw/toolStates/Drawing.ts +4 -4
  218. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  219. package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
  220. package/src/lib/shapes/frame/FrameShapeUtil.tsx +1 -1
  221. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +10 -2
  222. package/src/lib/shapes/geo/GeoShapeUtil.tsx +9 -4
  223. package/src/lib/shapes/geo/toolStates/Pointing.ts +3 -3
  224. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +1 -1
  225. package/src/lib/shapes/line/LineShapeTool.test.ts +6 -6
  226. package/src/lib/shapes/line/LineShapeUtil.test.tsx +5 -5
  227. package/src/lib/shapes/line/toolStates/Pointing.ts +1 -1
  228. package/src/lib/shapes/note/NoteShapeTool.test.ts +2 -1
  229. package/src/lib/shapes/note/NoteShapeUtil.tsx +7 -8
  230. package/src/lib/shapes/note/noteHelpers.ts +2 -2
  231. package/src/lib/shapes/shared/HyperlinkButton.tsx +3 -2
  232. package/src/lib/shapes/shared/PlainTextLabel.tsx +12 -2
  233. package/src/lib/shapes/shared/RichTextLabel.tsx +13 -3
  234. package/src/lib/shapes/shared/ShapeFill.tsx +2 -2
  235. package/src/lib/shapes/shared/crop.ts +1 -0
  236. package/src/lib/shapes/shared/useEditablePlainText.ts +7 -3
  237. package/src/lib/shapes/shared/useEditableRichText.ts +7 -3
  238. package/src/lib/shapes/shared/useEfficientZoomThreshold.ts +10 -0
  239. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +1 -1
  240. package/src/lib/shapes/text/TextShapeTool.test.ts +4 -4
  241. package/src/lib/shapes/text/TextShapeUtil.tsx +5 -0
  242. package/src/lib/shapes/text/toolStates/Pointing.ts +1 -1
  243. package/src/lib/shapes/video/VideoShapeUtil.tsx +2 -1
  244. package/src/lib/tools/EraserTool/childStates/Erasing.ts +3 -5
  245. package/src/lib/tools/EraserTool/childStates/Pointing.ts +3 -16
  246. package/src/lib/tools/SelectTool/DragAndDropManager.ts +2 -4
  247. package/src/lib/tools/SelectTool/childStates/Brushing.ts +2 -6
  248. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +2 -3
  249. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +4 -7
  250. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +46 -15
  251. package/src/lib/tools/SelectTool/childStates/Idle.ts +6 -10
  252. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +1 -1
  253. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +4 -12
  254. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +2 -2
  255. package/src/lib/tools/SelectTool/childStates/Resizing.ts +2 -4
  256. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +2 -4
  257. package/src/lib/tools/SelectTool/childStates/Translating.ts +1 -3
  258. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx +1 -9
  259. package/src/lib/ui/components/EditLinkDialog.tsx +16 -6
  260. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -2
  261. package/src/lib/ui/components/ZoomMenu/DefaultZoomMenu.tsx +1 -1
  262. package/src/lib/ui/components/menu-items.tsx +9 -15
  263. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
  264. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +196 -108
  265. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +2 -2
  266. package/src/lib/ui/context/actions.tsx +9 -13
  267. package/src/lib/ui/hooks/menu-hooks.ts +9 -19
  268. package/src/lib/ui/hooks/useFlatten.ts +1 -2
  269. package/src/lib/ui/hooks/useTools.tsx +1 -2
  270. package/src/lib/ui/version.ts +3 -3
  271. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +8 -0
  272. package/src/lib/utils/export/exportAs.ts +2 -9
  273. package/src/lib/utils/frames/frames.ts +1 -1
  274. package/src/lib/utils/text/richText.ts +3 -3
  275. package/src/lib/utils/tldr/buildFromV1Document.ts +12 -17
  276. package/src/test/Editor.test.tsx +38 -12
  277. package/src/test/SelectTool.test.ts +11 -19
  278. package/src/test/TestEditor.ts +1 -4
  279. package/src/test/TldrawEditor.test.tsx +21 -18
  280. package/src/test/bindings.test.tsx +29 -25
  281. package/src/test/bindingsIndex.test.tsx +4 -4
  282. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
  283. package/src/test/commands/cameraState.test.ts +299 -0
  284. package/src/test/commands/createShape.test.ts +64 -0
  285. package/src/test/commands/createShapes.test.ts +15 -1
  286. package/src/test/commands/getSvgString.test.ts +2 -2
  287. package/src/test/commands/isShapeOfType.test.ts +44 -0
  288. package/src/test/commands/putContent.test.ts +80 -1
  289. package/src/test/commands/updateShape.test.ts +67 -0
  290. package/src/test/commands/updateShapes.test.ts +21 -5
  291. package/src/test/custom-clipping.test.ts +36 -35
  292. package/src/test/customSnapping.test.tsx +77 -62
  293. package/src/test/duplicate.test.ts +1 -1
  294. package/src/test/frames.test.ts +2 -2
  295. package/src/test/getCulledShapes.test.tsx +11 -3
  296. package/src/test/getShapeAtPoint.test.ts +2 -2
  297. package/src/test/groups.test.tsx +6 -3
  298. package/src/test/resizing.test.ts +9 -13
  299. package/src/test/selection-omnibus.test.ts +11 -11
  300. package/src/test/shapeutils.test.ts +1 -1
  301. package/src/test/styles2.test.tsx +1 -1
  302. package/src/test/styles3.test.ts +5 -5
  303. package/src/test/test-jsx.tsx +69 -57
  304. package/src/test/text.test.ts +15 -17
  305. package/src/test/translating.test.ts +6 -8
  306. package/tldraw.css +8 -4
  307. package/dist-cjs/lib/shapes/shared/useForceSolid.js.map +0 -7
  308. package/dist-esm/lib/shapes/shared/useForceSolid.mjs +0 -9
  309. package/dist-esm/lib/shapes/shared/useForceSolid.mjs.map +0 -7
  310. package/src/lib/shapes/shared/useForceSolid.ts +0 -6
@@ -48,7 +48,7 @@ export const DefaultZoomMenu = memo(function DefaultZoomMenu({ children }: TLUiZ
48
48
  const ZoomTriggerButton = () => {
49
49
  const editor = useEditor()
50
50
  const breakpoint = useBreakpoint()
51
- const zoom = useValue('zoom', () => editor.getZoomLevel(), [editor])
51
+ const zoom = useValue('zoom', () => editor.getEfficientZoomLevel(), [editor])
52
52
  const msg = useTranslation()
53
53
 
54
54
  const handleDoubleClick = useCallback(() => {
@@ -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
  },
@@ -190,7 +182,9 @@ export function UnlockAllMenuItem() {
190
182
  /** @public @react */
191
183
  export function ZoomTo100MenuItem() {
192
184
  const editor = useEditor()
193
- const isZoomedTo100 = useValue('zoomed to 100', () => editor.getZoomLevel() === 1, [editor])
185
+ const isZoomedTo100 = useValue('zoomed to 100', () => editor.getEfficientZoomLevel() === 1, [
186
+ editor,
187
+ ])
194
188
 
195
189
  return <TldrawUiMenuActionItem actionId="zoom-to-100" noClose disabled={isZoomedTo100} />
196
190
  }
@@ -518,7 +512,7 @@ export function ConvertToBookmarkMenuItem() {
518
512
  const onlySelectedShape = editor.getOnlySelectedShape()
519
513
  if (!onlySelectedShape) return false
520
514
  return !!(
521
- editor.isShapeOfType<TLEmbedShape>(onlySelectedShape, 'embed') &&
515
+ editor.isShapeOfType(onlySelectedShape, 'embed') &&
522
516
  onlySelectedShape.props.url &&
523
517
  !editor.isShapeOrAncestorLocked(onlySelectedShape)
524
518
  )
@@ -542,7 +536,7 @@ export function ConvertToEmbedMenuItem() {
542
536
  const onlySelectedShape = editor.getOnlySelectedShape()
543
537
  if (!onlySelectedShape) return false
544
538
  return !!(
545
- editor.isShapeOfType<TLBookmarkShape>(onlySelectedShape, 'bookmark') &&
539
+ editor.isShapeOfType(onlySelectedShape, 'bookmark') &&
546
540
  onlySelectedShape.props.url &&
547
541
  getEmbedDefinition(onlySelectedShape.props.url) &&
548
542
  !editor.isShapeOrAncestorLocked(onlySelectedShape)
@@ -3,7 +3,7 @@ import { Slider as _Slider } from 'radix-ui'
3
3
  import React, { useCallback, useEffect, useState } from 'react'
4
4
  import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
5
5
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
6
- import { TldrawUiTooltip, tooltipManager } from './TldrawUiTooltip'
6
+ import { hideAllTooltips, TldrawUiTooltip } from './TldrawUiTooltip'
7
7
 
8
8
  /** @public */
9
9
  export interface TLUiSliderProps {
@@ -52,7 +52,7 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
52
52
  )
53
53
 
54
54
  const handlePointerDown = useCallback(() => {
55
- tooltipManager.hideAllTooltips()
55
+ hideAllTooltips()
56
56
  onHistoryMark?.('click slider')
57
57
  }, [onHistoryMark])
58
58
 
@@ -1,4 +1,12 @@
1
- import { assert, Atom, atom, Editor, uniqueId, useMaybeEditor, useValue } from '@tldraw/editor'
1
+ import {
2
+ assert,
3
+ atom,
4
+ Editor,
5
+ tlenvReactive,
6
+ uniqueId,
7
+ useMaybeEditor,
8
+ useValue,
9
+ } from '@tldraw/editor'
2
10
  import { Tooltip as _Tooltip } from 'radix-ui'
3
11
  import React, {
4
12
  createContext,
@@ -6,7 +14,6 @@ import React, {
6
14
  ReactNode,
7
15
  useContext,
8
16
  useEffect,
9
- useLayoutEffect,
10
17
  useRef,
11
18
  useState,
12
19
  } from 'react'
@@ -25,7 +32,7 @@ export interface TldrawUiTooltipProps {
25
32
  delayDuration?: number
26
33
  }
27
34
 
28
- interface CurrentTooltip {
35
+ interface TooltipData {
29
36
  id: string
30
37
  content: ReactNode
31
38
  side: 'top' | 'right' | 'bottom' | 'left'
@@ -35,11 +42,25 @@ interface CurrentTooltip {
35
42
  delayDuration: number
36
43
  }
37
44
 
38
- // Singleton tooltip manager
45
+ // State machine states
46
+ type TooltipState =
47
+ | { name: 'idle' }
48
+ | { name: 'pointer_down' }
49
+ | { name: 'showing'; tooltip: TooltipData }
50
+ | { name: 'waiting_to_hide'; tooltip: TooltipData; timeoutId: number }
51
+
52
+ // State machine events
53
+ type TooltipEvent =
54
+ | { type: 'pointer_down' }
55
+ | { type: 'pointer_up' }
56
+ | { type: 'show'; tooltip: TooltipData }
57
+ | { type: 'hide'; tooltipId: string; editor: Editor | null; instant: boolean }
58
+ | { type: 'hide_all' }
59
+
60
+ // Singleton tooltip manager using explicit state machine
39
61
  class TooltipManager {
40
62
  private static instance: TooltipManager | null = null
41
- private currentTooltip = atom<CurrentTooltip | null>('current tooltip', null)
42
- private destroyTimeoutId: number | null = null
63
+ private state = atom<TooltipState>('tooltip state', { name: 'idle' })
43
64
 
44
65
  static getInstance(): TooltipManager {
45
66
  if (!TooltipManager.instance) {
@@ -48,86 +69,117 @@ class TooltipManager {
48
69
  return TooltipManager.instance
49
70
  }
50
71
 
51
- showTooltip(
52
- tooltipId: string,
53
- content: string | React.ReactNode,
54
- targetElement: HTMLElement,
55
- side: 'top' | 'right' | 'bottom' | 'left',
56
- sideOffset: number,
57
- showOnMobile: boolean,
58
- delayDuration: number
59
- ) {
60
- // Clear any existing destroy timeout
61
- if (this.destroyTimeoutId) {
62
- clearTimeout(this.destroyTimeoutId)
63
- this.destroyTimeoutId = null
64
- }
65
-
66
- // Update current tooltip
67
- this.currentTooltip.set({
68
- id: tooltipId,
69
- content,
70
- side,
71
- sideOffset,
72
- showOnMobile,
73
- targetElement,
74
- delayDuration,
75
- })
72
+ hideAllTooltips() {
73
+ this.handleEvent({ type: 'hide_all' })
76
74
  }
77
75
 
78
- updateCurrentTooltip(tooltipId: string, update: (tooltip: CurrentTooltip) => CurrentTooltip) {
79
- this.currentTooltip.update((tooltip) => {
80
- if (tooltip?.id === tooltipId) {
81
- return update(tooltip)
76
+ handleEvent(event: TooltipEvent) {
77
+ const currentState = this.state.get()
78
+
79
+ switch (event.type) {
80
+ case 'pointer_down': {
81
+ // Transition to pointer_down from any state
82
+ if (currentState.name === 'waiting_to_hide') {
83
+ clearTimeout(currentState.timeoutId)
84
+ }
85
+ this.state.set({ name: 'pointer_down' })
86
+ break
82
87
  }
83
- return tooltip
84
- })
85
- }
86
88
 
87
- hideTooltip(editor: Editor | null, tooltipId: string, instant: boolean = false) {
88
- const hide = () => {
89
- // Only hide if this is the current tooltip
90
- if (this.currentTooltip.get()?.id === tooltipId) {
91
- this.currentTooltip.set(null)
92
- this.destroyTimeoutId = null
89
+ case 'pointer_up': {
90
+ // Only transition from pointer_down to idle
91
+ if (currentState.name === 'pointer_down') {
92
+ this.state.set({ name: 'idle' })
93
+ }
94
+ break
93
95
  }
94
- }
95
96
 
96
- if (editor && !instant) {
97
- // Start destroy timeout (1 second)
98
- this.destroyTimeoutId = editor.timers.setTimeout(hide, 300)
99
- } else {
100
- hide()
101
- }
102
- }
97
+ case 'show': {
98
+ // Don't show tooltips while pointer is down
99
+ if (currentState.name === 'pointer_down') {
100
+ return
101
+ }
103
102
 
104
- hideAllTooltips() {
105
- this.currentTooltip.set(null)
106
- this.destroyTimeoutId = null
107
- }
103
+ // Clear any existing timeout if transitioning from waiting_to_hide
104
+ if (currentState.name === 'waiting_to_hide') {
105
+ clearTimeout(currentState.timeoutId)
106
+ }
107
+
108
+ // Transition to showing state
109
+ this.state.set({ name: 'showing', tooltip: event.tooltip })
110
+ break
111
+ }
112
+
113
+ case 'hide': {
114
+ const { tooltipId, editor, instant } = event
115
+
116
+ // Only hide if the tooltip matches
117
+ if (currentState.name === 'showing' && currentState.tooltip.id === tooltipId) {
118
+ if (editor && !instant) {
119
+ // Transition to waiting_to_hide state
120
+ const timeoutId = editor.timers.setTimeout(() => {
121
+ const state = this.state.get()
122
+ if (state.name === 'waiting_to_hide' && state.tooltip.id === tooltipId) {
123
+ this.state.set({ name: 'idle' })
124
+ }
125
+ }, 300)
126
+ this.state.set({
127
+ name: 'waiting_to_hide',
128
+ tooltip: currentState.tooltip,
129
+ timeoutId,
130
+ })
131
+ } else {
132
+ this.state.set({ name: 'idle' })
133
+ }
134
+ } else if (
135
+ currentState.name === 'waiting_to_hide' &&
136
+ currentState.tooltip.id === tooltipId
137
+ ) {
138
+ // Already waiting to hide, make it instant if requested
139
+ if (instant) {
140
+ clearTimeout(currentState.timeoutId)
141
+ this.state.set({ name: 'idle' })
142
+ }
143
+ }
144
+ break
145
+ }
108
146
 
109
- getCurrentTooltipData() {
110
- const currentTooltip = this.currentTooltip.get()
111
- if (!currentTooltip) return null
112
- if (!this.supportsHover() && !currentTooltip.showOnMobile) return null
113
- return currentTooltip
147
+ case 'hide_all': {
148
+ if (currentState.name === 'waiting_to_hide') {
149
+ clearTimeout(currentState.timeoutId)
150
+ }
151
+ // Preserve pointer_down state if that's the current state
152
+ if (currentState.name === 'pointer_down') {
153
+ return
154
+ }
155
+ this.state.set({ name: 'idle' })
156
+ break
157
+ }
158
+ }
114
159
  }
115
160
 
116
- private supportsHoverAtom: Atom<boolean> | null = null
117
- supportsHover() {
118
- if (!this.supportsHoverAtom) {
119
- const mediaQuery = window.matchMedia('(hover: hover)')
120
- const supportsHover = atom('has hover', mediaQuery.matches)
121
- this.supportsHoverAtom = supportsHover
122
- mediaQuery.addEventListener('change', (e) => {
123
- supportsHover.set(e.matches)
124
- })
161
+ getCurrentTooltipData(): TooltipData | null {
162
+ const currentState = this.state.get()
163
+ let tooltip: TooltipData | null = null
164
+
165
+ if (currentState.name === 'showing') {
166
+ tooltip = currentState.tooltip
167
+ } else if (currentState.name === 'waiting_to_hide') {
168
+ tooltip = currentState.tooltip
125
169
  }
126
- return this.supportsHoverAtom.get()
170
+
171
+ if (!tooltip) return null
172
+ if (tlenvReactive.get().isCoarsePointer && !tooltip.showOnMobile) return null
173
+ return tooltip
127
174
  }
128
175
  }
129
176
 
130
- export const tooltipManager = TooltipManager.getInstance()
177
+ const tooltipManager = TooltipManager.getInstance()
178
+
179
+ /** @public */
180
+ export function hideAllTooltips() {
181
+ tooltipManager.hideAllTooltips()
182
+ }
131
183
 
132
184
  // Context for the tooltip singleton
133
185
  const TooltipSingletonContext = createContext<boolean>(false)
@@ -167,14 +219,19 @@ function TooltipSingleton() {
167
219
  // Hide tooltip when camera is moving (panning/zooming)
168
220
  useEffect(() => {
169
221
  if (cameraState === 'moving' && isOpen && currentTooltip) {
170
- tooltipManager.hideTooltip(editor, currentTooltip.id, true)
222
+ tooltipManager.handleEvent({
223
+ type: 'hide',
224
+ tooltipId: currentTooltip.id,
225
+ editor,
226
+ instant: true,
227
+ })
171
228
  }
172
229
  }, [cameraState, isOpen, currentTooltip, editor])
173
230
 
174
231
  useEffect(() => {
175
232
  function handleKeyDown(event: KeyboardEvent) {
176
233
  if (event.key === 'Escape' && currentTooltip && isOpen) {
177
- tooltipManager.hideTooltip(editor, currentTooltip.id)
234
+ hideAllTooltips()
178
235
  event.stopPropagation()
179
236
  }
180
237
  }
@@ -183,7 +240,29 @@ function TooltipSingleton() {
183
240
  return () => {
184
241
  document.removeEventListener('keydown', handleKeyDown, { capture: true })
185
242
  }
186
- }, [editor, currentTooltip, isOpen])
243
+ }, [currentTooltip, isOpen])
244
+
245
+ // Hide tooltip and prevent new ones from opening while pointer is down
246
+ useEffect(() => {
247
+ function handlePointerDown() {
248
+ tooltipManager.handleEvent({ type: 'pointer_down' })
249
+ }
250
+
251
+ function handlePointerUp() {
252
+ tooltipManager.handleEvent({ type: 'pointer_up' })
253
+ }
254
+
255
+ document.addEventListener('pointerdown', handlePointerDown, { capture: true })
256
+ document.addEventListener('pointerup', handlePointerUp, { capture: true })
257
+ document.addEventListener('pointercancel', handlePointerUp, { capture: true })
258
+ return () => {
259
+ document.removeEventListener('pointerdown', handlePointerDown, { capture: true })
260
+ document.removeEventListener('pointerup', handlePointerUp, { capture: true })
261
+ document.removeEventListener('pointercancel', handlePointerUp, { capture: true })
262
+ // Reset pointer state on unmount to prevent stuck state
263
+ tooltipManager.handleEvent({ type: 'pointer_up' })
264
+ }
265
+ }, [])
187
266
 
188
267
  // Update open state and trigger position
189
268
  useEffect(() => {
@@ -280,23 +359,16 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
280
359
  const currentTooltipId = tooltipId.current
281
360
  return () => {
282
361
  if (hasProvider) {
283
- tooltipManager.hideTooltip(editor, currentTooltipId, true)
362
+ tooltipManager.handleEvent({
363
+ type: 'hide',
364
+ tooltipId: currentTooltipId,
365
+ editor,
366
+ instant: true,
367
+ })
284
368
  }
285
369
  }
286
370
  }, [editor, hasProvider])
287
371
 
288
- useLayoutEffect(() => {
289
- if (hasProvider && tooltipManager.getCurrentTooltipData()?.id === tooltipId.current) {
290
- tooltipManager.updateCurrentTooltip(tooltipId.current, (tooltip) => ({
291
- ...tooltip,
292
- content,
293
- side: sideToUse,
294
- sideOffset,
295
- showOnMobile,
296
- }))
297
- }
298
- }, [content, sideToUse, sideOffset, showOnMobile, hasProvider])
299
-
300
372
  // Don't show tooltip if disabled, no content, or enhanced accessibility mode is disabled
301
373
  if (disabled || !content) {
302
374
  return <>{children}</>
@@ -340,38 +412,54 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
340
412
 
341
413
  const handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {
342
414
  child.props.onMouseEnter?.(event)
343
- tooltipManager.showTooltip(
344
- tooltipId.current,
345
- content,
346
- event.currentTarget as HTMLElement,
347
- sideToUse,
348
- sideOffset,
349
- showOnMobile,
350
- delayDurationToUse
351
- )
415
+ tooltipManager.handleEvent({
416
+ type: 'show',
417
+ tooltip: {
418
+ id: tooltipId.current,
419
+ content,
420
+ targetElement: event.currentTarget as HTMLElement,
421
+ side: sideToUse,
422
+ sideOffset,
423
+ showOnMobile,
424
+ delayDuration: delayDurationToUse,
425
+ },
426
+ })
352
427
  }
353
428
 
354
429
  const handleMouseLeave = (event: React.MouseEvent<HTMLElement>) => {
355
430
  child.props.onMouseLeave?.(event)
356
- tooltipManager.hideTooltip(editor, tooltipId.current)
431
+ tooltipManager.handleEvent({
432
+ type: 'hide',
433
+ tooltipId: tooltipId.current,
434
+ editor,
435
+ instant: false,
436
+ })
357
437
  }
358
438
 
359
439
  const handleFocus = (event: React.FocusEvent<HTMLElement>) => {
360
440
  child.props.onFocus?.(event)
361
- tooltipManager.showTooltip(
362
- tooltipId.current,
363
- content,
364
- event.currentTarget as HTMLElement,
365
- sideToUse,
366
- sideOffset,
367
- showOnMobile,
368
- delayDurationToUse
369
- )
441
+ tooltipManager.handleEvent({
442
+ type: 'show',
443
+ tooltip: {
444
+ id: tooltipId.current,
445
+ content,
446
+ targetElement: event.currentTarget as HTMLElement,
447
+ side: sideToUse,
448
+ sideOffset,
449
+ showOnMobile,
450
+ delayDuration: delayDurationToUse,
451
+ },
452
+ })
370
453
  }
371
454
 
372
455
  const handleBlur = (event: React.FocusEvent<HTMLElement>) => {
373
456
  child.props.onBlur?.(event)
374
- tooltipManager.hideTooltip(editor, tooltipId.current)
457
+ tooltipManager.handleEvent({
458
+ type: 'hide',
459
+ tooltipId: tooltipId.current,
460
+ editor,
461
+ instant: false,
462
+ })
375
463
  }
376
464
 
377
465
  const childrenWithHandlers = React.cloneElement(children as React.ReactElement, {
@@ -24,7 +24,7 @@ import { TldrawUiDropdownMenuItem } from '../TldrawUiDropdownMenu'
24
24
  import { TLUiIconJsx } from '../TldrawUiIcon'
25
25
  import { TldrawUiKbd } from '../TldrawUiKbd'
26
26
  import { TldrawUiToolbarButton } from '../TldrawUiToolbar'
27
- import { tooltipManager } from '../TldrawUiTooltip'
27
+ import { hideAllTooltips } from '../TldrawUiTooltip'
28
28
  import { useTldrawUiMenuContext } from './TldrawUiMenuContext'
29
29
 
30
30
  /** @public */
@@ -350,7 +350,7 @@ function useDraggableEvents(
350
350
  point: screenSpaceStart,
351
351
  })
352
352
 
353
- tooltipManager.hideAllTooltips()
353
+ hideAllTooltips()
354
354
  editor.getContainer().focus()
355
355
  })
356
356
  }
@@ -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,