tldraw 4.3.0-canary.d4af7a11f36b → 4.3.0-canary.da3162650c27

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 (561) hide show
  1. package/README.md +0 -2
  2. package/dist-cjs/index.d.ts +297 -237
  3. package/dist-cjs/index.js +13 -5
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +2 -2
  6. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  7. package/dist-cjs/lib/defaultEmbedDefinitions.js +1 -1
  8. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -5
  10. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  11. package/dist-cjs/lib/defaultSideEffects.js +6 -1
  12. package/dist-cjs/lib/defaultSideEffects.js.map +2 -2
  13. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +14 -13
  14. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  16. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +1 -1
  17. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  18. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  19. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  20. package/dist-cjs/lib/shapes/arrow/elbow/getElbowArrowInfo.js +1 -1
  21. package/dist-cjs/lib/shapes/arrow/elbow/getElbowArrowInfo.js.map +2 -2
  22. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js +4 -10
  23. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js.map +2 -2
  24. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +7 -4
  25. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  26. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +1 -1
  27. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  28. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +25 -23
  29. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/draw/getPath.js +20 -11
  31. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  32. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +82 -86
  33. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +3 -3
  34. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +6 -0
  35. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +6 -5
  37. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  38. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +146 -142
  39. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  40. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js +5 -10
  41. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js.map +2 -2
  42. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -3
  43. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  44. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +23 -21
  45. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  46. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +3 -3
  47. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  48. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +6 -11
  49. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  50. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +5 -10
  51. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  52. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +3 -2
  53. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  54. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +14 -2
  55. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +3 -3
  56. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +12 -4
  57. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +3 -3
  58. package/dist-cjs/lib/shapes/shared/ShapeFill.js +2 -2
  59. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  60. package/dist-cjs/lib/shapes/shared/interpolate-props.js +3 -3
  61. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  62. package/dist-cjs/lib/shapes/shared/{useForceSolid.js → useEfficientZoomThreshold.js} +10 -7
  63. package/dist-cjs/lib/shapes/shared/useEfficientZoomThreshold.js.map +7 -0
  64. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +1 -1
  65. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  66. package/dist-cjs/lib/shapes/text/RichTextArea.js +5 -0
  67. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  68. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +5 -2
  69. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  70. package/dist-cjs/lib/shapes/text/toolStates/Idle.js +4 -10
  71. package/dist-cjs/lib/shapes/text/toolStates/Idle.js.map +2 -2
  72. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +7 -5
  73. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  74. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  75. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
  76. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +4 -5
  77. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  78. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +2 -4
  79. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  80. package/dist-cjs/lib/tools/HandTool/HandTool.js +3 -5
  81. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  82. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +3 -2
  83. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  84. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js +1 -1
  85. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js.map +2 -2
  86. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js +1 -1
  87. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js.map +2 -2
  88. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +9 -7
  89. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  90. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js +6 -5
  91. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  92. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +4 -6
  93. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  94. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  95. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  96. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +1 -1
  97. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
  98. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +1 -1
  99. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  100. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js +2 -1
  101. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js.map +2 -2
  102. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js +1 -1
  103. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js.map +2 -2
  104. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +7 -5
  105. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  106. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js +38 -11
  107. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  108. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +42 -50
  109. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  110. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +6 -6
  111. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  112. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js +1 -1
  113. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js.map +2 -2
  114. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js +4 -14
  115. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  116. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +1 -1
  117. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  118. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +1 -1
  119. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  120. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js +2 -2
  121. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  122. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -13
  123. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  124. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +5 -6
  125. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  126. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +2 -3
  127. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  128. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js +7 -6
  129. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
  130. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +13 -11
  131. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  132. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js +15 -4
  133. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js.map +2 -2
  134. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js +1 -1
  135. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js.map +2 -2
  136. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js +3 -3
  137. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js.map +2 -2
  138. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js +5 -6
  139. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js.map +2 -2
  140. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js +1 -3
  141. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  142. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js +1 -1
  143. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js.map +2 -2
  144. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js +1 -1
  145. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js.map +2 -2
  146. package/dist-cjs/lib/ui/TldrawUi.js +2 -2
  147. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  148. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js +3 -9
  149. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js.map +2 -2
  150. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +1 -3
  151. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  152. package/dist-cjs/lib/ui/components/CursorChatBubble.js +1 -1
  153. package/dist-cjs/lib/ui/components/CursorChatBubble.js.map +2 -2
  154. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js +1 -21
  155. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js.map +2 -2
  156. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +1 -1
  157. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
  158. package/dist-cjs/lib/ui/components/HelperButtons/StopFollowing.js.map +2 -2
  159. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
  160. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  161. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +2 -15
  162. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js.map +3 -3
  163. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js +3 -1
  164. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js.map +2 -2
  165. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +6 -0
  166. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
  167. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js +1 -1
  168. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js.map +2 -2
  169. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js +1 -1
  170. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js.map +2 -2
  171. package/dist-cjs/lib/ui/components/TopPanel/CenteredTopPanelContainer.js.map +1 -1
  172. package/dist-cjs/lib/ui/components/menu-items.js +3 -1
  173. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  174. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +3 -1
  175. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  176. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  177. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  178. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +149 -93
  179. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  180. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.js.map +2 -2
  181. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.js.map +2 -2
  182. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +14 -7
  183. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  184. package/dist-cjs/lib/ui/context/actions.js +6 -6
  185. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  186. package/dist-cjs/lib/ui/context/components.js +1 -2
  187. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  188. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +2 -2
  189. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  190. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
  191. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  192. package/dist-cjs/lib/ui/hooks/useTools.js +4 -5
  193. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  194. package/dist-cjs/lib/ui/version.js +3 -3
  195. package/dist-cjs/lib/ui/version.js.map +1 -1
  196. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +8 -6
  197. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  198. package/dist-cjs/lib/{tools/selection-logic/getShouldEnterCropModeOnPointerDown.js → utils/test-helpers.js} +21 -8
  199. package/dist-cjs/lib/utils/test-helpers.js.map +7 -0
  200. package/dist-cjs/lib/utils/text/richText.js +11 -19
  201. package/dist-cjs/lib/utils/text/richText.js.map +3 -3
  202. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +7 -2
  203. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  204. package/dist-esm/index.d.mts +297 -237
  205. package/dist-esm/index.mjs +14 -5
  206. package/dist-esm/index.mjs.map +2 -2
  207. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +2 -2
  208. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  209. package/dist-esm/lib/defaultEmbedDefinitions.mjs +1 -1
  210. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  211. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -5
  212. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  213. package/dist-esm/lib/defaultSideEffects.mjs +6 -1
  214. package/dist-esm/lib/defaultSideEffects.mjs.map +2 -2
  215. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +15 -15
  216. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  217. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +1 -1
  218. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  219. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  220. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  221. package/dist-esm/lib/shapes/arrow/elbow/getElbowArrowInfo.mjs +1 -1
  222. package/dist-esm/lib/shapes/arrow/elbow/getElbowArrowInfo.mjs.map +2 -2
  223. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs +4 -10
  224. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs.map +2 -2
  225. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +7 -4
  226. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  227. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +1 -1
  228. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  229. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +30 -25
  230. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  231. package/dist-esm/lib/shapes/draw/getPath.mjs +21 -11
  232. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  233. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +83 -86
  234. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +3 -3
  235. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +6 -0
  236. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  237. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +6 -5
  238. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  239. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +147 -142
  240. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  241. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs +5 -10
  242. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs.map +2 -2
  243. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +3 -3
  244. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  245. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +24 -22
  246. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  247. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +3 -3
  248. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  249. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +7 -12
  250. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  251. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +5 -10
  252. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  253. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +4 -3
  254. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  255. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +14 -2
  256. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  257. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +12 -4
  258. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  259. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +2 -2
  260. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  261. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +4 -4
  262. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  263. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs +12 -0
  264. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs.map +7 -0
  265. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +1 -1
  266. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  267. package/dist-esm/lib/shapes/text/RichTextArea.mjs +5 -0
  268. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  269. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +5 -2
  270. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  271. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs +4 -10
  272. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs.map +2 -2
  273. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +7 -5
  274. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  275. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +1 -1
  276. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
  277. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +4 -5
  278. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  279. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +2 -4
  280. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  281. package/dist-esm/lib/tools/HandTool/HandTool.mjs +3 -5
  282. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  283. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +3 -2
  284. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  285. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs +1 -1
  286. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs.map +2 -2
  287. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs +1 -1
  288. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs.map +2 -2
  289. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +9 -7
  290. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  291. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs +6 -5
  292. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  293. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +4 -6
  294. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  295. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  296. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  297. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +1 -1
  298. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
  299. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +1 -1
  300. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  301. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs +2 -1
  302. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs.map +2 -2
  303. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs +1 -1
  304. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs.map +2 -2
  305. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +7 -5
  306. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  307. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs +38 -11
  308. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  309. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +43 -51
  310. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  311. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +6 -6
  312. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  313. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs +1 -1
  314. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs.map +2 -2
  315. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +5 -15
  316. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  317. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +1 -1
  318. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  319. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +1 -1
  320. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  321. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs +2 -2
  322. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  323. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -13
  324. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  325. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +5 -6
  326. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  327. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +2 -3
  328. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  329. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs +7 -6
  330. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
  331. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +13 -11
  332. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  333. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs +17 -4
  334. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs.map +2 -2
  335. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs +1 -1
  336. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs.map +2 -2
  337. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs +3 -3
  338. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs.map +2 -2
  339. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs +5 -6
  340. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs.map +2 -2
  341. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs +1 -3
  342. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  343. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs +1 -1
  344. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs.map +2 -2
  345. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs +1 -1
  346. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs.map +2 -2
  347. package/dist-esm/lib/ui/TldrawUi.mjs +2 -2
  348. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  349. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs +2 -8
  350. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs.map +2 -2
  351. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +1 -3
  352. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  353. package/dist-esm/lib/ui/components/CursorChatBubble.mjs +1 -1
  354. package/dist-esm/lib/ui/components/CursorChatBubble.mjs.map +2 -2
  355. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs +3 -30
  356. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs.map +2 -2
  357. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +1 -1
  358. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
  359. package/dist-esm/lib/ui/components/HelperButtons/StopFollowing.mjs.map +2 -2
  360. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -1
  361. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  362. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs +3 -6
  363. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs.map +2 -2
  364. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs +3 -1
  365. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs.map +2 -2
  366. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +6 -0
  367. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
  368. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs +1 -1
  369. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs.map +2 -2
  370. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs +1 -1
  371. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs.map +2 -2
  372. package/dist-esm/lib/ui/components/TopPanel/CenteredTopPanelContainer.mjs.map +1 -1
  373. package/dist-esm/lib/ui/components/menu-items.mjs +3 -1
  374. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  375. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +3 -1
  376. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  377. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -2
  378. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  379. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +157 -95
  380. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  381. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.mjs.map +2 -2
  382. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.mjs.map +2 -2
  383. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +15 -8
  384. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  385. package/dist-esm/lib/ui/context/actions.mjs +6 -6
  386. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  387. package/dist-esm/lib/ui/context/components.mjs +1 -2
  388. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  389. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  390. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  391. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
  392. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  393. package/dist-esm/lib/ui/hooks/useTools.mjs +4 -5
  394. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  395. package/dist-esm/lib/ui/version.mjs +3 -3
  396. package/dist-esm/lib/ui/version.mjs.map +1 -1
  397. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +9 -6
  398. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  399. package/dist-esm/lib/utils/test-helpers.mjs +21 -0
  400. package/dist-esm/lib/utils/test-helpers.mjs.map +7 -0
  401. package/dist-esm/lib/utils/text/richText.mjs +8 -5
  402. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  403. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +8 -2
  404. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  405. package/package.json +18 -16
  406. package/src/index.ts +6 -2
  407. package/src/lib/Tldraw.test.tsx +46 -1
  408. package/src/lib/canvas/TldrawSelectionForeground.tsx +2 -2
  409. package/src/lib/defaultEmbedDefinitions.ts +2 -1
  410. package/src/lib/defaultExternalContentHandlers.ts +10 -10
  411. package/src/lib/defaultSideEffects.ts +6 -1
  412. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +40 -133
  413. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +8 -8
  414. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +15 -15
  415. package/src/lib/shapes/arrow/arrow-types.ts +2 -0
  416. package/src/lib/shapes/arrow/arrowLabel.ts +1 -1
  417. package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
  418. package/src/lib/shapes/arrow/elbow/getElbowArrowInfo.test.ts +80 -0
  419. package/src/lib/shapes/arrow/elbow/getElbowArrowInfo.tsx +1 -1
  420. package/src/lib/shapes/arrow/toolStates/Idle.tsx +4 -14
  421. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +7 -4
  422. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +1 -1
  423. package/src/lib/shapes/draw/DrawShapeUtil.test.ts +146 -0
  424. package/src/lib/shapes/draw/DrawShapeUtil.tsx +31 -27
  425. package/src/lib/shapes/draw/getPath.ts +31 -10
  426. package/src/lib/shapes/draw/toolStates/Drawing.ts +96 -86
  427. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +7 -0
  428. package/src/lib/shapes/frame/FrameShapeUtil.tsx +10 -4
  429. package/src/lib/shapes/geo/GeoShapeUtil.tsx +228 -176
  430. package/src/lib/shapes/geo/toolStates/Idle.ts +5 -15
  431. package/src/lib/shapes/geo/toolStates/Pointing.ts +3 -3
  432. package/src/lib/shapes/highlight/HighlightShapeUtil.test.ts +146 -0
  433. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +25 -24
  434. package/src/lib/shapes/line/toolStates/Pointing.ts +3 -3
  435. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -10
  436. package/src/lib/shapes/note/noteCloning.test.ts +3 -1
  437. package/src/lib/shapes/note/toolStates/Pointing.ts +5 -10
  438. package/src/lib/shapes/shared/HyperlinkButton.tsx +4 -3
  439. package/src/lib/shapes/shared/PlainTextLabel.tsx +10 -1
  440. package/src/lib/shapes/shared/RichTextLabel.tsx +12 -3
  441. package/src/lib/shapes/shared/ShapeFill.tsx +2 -2
  442. package/src/lib/shapes/shared/interpolate-props.ts +4 -4
  443. package/src/lib/shapes/shared/useEfficientZoomThreshold.ts +10 -0
  444. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +1 -1
  445. package/src/lib/shapes/text/RichTextArea.tsx +5 -0
  446. package/src/lib/shapes/text/TextShapeUtil.tsx +5 -0
  447. package/src/lib/shapes/text/toolStates/Idle.ts +4 -14
  448. package/src/lib/shapes/text/toolStates/Pointing.ts +7 -7
  449. package/src/lib/shapes/video/VideoShapeUtil.tsx +2 -1
  450. package/src/lib/tools/EraserTool/childStates/Erasing.ts +4 -5
  451. package/src/lib/tools/EraserTool/childStates/Pointing.ts +2 -4
  452. package/src/lib/tools/HandTool/HandTool.ts +3 -5
  453. package/src/lib/tools/HandTool/childStates/Dragging.ts +3 -2
  454. package/src/lib/tools/HandTool/childStates/Pointing.ts +1 -1
  455. package/src/lib/tools/LaserTool/childStates/Lasering.ts +1 -1
  456. package/src/lib/tools/SelectTool/DragAndDropManager.ts +12 -7
  457. package/src/lib/tools/SelectTool/childStates/Brushing.ts +6 -5
  458. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +7 -6
  459. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +1 -1
  460. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +1 -1
  461. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +1 -1
  462. package/src/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.ts +2 -1
  463. package/src/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.ts +1 -1
  464. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +7 -5
  465. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +55 -12
  466. package/src/lib/tools/SelectTool/childStates/Idle.ts +58 -71
  467. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +6 -7
  468. package/src/lib/tools/SelectTool/childStates/PointingCanvas.ts +1 -1
  469. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +5 -5
  470. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +1 -1
  471. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +1 -1
  472. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +2 -2
  473. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +4 -14
  474. package/src/lib/tools/SelectTool/childStates/Resizing.ts +6 -6
  475. package/src/lib/tools/SelectTool/childStates/Rotating.ts +2 -3
  476. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +7 -6
  477. package/src/lib/tools/SelectTool/childStates/Translating.ts +15 -12
  478. package/src/lib/tools/SelectTool/selectHelpers.ts +39 -4
  479. package/src/lib/tools/ZoomTool/ZoomTool.ts +1 -1
  480. package/src/lib/tools/ZoomTool/childStates/Pointing.ts +3 -3
  481. package/src/lib/tools/ZoomTool/childStates/ZoomBrushing.ts +5 -6
  482. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -3
  483. package/src/lib/tools/selection-logic/selectOnCanvasPointerUp.ts +1 -1
  484. package/src/lib/tools/selection-logic/updateHoveredShapeId.ts +1 -1
  485. package/src/lib/ui/TldrawUi.tsx +5 -2
  486. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx +1 -9
  487. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +1 -3
  488. package/src/lib/ui/components/CursorChatBubble.tsx +2 -2
  489. package/src/lib/ui/components/DefaultDebugPanel.tsx +3 -42
  490. package/src/lib/ui/components/HelperButtons/BackToContent.tsx +1 -1
  491. package/src/lib/ui/components/HelperButtons/StopFollowing.tsx +2 -2
  492. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -1
  493. package/src/lib/ui/components/OfflineIndicator/OfflineIndicator.tsx +6 -5
  494. package/src/lib/ui/components/PageMenu/PageItemInput.tsx +3 -1
  495. package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +8 -0
  496. package/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx +1 -1
  497. package/src/lib/ui/components/Toolbar/DefaultRichTextToolbar.tsx +1 -1
  498. package/src/lib/ui/components/TopPanel/CenteredTopPanelContainer.tsx +1 -1
  499. package/src/lib/ui/components/menu-items.tsx +3 -1
  500. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +5 -3
  501. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
  502. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +208 -113
  503. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.tsx +1 -1
  504. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.tsx +1 -1
  505. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +7 -4
  506. package/src/lib/ui/context/actions.tsx +6 -6
  507. package/src/lib/ui/context/components.tsx +1 -2
  508. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  509. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +2 -2
  510. package/src/lib/ui/hooks/useTools.tsx +4 -5
  511. package/src/lib/ui/version.ts +3 -3
  512. package/src/lib/ui.css +27 -23
  513. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +12 -48
  514. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +11 -6
  515. package/src/lib/utils/test-helpers.ts +60 -0
  516. package/src/lib/utils/text/richText.ts +9 -8
  517. package/src/lib/utils/tldr/buildFromV1Document.ts +9 -2
  518. package/src/test/Editor.test.tsx +40 -29
  519. package/src/test/EraserTool.test.ts +10 -12
  520. package/src/test/TestEditor.ts +48 -47
  521. package/src/test/TldrawEditor.test.tsx +6 -4
  522. package/src/test/__snapshots__/drawing.test.ts.snap +3 -1257
  523. package/src/test/__snapshots__/resizing.test.ts.snap +3 -12
  524. package/src/test/arrows-megabus.test.tsx +1 -1
  525. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +10 -10
  526. package/src/test/commands/cameraState.test.ts +299 -0
  527. package/src/test/commands/putContent.test.ts +79 -1
  528. package/src/test/commands/setCamera.test.ts +13 -11
  529. package/src/test/commands/stackShapes.test.ts +34 -8
  530. package/src/test/commands/zoomToBounds.test.ts +19 -3
  531. package/src/test/commands/zoomToSelection.test.ts +14 -3
  532. package/src/test/custom-clipping.test.ts +16 -9
  533. package/src/test/drawing.test.ts +17 -10
  534. package/src/test/flipShapes.test.ts +33 -0
  535. package/src/test/frames.test.ts +92 -0
  536. package/src/test/groups.test.tsx +1 -1
  537. package/src/test/modifiers.test.ts +6 -6
  538. package/src/test/resizing.test.ts +7 -9
  539. package/src/test/selection-omnibus.test.ts +2 -2
  540. package/src/test/spacebarPanning.test.ts +28 -10
  541. package/src/test/test-jsx.tsx +3 -0
  542. package/src/test/ui/BackToContent.test.tsx +111 -0
  543. package/tldraw.css +41 -35
  544. package/dist-cjs/lib/shapes/shared/useForceSolid.js.map +0 -7
  545. package/dist-cjs/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.js.map +0 -7
  546. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js +0 -32
  547. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js.map +0 -7
  548. package/dist-cjs/lib/utils/text/textDirection.js +0 -51
  549. package/dist-cjs/lib/utils/text/textDirection.js.map +0 -7
  550. package/dist-esm/lib/shapes/shared/useForceSolid.mjs +0 -9
  551. package/dist-esm/lib/shapes/shared/useForceSolid.mjs.map +0 -7
  552. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs +0 -8
  553. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs.map +0 -7
  554. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs +0 -12
  555. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs.map +0 -7
  556. package/dist-esm/lib/utils/text/textDirection.mjs +0 -31
  557. package/dist-esm/lib/utils/text/textDirection.mjs.map +0 -7
  558. package/src/lib/shapes/shared/useForceSolid.ts +0 -6
  559. package/src/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.ts +0 -10
  560. package/src/lib/ui/components/TopPanel/DefaultTopPanel.tsx +0 -10
  561. package/src/lib/utils/text/textDirection.ts +0 -32
