tldraw 4.2.2 → 4.2.3

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 (621) hide show
  1. package/dist-cjs/index.d.ts +242 -311
  2. package/dist-cjs/index.js +5 -13
  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 +4 -7
  6. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  7. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -5
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  10. package/dist-cjs/lib/defaultSideEffects.js +1 -6
  11. package/dist-cjs/lib/defaultSideEffects.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +13 -14
  13. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  15. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +1 -1
  16. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  17. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  18. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  19. package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +2 -2
  20. package/dist-cjs/lib/shapes/arrow/shared.js.map +2 -2
  21. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js +10 -4
  22. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js.map +2 -2
  23. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +4 -7
  24. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  25. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +1 -1
  26. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  27. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  28. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +22 -24
  29. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/draw/getPath.js +11 -20
  31. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  32. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +86 -82
  33. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +3 -3
  34. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +0 -6
  35. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
  37. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +5 -6
  38. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +142 -146
  40. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  41. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js +10 -5
  42. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js.map +2 -2
  43. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -3
  44. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  45. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +21 -23
  46. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  47. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +3 -3
  48. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  49. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +11 -6
  50. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  51. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  52. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +10 -5
  53. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  54. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +2 -3
  55. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  56. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +2 -14
  57. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +3 -3
  58. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +4 -12
  59. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +3 -3
  60. package/dist-cjs/lib/shapes/shared/ShapeFill.js +2 -2
  61. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  62. package/dist-cjs/lib/shapes/shared/crop.js +0 -1
  63. package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
  64. package/dist-cjs/lib/shapes/shared/interpolate-props.js +3 -3
  65. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  66. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  67. package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
  68. package/dist-cjs/lib/shapes/shared/{useEfficientZoomThreshold.js → useForceSolid.js} +7 -10
  69. package/dist-cjs/lib/shapes/shared/useForceSolid.js.map +7 -0
  70. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +1 -1
  71. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  72. package/dist-cjs/lib/shapes/text/RichTextArea.js +0 -5
  73. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  74. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -5
  75. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  76. package/dist-cjs/lib/shapes/text/toolStates/Idle.js +10 -4
  77. package/dist-cjs/lib/shapes/text/toolStates/Idle.js.map +2 -2
  78. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +5 -7
  79. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  80. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  81. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
  82. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +5 -4
  83. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  84. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +4 -2
  85. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  86. package/dist-cjs/lib/tools/HandTool/HandTool.js +5 -3
  87. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  88. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +2 -3
  89. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  90. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js +1 -1
  91. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js.map +2 -2
  92. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js +1 -1
  93. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js.map +2 -2
  94. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +11 -10
  95. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  96. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js +5 -6
  97. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  98. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +6 -4
  99. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  100. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  101. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  102. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +1 -1
  103. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
  104. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +1 -1
  105. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  106. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js +1 -2
  107. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js.map +2 -2
  108. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js +1 -1
  109. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js.map +2 -2
  110. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +6 -8
  111. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  112. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js +11 -38
  113. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  114. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +50 -42
  115. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  116. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +6 -6
  117. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  118. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js +1 -1
  119. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js.map +2 -2
  120. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js +14 -4
  121. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  122. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +1 -1
  123. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  124. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +1 -1
  125. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  126. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js +2 -2
  127. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  128. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +13 -4
  129. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  130. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +6 -5
  131. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  132. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +3 -2
  133. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  134. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js +6 -7
  135. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
  136. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +11 -13
  137. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  138. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js +4 -15
  139. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js.map +2 -2
  140. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js +1 -1
  141. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js.map +2 -2
  142. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js +3 -3
  143. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js.map +2 -2
  144. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js +6 -5
  145. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js.map +2 -2
  146. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js +3 -1
  147. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  148. package/dist-cjs/lib/{utils/test-helpers.js → tools/selection-logic/getShouldEnterCropModeOnPointerDown.js} +8 -21
  149. package/dist-cjs/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.js.map +7 -0
  150. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js +1 -1
  151. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js.map +2 -2
  152. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js +1 -1
  153. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js.map +2 -2
  154. package/dist-cjs/lib/ui/TldrawUi.js +2 -2
  155. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  156. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js +9 -3
  157. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js.map +2 -2
  158. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +3 -1
  159. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  160. package/dist-cjs/lib/ui/components/CursorChatBubble.js +1 -1
  161. package/dist-cjs/lib/ui/components/CursorChatBubble.js.map +2 -2
  162. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js +21 -1
  163. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js.map +2 -2
  164. package/dist-cjs/lib/ui/components/EditLinkDialog.js +1 -11
  165. package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
  166. package/dist-cjs/lib/ui/components/HelperButtons/StopFollowing.js.map +2 -2
  167. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
  168. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  169. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +15 -2
  170. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js.map +3 -3
  171. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js +1 -3
  172. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js.map +2 -2
  173. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +0 -6
  174. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
  175. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  176. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js +1 -1
  177. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js.map +2 -2
  178. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js +1 -1
  179. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js.map +2 -2
  180. package/dist-cjs/lib/ui/components/TopPanel/CenteredTopPanelContainer.js.map +1 -1
  181. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js +32 -0
  182. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js.map +7 -0
  183. package/dist-cjs/lib/ui/components/menu-items.js +1 -3
  184. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  185. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -3
  186. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  187. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  188. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  189. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +93 -149
  190. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  191. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.js.map +2 -2
  192. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.js.map +2 -2
  193. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +1 -1
  194. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  195. package/dist-cjs/lib/ui/context/actions.js +8 -7
  196. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  197. package/dist-cjs/lib/ui/context/components.js +2 -1
  198. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  199. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  200. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +2 -2
  201. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  202. package/dist-cjs/lib/ui/hooks/useFlatten.js.map +2 -2
  203. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
  204. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  205. package/dist-cjs/lib/ui/hooks/useTools.js +5 -4
  206. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  207. package/dist-cjs/lib/ui/version.js +3 -3
  208. package/dist-cjs/lib/ui/version.js.map +1 -1
  209. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +6 -16
  210. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  211. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  212. package/dist-cjs/lib/utils/frames/frames.js.map +2 -2
  213. package/dist-cjs/lib/utils/text/richText.js +2 -4
  214. package/dist-cjs/lib/utils/text/richText.js.map +2 -2
  215. package/dist-cjs/lib/utils/text/textDirection.js +51 -0
  216. package/dist-cjs/lib/utils/text/textDirection.js.map +7 -0
  217. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +2 -7
  218. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  219. package/dist-esm/index.d.mts +242 -311
  220. package/dist-esm/index.mjs +5 -14
  221. package/dist-esm/index.mjs.map +2 -2
  222. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  223. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +4 -8
  224. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  225. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  226. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -5
  227. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  228. package/dist-esm/lib/defaultSideEffects.mjs +1 -6
  229. package/dist-esm/lib/defaultSideEffects.mjs.map +2 -2
  230. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +15 -15
  231. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  232. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +1 -1
  233. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  234. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  235. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  236. package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +2 -2
  237. package/dist-esm/lib/shapes/arrow/shared.mjs.map +2 -2
  238. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs +10 -4
  239. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs.map +2 -2
  240. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +4 -7
  241. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  242. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +1 -1
  243. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  244. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  245. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +24 -29
  246. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  247. package/dist-esm/lib/shapes/draw/getPath.mjs +11 -21
  248. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  249. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +86 -83
  250. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +3 -3
  251. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +0 -6
  252. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  253. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
  254. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +5 -6
  255. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  256. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +142 -147
  257. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  258. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs +10 -5
  259. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs.map +2 -2
  260. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +3 -3
  261. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  262. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +22 -24
  263. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  264. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +3 -3
  265. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  266. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +12 -7
  267. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  268. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  269. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +10 -5
  270. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  271. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +3 -4
  272. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  273. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +2 -14
  274. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  275. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -12
  276. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  277. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +2 -2
  278. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  279. package/dist-esm/lib/shapes/shared/crop.mjs +0 -1
  280. package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
  281. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +4 -4
  282. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  283. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  284. package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
  285. package/dist-esm/lib/shapes/shared/useForceSolid.mjs +9 -0
  286. package/dist-esm/lib/shapes/shared/useForceSolid.mjs.map +7 -0
  287. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +1 -1
  288. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  289. package/dist-esm/lib/shapes/text/RichTextArea.mjs +0 -5
  290. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  291. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +2 -5
  292. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  293. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs +10 -4
  294. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs.map +2 -2
  295. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +5 -7
  296. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  297. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +1 -1
  298. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
  299. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +5 -4
  300. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  301. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +8 -3
  302. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  303. package/dist-esm/lib/tools/HandTool/HandTool.mjs +5 -3
  304. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  305. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +2 -3
  306. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  307. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs +1 -1
  308. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs.map +2 -2
  309. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs +1 -1
  310. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs.map +2 -2
  311. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +11 -10
  312. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  313. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs +5 -6
  314. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  315. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +6 -4
  316. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  317. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  318. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  319. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +1 -1
  320. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
  321. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +1 -1
  322. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  323. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs +1 -2
  324. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs.map +2 -2
  325. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs +1 -1
  326. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs.map +2 -2
  327. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +6 -8
  328. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  329. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs +11 -38
  330. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  331. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +51 -43
  332. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  333. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +6 -6
  334. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  335. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs +1 -1
  336. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs.map +2 -2
  337. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +19 -6
  338. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  339. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +1 -1
  340. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  341. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +1 -1
  342. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  343. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs +2 -2
  344. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  345. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +13 -4
  346. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  347. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +6 -5
  348. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  349. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +3 -2
  350. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  351. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs +6 -7
  352. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
  353. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +11 -13
  354. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  355. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs +4 -17
  356. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs.map +2 -2
  357. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs +1 -1
  358. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs.map +2 -2
  359. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs +3 -3
  360. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs.map +2 -2
  361. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs +6 -5
  362. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs.map +2 -2
  363. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs +3 -1
  364. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  365. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs +8 -0
  366. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs.map +7 -0
  367. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs +1 -1
  368. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs.map +2 -2
  369. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs +1 -1
  370. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs.map +2 -2
  371. package/dist-esm/lib/ui/TldrawUi.mjs +2 -2
  372. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  373. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs +8 -2
  374. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs.map +2 -2
  375. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +3 -1
  376. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  377. package/dist-esm/lib/ui/components/CursorChatBubble.mjs +1 -1
  378. package/dist-esm/lib/ui/components/CursorChatBubble.mjs.map +2 -2
  379. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs +30 -3
  380. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs.map +2 -2
  381. package/dist-esm/lib/ui/components/EditLinkDialog.mjs +1 -11
  382. package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
  383. package/dist-esm/lib/ui/components/HelperButtons/StopFollowing.mjs.map +2 -2
  384. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -1
  385. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  386. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs +6 -3
  387. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs.map +2 -2
  388. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs +1 -3
  389. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs.map +2 -2
  390. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +0 -6
  391. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
  392. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  393. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs +1 -1
  394. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs.map +2 -2
  395. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs +1 -1
  396. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs.map +2 -2
  397. package/dist-esm/lib/ui/components/TopPanel/CenteredTopPanelContainer.mjs.map +1 -1
  398. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs +12 -0
  399. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs.map +7 -0
  400. package/dist-esm/lib/ui/components/menu-items.mjs +5 -4
  401. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  402. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -3
  403. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  404. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -2
  405. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  406. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +95 -157
  407. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  408. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.mjs.map +2 -2
  409. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.mjs.map +2 -2
  410. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -2
  411. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  412. package/dist-esm/lib/ui/context/actions.mjs +8 -7
  413. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  414. package/dist-esm/lib/ui/context/components.mjs +2 -1
  415. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  416. package/dist-esm/lib/ui/hooks/menu-hooks.mjs +4 -1
  417. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  418. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  419. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  420. package/dist-esm/lib/ui/hooks/useFlatten.mjs.map +2 -2
  421. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
  422. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  423. package/dist-esm/lib/ui/hooks/useTools.mjs +5 -4
  424. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  425. package/dist-esm/lib/ui/version.mjs +3 -3
  426. package/dist-esm/lib/ui/version.mjs.map +1 -1
  427. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +6 -17
  428. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  429. package/dist-esm/lib/utils/export/exportAs.mjs +3 -1
  430. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  431. package/dist-esm/lib/utils/frames/frames.mjs.map +2 -2
  432. package/dist-esm/lib/utils/text/richText.mjs +2 -5
  433. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  434. package/dist-esm/lib/utils/text/textDirection.mjs +31 -0
  435. package/dist-esm/lib/utils/text/textDirection.mjs.map +7 -0
  436. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +2 -8
  437. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  438. package/package.json +16 -18
  439. package/src/index.ts +2 -6
  440. package/src/lib/Tldraw.test.tsx +1 -46
  441. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +1 -1
  442. package/src/lib/canvas/TldrawSelectionForeground.tsx +9 -20
  443. package/src/lib/defaultEmbedDefinitions.ts +0 -1
  444. package/src/lib/defaultExternalContentHandlers.ts +14 -13
  445. package/src/lib/defaultSideEffects.ts +1 -6
  446. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +133 -40
  447. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +8 -8
  448. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +2 -2
  449. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +16 -16
  450. package/src/lib/shapes/arrow/arrow-types.ts +0 -2
  451. package/src/lib/shapes/arrow/arrowLabel.ts +2 -2
  452. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -2
  453. package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +3 -3
  454. package/src/lib/shapes/arrow/shared.ts +4 -4
  455. package/src/lib/shapes/arrow/toolStates/Idle.tsx +14 -4
  456. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +5 -8
  457. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +1 -1
  458. package/src/lib/shapes/bookmark/bookmarks.ts +3 -3
  459. package/src/lib/shapes/draw/DrawShapeUtil.tsx +26 -30
  460. package/src/lib/shapes/draw/getPath.ts +10 -31
  461. package/src/lib/shapes/draw/toolStates/Drawing.ts +90 -100
  462. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -8
  463. package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
  464. package/src/lib/shapes/frame/FrameShapeUtil.tsx +4 -10
  465. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +2 -10
  466. package/src/lib/shapes/geo/GeoShapeUtil.tsx +176 -228
  467. package/src/lib/shapes/geo/toolStates/Idle.ts +15 -5
  468. package/src/lib/shapes/geo/toolStates/Pointing.ts +6 -6
  469. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +24 -25
  470. package/src/lib/shapes/line/LineShapeTool.test.ts +6 -6
  471. package/src/lib/shapes/line/LineShapeUtil.test.tsx +5 -5
  472. package/src/lib/shapes/line/toolStates/Pointing.ts +4 -4
  473. package/src/lib/shapes/note/NoteShapeTool.test.ts +1 -2
  474. package/src/lib/shapes/note/NoteShapeUtil.tsx +10 -9
  475. package/src/lib/shapes/note/noteCloning.test.ts +1 -3
  476. package/src/lib/shapes/note/noteHelpers.ts +2 -2
  477. package/src/lib/shapes/note/toolStates/Pointing.ts +10 -5
  478. package/src/lib/shapes/shared/HyperlinkButton.tsx +3 -4
  479. package/src/lib/shapes/shared/PlainTextLabel.tsx +2 -12
  480. package/src/lib/shapes/shared/RichTextLabel.tsx +4 -14
  481. package/src/lib/shapes/shared/ShapeFill.tsx +2 -2
  482. package/src/lib/shapes/shared/crop.ts +0 -1
  483. package/src/lib/shapes/shared/interpolate-props.ts +4 -4
  484. package/src/lib/shapes/shared/useEditablePlainText.ts +3 -7
  485. package/src/lib/shapes/shared/useEditableRichText.ts +3 -7
  486. package/src/lib/shapes/shared/useForceSolid.ts +6 -0
  487. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +1 -1
  488. package/src/lib/shapes/text/RichTextArea.tsx +0 -5
  489. package/src/lib/shapes/text/TextShapeTool.test.ts +4 -4
  490. package/src/lib/shapes/text/TextShapeUtil.tsx +0 -5
  491. package/src/lib/shapes/text/toolStates/Idle.ts +14 -4
  492. package/src/lib/shapes/text/toolStates/Pointing.ts +8 -8
  493. package/src/lib/shapes/video/VideoShapeUtil.tsx +1 -2
  494. package/src/lib/tools/EraserTool/childStates/Erasing.ts +10 -7
  495. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -5
  496. package/src/lib/tools/HandTool/HandTool.ts +5 -3
  497. package/src/lib/tools/HandTool/childStates/Dragging.ts +2 -3
  498. package/src/lib/tools/HandTool/childStates/Pointing.ts +1 -1
  499. package/src/lib/tools/LaserTool/childStates/Lasering.ts +1 -1
  500. package/src/lib/tools/SelectTool/DragAndDropManager.ts +11 -14
  501. package/src/lib/tools/SelectTool/childStates/Brushing.ts +11 -8
  502. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +6 -7
  503. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +4 -3
  504. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +1 -1
  505. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +1 -1
  506. package/src/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.ts +1 -2
  507. package/src/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.ts +1 -1
  508. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +12 -11
  509. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +16 -57
  510. package/src/lib/tools/SelectTool/childStates/Idle.ts +81 -64
  511. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +8 -7
  512. package/src/lib/tools/SelectTool/childStates/PointingCanvas.ts +1 -1
  513. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +17 -9
  514. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +1 -1
  515. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +1 -1
  516. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +4 -4
  517. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +14 -4
  518. package/src/lib/tools/SelectTool/childStates/Resizing.ts +10 -8
  519. package/src/lib/tools/SelectTool/childStates/Rotating.ts +3 -2
  520. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +10 -9
  521. package/src/lib/tools/SelectTool/childStates/Translating.ts +15 -16
  522. package/src/lib/tools/SelectTool/selectHelpers.ts +4 -39
  523. package/src/lib/tools/ZoomTool/ZoomTool.ts +1 -1
  524. package/src/lib/tools/ZoomTool/childStates/Pointing.ts +3 -3
  525. package/src/lib/tools/ZoomTool/childStates/ZoomBrushing.ts +6 -5
  526. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +3 -1
  527. package/src/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.ts +10 -0
  528. package/src/lib/tools/selection-logic/selectOnCanvasPointerUp.ts +1 -1
  529. package/src/lib/tools/selection-logic/updateHoveredShapeId.ts +1 -1
  530. package/src/lib/ui/TldrawUi.tsx +2 -5
  531. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx +9 -1
  532. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +3 -1
  533. package/src/lib/ui/components/CursorChatBubble.tsx +2 -2
  534. package/src/lib/ui/components/DefaultDebugPanel.tsx +42 -3
  535. package/src/lib/ui/components/EditLinkDialog.tsx +6 -16
  536. package/src/lib/ui/components/HelperButtons/StopFollowing.tsx +2 -2
  537. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -1
  538. package/src/lib/ui/components/OfflineIndicator/OfflineIndicator.tsx +5 -6
  539. package/src/lib/ui/components/PageMenu/PageItemInput.tsx +1 -3
  540. package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +0 -8
  541. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -2
  542. package/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx +1 -1
  543. package/src/lib/ui/components/Toolbar/DefaultRichTextToolbar.tsx +1 -1
  544. package/src/lib/ui/components/TopPanel/CenteredTopPanelContainer.tsx +1 -1
  545. package/src/lib/ui/components/TopPanel/DefaultTopPanel.tsx +10 -0
  546. package/src/lib/ui/components/menu-items.tsx +15 -9
  547. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +3 -5
  548. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
  549. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +113 -208
  550. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.tsx +1 -1
  551. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.tsx +1 -1
  552. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +2 -2
  553. package/src/lib/ui/context/actions.tsx +19 -15
  554. package/src/lib/ui/context/components.tsx +2 -1
  555. package/src/lib/ui/hooks/menu-hooks.ts +19 -9
  556. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  557. package/src/lib/ui/hooks/useFlatten.ts +2 -1
  558. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +2 -2
  559. package/src/lib/ui/hooks/useTools.tsx +7 -5
  560. package/src/lib/ui/version.ts +3 -3
  561. package/src/lib/ui.css +29 -31
  562. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +48 -12
  563. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +6 -19
  564. package/src/lib/utils/export/exportAs.ts +9 -2
  565. package/src/lib/utils/frames/frames.ts +1 -1
  566. package/src/lib/utils/text/richText.ts +5 -6
  567. package/src/lib/utils/text/textDirection.ts +32 -0
  568. package/src/lib/utils/tldr/buildFromV1Document.ts +19 -21
  569. package/src/test/Editor.test.tsx +41 -78
  570. package/src/test/EraserTool.test.ts +12 -10
  571. package/src/test/SelectTool.test.ts +19 -11
  572. package/src/test/TestEditor.ts +51 -49
  573. package/src/test/TldrawEditor.test.tsx +20 -24
  574. package/src/test/__snapshots__/drawing.test.ts.snap +1257 -3
  575. package/src/test/__snapshots__/resizing.test.ts.snap +12 -3
  576. package/src/test/arrows-megabus.test.tsx +1 -1
  577. package/src/test/bindings.test.tsx +25 -29
  578. package/src/test/bindingsIndex.test.tsx +4 -4
  579. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +10 -10
  580. package/src/test/commands/createShapes.test.ts +1 -15
  581. package/src/test/commands/getSvgString.test.ts +2 -2
  582. package/src/test/commands/putContent.test.ts +1 -80
  583. package/src/test/commands/setCamera.test.ts +11 -13
  584. package/src/test/commands/stackShapes.test.ts +8 -34
  585. package/src/test/commands/updateShapes.test.ts +5 -21
  586. package/src/test/commands/zoomToBounds.test.ts +3 -19
  587. package/src/test/commands/zoomToSelection.test.ts +3 -14
  588. package/src/test/custom-clipping.test.ts +44 -52
  589. package/src/test/customSnapping.test.tsx +62 -77
  590. package/src/test/drawing.test.ts +10 -17
  591. package/src/test/duplicate.test.ts +1 -1
  592. package/src/test/flipShapes.test.ts +0 -33
  593. package/src/test/frames.test.ts +2 -94
  594. package/src/test/getCulledShapes.test.tsx +3 -11
  595. package/src/test/getShapeAtPoint.test.ts +2 -2
  596. package/src/test/groups.test.tsx +4 -7
  597. package/src/test/modifiers.test.ts +6 -6
  598. package/src/test/resizing.test.ts +22 -16
  599. package/src/test/selection-omnibus.test.ts +13 -13
  600. package/src/test/shapeutils.test.ts +1 -1
  601. package/src/test/spacebarPanning.test.ts +10 -28
  602. package/src/test/styles2.test.tsx +1 -1
  603. package/src/test/styles3.test.ts +5 -5
  604. package/src/test/test-jsx.tsx +57 -72
  605. package/src/test/text.test.ts +17 -15
  606. package/src/test/translating.test.ts +8 -6
  607. package/tldraw.css +41 -45
  608. package/dist-cjs/lib/shapes/shared/useEfficientZoomThreshold.js.map +0 -7
  609. package/dist-cjs/lib/utils/test-helpers.js.map +0 -7
  610. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs +0 -12
  611. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs.map +0 -7
  612. package/dist-esm/lib/utils/test-helpers.mjs +0 -21
  613. package/dist-esm/lib/utils/test-helpers.mjs.map +0 -7
  614. package/src/lib/shapes/draw/DrawShapeUtil.test.ts +0 -146
  615. package/src/lib/shapes/highlight/HighlightShapeUtil.test.ts +0 -146
  616. package/src/lib/shapes/shared/useEfficientZoomThreshold.ts +0 -10
  617. package/src/lib/utils/test-helpers.ts +0 -60
  618. package/src/test/commands/cameraState.test.ts +0 -299
  619. package/src/test/commands/createShape.test.ts +0 -64
  620. package/src/test/commands/isShapeOfType.test.ts +0 -44
  621. package/src/test/commands/updateShape.test.ts +0 -67
