tldraw 4.3.0-canary.9c474ef3fad5 → 4.3.0-canary.a2419250444e

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 (507) hide show
  1. package/dist-cjs/index.d.ts +285 -237
  2. package/dist-cjs/index.js +12 -5
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/defaultEmbedDefinitions.js +1 -1
  5. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  6. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -5
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/defaultSideEffects.js +6 -1
  9. package/dist-cjs/lib/defaultSideEffects.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +6 -2
  11. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +1 -1
  13. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  14. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  15. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  16. package/dist-cjs/lib/shapes/arrow/elbow/getElbowArrowInfo.js +1 -1
  17. package/dist-cjs/lib/shapes/arrow/elbow/getElbowArrowInfo.js.map +2 -2
  18. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js +4 -10
  19. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js.map +2 -2
  20. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +7 -4
  21. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  22. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +1 -1
  23. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +22 -20
  25. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  26. package/dist-cjs/lib/shapes/draw/getPath.js +20 -11
  27. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  28. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +82 -86
  29. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +3 -3
  30. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +6 -0
  31. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +5 -4
  33. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  34. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +136 -136
  35. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js +5 -10
  37. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js.map +2 -2
  38. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -3
  39. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  40. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +22 -20
  41. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  42. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +3 -3
  43. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  44. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +1 -6
  45. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  46. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +5 -10
  47. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  48. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +1 -1
  49. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  50. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +1 -1
  51. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  52. package/dist-cjs/lib/shapes/shared/interpolate-props.js +3 -3
  53. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  54. package/dist-cjs/lib/shapes/text/RichTextArea.js +5 -0
  55. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  56. package/dist-cjs/lib/shapes/text/toolStates/Idle.js +4 -10
  57. package/dist-cjs/lib/shapes/text/toolStates/Idle.js.map +2 -2
  58. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +7 -5
  59. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  60. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +4 -5
  61. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  62. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +2 -4
  63. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  64. package/dist-cjs/lib/tools/HandTool/HandTool.js +3 -5
  65. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  66. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +3 -2
  67. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  68. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js +1 -1
  69. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js.map +2 -2
  70. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js +1 -1
  71. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js.map +2 -2
  72. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +9 -7
  73. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  74. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js +6 -5
  75. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  76. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +4 -6
  77. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  78. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  79. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  80. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +1 -1
  81. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
  82. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +1 -1
  83. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  84. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js +2 -1
  85. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js.map +2 -2
  86. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js +1 -1
  87. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js.map +2 -2
  88. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +7 -5
  89. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  90. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js +38 -11
  91. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  92. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +42 -50
  93. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  94. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +6 -6
  95. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  96. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js +1 -1
  97. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js.map +2 -2
  98. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js +4 -14
  99. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  100. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +1 -1
  101. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  102. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +1 -1
  103. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  104. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js +2 -2
  105. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  106. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -13
  107. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  108. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +5 -6
  109. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  110. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +2 -3
  111. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  112. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js +7 -6
  113. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
  114. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +13 -11
  115. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  116. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js +15 -4
  117. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js.map +2 -2
  118. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js +1 -1
  119. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js.map +2 -2
  120. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js +3 -3
  121. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js.map +2 -2
  122. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js +5 -6
  123. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js.map +2 -2
  124. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js +1 -3
  125. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  126. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js +1 -1
  127. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js.map +2 -2
  128. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js +1 -1
  129. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js.map +2 -2
  130. package/dist-cjs/lib/ui/TldrawUi.js +2 -2
  131. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  132. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +1 -3
  133. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  134. package/dist-cjs/lib/ui/components/CursorChatBubble.js +1 -1
  135. package/dist-cjs/lib/ui/components/CursorChatBubble.js.map +2 -2
  136. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js +1 -21
  137. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js.map +2 -2
  138. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +1 -1
  139. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
  140. package/dist-cjs/lib/ui/components/HelperButtons/StopFollowing.js.map +2 -2
  141. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
  142. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  143. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +2 -15
  144. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js.map +3 -3
  145. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js +3 -1
  146. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js.map +2 -2
  147. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +6 -0
  148. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
  149. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js +1 -1
  150. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js.map +2 -2
  151. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js +1 -1
  152. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js.map +2 -2
  153. package/dist-cjs/lib/ui/components/TopPanel/CenteredTopPanelContainer.js.map +1 -1
  154. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js +1 -1
  155. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js.map +2 -2
  156. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +3 -1
  157. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  158. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +6 -5
  159. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  160. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.js.map +2 -2
  161. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.js.map +2 -2
  162. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +13 -6
  163. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  164. package/dist-cjs/lib/ui/context/actions.js +6 -6
  165. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  166. package/dist-cjs/lib/ui/context/components.js +1 -2
  167. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  168. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +2 -2
  169. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  170. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
  171. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  172. package/dist-cjs/lib/ui/hooks/useTools.js +4 -5
  173. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  174. package/dist-cjs/lib/ui/version.js +3 -3
  175. package/dist-cjs/lib/ui/version.js.map +1 -1
  176. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +8 -6
  177. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  178. package/dist-cjs/lib/{tools/selection-logic/getShouldEnterCropModeOnPointerDown.js → utils/test-helpers.js} +21 -8
  179. package/dist-cjs/lib/utils/test-helpers.js.map +7 -0
  180. package/dist-cjs/lib/utils/text/richText.js +4 -2
  181. package/dist-cjs/lib/utils/text/richText.js.map +2 -2
  182. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +7 -2
  183. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  184. package/dist-esm/index.d.mts +285 -237
  185. package/dist-esm/index.mjs +12 -5
  186. package/dist-esm/index.mjs.map +2 -2
  187. package/dist-esm/lib/defaultEmbedDefinitions.mjs +1 -1
  188. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  189. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -5
  190. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  191. package/dist-esm/lib/defaultSideEffects.mjs +6 -1
  192. package/dist-esm/lib/defaultSideEffects.mjs.map +2 -2
  193. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +6 -2
  194. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  195. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +1 -1
  196. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  197. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  198. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  199. package/dist-esm/lib/shapes/arrow/elbow/getElbowArrowInfo.mjs +1 -1
  200. package/dist-esm/lib/shapes/arrow/elbow/getElbowArrowInfo.mjs.map +2 -2
  201. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs +4 -10
  202. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs.map +2 -2
  203. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +7 -4
  204. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  205. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +1 -1
  206. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  207. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +27 -22
  208. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  209. package/dist-esm/lib/shapes/draw/getPath.mjs +21 -11
  210. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  211. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +83 -86
  212. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +3 -3
  213. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +6 -0
  214. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  215. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +5 -4
  216. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  217. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +137 -136
  218. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  219. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs +5 -10
  220. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs.map +2 -2
  221. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +3 -3
  222. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  223. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +23 -21
  224. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  225. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +3 -3
  226. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  227. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -7
  228. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  229. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +5 -10
  230. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  231. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +1 -1
  232. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  233. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +1 -1
  234. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  235. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +4 -4
  236. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  237. package/dist-esm/lib/shapes/text/RichTextArea.mjs +5 -0
  238. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  239. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs +4 -10
  240. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs.map +2 -2
  241. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +7 -5
  242. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  243. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +4 -5
  244. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  245. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +2 -4
  246. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  247. package/dist-esm/lib/tools/HandTool/HandTool.mjs +3 -5
  248. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  249. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +3 -2
  250. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  251. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs +1 -1
  252. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs.map +2 -2
  253. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs +1 -1
  254. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs.map +2 -2
  255. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +9 -7
  256. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  257. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs +6 -5
  258. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  259. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +4 -6
  260. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  261. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  262. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  263. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +1 -1
  264. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
  265. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +1 -1
  266. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  267. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs +2 -1
  268. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs.map +2 -2
  269. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs +1 -1
  270. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs.map +2 -2
  271. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +7 -5
  272. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  273. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs +38 -11
  274. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  275. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +43 -51
  276. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  277. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +6 -6
  278. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  279. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs +1 -1
  280. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs.map +2 -2
  281. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +5 -15
  282. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  283. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +1 -1
  284. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  285. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +1 -1
  286. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  287. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs +2 -2
  288. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  289. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -13
  290. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  291. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +5 -6
  292. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  293. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +2 -3
  294. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  295. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs +7 -6
  296. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
  297. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +13 -11
  298. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  299. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs +17 -4
  300. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs.map +2 -2
  301. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs +1 -1
  302. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs.map +2 -2
  303. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs +3 -3
  304. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs.map +2 -2
  305. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs +5 -6
  306. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs.map +2 -2
  307. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs +1 -3
  308. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  309. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs +1 -1
  310. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs.map +2 -2
  311. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs +1 -1
  312. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs.map +2 -2
  313. package/dist-esm/lib/ui/TldrawUi.mjs +2 -2
  314. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  315. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +1 -3
  316. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  317. package/dist-esm/lib/ui/components/CursorChatBubble.mjs +1 -1
  318. package/dist-esm/lib/ui/components/CursorChatBubble.mjs.map +2 -2
  319. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs +3 -30
  320. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs.map +2 -2
  321. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +1 -1
  322. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
  323. package/dist-esm/lib/ui/components/HelperButtons/StopFollowing.mjs.map +2 -2
  324. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -1
  325. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  326. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs +3 -6
  327. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs.map +2 -2
  328. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs +3 -1
  329. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs.map +2 -2
  330. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +6 -0
  331. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
  332. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs +1 -1
  333. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs.map +2 -2
  334. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs +1 -1
  335. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs.map +2 -2
  336. package/dist-esm/lib/ui/components/TopPanel/CenteredTopPanelContainer.mjs.map +1 -1
  337. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs +1 -1
  338. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs.map +2 -2
  339. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +3 -1
  340. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  341. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +6 -5
  342. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  343. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.mjs.map +2 -2
  344. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.mjs.map +2 -2
  345. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +13 -6
  346. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  347. package/dist-esm/lib/ui/context/actions.mjs +6 -6
  348. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  349. package/dist-esm/lib/ui/context/components.mjs +1 -2
  350. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  351. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  352. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  353. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
  354. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  355. package/dist-esm/lib/ui/hooks/useTools.mjs +4 -5
  356. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  357. package/dist-esm/lib/ui/version.mjs +3 -3
  358. package/dist-esm/lib/ui/version.mjs.map +1 -1
  359. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +9 -6
  360. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  361. package/dist-esm/lib/utils/test-helpers.mjs +21 -0
  362. package/dist-esm/lib/utils/test-helpers.mjs.map +7 -0
  363. package/dist-esm/lib/utils/text/richText.mjs +5 -2
  364. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  365. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +8 -2
  366. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  367. package/package.json +18 -16
  368. package/src/index.ts +5 -2
  369. package/src/lib/Tldraw.test.tsx +46 -1
  370. package/src/lib/defaultEmbedDefinitions.ts +2 -1
  371. package/src/lib/defaultExternalContentHandlers.ts +10 -10
  372. package/src/lib/defaultSideEffects.ts +6 -1
  373. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +40 -133
  374. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +8 -8
  375. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +6 -4
  376. package/src/lib/shapes/arrow/arrowLabel.ts +1 -1
  377. package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
  378. package/src/lib/shapes/arrow/elbow/getElbowArrowInfo.test.ts +80 -0
  379. package/src/lib/shapes/arrow/elbow/getElbowArrowInfo.tsx +1 -1
  380. package/src/lib/shapes/arrow/toolStates/Idle.tsx +4 -14
  381. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +7 -4
  382. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +1 -1
  383. package/src/lib/shapes/draw/DrawShapeUtil.test.ts +146 -0
  384. package/src/lib/shapes/draw/DrawShapeUtil.tsx +28 -24
  385. package/src/lib/shapes/draw/getPath.ts +31 -10
  386. package/src/lib/shapes/draw/toolStates/Drawing.ts +96 -86
  387. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +7 -0
  388. package/src/lib/shapes/frame/FrameShapeUtil.tsx +9 -3
  389. package/src/lib/shapes/geo/GeoShapeUtil.tsx +219 -172
  390. package/src/lib/shapes/geo/toolStates/Idle.ts +5 -15
  391. package/src/lib/shapes/geo/toolStates/Pointing.ts +3 -3
  392. package/src/lib/shapes/highlight/HighlightShapeUtil.test.ts +146 -0
  393. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +24 -23
  394. package/src/lib/shapes/line/toolStates/Pointing.ts +3 -3
  395. package/src/lib/shapes/note/NoteShapeUtil.tsx +2 -2
  396. package/src/lib/shapes/note/noteCloning.test.ts +3 -1
  397. package/src/lib/shapes/note/toolStates/Pointing.ts +5 -10
  398. package/src/lib/shapes/shared/HyperlinkButton.tsx +1 -1
  399. package/src/lib/shapes/shared/RichTextLabel.tsx +1 -1
  400. package/src/lib/shapes/shared/interpolate-props.ts +4 -4
  401. package/src/lib/shapes/text/RichTextArea.tsx +5 -0
  402. package/src/lib/shapes/text/toolStates/Idle.ts +4 -14
  403. package/src/lib/shapes/text/toolStates/Pointing.ts +7 -7
  404. package/src/lib/tools/EraserTool/childStates/Erasing.ts +4 -5
  405. package/src/lib/tools/EraserTool/childStates/Pointing.ts +2 -4
  406. package/src/lib/tools/HandTool/HandTool.ts +3 -5
  407. package/src/lib/tools/HandTool/childStates/Dragging.ts +3 -2
  408. package/src/lib/tools/HandTool/childStates/Pointing.ts +1 -1
  409. package/src/lib/tools/LaserTool/childStates/Lasering.ts +1 -1
  410. package/src/lib/tools/SelectTool/DragAndDropManager.ts +12 -7
  411. package/src/lib/tools/SelectTool/childStates/Brushing.ts +6 -5
  412. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +7 -6
  413. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +1 -1
  414. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +1 -1
  415. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +1 -1
  416. package/src/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.ts +2 -1
  417. package/src/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.ts +1 -1
  418. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +7 -5
  419. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +55 -12
  420. package/src/lib/tools/SelectTool/childStates/Idle.ts +58 -71
  421. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +6 -7
  422. package/src/lib/tools/SelectTool/childStates/PointingCanvas.ts +1 -1
  423. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +5 -5
  424. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +1 -1
  425. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +1 -1
  426. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +2 -2
  427. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +4 -14
  428. package/src/lib/tools/SelectTool/childStates/Resizing.ts +6 -6
  429. package/src/lib/tools/SelectTool/childStates/Rotating.ts +2 -3
  430. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +7 -6
  431. package/src/lib/tools/SelectTool/childStates/Translating.ts +15 -12
  432. package/src/lib/tools/SelectTool/selectHelpers.ts +39 -4
  433. package/src/lib/tools/ZoomTool/ZoomTool.ts +1 -1
  434. package/src/lib/tools/ZoomTool/childStates/Pointing.ts +3 -3
  435. package/src/lib/tools/ZoomTool/childStates/ZoomBrushing.ts +5 -6
  436. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -3
  437. package/src/lib/tools/selection-logic/selectOnCanvasPointerUp.ts +1 -1
  438. package/src/lib/tools/selection-logic/updateHoveredShapeId.ts +1 -1
  439. package/src/lib/ui/TldrawUi.tsx +5 -2
  440. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +1 -3
  441. package/src/lib/ui/components/CursorChatBubble.tsx +2 -2
  442. package/src/lib/ui/components/DefaultDebugPanel.tsx +3 -42
  443. package/src/lib/ui/components/HelperButtons/BackToContent.tsx +1 -1
  444. package/src/lib/ui/components/HelperButtons/StopFollowing.tsx +2 -2
  445. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -1
  446. package/src/lib/ui/components/OfflineIndicator/OfflineIndicator.tsx +6 -5
  447. package/src/lib/ui/components/PageMenu/PageItemInput.tsx +3 -1
  448. package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +8 -0
  449. package/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx +1 -1
  450. package/src/lib/ui/components/Toolbar/DefaultRichTextToolbar.tsx +1 -1
  451. package/src/lib/ui/components/TopPanel/CenteredTopPanelContainer.tsx +1 -1
  452. package/src/lib/ui/components/ZoomMenu/DefaultZoomMenu.tsx +1 -1
  453. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +5 -3
  454. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +12 -5
  455. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.tsx +1 -1
  456. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.tsx +1 -1
  457. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +5 -2
  458. package/src/lib/ui/context/actions.tsx +6 -6
  459. package/src/lib/ui/context/components.tsx +1 -2
  460. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  461. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +2 -2
  462. package/src/lib/ui/hooks/useTools.tsx +4 -5
  463. package/src/lib/ui/version.ts +3 -3
  464. package/src/lib/ui.css +27 -23
  465. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +12 -48
  466. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +11 -6
  467. package/src/lib/utils/test-helpers.ts +60 -0
  468. package/src/lib/utils/text/richText.ts +6 -5
  469. package/src/lib/utils/tldr/buildFromV1Document.ts +9 -2
  470. package/src/test/Editor.test.tsx +40 -29
  471. package/src/test/EraserTool.test.ts +10 -12
  472. package/src/test/TestEditor.ts +48 -47
  473. package/src/test/TldrawEditor.test.tsx +3 -2
  474. package/src/test/__snapshots__/drawing.test.ts.snap +3 -1257
  475. package/src/test/__snapshots__/resizing.test.ts.snap +3 -12
  476. package/src/test/arrows-megabus.test.tsx +1 -1
  477. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +8 -8
  478. package/src/test/commands/setCamera.test.ts +13 -11
  479. package/src/test/commands/stackShapes.test.ts +34 -8
  480. package/src/test/commands/zoomToBounds.test.ts +19 -3
  481. package/src/test/commands/zoomToSelection.test.ts +14 -3
  482. package/src/test/custom-clipping.test.ts +16 -9
  483. package/src/test/drawing.test.ts +17 -10
  484. package/src/test/flipShapes.test.ts +33 -0
  485. package/src/test/frames.test.ts +92 -0
  486. package/src/test/groups.test.tsx +1 -1
  487. package/src/test/modifiers.test.ts +6 -6
  488. package/src/test/resizing.test.ts +7 -9
  489. package/src/test/selection-omnibus.test.ts +2 -2
  490. package/src/test/spacebarPanning.test.ts +28 -10
  491. package/src/test/test-jsx.tsx +3 -0
  492. package/src/test/ui/BackToContent.test.tsx +111 -0
  493. package/tldraw.css +33 -31
  494. package/dist-cjs/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.js.map +0 -7
  495. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js +0 -32
  496. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js.map +0 -7
  497. package/dist-cjs/lib/utils/text/textDirection.js +0 -51
  498. package/dist-cjs/lib/utils/text/textDirection.js.map +0 -7
  499. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs +0 -8
  500. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs.map +0 -7
  501. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs +0 -12
  502. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs.map +0 -7
  503. package/dist-esm/lib/utils/text/textDirection.mjs +0 -31
  504. package/dist-esm/lib/utils/text/textDirection.mjs.map +0 -7
  505. package/src/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.ts +0 -10
  506. package/src/lib/ui/components/TopPanel/DefaultTopPanel.tsx +0 -10
  507. package/src/lib/utils/text/textDirection.ts +0 -32