@@ -0,0 +1,146 @@
1
+ import { createShapeId, TLHighlightShape } from '@tldraw/editor'
2
+ import { TestEditor } from '../../../test/TestEditor'
3
+ import { createDrawSegments, pointsToBase64 } from '../../utils/test-helpers'
4
+
5
+ let editor: TestEditor
6
+
7
+ beforeEach(() => {
8
+ editor = new TestEditor()
9
+ })
10
+
11
+ afterEach(() => {
12
+ editor?.dispose()
13
+ })
14
+
15
+ describe('HighlightShapeUtil dot detection', () => {
16
+ const shapeId = createShapeId('test-highlight')
17
+
18
+ function createHighlightShape(segments: TLHighlightShape['props']['segments']): TLHighlightShape {
19
+ editor.createShapes([
20
+ {
21
+ id: shapeId,
22
+ type: 'highlight',
23
+ props: { segments },
24
+ },
25
+ ])
26
+ return editor.getShape(shapeId) as TLHighlightShape
27
+ }
28
+
29
+ describe('getIsDot behavior via hideResizeHandles', () => {
30
+ it('treats a shape with one segment and zero points as a dot', () => {
31
+ const shape = createHighlightShape([{ type: 'free', points: '' }])
32
+ const util = editor.getShapeUtil('highlight')
33
+ expect(util.hideResizeHandles(shape)).toBe(true)
34
+ })
35
+
36
+ it('treats a shape with one segment and one point as a dot', () => {
37
+ const shape = createHighlightShape(createDrawSegments([[{ x: 0, y: 0, z: 0.5 }]]))
38
+ const util = editor.getShapeUtil('highlight')
39
+ expect(util.hideResizeHandles(shape)).toBe(true)
40
+ })
41
+
42
+ it('treats a shape with one segment and two points as NOT a dot', () => {
43
+ const shape = createHighlightShape(
44
+ createDrawSegments([
45
+ [
46
+ { x: 0, y: 0, z: 0.5 },
47
+ { x: 10, y: 10, z: 0.5 },
48
+ ],
49
+ ])
50
+ )
51
+ const util = editor.getShapeUtil('highlight')
52
+ expect(util.hideResizeHandles(shape)).toBe(false)
53
+ })
54
+
55
+ it('treats a shape with one segment and many points as NOT a dot', () => {
56
+ const shape = createHighlightShape(
57
+ createDrawSegments([
58
+ [
59
+ { x: 0, y: 0, z: 0.5 },
60
+ { x: 10, y: 10, z: 0.5 },
61
+ { x: 20, y: 5, z: 0.5 },
62
+ { x: 30, y: 15, z: 0.5 },
63
+ ],
64
+ ])
65
+ )
66
+ const util = editor.getShapeUtil('highlight')
67
+ expect(util.hideResizeHandles(shape)).toBe(false)
68
+ })
69
+
70
+ it('treats a shape with multiple segments as NOT a dot', () => {
71
+ const shape = createHighlightShape(
72
+ createDrawSegments([[{ x: 0, y: 0, z: 0.5 }], [{ x: 10, y: 10, z: 0.5 }]])
73
+ )
74
+ const util = editor.getShapeUtil('highlight')
75
+ expect(util.hideResizeHandles(shape)).toBe(false)
76
+ })
77
+ })
78
+
79
+ describe('hideRotateHandle mirrors hideResizeHandles for dots', () => {
80
+ it('hides rotate handle for dots', () => {
81
+ const shape = createHighlightShape(createDrawSegments([[{ x: 0, y: 0, z: 0.5 }]]))
82
+ const util = editor.getShapeUtil('highlight')
83
+ expect(util.hideRotateHandle(shape)).toBe(true)
84
+ })
85
+
86
+ it('shows rotate handle for non-dots', () => {
87
+ const shape = createHighlightShape(
88
+ createDrawSegments([
89
+ [
90
+ { x: 0, y: 0, z: 0.5 },
91
+ { x: 10, y: 10, z: 0.5 },
92
+ ],
93
+ ])
94
+ )
95
+ const util = editor.getShapeUtil('highlight')
96
+ expect(util.hideRotateHandle(shape)).toBe(false)
97
+ })
98
+ })
99
+
100
+ describe('hideSelectionBoundsFg mirrors hideResizeHandles for dots', () => {
101
+ it('hides selection bounds for dots', () => {
102
+ const shape = createHighlightShape(createDrawSegments([[{ x: 0, y: 0, z: 0.5 }]]))
103
+ const util = editor.getShapeUtil('highlight')
104
+ expect(util.hideSelectionBoundsFg(shape)).toBe(true)
105
+ })
106
+
107
+ it('shows selection bounds for non-dots', () => {
108
+ const shape = createHighlightShape(
109
+ createDrawSegments([
110
+ [
111
+ { x: 0, y: 0, z: 0.5 },
112
+ { x: 10, y: 10, z: 0.5 },
113
+ ],
114
+ ])
115
+ )
116
+ const util = editor.getShapeUtil('highlight')
117
+ expect(util.hideSelectionBoundsFg(shape)).toBe(false)
118
+ })
119
+ })
120
+
121
+ describe('base64 encoding boundary conditions', () => {
122
+ it('correctly handles the boundary at exactly 16 base64 characters (2 points)', () => {
123
+ // Each point is 8 base64 characters (3 Float16s = 6 bytes = 8 base64 chars)
124
+ // 2 points = 16 characters, which should NOT be a dot
125
+ const twoPointsBase64 = pointsToBase64([
126
+ { x: 0, y: 0, z: 0.5 },
127
+ { x: 1, y: 1, z: 0.5 },
128
+ ])
129
+ expect(twoPointsBase64.length).toBe(16)
130
+
131
+ const shape = createHighlightShape([{ type: 'free', points: twoPointsBase64 }])
132
+ const util = editor.getShapeUtil('highlight')
133
+ expect(util.hideResizeHandles(shape)).toBe(false)
134
+ })
135
+
136
+ it('correctly handles the boundary at exactly 8 base64 characters (1 point)', () => {
137
+ // 1 point = 8 characters, which should be a dot
138
+ const onePointBase64 = pointsToBase64([{ x: 0, y: 0, z: 0.5 }])
139
+ expect(onePointBase64.length).toBe(8)
140
+
141
+ const shape = createHighlightShape([{ type: 'free', points: onePointBase64 }])
142
+ const util = editor.getShapeUtil('highlight')
143
+ expect(util.hideResizeHandles(shape)).toBe(true)
144
+ })
145
+ })
146
+ })
@@ -5,7 +5,6 @@ import {
5
5
  Polygon2d,
6
6
  SVGContainer,
7
7
  ShapeUtil,
8
- TLDrawShapeSegment,
9
8
  TLHighlightShape,
10
9
  TLHighlightShapeProps,
11
10
  TLResizeInfo,
@@ -19,7 +18,7 @@ import {
19
18
  useValue,
20
19
  } from '@tldraw/editor'
21
20
 
22
- import { getHighlightFreehandSettings, getPointsFromSegments } from '../draw/getPath'
21
+ import { getHighlightFreehandSettings, getPointsFromDrawSegments } from '../draw/getPath'
23
22
  import { FONT_SIZES } from '../shared/default-shape-constants'
24
23
  import { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'
25
24
  import { getStrokePoints } from '../shared/freehand/getStrokePoints'
@@ -70,6 +69,8 @@ export class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {
70
69
  isComplete: false,
71
70
  isPen: false,
72
71
  scale: 1,
72
+ scaleX: 1,
73
+ scaleY: 1,
73
74
  }
74
75
  }
75
76
 
@@ -130,7 +131,11 @@ export class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {
130
131
  const strokeWidth = getStrokeWidth(shape)
131
132
 
132
133
  const { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)
133
- const allPointsFromSegments = getPointsFromSegments(shape.props.segments)
134
+ const allPointsFromSegments = getPointsFromDrawSegments(
135
+ shape.props.segments,
136
+ shape.props.scaleX,
137
+ shape.props.scaleY
138
+ )
134
139
 
135
140
  let strokePath
136
141
  if (strokePoints.length < 2) {
@@ -177,24 +182,10 @@ export class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {
177
182
  override onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {
178
183
  const { scaleX, scaleY } = info
179
184
 
180
- const newSegments: TLDrawShapeSegment[] = []
181
-
182
- for (const segment of shape.props.segments) {
183
- newSegments.push({
184
- ...segment,
185
- points: segment.points.map(({ x, y, z }) => {
186
- return {
187
- x: scaleX * x,
188
- y: scaleY * y,
189
- z,
190
- }
191
- }),
192
- })
193
- }
194
-
195
185
  return {
196
186
  props: {
197
- segments: newSegments,
187
+ scaleX: scaleX * shape.props.scaleX,
188
+ scaleY: scaleY * shape.props.scaleY,
198
189
  },
199
190
  }
200
191
  }
@@ -231,7 +222,11 @@ function getHighlightStrokePoints(
231
222
  strokeWidth: number,
232
223
  forceSolid: boolean
233
224
  ) {
234
- const allPointsFromSegments = getPointsFromSegments(shape.props.segments)
225
+ const allPointsFromSegments = getPointsFromDrawSegments(
226
+ shape.props.segments,
227
+ shape.props.scaleX,
228
+ shape.props.scaleY
229
+ )
235
230
  const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'
236
231
 
237
232
  let sw = strokeWidth
@@ -254,7 +249,9 @@ function getStrokeWidth(shape: TLHighlightShape) {
254
249
  }
255
250
 
256
251
  function getIsDot(shape: TLHighlightShape) {
257
- return shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2
252
+ // Each point is 8 base64 characters (3 Float16s = 6 bytes = 8 base64 chars)
253
+ // Check if we have less than 2 points without decoding
254
+ return shape.props.segments.length === 1 && shape.props.segments[0].points.length < 16
258
255
  }
259
256
 
260
257
  function HighlightRenderer({
@@ -270,7 +267,11 @@ function HighlightRenderer({
270
267
  }) {
271
268
  const theme = useDefaultColorTheme()
272
269
 
273
- const allPointsFromSegments = getPointsFromSegments(shape.props.segments)
270
+ const allPointsFromSegments = getPointsFromDrawSegments(
271
+ shape.props.segments,
272
+ shape.props.scaleX,
273
+ shape.props.scaleY
274
+ )
274
275
 
275
276
  let sw = strokeWidth
276
277
  if (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {
@@ -287,7 +288,7 @@ function HighlightRenderer({
287
288
  const solidStrokePath =
288
289
  strokePoints.length > 1
289
290
  ? getSvgPathFromStrokePoints(strokePoints, false)
290
- : getShapeDot(shape.props.segments[0].points[0])
291
+ : getShapeDot(allPointsFromSegments[0])
291
292
 
292
293
  const colorSpace = useColorSpace()
293
294
 
@@ -315,7 +316,7 @@ function useHighlightForceSolid(editor: Editor, shape: TLHighlightShape) {
315
316
  'forceSolid',
316
317
  () => {
317
318
  const sw = getStrokeWidth(shape)
318
- const zoomLevel = editor.getZoomLevel()
319
+ const zoomLevel = editor.getEfficientZoomLevel()
319
320
  if (sw / zoomLevel < 1.5) {
320
321
  return true
321
322
  }
@@ -23,14 +23,14 @@ export class Pointing extends StateNode {
23
23
 
24
24
  override onEnter(info: { shapeId?: TLShapeId }) {
25
25
  const { inputs } = this.editor
26
- const { currentPagePoint } = inputs
26
+ const currentPagePoint = inputs.getCurrentPagePoint()
27
27
 
28
28
  this.markId = undefined
29
29
 
30
30
  // Previously created line shape that we might be extending
31
31
  const shape = info.shapeId && this.editor.getShape<TLLineShape>(info.shapeId)
32
32
 
33
- if (shape && inputs.shiftKey) {
33
+ if (shape && inputs.getShiftKey()) {
34
34
  // Extending a previous shape
35
35
  this.markId = this.editor.markHistoryStoppingPoint(`creating_line:${shape.id}`)
36
36
  this.shape = shape
@@ -114,7 +114,7 @@ export class Pointing extends StateNode {
114
114
  override onPointerMove() {
115
115
  if (!this.shape) return
116
116
 
117
- if (this.editor.inputs.isDragging) {
117
+ if (this.editor.inputs.getIsDragging()) {
118
118
  const handles = this.editor.getShapeHandles(this.shape)
119
119
  if (!handles) {
120
120
  if (this.markId) this.editor.bailToMark(this.markId)
@@ -32,7 +32,7 @@ import {
32
32
  useValue,
33
33
  } from '@tldraw/editor'
34
34
  import { useCallback, useContext } from 'react'
35
- import { startEditingShapeWithLabel } from '../../tools/SelectTool/selectHelpers'
35
+ import { startEditingShapeWithRichText } from '../../tools/SelectTool/selectHelpers'
36
36
  import { TranslationsContext } from '../../ui/hooks/useTranslation/useTranslation'
37
37
  import {
38
38
  isEmptyRichText,
@@ -50,6 +50,7 @@ import {
50
50
  } from '../shared/default-shape-constants'
51
51
  import { useDefaultColorTheme } from '../shared/useDefaultColorTheme'
52
52
  import { useIsReadyForEditing } from '../shared/useEditablePlainText'
53
+ import { useEfficientZoomThreshold } from '../shared/useEfficientZoomThreshold'
53
54
  import {
54
55
  CLONE_HANDLE_MARGIN,
55
56
  NOTE_CENTER_OFFSET,
@@ -158,7 +159,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
158
159
  const isCoarsePointer = this.editor.getInstanceState().isCoarsePointer
159
160
  if (isCoarsePointer) return []
160
161
 
161
- const zoom = this.editor.getZoomLevel()
162
+ const zoom = this.editor.getEfficientZoomLevel()
162
163
  if (zoom * scale < 0.25) return []
163
164
 
164
165
  const nh = getNoteHeight(shape)
@@ -268,15 +269,12 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
268
269
  [this.editor]
269
270
  )
270
271
 
271
- // todo: consider hiding shadows on dark mode if they're invisible anyway
272
-
273
- const hideShadows = useValue('zoom', () => this.editor.getZoomLevel() < 0.35 / scale, [
274
- scale,
275
- this.editor,
276
- ])
277
-
278
272
  const isDarkMode = useValue('dark mode', () => this.editor.user.getIsDarkMode(), [this.editor])
279
273
 
274
+ // Shadows are hidden when zoomed out far enough or in dark mode
275
+ let hideShadows = useEfficientZoomThreshold(scale * 0.25)
276
+ if (isDarkMode) hideShadows = true
277
+
280
278
  const isSelected = shape.id === this.editor.getOnlySelectedShapeId()
281
279
 
282
280
  const isReadyForEditing = useIsReadyForEditing(this.editor, shape.id)
@@ -318,6 +316,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
318
316
  wrap
319
317
  padding={LABEL_PADDING * scale}
320
318
  hasCustomTabBehavior
319
+ showTextOutline={false}
321
320
  onKeyDown={handleKeyDown}
322
321
  />
323
322
  )}
@@ -537,7 +536,7 @@ function useNoteKeydownHandler(id: TLShapeId) {
537
536
  const newNote = getNoteShapeForAdjacentPosition(editor, shape, adjacentCenter, pageRotation)
538
537
 
539
538
  if (newNote) {
540
- startEditingShapeWithLabel(editor, newNote, true /* selectAll */)
539
+ startEditingShapeWithRichText(editor, newNote, { selectAll: true })
541
540
  }
542
541
  }
543
542
  },
@@ -30,7 +30,7 @@ function testCloneHandles(x: number, y: number, rotation: number) {
30
30
  const handleInPageSpace = editor.getShapePageTransform(shape).applyToPoint(handle)
31
31
  editor.select(shape.id)
32
32
  editor.pointerMove(handleInPageSpace.x, handleInPageSpace.y)
33
- expect(editor.inputs.currentPagePoint).toMatchObject({
33
+ expect(editor.inputs.getCurrentPagePoint()).toMatchObject({
34
34
  x: handleInPageSpace.x,
35
35
  y: handleInPageSpace.y,
36
36
  })
@@ -99,6 +99,7 @@ function testDragCloneHandles(x: number, y: number, rotation: number) {
99
99
  editor.expectToBeIn('select.pointing_handle')
100
100
 
101
101
  editor.pointerMove(handleInPageSpace.x + 30, handleInPageSpace.y + 30)
102
+ editor.forceTick()
102
103
 
103
104
  editor.expectToBeIn('select.translating')
104
105
 
@@ -205,6 +206,7 @@ it('Creates an adjacent note when dragging the clone handle', () => {
205
206
  editor.expectToBeIn('select.pointing_handle')
206
207
 
207
208
  editor.pointerMove(handle.x + 30, handle.y + 30)
209
+ editor.forceTick()
208
210
 
209
211
  const newShape = editor.getLastCreatedShape()
210
212
 
@@ -9,6 +9,7 @@ import {
9
9
  maybeSnapToGrid,
10
10
  } from '@tldraw/editor'
11
11
 
12
+ import { startEditingShapeWithRichText } from '../../../tools/SelectTool/selectHelpers'
12
13
  import {
13
14
  NOTE_ADJACENT_POSITION_SNAP_RADIUS,
14
15
  getAvailableNoteAdjacentPositions,
@@ -32,7 +33,7 @@ export class Pointing extends StateNode {
32
33
  this.markId = editor.markHistoryStoppingPoint(`creating_note:${id}`)
33
34
 
34
35
  // Check for note pits; if the pointer is close to one, place the note centered on the pit
35
- const center = this.editor.inputs.originPagePoint.clone()
36
+ const center = this.editor.inputs.getOriginPagePoint().clone()
36
37
  const offset = getNoteShapeAdjacentPositionOffset(
37
38
  this.editor,
38
39
  center,
@@ -52,7 +53,7 @@ export class Pointing extends StateNode {
52
53
  }
53
54
 
54
55
  override onPointerMove(info: TLPointerEventInfo) {
55
- if (this.editor.inputs.isDragging) {
56
+ if (this.editor.inputs.getIsDragging()) {
56
57
  this.editor.setCurrentTool('select.translating', {
57
58
  ...info,
58
59
  target: 'shape',
@@ -61,8 +62,7 @@ export class Pointing extends StateNode {
61
62
  isCreating: true,
62
63
  creatingMarkId: this.markId,
63
64
  onCreate: () => {
64
- this.editor.setEditingShape(this.shape.id)
65
- this.editor.setCurrentTool('select.editing_shape')
65
+ startEditingShapeWithRichText(this.editor, this.shape.id)
66
66
  },
67
67
  })
68
68
  }
@@ -88,12 +88,7 @@ export class Pointing extends StateNode {
88
88
  if (this.editor.getInstanceState().isToolLocked) {
89
89
  this.parent.transition('idle')
90
90
  } else {
91
- this.editor.setEditingShape(this.shape.id)
92
- this.editor.setCurrentTool('select.editing_shape', {
93
- ...this.info,
94
- target: 'shape',
95
- shape: this.shape,
96
- })
91
+ startEditingShapeWithRichText(this.editor, this.shape.id, { info: this.info })
97
92
  }
98
93
  }
99
94
 
@@ -1,16 +1,17 @@
1
- import { useEditor, useValue } from '@tldraw/editor'
1
+ import { useEditor } from '@tldraw/editor'
2
2
  import classNames from 'classnames'
3
3
  import { PointerEventHandler, useCallback } from 'react'
4
+ import { useEfficientZoomThreshold } from './useEfficientZoomThreshold'
4
5
 
5
6
  const LINK_ICON =
6
7
  "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E"
7
8
 
8
9
  export function HyperlinkButton({ url }: { url: string }) {
9
10
  const editor = useEditor()
10
- const hideButton = useValue('zoomLevel', () => editor.getZoomLevel() < 0.32, [editor])
11
+ const hideButton = useEfficientZoomThreshold()
11
12
  const markAsHandledOnShiftKey = useCallback<PointerEventHandler>(
12
13
  (e) => {
13
- if (!editor.inputs.shiftKey) editor.markEventAsHandled(e)
14
+ if (!editor.inputs.getShiftKey()) editor.markEventAsHandled(e)
14
15
  },
15
16
  [editor]
16
17
  )
@@ -7,6 +7,7 @@ import {
7
7
  TLDefaultVerticalAlignStyle,
8
8
  TLShapeId,
9
9
  } from '@tldraw/editor'
10
+ import classNames from 'classnames'
10
11
  import React from 'react'
11
12
  import { PlainTextArea } from '../text/PlainTextArea'
12
13
  import { TextHelpers } from './TextHelpers'
@@ -34,6 +35,7 @@ export interface PlainTextLabelProps {
34
35
  textWidth?: number
35
36
  textHeight?: number
36
37
  padding?: number
38
+ showTextOutline?: boolean
37
39
  }
38
40
 
39
41
  /**
@@ -61,6 +63,7 @@ export const PlainTextLabel = React.memo(function PlainTextLabel({
61
63
  style,
62
64
  textWidth,
63
65
  textHeight,
66
+ showTextOutline = true,
64
67
  }: PlainTextLabelProps) {
65
68
  const { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =
66
69
  useEditablePlainText(shapeId, type, plaintext)
@@ -109,7 +112,13 @@ export const PlainTextLabel = React.memo(function PlainTextLabel({
109
112
  height: textHeight ? Math.ceil(textHeight) : undefined,
110
113
  }}
111
114
  >
112
- <div className={`${cssPrefix} tl-text tl-text-content`} dir="auto">
115
+ <div
116
+ className={classNames(
117
+ `${cssPrefix} tl-text tl-text-content`,
118
+ showTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'
119
+ )}
120
+ dir="auto"
121
+ >
113
122
  {finalPlainText.split('\n').map((lineOfText, index) => (
114
123
  <div key={index} dir="auto">
115
124
  {lineOfText}
@@ -15,6 +15,7 @@ import {
15
15
  useReactor,
16
16
  useValue,
17
17
  } from '@tldraw/editor'
18
+ import classNames from 'classnames'
18
19
  import React, { useMemo } from 'react'
19
20
  import { renderHtmlFromRichText } from '../../utils/text/richText'
20
21
  import { RichTextArea } from '../text/RichTextArea'
@@ -44,6 +45,7 @@ export interface RichTextLabelProps {
44
45
  textHeight?: number
45
46
  padding?: number
46
47
  hasCustomTabBehavior?: boolean
48
+ showTextOutline?: boolean
47
49
  }
48
50
 
49
51
  /**
@@ -72,6 +74,7 @@ export const RichTextLabel = React.memo(function RichTextLabel({
72
74
  textWidth,
73
75
  textHeight,
74
76
  hasCustomTabBehavior,
77
+ showTextOutline = true,
75
78
  }: RichTextLabelProps) {
76
79
  const editor = useEditor()
77
80
  const isDragging = React.useRef(false)
@@ -94,7 +97,7 @@ export const RichTextLabel = React.memo(function RichTextLabel({
94
97
  'isDragging',
95
98
  () => {
96
99
  editor.getInstanceState()
97
- isDragging.current = editor.inputs.isDragging
100
+ isDragging.current = editor.inputs.getIsDragging()
98
101
  },
99
102
  [editor]
100
103
  )
@@ -129,7 +132,10 @@ export const RichTextLabel = React.memo(function RichTextLabel({
129
132
  const cssPrefix = classNamePrefix || 'tl-text'
130
133
  return (
131
134
  <div
132
- className={`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`}
135
+ className={classNames(
136
+ `${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`,
137
+ showTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'
138
+ )}
133
139
  aria-hidden={!isEditing}
134
140
  data-font={font}
135
141
  data-align={align}
@@ -259,7 +265,10 @@ export function RichTextSVG({
259
265
  y={bounds.minY}
260
266
  width={bounds.w}
261
267
  height={bounds.h}
262
- className="tl-export-embed-styles tl-rich-text tl-rich-text-svg"
268
+ className={classNames(
269
+ 'tl-export-embed-styles tl-rich-text tl-rich-text-svg',
270
+ showTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'
271
+ )}
263
272
  >
264
273
  <div style={wrapperStyle}>
265
274
  <div dangerouslySetInnerHTML={{ __html: html }} style={style} />
@@ -50,10 +50,10 @@ export const ShapeFill = React.memo(function ShapeFill({
50
50
  export function PatternFill({ d, color, theme }: ShapeFillProps) {
51
51
  const editor = useEditor()
52
52
  const svgExport = useSvgExportContext()
53
- const zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])
53
+ const zoomLevel = useValue('zoomLevel', () => editor.getEfficientZoomLevel(), [editor])
54
54
  const getHashPatternZoomName = useGetHashPatternZoomName()
55
55
 
56
- const teenyTiny = editor.getZoomLevel() <= 0.18
56
+ const teenyTiny = zoomLevel <= 0.18
57
57
 
58
58
  return (
59
59
  <>
@@ -1,4 +1,4 @@
1
- import { TLDrawShapeSegment, VecModel, lerp } from '@tldraw/editor'
1
+ import { TLDrawShapeSegment, VecModel, b64Vecs, lerp } from '@tldraw/editor'
2
2
 
3
3
  /** @public */
4
4
  export const interpolateSegments = (
@@ -10,8 +10,8 @@ export const interpolateSegments = (
10
10
  const endPoints: VecModel[] = []
11
11
 
12
12
  // Extract all points from startSegments and endSegments
13
- startSegments.forEach((segment) => startPoints.push(...segment.points))
14
- endSegments.forEach((segment) => endPoints.push(...segment.points))
13
+ startSegments.forEach((segment) => startPoints.push(...b64Vecs.decodePoints(segment.points)))
14
+ endSegments.forEach((segment) => endPoints.push(...b64Vecs.decodePoints(segment.points)))
15
15
 
16
16
  const maxLength = Math.max(startPoints.length, endPoints.length)
17
17
  const pointsToUseStart: VecModel[] = []
@@ -39,7 +39,7 @@ export const interpolateSegments = (
39
39
  return [
40
40
  {
41
41
  type: 'free',
42
- points: interpolatedPoints,
42
+ points: b64Vecs.encodePoints(interpolatedPoints),
43
43
  },
44
44
  ]
45
45
  }
@@ -0,0 +1,10 @@
1
+ import { useEditor, useValue } from '@tldraw/editor'
2
+
3
+ /** Returns true when zoomed out far enough that shapes should render in a simplified "solid" style. */
4
+ export function useEfficientZoomThreshold(threshold = 0.25) {
5
+ const editor = useEditor()
6
+ return useValue('efficient zoom threshold', () => editor.getEfficientZoomLevel() < threshold, [
7
+ editor,
8
+ threshold,
9
+ ])
10
+ }
@@ -96,7 +96,7 @@ export function useImageOrVideoAsset({ shapeId, assetId, width }: UseImageOrVide
96
96
 
97
97
  const screenScale = exportInfo
98
98
  ? exportInfo.scale * (width / asset.props.w)
99
- : editor.getZoomLevel() * (width / asset.props.w)
99
+ : editor.getEfficientZoomLevel() * (width / asset.props.w)
100
100
 
101
101
  function resolve(asset: TLImageAsset | TLVideoAsset, url: string | null) {
102
102
  if (isCancelled) return // don't update if the hook has remounted
@@ -183,6 +183,11 @@ export const RichTextArea = React.forwardRef<HTMLDivElement, TextAreaProps>(func
183
183
  blockSeparator: '\n',
184
184
  },
185
185
  },
186
+ // N.B. We disable the text direction in the core list here,
187
+ // but we add it back in again in our own extensions list so that
188
+ // people can omit/override it if they want to.
189
+ enableCoreExtensions: { textDirection: false },
190
+ textDirection: 'auto',
186
191
  ...restOfTipTapConfig,
187
192
  content: rInitialRichText.current as JSONContent,
188
193
  })
@@ -43,6 +43,8 @@ const sizeCache = createComputedCache(
43
43
  export interface TextShapeOptions {
44
44
  /** How much addition padding should be added to the horizontal geometry of the shape when binding to an arrow? */
45
45
  extraArrowHorizontalPadding: number
46
+ /** Whether to show the outline of the text shape (using the same color as the canvas). This helps with overlapping shapes. It does not show up on Safari, where text outline is a performance issues. */
47
+ showTextOutline: boolean
46
48
  }
47
49
 
48
50
  /** @public */
@@ -53,6 +55,7 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
53
55
 
54
56
  override options: TextShapeOptions = {
55
57
  extraArrowHorizontalPadding: 10,
58
+ showTextOutline: true,
56
59
  }
57
60
 
58
61
  getDefaultProps(): TLTextShape['props'] {
@@ -140,6 +143,7 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
140
143
  isSelected={isSelected}
141
144
  textWidth={width}
142
145
  textHeight={height}
146
+ showTextOutline={this.options.showTextOutline}
143
147
  style={{
144
148
  transform: `scale(${scale})`,
145
149
  transformOrigin: 'top left',
@@ -175,6 +179,7 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
175
179
  labelColor={getColorValue(theme, shape.props.color, 'solid')}
176
180
  bounds={exportBounds}
177
181
  padding={0}
182
+ showTextOutline={this.options.showTextOutline}
178
183
  />
179
184
  )
180
185
  }