@@ -3,8 +3,10 @@ import {
3
3
  TLCancelEventInfo,
4
4
  TLCompleteEventInfo,
5
5
  tlenv,
6
+ TLFrameShape,
6
7
  TLPointerEventInfo,
7
8
  TLShape,
9
+ TLTextShape,
8
10
  } from '@tldraw/editor'
9
11
  import { getTextLabels } from '../../../utils/shapes/shapes'
10
12
  import { renderPlaintextFromRichText } from '../../../utils/text/richText'
@@ -18,25 +20,13 @@ interface EditingShapeInfo {
18
20
  export class EditingShape extends StateNode {
19
21
  static override id = 'editing_shape'
20
22
 
21
- hitLabelOnShapeForPointerUp: TLShape | null = null
23
+ hitShapeForPointerUp: TLShape | null = null
22
24
  private info = {} as EditingShapeInfo
23
- private didPointerDownOnEditingShape = false
24
-
25
- private isTextInputFocused(): boolean {
26
- const container = this.editor.getContainer()
27
- return (
28
- container.contains(document.activeElement) &&
29
- (document.activeElement?.nodeName === 'INPUT' ||
30
- document.activeElement?.nodeName === 'TEXTAREA' ||
31
- (document.activeElement as HTMLElement)?.isContentEditable)
32
- )
33
- }
34
25
 
35
26
  override onEnter(info: EditingShapeInfo) {
36
27
  const editingShape = this.editor.getEditingShape()
37
28
  if (!editingShape) throw Error('Entered editing state without an editing shape')
38
- this.hitLabelOnShapeForPointerUp = null
39
- this.didPointerDownOnEditingShape = false
29
+ this.hitShapeForPointerUp = null
40
30
 
41
31
  this.info = info
42
32
 
@@ -66,34 +56,15 @@ export class EditingShape extends StateNode {
66
56
  override onPointerMove(info: TLPointerEventInfo) {
67
57
  // In the case where on pointer down we hit a shape's label, we need to check if the user is dragging.
68
58
  // and if they are, we need to transition to translating instead.
69
- if (this.hitLabelOnShapeForPointerUp && this.editor.inputs.getIsDragging()) {
59
+ if (this.hitShapeForPointerUp && this.editor.inputs.isDragging) {
70
60
  if (this.editor.getIsReadonly()) return
71
- if (this.hitLabelOnShapeForPointerUp.isLocked) return
72
-
73
- this.editor.select(this.hitLabelOnShapeForPointerUp)
61
+ if (this.hitShapeForPointerUp.isLocked) return
62
+ this.editor.select(this.hitShapeForPointerUp)
74
63
  this.parent.transition('translating', info)
75
- this.hitLabelOnShapeForPointerUp = null
64
+ this.hitShapeForPointerUp = null
76
65
  return
77
66
  }
78
67
 
79
- // Check if dragging from editing shape with blurred input
80
- if (this.didPointerDownOnEditingShape && this.editor.inputs.isDragging) {
81
- if (this.editor.getIsReadonly()) return
82
-
83
- const editingShape = this.editor.getEditingShape()
84
- if (!editingShape || editingShape.isLocked) return
85
-
86
- if (!this.isTextInputFocused()) {
87
- // Input blurred during drag - exit edit mode and start translating
88
- this.editor.select(editingShape)
89
- this.parent.transition('translating', info)
90
- this.didPointerDownOnEditingShape = false
91
- return
92
- }
93
- // Input still focused - user is selecting text, stay in edit mode
94
- this.didPointerDownOnEditingShape = false
95
- }
96
-
97
68
  switch (info.target) {
98
69
  case 'shape':
99
70
  case 'canvas': {
@@ -104,8 +75,7 @@ export class EditingShape extends StateNode {
104
75
  }
105
76
 
106
77
  override onPointerDown(info: TLPointerEventInfo) {
107
- this.hitLabelOnShapeForPointerUp = null
108
- this.didPointerDownOnEditingShape = false
78
+ this.hitShapeForPointerUp = null
109
79
 
110
80
  switch (info.target) {
111
81
  // N.B. This bit of logic has a bit of history to it.
@@ -139,12 +109,12 @@ export class EditingShape extends StateNode {
139
109
  const textLabel = textLabels.length === 1 ? textLabels[0] : undefined
140
110
  // N.B. One nuance here is that we want empty text fields to be removed from the canvas when the user clicks away from them.
141
111
  const isEmptyTextShape =
142
- this.editor.isShapeOfType(editingShape, 'text') &&
112
+ this.editor.isShapeOfType<TLTextShape>(editingShape, 'text') &&
143
113
  renderPlaintextFromRichText(this.editor, editingShape.props.richText).trim() === ''
144
114
  if (textLabel && !isEmptyTextShape) {
145
115
  const pointInShapeSpace = this.editor.getPointInShapeSpace(
146
116
  selectingShape,
147
- this.editor.inputs.getCurrentPagePoint()
117
+ this.editor.inputs.currentPagePoint
148
118
  )
149
119
  if (
150
120
  textLabel.bounds.containsPoint(pointInShapeSpace, 0) &&
@@ -152,11 +122,10 @@ export class EditingShape extends StateNode {
152
122
  ) {
153
123
  // it's a hit to the label!
154
124
  if (selectingShape.id === editingShape.id) {
155
- // Track click on editing shape for drag detection
156
- this.didPointerDownOnEditingShape = true
125
+ // If we clicked on the editing geo / arrow shape's label, do nothing
157
126
  return
158
127
  } else {
159
- this.hitLabelOnShapeForPointerUp = selectingShape
128
+ this.hitShapeForPointerUp = selectingShape
160
129
 
161
130
  this.editor.markHistoryStoppingPoint('editing on pointer up')
162
131
  this.editor.select(selectingShape.id)
@@ -166,7 +135,7 @@ export class EditingShape extends StateNode {
166
135
  } else {
167
136
  if (selectingShape.id === editingShape.id) {
168
137
  // If we clicked on a frame, while editing its heading, cancel editing
169
- if (this.editor.isShapeOfType(selectingShape, 'frame')) {
138
+ if (this.editor.isShapeOfType<TLFrameShape>(selectingShape, 'frame')) {
170
139
  this.editor.setEditingShape(null)
171
140
  this.parent.transition('idle', info)
172
141
  }
@@ -189,20 +158,10 @@ export class EditingShape extends StateNode {
189
158
  }
190
159
 
191
160
  override onPointerUp(info: TLPointerEventInfo) {
192
- if (this.didPointerDownOnEditingShape) {
193
- this.didPointerDownOnEditingShape = false
194
- if (!this.isTextInputFocused()) {
195
- // We clicked on the text label, which blured the input.
196
- // We want to stay in edit mode and select all the text.
197
- this.editor.getRichTextEditor()?.commands.focus('all')
198
- return
199
- }
200
- }
201
-
202
161
  // If we're not dragging, and it's a hit to the label, begin editing the shape.
203
- const hitShape = this.hitLabelOnShapeForPointerUp
162
+ const hitShape = this.hitShapeForPointerUp
204
163
  if (!hitShape) return
205
- this.hitLabelOnShapeForPointerUp = null
164
+ this.hitShapeForPointerUp = null
206
165
 
207
166
  // Stay in edit mode to maintain flow of editing.
208
167
  const util = this.editor.getShapeUtil(hitShape)
@@ -3,9 +3,11 @@ import {
3
3
  StateNode,
4
4
  TLAdjacentDirection,
5
5
  TLClickEventInfo,
6
+ TLGroupShape,
6
7
  TLKeyboardEventInfo,
7
8
  TLPointerEventInfo,
8
9
  TLShape,
10
+ TLTextShape,
9
11
  Vec,
10
12
  VecLike,
11
13
  createShapeId,
@@ -16,9 +18,10 @@ import {
16
18
  } from '@tldraw/editor'
17
19
  import { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'
18
20
  import { getHitShapeOnCanvasPointerDown } from '../../selection-logic/getHitShapeOnCanvasPointerDown'
21
+ import { getShouldEnterCropMode } from '../../selection-logic/getShouldEnterCropModeOnPointerDown'
19
22
  import { selectOnCanvasPointerUp } from '../../selection-logic/selectOnCanvasPointerUp'
20
23
  import { updateHoveredShapeId } from '../../selection-logic/updateHoveredShapeId'
21
- import { hasRichText, startEditingShapeWithRichText } from '../selectHelpers'
24
+ import { startEditingShapeWithLabel } from '../selectHelpers'
22
25
 
23
26
  const SKIPPED_KEYS_FOR_AUTO_EDITING = [
24
27
  'Delete',
@@ -52,6 +55,8 @@ export class Idle extends StateNode {
52
55
  }
53
56
 
54
57
  override onPointerDown(info: TLPointerEventInfo) {
58
+ const shouldEnterCropMode = info.ctrlKey && getShouldEnterCropMode(this.editor)
59
+
55
60
  switch (info.target) {
56
61
  case 'canvas': {
57
62
  // Check to see if we hit any shape under the pointer; if so,
@@ -68,7 +73,9 @@ export class Idle extends StateNode {
68
73
 
69
74
  const selectedShapeIds = this.editor.getSelectedShapeIds()
70
75
  const onlySelectedShape = this.editor.getOnlySelectedShape()
71
- const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
76
+ const {
77
+ inputs: { currentPagePoint },
78
+ } = this.editor
72
79
 
73
80
  if (
74
81
  selectedShapeIds.length > 1 ||
@@ -101,7 +108,7 @@ export class Idle extends StateNode {
101
108
  }
102
109
  case 'handle': {
103
110
  if (this.editor.getIsReadonly()) break
104
- if (this.editor.inputs.getAltKey()) {
111
+ if (this.editor.inputs.altKey) {
105
112
  this.parent.transition('pointing_shape', info)
106
113
  } else {
107
114
  // If we're holding ctrl key, we might select it, or start brushing...
@@ -131,8 +138,7 @@ export class Idle extends StateNode {
131
138
  case 'top_right':
132
139
  case 'bottom_left':
133
140
  case 'bottom_right': {
134
- const onlySelectedShape = this.editor.getOnlySelectedShape()
135
- if (info.ctrlKey && this.editor.canCropShape(onlySelectedShape)) {
141
+ if (shouldEnterCropMode) {
136
142
  this.parent.transition('crop.pointing_crop_handle', info)
137
143
  } else {
138
144
  if (info.accelKey) {
@@ -167,7 +173,7 @@ export class Idle extends StateNode {
167
173
  }
168
174
 
169
175
  override onDoubleClick(info: TLClickEventInfo) {
170
- if (this.editor.inputs.getShiftKey() || info.phase !== 'up') return
176
+ if (this.editor.inputs.shiftKey || info.phase !== 'up') return
171
177
 
172
178
  // We don't want to double click while toggling shapes
173
179
  if (info.ctrlKey || info.shiftKey) return
@@ -183,12 +189,11 @@ export class Idle extends StateNode {
183
189
  // of the shape yet because that also creates text shapes, and can produce
184
190
  // unexpected results when working "inside of" a hollow shape.
185
191
 
186
- const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
187
192
  const hitShape =
188
- hoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')
193
+ hoveredShape && !this.editor.isShapeOfType<TLGroupShape>(hoveredShape, 'group')
189
194
  ? hoveredShape
190
- : (this.editor.getSelectedShapeAtPoint(currentPagePoint) ??
191
- this.editor.getShapeAtPoint(currentPagePoint, {
195
+ : (this.editor.getSelectedShapeAtPoint(this.editor.inputs.currentPagePoint) ??
196
+ this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
192
197
  margin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),
193
198
  hitInside: false,
194
199
  }))
@@ -196,13 +201,13 @@ export class Idle extends StateNode {
196
201
  const focusedGroupId = this.editor.getFocusedGroupId()
197
202
 
198
203
  if (hitShape) {
199
- if (this.editor.isShapeOfType(hitShape, 'group')) {
204
+ if (this.editor.isShapeOfType<TLGroupShape>(hitShape, 'group')) {
200
205
  // Probably select the shape
201
206
  selectOnCanvasPointerUp(this.editor, info)
202
207
  return
203
208
  } else {
204
209
  const parent = this.editor.getShape(hitShape.parentId)
205
- if (parent && this.editor.isShapeOfType(parent, 'group')) {
210
+ if (parent && this.editor.isShapeOfType<TLGroupShape>(parent, 'group')) {
206
211
  // The shape is the direct child of a group. If the group is
207
212
  // selected, then we can select the shape. If the group is the
208
213
  // focus layer id, then we can double click into it as usual.
@@ -229,45 +234,30 @@ export class Idle extends StateNode {
229
234
  return
230
235
  }
231
236
 
232
- if (!this.editor.inputs.getShiftKey()) {
237
+ if (!this.editor.inputs.shiftKey) {
233
238
  this.handleDoubleClickOnCanvas(info)
234
239
  }
235
240
  break
236
241
  }
237
242
  case 'selection': {
243
+ if (this.editor.getIsReadonly()) break
244
+
238
245
  const onlySelectedShape = this.editor.getOnlySelectedShape()
239
246
 
240
247
  if (onlySelectedShape) {
241
248
  const util = this.editor.getShapeUtil(onlySelectedShape)
242
- const isEdge =
243
- info.handle === 'right' ||
244
- info.handle === 'left' ||
245
- info.handle === 'top' ||
246
- info.handle === 'bottom'
247
- const isCorner =
248
- info.handle === 'top_left' ||
249
- info.handle === 'top_right' ||
250
- info.handle === 'bottom_right' ||
251
- info.handle === 'bottom_left'
252
249
 
253
- if (this.editor.getIsReadonly()) {
254
- // includes readonly check
255
- if (
256
- this.editor.canEditShape(onlySelectedShape, {
257
- type: isCorner
258
- ? 'double-click-corner'
259
- : isEdge
260
- ? 'double-click-edge'
261
- : 'double-click',
262
- })
263
- ) {
264
- this.startEditingShape(onlySelectedShape, info, true /* select all */)
265
- }
266
- break
250
+ if (!this.canInteractWithShapeInReadOnly(onlySelectedShape)) {
251
+ return
267
252
  }
268
253
 
269
254
  // Test edges for an onDoubleClickEdge handler
270
- if (isEdge) {
255
+ if (
256
+ info.handle === 'right' ||
257
+ info.handle === 'left' ||
258
+ info.handle === 'top' ||
259
+ info.handle === 'bottom'
260
+ ) {
271
261
  const change = util.onDoubleClickEdge?.(onlySelectedShape, info)
272
262
  if (change) {
273
263
  this.editor.markHistoryStoppingPoint('double click edge')
@@ -277,7 +267,12 @@ export class Idle extends StateNode {
277
267
  }
278
268
  }
279
269
 
280
- if (isCorner) {
270
+ if (
271
+ info.handle === 'top_left' ||
272
+ info.handle === 'top_right' ||
273
+ info.handle === 'bottom_right' ||
274
+ info.handle === 'bottom_left'
275
+ ) {
281
276
  const change = util.onDoubleClickCorner?.(onlySelectedShape, info)
282
277
  if (change) {
283
278
  this.editor.markHistoryStoppingPoint('double click corner')
@@ -286,14 +281,16 @@ export class Idle extends StateNode {
286
281
  return
287
282
  }
288
283
  }
289
-
290
284
  // For corners OR edges but NOT rotation corners
291
- if (this.editor.canCropShape(onlySelectedShape)) {
285
+ if (
286
+ util.canCrop(onlySelectedShape) &&
287
+ !this.editor.isShapeOrAncestorLocked(onlySelectedShape)
288
+ ) {
292
289
  this.parent.transition('crop', info)
293
290
  return
294
291
  }
295
292
 
296
- if (this.editor.canEditShape(onlySelectedShape)) {
293
+ if (this.shouldStartEditingShape(onlySelectedShape)) {
297
294
  this.startEditingShape(onlySelectedShape, info, true /* select all */)
298
295
  }
299
296
  }
@@ -324,7 +321,7 @@ export class Idle extends StateNode {
324
321
  }
325
322
 
326
323
  // If the shape can edit, then begin editing
327
- if (this.editor.canEditShape(shape)) {
324
+ if (this.shouldStartEditingShape(shape)) {
328
325
  this.startEditingShape(shape, info, true /* select all */)
329
326
  } else {
330
327
  // If the shape's double click handler has not created a change,
@@ -346,7 +343,7 @@ export class Idle extends StateNode {
346
343
  } else {
347
344
  // If the shape's double click handler has not created a change,
348
345
  // and if the shape can edit, then begin editing the shape.
349
- if (this.editor.canEditShape(shape)) {
346
+ if (this.shouldStartEditingShape(shape)) {
350
347
  this.startEditingShape(shape, info, true /* select all */)
351
348
  }
352
349
  }
@@ -359,9 +356,9 @@ export class Idle extends StateNode {
359
356
  case 'canvas': {
360
357
  const hoveredShape = this.editor.getHoveredShape()
361
358
  const hitShape =
362
- hoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')
359
+ hoveredShape && !this.editor.isShapeOfType<TLGroupShape>(hoveredShape, 'group')
363
360
  ? hoveredShape
364
- : this.editor.getShapeAtPoint(this.editor.inputs.getCurrentPagePoint(), {
361
+ : this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
365
362
  margin: this.editor.options.hitTestMargin / this.editor.getZoomLevel(),
366
363
  hitInside: false,
367
364
  hitLabels: true,
@@ -381,7 +378,9 @@ export class Idle extends StateNode {
381
378
 
382
379
  const selectedShapeIds = this.editor.getSelectedShapeIds()
383
380
  const onlySelectedShape = this.editor.getOnlySelectedShape()
384
- const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
381
+ const {
382
+ inputs: { currentPagePoint },
383
+ } = this.editor
385
384
 
386
385
  if (
387
386
  selectedShapeIds.length > 1 ||
@@ -474,7 +473,7 @@ export class Idle extends StateNode {
474
473
  // If it's a note shape, then edit on type
475
474
  this.editor.isShapeOfType(onlySelectedShape, 'note') &&
476
475
  // If it's not locked or anything
477
- this.editor.canEditShape(onlySelectedShape)
476
+ this.shouldStartEditingShape(onlySelectedShape)
478
477
  ) {
479
478
  this.startEditingShape(
480
479
  onlySelectedShape,
@@ -526,7 +525,9 @@ export class Idle extends StateNode {
526
525
  const selectedShapes = this.editor.getSelectedShapes()
527
526
 
528
527
  // On enter, if every selected shape is a group, then select all of the children of the groups
529
- if (selectedShapes.every((shape) => this.editor.isShapeOfType(shape, 'group'))) {
528
+ if (
529
+ selectedShapes.every((shape) => this.editor.isShapeOfType<TLGroupShape>(shape, 'group'))
530
+ ) {
530
531
  this.editor.setSelectedShapes(
531
532
  selectedShapes.flatMap((shape) => this.editor.getSortedChildIdsForParent(shape.id))
532
533
  )
@@ -535,10 +536,7 @@ export class Idle extends StateNode {
535
536
 
536
537
  // If the only selected shape is editable, then begin editing it
537
538
  const onlySelectedShape = this.editor.getOnlySelectedShape()
538
- if (
539
- onlySelectedShape &&
540
- this.editor.canEditShape(onlySelectedShape, { type: 'press_enter' })
541
- ) {
539
+ if (onlySelectedShape && this.shouldStartEditingShape(onlySelectedShape)) {
542
540
  this.startEditingShape(
543
541
  onlySelectedShape,
544
542
  {
@@ -552,7 +550,7 @@ export class Idle extends StateNode {
552
550
  }
553
551
 
554
552
  // If the only selected shape is croppable, then begin cropping it
555
- if (this.editor.canCropShape(onlySelectedShape)) {
553
+ if (getShouldEnterCropMode(this.editor)) {
556
554
  this.parent.transition('crop', info)
557
555
  }
558
556
  break
@@ -567,18 +565,23 @@ export class Idle extends StateNode {
567
565
  }
568
566
  }
569
567
 
568
+ private shouldStartEditingShape(
569
+ shape: TLShape | null = this.editor.getOnlySelectedShape()
570
+ ): boolean {
571
+ if (!shape) return false
572
+ if (this.editor.isShapeOrAncestorLocked(shape) && shape.type !== 'embed') return false
573
+ if (!this.canInteractWithShapeInReadOnly(shape)) return false
574
+ return this.editor.getShapeUtil(shape).canEdit(shape)
575
+ }
576
+
570
577
  private startEditingShape(
571
578
  shape: TLShape,
572
579
  info: TLClickEventInfo | TLKeyboardEventInfo,
573
580
  shouldSelectAll?: boolean
574
581
  ) {
575
- const { editor } = this
582
+ if (this.editor.isShapeOrAncestorLocked(shape) && shape.type !== 'embed') return
576
583
  this.editor.markHistoryStoppingPoint('editing shape')
577
- if (hasRichText(shape)) {
578
- startEditingShapeWithRichText(editor, shape, { selectAll: shouldSelectAll })
579
- } else {
580
- editor.setEditingShape(shape)
581
- }
584
+ startEditingShapeWithLabel(this.editor, shape, shouldSelectAll)
582
585
  this.parent.transition('editing_shape', info)
583
586
  }
584
587
 
@@ -598,10 +601,10 @@ export class Idle extends StateNode {
598
601
 
599
602
  const id = createShapeId()
600
603
 
601
- const { x, y } = this.editor.inputs.getCurrentPagePoint()
604
+ const { x, y } = this.editor.inputs.currentPagePoint
602
605
 
603
606
  // Allow this to trigger the max shapes reached alert
604
- this.editor.createShapes([
607
+ this.editor.createShapes<TLTextShape>([
605
608
  {
606
609
  id,
607
610
  type: 'text',
@@ -617,9 +620,16 @@ export class Idle extends StateNode {
617
620
  const shape = this.editor.getShape(id)
618
621
  if (!shape) return
619
622
 
620
- if (!this.editor.canEditShape(shape)) return
623
+ const util = this.editor.getShapeUtil(shape)
624
+ if (this.editor.getIsReadonly()) {
625
+ if (!util.canEditInReadonly(shape)) {
626
+ return
627
+ }
628
+ }
621
629
 
622
- startEditingShapeWithRichText(this.editor, id, { info })
630
+ this.editor.setEditingShape(id)
631
+ this.editor.select(id)
632
+ this.parent.transition('editing_shape', info)
623
633
  }
624
634
 
625
635
  private nudgeSelectedShapes(ephemeral = false) {
@@ -659,6 +669,13 @@ export class Idle extends StateNode {
659
669
  this.editor.nudgeShapes(selectedShapeIds, delta.mul(step))
660
670
  kickoutOccludedShapes(this.editor, selectedShapeIds)
661
671
  }
672
+
673
+ private canInteractWithShapeInReadOnly(shape: TLShape) {
674
+ if (!this.editor.getIsReadonly()) return true
675
+ const util = this.editor.getShapeUtil(shape)
676
+ if (util.canEditInReadonly(shape)) return true
677
+ return false
678
+ }
662
679
  }
663
680
 
664
681
  export const MAJOR_NUDGE_FACTOR = 10
@@ -11,7 +11,6 @@ import {
11
11
  getArrowBodyGeometry,
12
12
  getArrowLabelDefaultPosition,
13
13
  } from '../../../shapes/arrow/arrowLabel'
14
- import { startEditingShapeWithRichText } from '../selectHelpers'
15
14
 
16
15
  export class PointingArrowLabel extends StateNode {
17
16
  static override id = 'pointing_arrow_label'
@@ -55,7 +54,7 @@ export class PointingArrowLabel extends StateNode {
55
54
  if (!labelGeometry) {
56
55
  throw Error(`Expected to find an arrow label geometry for shape: ${shape.id}`)
57
56
  }
58
- const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
57
+ const { currentPagePoint } = this.editor.inputs
59
58
  const pointInShapeSpace = this.editor.getPointInShapeSpace(shape, currentPagePoint)
60
59
 
61
60
  this._labelDragOffset = Vec.Sub(labelGeometry.center, pointInShapeSpace)
@@ -82,7 +81,7 @@ export class PointingArrowLabel extends StateNode {
82
81
  private _labelDragOffset = new Vec(0, 0)
83
82
 
84
83
  override onPointerMove() {
85
- const isDragging = this.editor.inputs.getIsDragging()
84
+ const { isDragging } = this.editor.inputs
86
85
  if (!isDragging) return
87
86
 
88
87
  if (this.didCtrlOnEnter) {
@@ -98,7 +97,7 @@ export class PointingArrowLabel extends StateNode {
98
97
  const transform = this.editor.getShapePageTransform(shape.id)
99
98
 
100
99
  const pointInShapeSpace = this.editor
101
- .getPointInShapeSpace(shape, this.editor.inputs.getCurrentPagePoint())
100
+ .getPointInShapeSpace(shape, this.editor.inputs.currentPagePoint)
102
101
  .add(this._labelDragOffset)
103
102
 
104
103
  const defaultLabelPosition = getArrowLabelDefaultPosition(this.editor, shape)
@@ -125,7 +124,7 @@ export class PointingArrowLabel extends StateNode {
125
124
  }
126
125
 
127
126
  this.didDrag = true
128
- this.editor.updateShape({
127
+ this.editor.updateShape<TLArrowShape>({
129
128
  id: shape.id,
130
129
  type: shape.type,
131
130
  props: { labelPosition: nextLabelPosition },
@@ -138,8 +137,10 @@ export class PointingArrowLabel extends StateNode {
138
137
 
139
138
  if (this.didDrag || !this.wasAlreadySelected) {
140
139
  this.complete()
141
- } else if (this.editor.canEditShape(shape)) {
142
- startEditingShapeWithRichText(this.editor, shape.id)
140
+ } else if (!this.editor.getIsReadonly()) {
141
+ // Go into edit mode.
142
+ this.editor.setEditingShape(shape.id)
143
+ this.editor.setCurrentTool('select.editing_shape')
143
144
  }
144
145
  }
145
146
 
@@ -16,7 +16,7 @@ export class PointingCanvas extends StateNode {
16
16
  }
17
17
 
18
18
  override onPointerMove(info: TLPointerEventInfo) {
19
- if (this.editor.inputs.getIsDragging()) {
19
+ if (this.editor.inputs.isDragging) {
20
20
  this.parent.transition('brushing', info)
21
21
  }
22
22
  }
@@ -1,4 +1,12 @@
1
- import { Editor, StateNode, TLHandle, TLNoteShape, TLPointerEventInfo, Vec } from '@tldraw/editor'
1
+ import {
2
+ Editor,
3
+ StateNode,
4
+ TLArrowShape,
5
+ TLHandle,
6
+ TLNoteShape,
7
+ TLPointerEventInfo,
8
+ Vec,
9
+ } from '@tldraw/editor'
2
10
  import { updateArrowTargetState } from '../../../shapes/arrow/arrowTargetState'
3
11
  import { getArrowBindings } from '../../../shapes/arrow/shared'
4
12
  import {
@@ -6,7 +14,7 @@ import {
6
14
  getNoteAdjacentPositions,
7
15
  getNoteShapeForAdjacentPosition,
8
16
  } from '../../../shapes/note/noteHelpers'
9
- import { startEditingShapeWithRichText } from '../selectHelpers'
17
+ import { startEditingShapeWithLabel } from '../selectHelpers'
10
18
 
11
19
  export class PointingHandle extends StateNode {
12
20
  static override id = 'pointing_handle'
@@ -21,7 +29,7 @@ export class PointingHandle extends StateNode {
21
29
  this.didCtrlOnEnter = info.accelKey
22
30
 
23
31
  const { shape } = info
24
- if (this.editor.isShapeOfType(shape, 'arrow')) {
32
+ if (this.editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {
25
33
  const initialBindings = getArrowBindings(this.editor, shape)
26
34
  const currentBinding = initialBindings[info.handle.id as 'start' | 'end']
27
35
  const oppositeBinding = initialBindings[info.handle.id === 'start' ? 'end' : 'start']
@@ -50,11 +58,11 @@ export class PointingHandle extends StateNode {
50
58
  override onPointerUp() {
51
59
  const { shape, handle } = this.info
52
60
 
53
- if (this.editor.isShapeOfType(shape, 'note')) {
61
+ if (this.editor.isShapeOfType<TLNoteShape>(shape, 'note')) {
54
62
  const { editor } = this
55
63
  const nextNote = getNoteForAdjacentPosition(editor, shape, handle, false)
56
64
  if (nextNote) {
57
- startEditingShapeWithRichText(editor, nextNote, { selectAll: true })
65
+ startEditingShapeWithLabel(editor, nextNote, true /* selectAll */)
58
66
  return
59
67
  }
60
68
  }
@@ -64,7 +72,7 @@ export class PointingHandle extends StateNode {
64
72
 
65
73
  override onPointerMove(info: TLPointerEventInfo) {
66
74
  const { editor } = this
67
- if (editor.inputs.getIsDragging()) {
75
+ if (editor.inputs.isDragging) {
68
76
  if (this.didCtrlOnEnter) {
69
77
  this.parent.transition('brushing', info)
70
78
  } else {
@@ -82,12 +90,12 @@ export class PointingHandle extends StateNode {
82
90
  if (editor.getIsReadonly()) return
83
91
  const { shape, handle } = this.info
84
92
 
85
- if (editor.isShapeOfType(shape, 'note')) {
93
+ if (editor.isShapeOfType<TLNoteShape>(shape, 'note')) {
86
94
  const nextNote = getNoteForAdjacentPosition(editor, shape, handle, true)
87
95
  if (nextNote) {
88
96
  // Center the shape on the current pointer
89
97
  const centeredOnPointer = editor
90
- .getPointInParentSpace(nextNote, editor.inputs.getOriginPagePoint())
98
+ .getPointInParentSpace(nextNote, editor.inputs.originPagePoint)
91
99
  .sub(Vec.Rot(NOTE_CENTER_OFFSET.clone().mul(shape.props.scale), nextNote.rotation))
92
100
  editor.updateShape({ ...nextNote, x: centeredOnPointer.x, y: centeredOnPointer.y })
93
101
 
@@ -103,7 +111,7 @@ export class PointingHandle extends StateNode {
103
111
  isCreating: true,
104
112
  onCreate: () => {
105
113
  // When we're done, start editing it
106
- startEditingShapeWithRichText(editor, nextNote, { selectAll: true })
114
+ startEditingShapeWithLabel(editor, nextNote, true /* selectAll */)
107
115
  },
108
116
  })
109
117
  return
@@ -47,7 +47,7 @@ export class PointingResizeHandle extends StateNode {
47
47
  }
48
48
 
49
49
  override onPointerMove() {
50
- if (this.editor.inputs.getIsDragging()) {
50
+ if (this.editor.inputs.isDragging) {
51
51
  this.startResizing()
52
52
  }
53
53
  }
@@ -31,7 +31,7 @@ export class PointingRotateHandle extends StateNode {
31
31
  }
32
32
 
33
33
  override onPointerMove() {
34
- if (this.editor.inputs.getIsDragging()) {
34
+ if (this.editor.inputs.isDragging) {
35
35
  this.startRotating()
36
36
  }
37
37
  }
@@ -1,4 +1,4 @@
1
- import { StateNode, TLClickEventInfo, TLPointerEventInfo } from '@tldraw/editor'
1
+ import { StateNode, TLClickEventInfo, TLGroupShape, TLPointerEventInfo } from '@tldraw/editor'
2
2
  import { selectOnCanvasPointerUp } from '../../selection-logic/selectOnCanvasPointerUp'
3
3
 
4
4
  export class PointingSelection extends StateNode {
@@ -18,7 +18,7 @@ export class PointingSelection extends StateNode {
18
18
  }
19
19
 
20
20
  override onPointerMove(info: TLPointerEventInfo) {
21
- if (this.editor.inputs.getIsDragging()) {
21
+ if (this.editor.inputs.isDragging) {
22
22
  this.startTranslating(info)
23
23
  }
24
24
  }
@@ -35,9 +35,9 @@ export class PointingSelection extends StateNode {
35
35
  override onDoubleClick?(info: TLClickEventInfo) {
36
36
  const hoveredShape = this.editor.getHoveredShape()
37
37
  const hitShape =
38
- hoveredShape && !this.editor.isShapeOfType(hoveredShape, 'group')
38
+ hoveredShape && !this.editor.isShapeOfType<TLGroupShape>(hoveredShape, 'group')
39
39
  ? hoveredShape
40
- : this.editor.getShapeAtPoint(this.editor.inputs.getCurrentPagePoint(), {
40
+ : this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
41
41
  hitInside: true,
42
42
  margin: 0,
43
43
  renderingOnly: true,