@@ -15,6 +15,7 @@ import {
15
15
  TLResizeInfo,
16
16
  TLShapeUtilCanvasSvgDef,
17
17
  Vec,
18
+ WeakCache,
18
19
  exhaustiveSwitchError,
19
20
  geoShapeMigrations,
20
21
  geoShapeProps,
@@ -86,53 +87,40 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
86
87
  }
87
88
 
88
89
  override getGeometry(shape: TLGeoShape) {
89
- const w = Math.max(1, shape.props.w)
90
- const h = Math.max(1, shape.props.h + shape.props.growY)
91
-
90
+ const { props } = shape
91
+ const { scale } = props
92
92
  const path = getGeoShapePath(shape)
93
- const unscaledlabelSize = getUnscaledLabelSize(this.editor, shape)
94
- // unscaled w and h
95
- const unscaledW = w / shape.props.scale
96
- const unscaledH = h / shape.props.scale
97
- const unscaledminWidth = Math.min(100, unscaledW / 2)
98
- const unscaledMinHeight = Math.min(
99
- LABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2,
100
- unscaledH / 2
101
- )
93
+ const pathGeometry = path.toGeometry()
94
+
95
+ const scaledW = Math.max(1, props.w)
96
+ const scaledH = Math.max(1, props.h + props.growY)
97
+ const unscaledW = scaledW / scale
98
+ const unscaledH = scaledH / scale
102
99
 
103
- const unscaledLabelWidth = Math.min(
100
+ const isEmptyLabel = isEmptyRichText(props.richText)
101
+ const unscaledLabelSize = isEmptyLabel
102
+ ? EMPTY_LABEL_SIZE
103
+ : getUnscaledLabelSize(this.editor, shape)
104
+
105
+ const labelBounds = getLabelBounds(
104
106
  unscaledW,
105
- Math.max(unscaledlabelSize.w, Math.min(unscaledminWidth, Math.max(1, unscaledW - 8)))
106
- )
107
- const unscaledLabelHeight = Math.min(
108
107
  unscaledH,
109
- Math.max(unscaledlabelSize.h, Math.min(unscaledMinHeight, Math.max(1, unscaledH - 8)))
108
+ unscaledLabelSize,
109
+ props.size,
110
+ props.align,
111
+ props.verticalAlign,
112
+ scale
110
113
  )
111
114
 
112
- // todo: use centroid for label position
113
-
114
115
  return new Group2d({
115
116
  children: [
116
- path.toGeometry(),
117
+ pathGeometry,
117
118
  new Rectangle2d({
118
- x:
119
- shape.props.align === 'start'
120
- ? 0
121
- : shape.props.align === 'end'
122
- ? (unscaledW - unscaledLabelWidth) * shape.props.scale
123
- : ((unscaledW - unscaledLabelWidth) / 2) * shape.props.scale,
124
- y:
125
- shape.props.verticalAlign === 'start'
126
- ? 0
127
- : shape.props.verticalAlign === 'end'
128
- ? (unscaledH - unscaledLabelHeight) * shape.props.scale
129
- : ((unscaledH - unscaledLabelHeight) / 2) * shape.props.scale,
130
- width: unscaledLabelWidth * shape.props.scale,
131
- height: unscaledLabelHeight * shape.props.scale,
119
+ ...labelBounds,
132
120
  isFilled: true,
133
121
  isLabel: true,
134
122
  excludeFromShapeBounds: true,
135
- isEmptyLabel: isEmptyRichText(shape.props.richText),
123
+ isEmptyLabel: isEmptyLabel,
136
124
  }),
137
125
  ],
138
126
  })
@@ -308,41 +296,32 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
308
296
  shape: TLGeoShape,
309
297
  { handle, newPoint, scaleX, scaleY, initialShape }: TLResizeInfo<TLGeoShape>
310
298
  ) {
311
- const unscaledInitialW = initialShape.props.w / initialShape.props.scale
312
- const unscaledInitialH = initialShape.props.h / initialShape.props.scale
313
- const unscaledGrowY = initialShape.props.growY / initialShape.props.scale
299
+ const unscaledInitial = getUnscaledGeoProps(initialShape.props)
314
300
  // use the w/h from props here instead of the initialBounds here,
315
301
  // since cloud shapes calculated bounds can differ from the props w/h.
316
- let unscaledW = unscaledInitialW * scaleX
317
- let unscaledH = (unscaledInitialH + unscaledGrowY) * scaleY
302
+ let unscaledW = unscaledInitial.w * scaleX
303
+ let unscaledH = (unscaledInitial.h + unscaledInitial.growY) * scaleY
318
304
  let overShrinkX = 0
319
305
  let overShrinkY = 0
320
306
 
321
- const min = MIN_SIZE_WITH_LABEL
322
-
323
307
  if (!isEmptyRichText(shape.props.richText)) {
324
- let newW = Math.max(Math.abs(unscaledW), min)
325
- let newH = Math.max(Math.abs(unscaledH), min)
308
+ // Use initialShape for label measurement to hit the cache.
309
+ // Creating a temp shape with new dimensions would break WeakCache and cause
310
+ // expensive measurements on every resize frame.
311
+ const unscaledLabelSize = getUnscaledLabelSize(this.editor, initialShape)
326
312
 
327
- if (newW < min && newH === min) newW = min
328
- if (newW === min && newH < min) newH = min
313
+ const absUnscaledW = Math.abs(unscaledW)
314
+ const absUnscaledH = Math.abs(unscaledH)
329
315
 
330
- const unscaledLabelSize = getUnscaledLabelSize(this.editor, {
331
- ...shape,
332
- props: {
333
- ...shape.props,
334
- w: newW * shape.props.scale,
335
- h: newH * shape.props.scale,
336
- },
337
- })
316
+ // Constrain to label size (primary constraint) and min size with label (secondary)
317
+ const constrainedW = Math.max(absUnscaledW, unscaledLabelSize.w, MIN_SIZE_WITH_LABEL)
318
+ const constrainedH = Math.max(absUnscaledH, unscaledLabelSize.h, MIN_SIZE_WITH_LABEL)
338
319
 
339
- const nextW = Math.max(Math.abs(unscaledW), unscaledLabelSize.w) * Math.sign(unscaledW)
340
- const nextH = Math.max(Math.abs(unscaledH), unscaledLabelSize.h) * Math.sign(unscaledH)
341
- overShrinkX = Math.abs(nextW) - Math.abs(unscaledW)
342
- overShrinkY = Math.abs(nextH) - Math.abs(unscaledH)
320
+ overShrinkX = constrainedW - absUnscaledW
321
+ overShrinkY = constrainedH - absUnscaledH
343
322
 
344
- unscaledW = nextW
345
- unscaledH = nextH
323
+ unscaledW = constrainedW * Math.sign(unscaledW || 1)
324
+ unscaledH = constrainedH * Math.sign(unscaledH || 1)
346
325
  }
347
326
 
348
327
  const scaledW = unscaledW * shape.props.scale
@@ -384,147 +363,93 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
384
363
  }
385
364
 
386
365
  override onBeforeCreate(shape: TLGeoShape) {
387
- if (isEmptyRichText(shape.props.richText)) {
388
- if (shape.props.growY) {
389
- // No text / some growY, set growY to 0
390
- return {
391
- ...shape,
392
- props: {
393
- ...shape.props,
394
- growY: 0,
395
- },
396
- }
397
- } else {
398
- // No text / no growY, nothing to change
399
- return
400
- }
401
- }
366
+ const { props } = shape
402
367
 
403
- const unscaledPrevHeight = shape.props.h / shape.props.scale
404
- const unscaledNextHeight = getUnscaledLabelSize(this.editor, shape).h
405
-
406
- let growY: number | null = null
407
-
408
- if (unscaledNextHeight > unscaledPrevHeight) {
409
- growY = unscaledNextHeight - unscaledPrevHeight
410
- } else {
411
- if (shape.props.growY) {
412
- growY = 0
413
- }
368
+ // No text - ensure growY is 0
369
+ if (isEmptyRichText(props.richText)) {
370
+ return props.growY !== 0 ? { ...shape, props: { ...props, growY: 0 } } : undefined
414
371
  }
415
372
 
416
- if (growY !== null) {
373
+ // Has text - calculate growY needed to fit label
374
+ const unscaledShapeH = props.h / props.scale
375
+ const unscaledLabelH = getUnscaledLabelSize(this.editor, shape).h
376
+ const unscaledGrowY = calculateGrowY(unscaledShapeH, unscaledLabelH, props.growY / props.scale)
377
+
378
+ if (unscaledGrowY !== null) {
417
379
  return {
418
380
  ...shape,
419
- props: {
420
- ...shape.props,
421
- // scale the growY
422
- growY: growY * shape.props.scale,
423
- },
381
+ props: { ...props, growY: unscaledGrowY * props.scale },
424
382
  }
425
383
  }
426
384
  }
427
385
 
428
386
  override onBeforeUpdate(prev: TLGeoShape, next: TLGeoShape) {
429
- // No change to text, font, or size, no need to update update
387
+ const { props: prevProps } = prev
388
+ const { props: nextProps } = next
389
+
390
+ // No change to text, font, or size - no update needed
430
391
  if (
431
- isEqual(prev.props.richText, next.props.richText) &&
432
- prev.props.font === next.props.font &&
433
- prev.props.size === next.props.size
392
+ isEqual(prevProps.richText, nextProps.richText) &&
393
+ prevProps.font === nextProps.font &&
394
+ prevProps.size === nextProps.size
434
395
  ) {
435
396
  return
436
397
  }
437
398
 
438
- // If we got rid of the text, cancel out any growY from the prev text
439
- const wasEmpty = isEmptyRichText(prev.props.richText)
440
- const isEmpty = isEmptyRichText(next.props.richText)
441
- if (!wasEmpty && isEmpty) {
442
- return {
443
- ...next,
444
- props: {
445
- ...next.props,
446
- growY: 0,
447
- },
448
- }
449
- }
450
-
451
- // Get the prev width and height in unscaled values
452
- const unscaledPrevWidth = prev.props.w / prev.props.scale
453
- const unscaledPrevHeight = prev.props.h / prev.props.scale
454
- const unscaledPrevGrowY = prev.props.growY / prev.props.scale
399
+ const wasEmpty = isEmptyRichText(prevProps.richText)
400
+ const isEmpty = isEmptyRichText(nextProps.richText)
455
401
 
456
- // Get the next width and height in unscaled values
457
- const unscaledNextLabelSize = getUnscaledLabelSize(this.editor, next)
458
-
459
- // When entering the first character in a label (not pasting in multiple characters...)
460
- if (wasEmpty && !isEmpty && renderPlaintextFromRichText(this.editor, next.props.richText)) {
461
- let unscaledW = Math.max(unscaledPrevWidth, unscaledNextLabelSize.w)
462
- let unscaledH = Math.max(unscaledPrevHeight, unscaledNextLabelSize.h)
402
+ // If label is empty and used to be empty, skip label measurement and dimension adjustment
403
+ if (wasEmpty && isEmpty) {
404
+ return
405
+ }
463
406
 
464
- const min = MIN_SIZE_WITH_LABEL
407
+ // Text was removed - reset growY
408
+ if (isEmpty) {
409
+ return nextProps.growY !== 0 ? { ...next, props: { ...nextProps, growY: 0 } } : undefined
410
+ }
465
411
 
466
- // If both the width and height were less than the minimum size, make the shape square
467
- if (unscaledPrevWidth < min && unscaledPrevHeight < min) {
468
- unscaledW = Math.max(unscaledW, min)
469
- unscaledH = Math.max(unscaledH, min)
470
- unscaledW = Math.max(unscaledW, unscaledH)
471
- unscaledH = Math.max(unscaledW, unscaledH)
472
- }
412
+ const unscaledPrev = getUnscaledGeoProps(prevProps)
413
+ const unscaledLabelSize = getUnscaledLabelSize(this.editor, next)
414
+ const { scale } = nextProps
473
415
 
474
- // Don't set a growY—at least, not until we've implemented a growX property
416
+ // Text was added for the first time - expand shape to fit (if wasEmpty and now there's text...
417
+ // It might be just whitespace but it is faster to assume that it is NOT just whitespace and expand
418
+ // the shape in either case (a label with just spaces text will be less performant but that's acceptable)
419
+ if (wasEmpty && !isEmpty) {
420
+ const expanded = expandShapeForFirstLabel(unscaledPrev.w, unscaledPrev.h, unscaledLabelSize)
475
421
  return {
476
422
  ...next,
477
423
  props: {
478
- ...next.props,
479
- // Scale the results
480
- w: unscaledW * next.props.scale,
481
- h: unscaledH * next.props.scale,
424
+ ...nextProps,
425
+ w: expanded.w * scale,
426
+ h: expanded.h * scale,
482
427
  growY: 0,
483
428
  },
484
429
  }
485
430
  }
486
431
 
487
- let growY: number | null = null
432
+ // Text was modified - adjust dimensions to fit new label
433
+ const unscaledNextW = next.props.w / scale
434
+ const needsWidthExpand = unscaledLabelSize.w > unscaledNextW
435
+ const unscaledGrowY = calculateGrowY(unscaledPrev.h, unscaledLabelSize.h, unscaledPrev.growY)
488
436
 
489
- if (unscaledNextLabelSize.h > unscaledPrevHeight) {
490
- growY = unscaledNextLabelSize.h - unscaledPrevHeight
491
- } else {
492
- if (unscaledPrevGrowY) {
493
- growY = 0
494
- }
495
- }
496
-
497
- if (growY !== null) {
498
- const unscaledNextWidth = next.props.w / next.props.scale
499
- return {
500
- ...next,
501
- props: {
502
- ...next.props,
503
- // Scale the results
504
- growY: growY * next.props.scale,
505
- w: Math.max(unscaledNextWidth, unscaledNextLabelSize.w) * next.props.scale,
506
- },
507
- }
508
- }
509
-
510
- if (unscaledNextLabelSize.w > unscaledPrevWidth) {
437
+ if (unscaledGrowY !== null || needsWidthExpand) {
511
438
  return {
512
439
  ...next,
513
440
  props: {
514
- ...next.props,
515
- // Scale the results
516
- w: unscaledNextLabelSize.w * next.props.scale,
441
+ ...nextProps,
442
+ growY: (unscaledGrowY ?? unscaledPrev.growY) * scale,
443
+ w: Math.max(unscaledNextW, unscaledLabelSize.w) * scale,
517
444
  },
518
445
  }
519
446
  }
520
-
521
- // otherwise, no update needed
522
447
  }
523
448
 
524
449
  override onDoubleClick(shape: TLGeoShape) {
525
450
  // Little easter egg: double-clicking a rectangle / checkbox while
526
451
  // holding alt will toggle between check-box and rectangle
527
- if (this.editor.inputs.altKey) {
452
+ if (this.editor.inputs.getAltKey()) {
528
453
  switch (shape.props.geo) {
529
454
  case 'rectangle': {
530
455
  return {
@@ -562,29 +487,151 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
562
487
  }
563
488
 
564
489
  // imperfect but good enough, should be the width of the W in the font / size combo
565
- const minWidths = {
490
+ const MIN_WIDTHS = Object.freeze({
566
491
  s: 12,
567
492
  m: 14,
568
493
  l: 16,
569
494
  xl: 20,
570
- }
495
+ })
571
496
 
572
- const extraPaddings = {
497
+ const EXTRA_PADDINGS = Object.freeze({
573
498
  s: 2,
574
499
  m: 3.5,
575
500
  l: 5,
576
501
  xl: 10,
502
+ })
503
+
504
+ const EMPTY_LABEL_SIZE = Object.freeze({ w: 0, h: 0 })
505
+
506
+ // Margin between label edge and shape edge (in unscaled units)
507
+ const LABEL_EDGE_MARGIN = 8
508
+
509
+ /** Calculate label bounds for hit testing */
510
+ function getLabelBounds(
511
+ unscaledShapeW: number,
512
+ unscaledShapeH: number,
513
+ unscaledLabelSize: { w: number; h: number },
514
+ size: TLGeoShapeProps['size'],
515
+ align: TLGeoShapeProps['align'],
516
+ verticalAlign: TLGeoShapeProps['verticalAlign'],
517
+ scale: number
518
+ ): { x: number; y: number; width: number; height: number } {
519
+ // Calculate minimum label dimensions based on font size and shape size
520
+ const unscaledMinWidth = Math.min(100, unscaledShapeW / 2)
521
+ const unscaledMinHeight = Math.min(
522
+ LABEL_FONT_SIZES[size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2,
523
+ unscaledShapeH / 2
524
+ )
525
+
526
+ // Label dimensions: at least the measured size, but constrained to shape bounds
527
+ const unscaledLabelW = Math.min(
528
+ unscaledShapeW,
529
+ Math.max(
530
+ unscaledLabelSize.w,
531
+ Math.min(unscaledMinWidth, Math.max(1, unscaledShapeW - LABEL_EDGE_MARGIN))
532
+ )
533
+ )
534
+ const unscaledLabelH = Math.min(
535
+ unscaledShapeH,
536
+ Math.max(
537
+ unscaledLabelSize.h,
538
+ Math.min(unscaledMinHeight, Math.max(1, unscaledShapeH - LABEL_EDGE_MARGIN))
539
+ )
540
+ )
541
+
542
+ // Calculate position based on alignment
543
+ const unscaledX =
544
+ align === 'start'
545
+ ? 0
546
+ : align === 'end'
547
+ ? unscaledShapeW - unscaledLabelW
548
+ : (unscaledShapeW - unscaledLabelW) / 2
549
+
550
+ const unscaledY =
551
+ verticalAlign === 'start'
552
+ ? 0
553
+ : verticalAlign === 'end'
554
+ ? unscaledShapeH - unscaledLabelH
555
+ : (unscaledShapeH - unscaledLabelH) / 2
556
+
557
+ return {
558
+ x: unscaledX * scale,
559
+ y: unscaledY * scale,
560
+ width: unscaledLabelW * scale,
561
+ height: unscaledLabelH * scale,
562
+ }
577
563
  }
578
564
 
579
- function getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {
580
- const { richText, font, size, w } = shape.props
565
+ /** Get the unscaled dimensions from a geo shape's props */
566
+ function getUnscaledGeoProps(props: TLGeoShapeProps) {
567
+ const { w, h, growY, scale } = props
568
+ return {
569
+ w: w / scale,
570
+ h: h / scale,
571
+ growY: growY / scale,
572
+ }
573
+ }
581
574
 
582
- if (!richText || isEmptyRichText(richText)) {
583
- return { w: 0, h: 0 }
575
+ /**
576
+ * Calculate the growY needed to fit a label within a shape.
577
+ * Returns null if no change is needed, otherwise returns the new unscaled growY value.
578
+ */
579
+ function calculateGrowY(
580
+ unscaledShapeH: number,
581
+ unscaledLabelH: number,
582
+ unscaledCurrentGrowY: number
583
+ ): number | null {
584
+ if (unscaledLabelH > unscaledShapeH) {
585
+ // Label is taller than shape - need to grow
586
+ return unscaledLabelH - unscaledShapeH
587
+ }
588
+ if (unscaledCurrentGrowY > 0) {
589
+ // Label fits and we have existing growY - reset it
590
+ return 0
584
591
  }
592
+ // No change needed
593
+ return null
594
+ }
595
+
596
+ /**
597
+ * Calculate expanded dimensions when adding a label to a shape for the first time.
598
+ * Ensures the shape meets minimum size requirements and is square if originally small.
599
+ */
600
+ function expandShapeForFirstLabel(
601
+ unscaledW: number,
602
+ unscaledH: number,
603
+ unscaledLabelSize: { w: number; h: number }
604
+ ): { w: number; h: number } {
605
+ let w = Math.max(unscaledW, unscaledLabelSize.w)
606
+ let h = Math.max(unscaledH, unscaledLabelSize.h)
607
+
608
+ // If shape was smaller than min size in both dimensions, make it square
609
+ if (unscaledW < MIN_SIZE_WITH_LABEL && unscaledH < MIN_SIZE_WITH_LABEL) {
610
+ w = Math.max(w, MIN_SIZE_WITH_LABEL)
611
+ h = Math.max(h, MIN_SIZE_WITH_LABEL)
612
+ // Make square by using the larger dimension
613
+ const maxDim = Math.max(w, h)
614
+ w = maxDim
615
+ h = maxDim
616
+ }
617
+
618
+ return { w, h }
619
+ }
620
+
621
+ const labelSizesForGeo = new WeakCache<TLGeoShape, { w: number; h: number }>()
622
+
623
+ // Returns cached label size for the shape. Don't call with empty rich text.
624
+ function getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {
625
+ return labelSizesForGeo.get(shape, () => {
626
+ return measureUnscaledLabelSize(editor, shape)
627
+ })
628
+ }
629
+
630
+ // This is the expensive part of the code so we want to avoid calling it if we can
631
+ function measureUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {
632
+ const { richText, font, size, w } = shape.props
585
633
 
586
- // way too expensive to be recomputing on every update
587
- const minWidth = minWidths[size]
634
+ const minWidth = MIN_WIDTHS[size]
588
635
 
589
636
  const html = renderHtmlFromRichTextForMeasurement(editor, richText)
590
637
  const textSize = editor.textMeasure.measureHtml(html, {
@@ -596,7 +643,7 @@ function getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {
596
643
  // Guard because a DOM nodes can't be less 0
597
644
  0,
598
645
  // A 'w' width that we're setting as the min-width
599
- Math.ceil(minWidth + extraPaddings[size]),
646
+ Math.ceil(minWidth + EXTRA_PADDINGS[size]),
600
647
  // The actual text size
601
648
  Math.ceil(w / shape.props.scale - LABEL_PADDING * 2)
602
649
  ),
@@ -1,4 +1,5 @@
1
1
  import { StateNode, TLKeyboardEventInfo, TLPointerEventInfo } from '@tldraw/editor'
2
+ import { startEditingShapeWithRichText } from '../../../tools/SelectTool/selectHelpers'
2
3
 
3
4
  export class Idle extends StateNode {
4
5
  static override id = 'idle'
@@ -12,22 +13,11 @@ export class Idle extends StateNode {
12
13
  }
13
14
 
14
15
  override onKeyUp(info: TLKeyboardEventInfo) {
16
+ const { editor } = this
15
17
  if (info.key === 'Enter') {
16
- if (this.editor.getIsReadonly()) return null
17
-
18
- const onlySelectedShape = this.editor.getOnlySelectedShape()
19
- // If the only selected shape is editable, start editing it
20
- if (
21
- onlySelectedShape &&
22
- this.editor.getShapeUtil(onlySelectedShape).canEdit(onlySelectedShape)
23
- ) {
24
- this.editor.setCurrentTool('select')
25
- this.editor.setEditingShape(onlySelectedShape.id)
26
- this.editor.root.getCurrent()?.transition('editing_shape', {
27
- ...info,
28
- target: 'shape',
29
- shape: onlySelectedShape,
30
- })
18
+ const onlySelectedShape = editor.getOnlySelectedShape()
19
+ if (editor.canEditShape(onlySelectedShape)) {
20
+ startEditingShapeWithRichText(editor, onlySelectedShape, { selectAll: true })
31
21
  }
32
22
  }
33
23
  }
@@ -16,8 +16,8 @@ export class Pointing extends StateNode {
16
16
  }
17
17
 
18
18
  override onPointerMove(info: TLPointerEventInfo) {
19
- if (this.editor.inputs.isDragging) {
20
- const { originPagePoint } = this.editor.inputs
19
+ if (this.editor.inputs.getIsDragging()) {
20
+ const originPagePoint = this.editor.inputs.getOriginPagePoint()
21
21
 
22
22
  const id = createShapeId()
23
23
 
@@ -71,7 +71,7 @@ export class Pointing extends StateNode {
71
71
  }
72
72
 
73
73
  private complete() {
74
- const { originPagePoint } = this.editor.inputs
74
+ const originPagePoint = this.editor.inputs.getOriginPagePoint()
75
75
 
76
76
  const id = createShapeId()
77
77