tldraw 3.15.3 → 3.16.0-canary.016d4c2889b7

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 (436) hide show
  1. package/dist-cjs/index.d.ts +264 -10
  2. package/dist-cjs/index.js +32 -2
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
  7. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  8. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js +6 -4
  10. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  11. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +25 -39
  12. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  13. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +16 -4
  14. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  16. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  17. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  18. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  19. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  20. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  21. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  22. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  23. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  24. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  25. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +18 -12
  26. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  27. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  28. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  29. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  30. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  31. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  32. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  33. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  34. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  35. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
  36. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  37. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  38. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  40. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  41. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  42. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  43. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  44. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
  45. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
  46. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  47. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  48. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  49. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  50. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  51. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  52. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  53. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  54. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +4 -0
  55. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  56. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -15
  57. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  58. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +5 -0
  59. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  60. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  61. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  62. package/dist-cjs/lib/ui/TldrawUi.js +27 -12
  63. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  64. package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
  65. package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
  66. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  67. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  68. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  69. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  70. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  71. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +46 -6
  73. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  74. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +3 -3
  75. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  76. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  77. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  78. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  79. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  80. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
  81. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  82. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
  83. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  84. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  85. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  86. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  87. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  88. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
  89. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  90. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -140
  91. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  92. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
  93. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
  94. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
  95. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
  96. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  97. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  98. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  99. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  100. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  101. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  102. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
  103. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  104. package/dist-cjs/lib/ui/components/menu-items.js +6 -0
  105. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  106. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
  107. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
  108. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  109. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  110. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  111. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  112. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -0
  113. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  114. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +30 -7
  115. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  116. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +262 -0
  117. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
  118. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  119. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  120. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  121. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  122. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  123. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -20
  124. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  125. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
  126. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
  127. package/dist-cjs/lib/ui/context/actions.js +45 -9
  128. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  129. package/dist-cjs/lib/ui/context/components.js +2 -0
  130. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  131. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  132. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  133. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  134. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  135. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  136. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +8 -0
  137. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  138. package/dist-cjs/lib/ui/kbd-utils.js +11 -4
  139. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  140. package/dist-cjs/lib/ui/version.js +3 -3
  141. package/dist-cjs/lib/ui/version.js.map +1 -1
  142. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
  143. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  144. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +3 -2
  145. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  146. package/dist-esm/index.d.mts +264 -10
  147. package/dist-esm/index.mjs +50 -4
  148. package/dist-esm/index.mjs.map +2 -2
  149. package/dist-esm/lib/Tldraw.mjs +14 -4
  150. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  151. package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
  152. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  153. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  154. package/dist-esm/lib/defaultExternalContentHandlers.mjs +6 -4
  155. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  156. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +28 -39
  157. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  158. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +19 -5
  159. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  160. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  161. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  162. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  163. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  164. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +3 -0
  165. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  166. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  167. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  168. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  169. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  170. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +19 -12
  171. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  172. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  173. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  174. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  175. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  176. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  177. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  178. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  179. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  180. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
  181. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  182. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  183. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  184. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  185. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  186. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  187. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  188. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  189. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
  190. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
  191. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  192. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  193. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  194. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  195. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  196. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  197. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  198. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  199. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +4 -0
  200. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  201. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -15
  202. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  203. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +5 -0
  204. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  205. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  206. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  207. package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
  208. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  209. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
  210. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
  211. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  212. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  213. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  214. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  215. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
  216. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
  217. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +46 -6
  218. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  219. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +3 -5
  220. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
  221. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  222. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  223. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  224. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  225. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
  226. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  227. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
  228. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  229. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
  230. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
  231. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
  232. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
  233. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +3 -1
  234. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  235. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +171 -140
  236. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  237. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
  238. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
  239. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
  240. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  241. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  242. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  243. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
  244. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  245. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
  246. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  247. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +5 -4
  248. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  249. package/dist-esm/lib/ui/components/menu-items.mjs +6 -0
  250. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  251. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +6 -6
  252. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  253. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
  254. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  255. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
  256. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  257. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +1 -0
  258. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  259. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +30 -7
  260. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  261. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +239 -0
  262. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +7 -0
  263. package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
  264. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
  265. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  266. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  267. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  268. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -22
  269. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  270. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +3 -2
  271. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
  272. package/dist-esm/lib/ui/context/actions.mjs +45 -9
  273. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  274. package/dist-esm/lib/ui/context/components.mjs +2 -0
  275. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  276. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  277. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  278. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  279. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  280. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +8 -0
  281. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  282. package/dist-esm/lib/ui/kbd-utils.mjs +11 -4
  283. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  284. package/dist-esm/lib/ui/version.mjs +3 -3
  285. package/dist-esm/lib/ui/version.mjs.map +1 -1
  286. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
  287. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  288. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +3 -2
  289. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  290. package/package.json +11 -34
  291. package/src/index.ts +35 -2
  292. package/src/lib/Tldraw.tsx +15 -2
  293. package/src/lib/canvas/TldrawCropHandles.tsx +2 -0
  294. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  295. package/src/lib/defaultExternalContentHandlers.ts +14 -5
  296. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  297. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  298. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +12 -11
  299. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +29 -42
  300. package/src/lib/shapes/arrow/arrowLabel.ts +23 -3
  301. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -1
  302. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  303. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +3 -0
  304. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  305. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  306. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  307. package/src/lib/shapes/frame/FrameShapeUtil.tsx +29 -14
  308. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  309. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  310. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  311. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  312. package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
  313. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  314. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  315. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  316. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  317. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  318. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  319. package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
  320. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  321. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  322. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  323. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  324. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  325. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +4 -0
  326. package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -24
  327. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +7 -0
  328. package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
  329. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -0
  330. package/src/lib/ui/TldrawUi.tsx +33 -12
  331. package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
  332. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  333. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  334. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  335. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +38 -6
  336. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -4
  337. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  338. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  339. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
  340. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
  341. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  342. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  343. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
  344. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -107
  345. package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
  346. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
  347. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  348. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  349. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  350. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +17 -12
  351. package/src/lib/ui/components/menu-items.tsx +8 -0
  352. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
  353. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
  354. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  355. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +1 -0
  356. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +51 -12
  357. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +325 -0
  358. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  359. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  360. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  361. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +221 -19
  362. package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
  363. package/src/lib/ui/context/actions.tsx +45 -9
  364. package/src/lib/ui/context/components.tsx +3 -0
  365. package/src/lib/ui/context/events.tsx +5 -3
  366. package/src/lib/ui/hooks/menu-hooks.ts +1 -0
  367. package/src/lib/ui/hooks/useTools.tsx +140 -10
  368. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +8 -0
  369. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +8 -0
  370. package/src/lib/ui/kbd-utils.ts +12 -4
  371. package/src/lib/ui/version.ts +3 -3
  372. package/src/lib/ui.css +409 -292
  373. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +21 -7
  374. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
  375. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +28 -7
  376. package/src/lib/utils/tldr/buildFromV1Document.ts +2 -1
  377. package/src/test/A11y.test.tsx +3 -2
  378. package/src/test/ClickManager.test.ts +7 -6
  379. package/src/test/Editor.test.tsx +20 -19
  380. package/src/test/EraserTool.test.ts +184 -13
  381. package/src/test/HandTool.test.ts +10 -9
  382. package/src/test/HighlightShape.test.ts +2 -1
  383. package/src/test/SelectTool.test.ts +40 -13
  384. package/src/test/TLUserPreferences.test.ts +4 -3
  385. package/src/test/TestEditor.ts +13 -15
  386. package/src/test/TldrawEditor.test.tsx +11 -10
  387. package/src/test/ZoomTool.test.ts +7 -6
  388. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  389. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  390. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  391. package/src/test/arrows-megabus.test.tsx +17 -10
  392. package/src/test/bindings.test.tsx +24 -37
  393. package/src/test/bookmark-shapes.test.ts +1 -8
  394. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  395. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  396. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  397. package/src/test/commands/alignShapes.test.tsx +25 -24
  398. package/src/test/commands/animationSpeed.test.ts +2 -1
  399. package/src/test/commands/centerOnPoint.test.ts +3 -2
  400. package/src/test/commands/clipboard.test.ts +3 -2
  401. package/src/test/commands/createShapes.test.ts +2 -1
  402. package/src/test/commands/deletePage.test.ts +84 -1
  403. package/src/test/commands/deleteShapes.test.ts +2 -1
  404. package/src/test/commands/distributeShapes.test.tsx +11 -10
  405. package/src/test/commands/getSvgString.test.ts +2 -1
  406. package/src/test/commands/packShapes.test.ts +5 -4
  407. package/src/test/commands/resizeShape.test.ts +2 -1
  408. package/src/test/commands/rotateShapes.test.ts +7 -6
  409. package/src/test/commands/setCamera.test.ts +4 -3
  410. package/src/test/commands/setCurrentPage.test.ts +3 -2
  411. package/src/test/commands/stackShapes.test.ts +11 -10
  412. package/src/test/commands/stretch.test.tsx +13 -12
  413. package/src/test/createDeepLink.test.tsx +2 -1
  414. package/src/test/cropping.test.ts +3 -2
  415. package/src/test/custom-clipping.test.ts +436 -0
  416. package/src/test/drawing.test.ts +2 -1
  417. package/src/test/flipShapes.test.ts +4 -3
  418. package/src/test/frames.test.ts +25 -24
  419. package/src/test/getCulledShapes.test.tsx +3 -2
  420. package/src/test/groups.test.tsx +1 -1
  421. package/src/test/handleDeepLink.test.tsx +2 -1
  422. package/src/test/inner-outer-margin.test.ts +315 -0
  423. package/src/test/maxShapes.test.ts +3 -2
  424. package/src/test/modifiers.test.ts +5 -4
  425. package/src/test/navigation.test.ts +12 -11
  426. package/src/test/panning.test.ts +2 -1
  427. package/src/test/perf/perf.test.ts +2 -1
  428. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  429. package/src/test/resizing.test.ts +39 -38
  430. package/src/test/select.test.tsx +4 -3
  431. package/src/test/selection-omnibus.test.ts +11 -10
  432. package/src/test/shapeutils.test.ts +4 -3
  433. package/src/test/translating.test.ts +9 -8
  434. package/tldraw.css +714 -603
  435. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  436. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
package/src/index.ts CHANGED
@@ -22,8 +22,20 @@ export {
22
22
  } from './lib/shapes/shared/PathBuilder'
23
23
  export { usePrefersReducedMotion } from './lib/shapes/shared/usePrefersReducedMotion'
24
24
  export { DefaultA11yAnnouncer, useSelectedShapesAnnouncer } from './lib/ui/components/A11y'
25
+ export { AccessibilityMenu } from './lib/ui/components/AccessibilityMenu'
25
26
  export { ColorSchemeMenu } from './lib/ui/components/ColorSchemeMenu'
27
+ export { DefaultFollowingIndicator } from './lib/ui/components/DefaultFollowingIndicator'
26
28
  export { DefaultDialogs } from './lib/ui/components/Dialogs'
29
+ export {
30
+ TldrawUiColumn,
31
+ TldrawUiGrid,
32
+ TldrawUiOrientationProvider,
33
+ TldrawUiRow,
34
+ useTldrawUiOrientation,
35
+ type TldrawUiOrientationContext,
36
+ type TldrawUiOrientationProviderProps,
37
+ type TLUiLayoutProps,
38
+ } from './lib/ui/components/primitives/layout'
27
39
  export {
28
40
  TldrawUiMenuActionCheckboxItem,
29
41
  type TLUiMenuActionCheckboxItemProps,
@@ -41,6 +53,7 @@ export { TldrawUiTranslationProvider } from './lib/ui/hooks/useTranslation/useTr
41
53
  // eslint-disable-next-line local/no-export-star
42
54
  export * from '@tldraw/editor'
43
55
  export { ArrowBindingUtil } from './lib/bindings/arrow/ArrowBindingUtil'
56
+ export { TldrawCropHandles, type TldrawCropHandlesProps } from './lib/canvas/TldrawCropHandles'
44
57
  export { TldrawHandles } from './lib/canvas/TldrawHandles'
45
58
  export { TldrawArrowHints, TldrawOverlays } from './lib/canvas/TldrawOverlays'
46
59
  export { TldrawScribble } from './lib/canvas/TldrawScribble'
@@ -71,7 +84,9 @@ export {
71
84
  defaultHandleExternalTldrawContent,
72
85
  defaultHandleExternalUrlAsset,
73
86
  defaultHandleExternalUrlContent,
87
+ getAssetInfo,
74
88
  getMediaAssetInfoPartial,
89
+ notifyIfFileNotAllowed,
75
90
  registerDefaultExternalContentHandlers,
76
91
  type TLDefaultExternalContentHandlerOpts,
77
92
  type TLExternalContentProps,
@@ -153,6 +168,9 @@ export {
153
168
  type TLDefaultFont,
154
169
  type TLDefaultFonts,
155
170
  } from './lib/shapes/shared/defaultFonts'
171
+ export { getStrokePoints } from './lib/shapes/shared/freehand/getStrokePoints'
172
+ export { getSvgPathFromStrokePoints } from './lib/shapes/shared/freehand/svg'
173
+ export { type StrokeOptions, type StrokePoint } from './lib/shapes/shared/freehand/types'
156
174
  export {
157
175
  PlainTextLabel,
158
176
  TextLabel,
@@ -183,6 +201,7 @@ export { TldrawImage, type TldrawImageProps } from './lib/TldrawImage'
183
201
  export { EraserTool } from './lib/tools/EraserTool/EraserTool'
184
202
  export { HandTool } from './lib/tools/HandTool/HandTool'
185
203
  export { LaserTool } from './lib/tools/LaserTool/LaserTool'
204
+ export { getHitShapeOnCanvasPointerDown } from './lib/tools/selection-logic/getHitShapeOnCanvasPointerDown'
186
205
  export { SelectTool } from './lib/tools/SelectTool/SelectTool'
187
206
  export { ZoomTool } from './lib/tools/ZoomTool/ZoomTool'
188
207
  export {
@@ -250,6 +269,7 @@ export {
250
269
  EditSubmenu,
251
270
  ExportFileContentSubMenu,
252
271
  ExtrasGroup,
272
+ LockGroup,
253
273
  MiscMenuGroup,
254
274
  PreferencesGroup,
255
275
  UndoRedoGroup,
@@ -290,6 +310,7 @@ export {
290
310
  ToggleSnapModeItem,
291
311
  ToggleToolLockItem,
292
312
  ToggleTransparentBgMenuItem,
313
+ ToggleUiLabelsItem,
293
314
  ToggleWrapModeItem,
294
315
  UngroupMenuItem,
295
316
  UnlockAllMenuItem,
@@ -408,6 +429,12 @@ export {
408
429
  type TLUiToolbarToggleGroupProps,
409
430
  type TLUiToolbarToggleItemProps,
410
431
  } from './lib/ui/components/primitives/TldrawUiToolbar'
432
+ export {
433
+ TldrawUiTooltip,
434
+ TldrawUiTooltipProvider,
435
+ type TldrawUiTooltipProps,
436
+ type TldrawUiTooltipProviderProps,
437
+ } from './lib/ui/components/primitives/TldrawUiTooltip'
411
438
  export {
412
439
  DefaultQuickActions,
413
440
  type TLUiQuickActionsProps,
@@ -499,6 +526,10 @@ export {
499
526
  OverflowingToolbar,
500
527
  type OverflowingToolbarProps,
501
528
  } from './lib/ui/components/Toolbar/OverflowingToolbar'
529
+ export {
530
+ ToggleToolLockedButton,
531
+ type ToggleToolLockedButtonProps,
532
+ } from './lib/ui/components/Toolbar/ToggleToolLockedButton'
502
533
  export {
503
534
  CenteredTopPanelContainer,
504
535
  type CenteredTopPanelContainerProps,
@@ -568,7 +599,7 @@ export {
568
599
  type TLUiToastsContextType,
569
600
  type TLUiToastsProviderProps,
570
601
  } from './lib/ui/context/toasts'
571
- export { useCanRedo, useCanUndo } from './lib/ui/hooks/menu-hooks'
602
+ export { useCanRedo, useCanUndo, useUnlockedSelectedShapesCount } from './lib/ui/hooks/menu-hooks'
572
603
  export { useMenuClipboardEvents, useNativeClipboardEvents } from './lib/ui/hooks/useClipboardEvents'
573
604
  export {
574
605
  useCollaborationStatus,
@@ -582,7 +613,9 @@ export { useMenuIsOpen } from './lib/ui/hooks/useMenuIsOpen'
582
613
  export { useReadonly } from './lib/ui/hooks/useReadonly'
583
614
  export { useRelevantStyles } from './lib/ui/hooks/useRelevantStyles'
584
615
  export {
616
+ onDragFromToolbarToCreateShape,
585
617
  useTools,
618
+ type OnDragFromToolbarToCreateShapesOpts,
586
619
  type TLUiToolItem,
587
620
  type TLUiToolsContextType,
588
621
  type TLUiToolsProviderProps,
@@ -597,7 +630,7 @@ export {
597
630
  } from './lib/ui/hooks/useTranslation/useTranslation'
598
631
  export { type TLUiIconType } from './lib/ui/icon-types'
599
632
  export { useDefaultHelpers, type TLUiOverrideHelpers, type TLUiOverrides } from './lib/ui/overrides'
600
- export { TldrawUi, type TldrawUiProps } from './lib/ui/TldrawUi'
633
+ export { TldrawUi, TldrawUiInFrontOfTheCanvas, type TldrawUiProps } from './lib/ui/TldrawUi'
601
634
  export { containBoxSize, downsizeImage, type BoxWidthHeight } from './lib/utils/assets/assets'
602
635
  export { preloadFont, type TLTypeFace } from './lib/utils/assets/preload-font'
603
636
  export { getEmbedInfo, type TLEmbedResult } from './lib/utils/embeds/embeds'
@@ -33,7 +33,7 @@ import { registerDefaultSideEffects } from './defaultSideEffects'
33
33
  import { defaultTools } from './defaultTools'
34
34
  import { EmbedShapeUtil } from './shapes/embed/EmbedShapeUtil'
35
35
  import { allDefaultFontFaces } from './shapes/shared/defaultFonts'
36
- import { TldrawUi, TldrawUiProps } from './ui/TldrawUi'
36
+ import { TldrawUi, TldrawUiInFrontOfTheCanvas, TldrawUiProps } from './ui/TldrawUi'
37
37
  import { TLUiAssetUrlOverrides, useDefaultUiAssetUrlsWithOverrides } from './ui/assetUrls'
38
38
  import { LoadingScreen } from './ui/components/LoadingScreen'
39
39
  import { Spinner } from './ui/components/Spinner'
@@ -118,6 +118,18 @@ export function Tldraw(props: TldrawProps) {
118
118
 
119
119
  const _components = useShallowObjectIdentity(components)
120
120
 
121
+ const CustomInFrontOfTheCanvas = components?.InFrontOfTheCanvas
122
+ const InFrontOfTheCanvas = useMemo(() => {
123
+ if (rest.hideUi) return CustomInFrontOfTheCanvas ?? null
124
+ if (!CustomInFrontOfTheCanvas) return TldrawUiInFrontOfTheCanvas
125
+
126
+ return () => (
127
+ <>
128
+ <TldrawUiInFrontOfTheCanvas />
129
+ <CustomInFrontOfTheCanvas />
130
+ </>
131
+ )
132
+ }, [rest.hideUi, CustomInFrontOfTheCanvas])
121
133
  const componentsWithDefault = useMemo(
122
134
  () => ({
123
135
  Scribble: TldrawScribble,
@@ -129,8 +141,9 @@ export function Tldraw(props: TldrawProps) {
129
141
  Spinner,
130
142
  LoadingScreen,
131
143
  ..._components,
144
+ InFrontOfTheCanvas,
132
145
  }),
133
- [_components]
146
+ [_components, InFrontOfTheCanvas]
134
147
  )
135
148
 
136
149
  const _shapeUtils = useShallowArrayIdentity(shapeUtils)
@@ -2,6 +2,7 @@ import { toDomPrecision } from '@tldraw/editor'
2
2
  import classNames from 'classnames'
3
3
  import { useTranslation } from '../ui/hooks/useTranslation/useTranslation'
4
4
 
5
+ /** @public */
5
6
  export interface TldrawCropHandlesProps {
6
7
  size: number
7
8
  width: number
@@ -9,6 +10,7 @@ export interface TldrawCropHandlesProps {
9
10
  hideAlternateHandles: boolean
10
11
  }
11
12
 
13
+ /** @public @react */
12
14
  export function TldrawCropHandles({
13
15
  size,
14
16
  width,
@@ -31,7 +31,7 @@ export function TldrawScribble({ scribble, zoom, color, opacity, className }: TL
31
31
  <path
32
32
  className="tl-scribble"
33
33
  d={d}
34
- fill={color ?? `var(--color-${scribble.color})`}
34
+ fill={color ?? `var(--tl-color-${scribble.color})`}
35
35
  opacity={opacity ?? scribble.opacity}
36
36
  />
37
37
  </svg>
@@ -144,7 +144,7 @@ export async function defaultHandleExternalFileAsset(
144
144
  { file, assetId }: TLFileExternalAsset,
145
145
  options: TLDefaultExternalContentHandlerOpts
146
146
  ) {
147
- const isSuccess = runFileChecks(file, options)
147
+ const isSuccess = notifyIfFileNotAllowed(file, options)
148
148
  if (!isSuccess) assert(false, 'File checks failed')
149
149
 
150
150
  const assetInfo = await getAssetInfo(file, options, assetId)
@@ -161,7 +161,7 @@ export async function defaultHandleExternalFileReplaceContent(
161
161
  { file, shapeId, isImage }: TLFileReplaceExternalContent,
162
162
  options: TLDefaultExternalContentHandlerOpts
163
163
  ) {
164
- const isSuccess = runFileChecks(file, options)
164
+ const isSuccess = notifyIfFileNotAllowed(file, options)
165
165
  if (!isSuccess) assert(false, 'File checks failed')
166
166
 
167
167
  const shape = editor.getShape(shapeId)
@@ -399,7 +399,7 @@ export async function defaultHandleExternalFileContent(
399
399
  file: File
400
400
  }[] = []
401
401
  for (const file of files) {
402
- const isSuccess = runFileChecks(file, options)
402
+ const isSuccess = notifyIfFileNotAllowed(file, options)
403
403
  if (!isSuccess) continue
404
404
 
405
405
  const assetInfo = await getAssetInfo(file, options)
@@ -873,7 +873,15 @@ export function createEmptyBookmarkShape(
873
873
  return editor.getShape(partial.id) as TLBookmarkShape
874
874
  }
875
875
 
876
- function runFileChecks(file: File, options: TLDefaultExternalContentHandlerOpts) {
876
+ /**
877
+ * Checks if a file is allowed to be uploaded. If it is not, it will show a toast explaining why to the user.
878
+ *
879
+ * @param file - The file to check
880
+ * @param options - The options for the external content handler
881
+ * @returns True if the file is allowed, false otherwise
882
+ * @public
883
+ */
884
+ export function notifyIfFileNotAllowed(file: File, options: TLDefaultExternalContentHandlerOpts) {
877
885
  const {
878
886
  acceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES,
879
887
  acceptedVideoMimeTypes = DEFAULT_SUPPORT_VIDEO_TYPES,
@@ -915,7 +923,8 @@ function runFileChecks(file: File, options: TLDefaultExternalContentHandlerOpts)
915
923
  return true
916
924
  }
917
925
 
918
- async function getAssetInfo(
926
+ /** @public */
927
+ export async function getAssetInfo(
919
928
  file: File,
920
929
  options: TLDefaultExternalContentHandlerOpts,
921
930
  assetId?: TLAssetId
@@ -1,4 +1,5 @@
1
1
  import { TLArrowShape, createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from '../../../test/TestEditor'
3
4
  import { ArrowShapeUtil } from './ArrowShapeUtil'
4
5
  import { updateArrowTargetState } from './arrowTargetState'
@@ -12,7 +13,7 @@ const ids = {
12
13
  arrow1: createShapeId('arrow1'),
13
14
  }
14
15
 
15
- jest.useFakeTimers()
16
+ vi.useFakeTimers()
16
17
 
17
18
  window.requestAnimationFrame = function requestAnimationFrame(cb) {
18
19
  return setTimeout(cb, 1000 / 60)
@@ -1,4 +1,5 @@
1
1
  import { IndexKey, TLArrowShape, TLShapeId, Vec, createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from '../../../test/TestEditor'
3
4
  import { getArrowTargetState } from './arrowTargetState'
4
5
  import { getArrowBindings } from './shared'
@@ -13,7 +14,7 @@ global.cancelAnimationFrame = function cancelAnimationFrame(id) {
13
14
  clearTimeout(id)
14
15
  }
15
16
 
16
- jest.useFakeTimers()
17
+ vi.useFakeTimers()
17
18
 
18
19
  const ids = {
19
20
  box1: createShapeId('box1'),
@@ -242,7 +243,7 @@ describe('When pointing an end shape', () => {
242
243
  },
243
244
  })
244
245
 
245
- jest.advanceTimersByTime(1000)
246
+ vi.advanceTimersByTime(1000)
246
247
 
247
248
  arrow = editor.getCurrentPageShapes()[editor.getCurrentPageShapes().length - 1]
248
249
 
@@ -306,7 +307,7 @@ describe('When pointing an end shape', () => {
306
307
  })
307
308
 
308
309
  // Give time for the velocity to die down
309
- jest.advanceTimersByTime(1000)
310
+ vi.advanceTimersByTime(1000)
310
311
 
311
312
  arrow = editor.getCurrentPageShapes()[editor.getCurrentPageShapes().length - 1]
312
313
 
@@ -1,4 +1,5 @@
1
- import { HALF_PI, TLArrowShape, TLShapeId, createShapeId } from '@tldraw/editor'
1
+ import { HALF_PI, TLArrowShape, TLShapeId, createShapeId, toRichText } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from '../../../test/TestEditor'
3
4
  import { createOrUpdateArrowBinding, getArrowBindings } from './shared'
4
5
 
@@ -12,7 +13,7 @@ const ids = {
12
13
  arrow1: createShapeId('arrow1'),
13
14
  }
14
15
 
15
- jest.useFakeTimers()
16
+ vi.useFakeTimers()
16
17
 
17
18
  window.requestAnimationFrame = function requestAnimationFrame(cb) {
18
19
  return setTimeout(cb, 1000 / 60)
@@ -217,7 +218,7 @@ describe('Other cases when arrow are moved', () => {
217
218
  // When box one is not selected, unbinds box1 and keeps binding to box2
218
219
  editor.select(ids.arrow1, ids.box2, ids.box3)
219
220
  editor.alignShapes(editor.getSelectedShapeIds(), 'right')
220
- jest.advanceTimersByTime(1000)
221
+ vi.advanceTimersByTime(1000)
221
222
 
222
223
  expect(bindings()).toMatchObject({
223
224
  start: { toId: ids.box1, props: { isPrecise: false } },
@@ -227,7 +228,7 @@ describe('Other cases when arrow are moved', () => {
227
228
  // maintains bindings if they would still be over the same shape (but makes them precise), but unbinds others
228
229
  editor.select(ids.arrow1, ids.box3)
229
230
  editor.alignShapes(editor.getSelectedShapeIds(), 'top')
230
- jest.advanceTimersByTime(1000)
231
+ vi.advanceTimersByTime(1000)
231
232
 
232
233
  expect(bindings()).toMatchObject({
233
234
  start: { toId: ids.box1, props: { isPrecise: true } },
@@ -244,7 +245,7 @@ describe('Other cases when arrow are moved', () => {
244
245
  // When box one is not selected, unbinds box1 and keeps binding to box2
245
246
  editor.select(ids.arrow1, ids.box2, ids.box3)
246
247
  editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')
247
- jest.advanceTimersByTime(1000)
248
+ vi.advanceTimersByTime(1000)
248
249
 
249
250
  expect(bindings()).toMatchObject({
250
251
  start: { toId: ids.box1, props: { isPrecise: false } },
@@ -254,7 +255,7 @@ describe('Other cases when arrow are moved', () => {
254
255
  // unbinds when only the arrow is selected (not its bound shapes) if the arrow itself has moved
255
256
  editor.select(ids.arrow1, ids.box3, ids.box4)
256
257
  editor.distributeShapes(editor.getSelectedShapeIds(), 'vertical')
257
- jest.advanceTimersByTime(1000)
258
+ vi.advanceTimersByTime(1000)
258
259
 
259
260
  // The arrow didn't actually move
260
261
  expect(bindings()).toMatchObject({
@@ -265,7 +266,7 @@ describe('Other cases when arrow are moved', () => {
265
266
  // The arrow will not move because it is still bound to another shape
266
267
  editor.updateShapes([{ id: ids.box4, type: 'geo', y: -600 }])
267
268
  editor.distributeShapes(editor.getSelectedShapeIds(), 'vertical')
268
- jest.advanceTimersByTime(1000)
269
+ vi.advanceTimersByTime(1000)
269
270
 
270
271
  expect(bindings()).toMatchObject({
271
272
  start: undefined,
@@ -333,7 +334,7 @@ describe('Arrow labels', () => {
333
334
  editor.setCurrentTool('arrow').pointerDown(10, 10).pointerMove(100, 100).pointerUp()
334
335
  const arrowId = editor.getOnlySelectedShape()!.id
335
336
  editor.updateShapes<TLArrowShape>([
336
- { id: arrowId, type: 'arrow', props: { text: 'Test Label' } },
337
+ { id: arrowId, type: 'arrow', props: { richText: toRichText('Test Label') } },
337
338
  ])
338
339
  })
339
340
 
@@ -341,7 +342,7 @@ describe('Arrow labels', () => {
341
342
  const arrowId = editor.getOnlySelectedShape()!.id
342
343
  expect(arrow(arrowId)).toMatchObject({
343
344
  props: {
344
- text: 'Test Label',
345
+ richText: toRichText('Test Label'),
345
346
  },
346
347
  })
347
348
  })
@@ -349,11 +350,11 @@ describe('Arrow labels', () => {
349
350
  it('should update the label of an arrow', () => {
350
351
  const arrowId = editor.getOnlySelectedShape()!.id
351
352
  editor.updateShapes<TLArrowShape>([
352
- { id: arrowId, type: 'arrow', props: { text: 'New Label' } },
353
+ { id: arrowId, type: 'arrow', props: { richText: toRichText('New Label') } },
353
354
  ])
354
355
  expect(arrow(arrowId)).toMatchObject({
355
356
  props: {
356
- text: 'New Label',
357
+ richText: toRichText('New Label'),
357
358
  },
358
359
  })
359
360
  })
@@ -31,13 +31,16 @@ import {
31
31
  clamp,
32
32
  debugFlags,
33
33
  exhaustiveSwitchError,
34
+ getColorValue,
34
35
  getDefaultColorTheme,
36
+ getFontsFromRichText,
35
37
  invLerp,
36
38
  lerp,
37
39
  mapObjectMapValues,
38
40
  maybeSnapToGrid,
39
41
  structuredClone,
40
42
  toDomPrecision,
43
+ toRichText,
41
44
  track,
42
45
  useEditor,
43
46
  useIsEditing,
@@ -46,12 +49,11 @@ import {
46
49
  } from '@tldraw/editor'
47
50
  import React, { useMemo } from 'react'
48
51
  import { updateArrowTerminal } from '../../bindings/arrow/ArrowBindingUtil'
52
+ import { isEmptyRichText, renderPlaintextFromRichText } from '../../utils/text/richText'
49
53
  import { PathBuilder } from '../shared/PathBuilder'
50
- import { PlainTextLabel } from '../shared/PlainTextLabel'
54
+ import { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'
51
55
  import { ShapeFill } from '../shared/ShapeFill'
52
- import { SvgTextLabel } from '../shared/SvgTextLabel'
53
56
  import { ARROW_LABEL_PADDING, STROKE_SIZES, TEXT_PROPS } from '../shared/default-shape-constants'
54
- import { DefaultFontFaces } from '../shared/defaultFonts'
55
57
  import { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'
56
58
  import { useDefaultColorTheme } from '../shared/useDefaultColorTheme'
57
59
  import { getArrowBodyPath, getArrowHandlePath } from './ArrowPath'
@@ -156,8 +158,13 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
156
158
  }
157
159
 
158
160
  override getFontFaces(shape: TLArrowShape) {
159
- if (!shape.props.text) return EMPTY_ARRAY
160
- return [DefaultFontFaces[`tldraw_${shape.props.font}`].normal.normal]
161
+ if (isEmptyRichText(shape.props.richText)) return EMPTY_ARRAY
162
+
163
+ return getFontsFromRichText(this.editor, shape.props.richText, {
164
+ family: `tldraw_${shape.props.font}`,
165
+ weight: 'normal',
166
+ style: 'normal',
167
+ })
161
168
  }
162
169
 
163
170
  override getDefaultProps(): TLArrowShape['props'] {
@@ -174,7 +181,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
174
181
  end: { x: 2, y: 0 },
175
182
  arrowheadStart: 'none',
176
183
  arrowheadEnd: 'arrow',
177
- text: '',
184
+ richText: toRichText(''),
178
185
  labelPosition: 0.5,
179
186
  font: 'draw',
180
187
  scale: 1,
@@ -204,7 +211,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
204
211
  : new Polyline2d({ points: info.route.points })
205
212
 
206
213
  let labelGeom
207
- if (isEditing || shape.props.text.trim()) {
214
+ if (isEditing || !isEmptyRichText(shape.props.richText)) {
208
215
  const labelPosition = getArrowLabelPosition(this.editor, shape)
209
216
  if (debugFlags.debugGeometry.get()) {
210
217
  debugGeom.push(...labelPosition.debugGeom)
@@ -276,7 +283,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
276
283
  }
277
284
 
278
285
  override getText(shape: TLArrowShape) {
279
- return shape.props.text
286
+ return renderPlaintextFromRichText(this.editor, shape.props.richText)
280
287
  }
281
288
 
282
289
  override onHandleDrag(shape: TLArrowShape, info: TLHandleDragInfo<TLArrowShape>) {
@@ -757,7 +764,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
757
764
  const labelPosition = getArrowLabelPosition(this.editor, shape)
758
765
  const isSelected = shape.id === this.editor.getOnlySelectedShapeId()
759
766
  const isEditing = this.editor.getEditingShapeId() === shape.id
760
- const showArrowLabel = isEditing || shape.props.text
767
+ const showArrowLabel = isEditing || !isEmptyRichText(shape.props.richText)
761
768
 
762
769
  return (
763
770
  <>
@@ -771,17 +778,16 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
771
778
  )}
772
779
  </SVGContainer>
773
780
  {showArrowLabel && (
774
- <PlainTextLabel
781
+ <RichTextLabel
775
782
  shapeId={shape.id}
776
- classNamePrefix="tl-arrow"
777
783
  type="arrow"
778
784
  font={shape.props.font}
779
785
  fontSize={getArrowLabelFontSize(shape)}
780
786
  lineHeight={TEXT_PROPS.lineHeight}
781
787
  align="middle"
782
788
  verticalAlign="middle"
783
- text={shape.props.text}
784
- labelColor={theme[shape.props.labelColor].solid}
789
+ labelColor={getColorValue(theme, shape.props.labelColor, 'solid')}
790
+ richText={shape.props.richText}
785
791
  textWidth={labelPosition.box.w - ARROW_LABEL_PADDING * 2 * shape.props.scale}
786
792
  isSelected={isSelected}
787
793
  padding={0}
@@ -806,9 +812,9 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
806
812
  const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape, info?.bindings)
807
813
  const geometry = this.editor.getShapeGeometry<Group2d>(shape)
808
814
  const bounds = geometry.bounds
815
+ const isEmpty = isEmptyRichText(shape.props.richText)
809
816
 
810
- const labelGeometry =
811
- isEditing || shape.props.text.trim() ? (geometry.children[1] as Rectangle2d) : null
817
+ const labelGeometry = isEditing || !isEmpty ? (geometry.children[1] as Rectangle2d) : null
812
818
 
813
819
  if (Vec.Equals(start, end)) return null
814
820
 
@@ -847,7 +853,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
847
853
  <defs>
848
854
  <ArrowClipPath
849
855
  radius={3.5 * shape.props.scale}
850
- hasText={shape.props.text.trim().length > 0}
856
+ hasText={!isEmpty}
851
857
  bounds={bounds}
852
858
  labelBounds={labelBounds}
853
859
  as={clipStartArrowhead && as ? as : ''}
@@ -905,7 +911,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
905
911
  }
906
912
 
907
913
  override onEditStart(shape: TLArrowShape) {
908
- if (shape.props.text.trim() === '') {
914
+ if (isEmptyRichText(shape.props.richText)) {
909
915
  // editing text for the first time, so set the position to the default:
910
916
  const labelPosition = getArrowLabelDefaultPosition(this.editor, shape)
911
917
  this.editor.updateShape<TLArrowShape>({
@@ -916,26 +922,6 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
916
922
  }
917
923
  }
918
924
 
919
- override onEditEnd(shape: TLArrowShape) {
920
- const {
921
- id,
922
- type,
923
- props: { text },
924
- } = shape
925
-
926
- if (text.trimEnd() !== shape.props.text) {
927
- this.editor.updateShapes<TLArrowShape>([
928
- {
929
- id,
930
- type,
931
- props: {
932
- text: text.trimEnd(),
933
- },
934
- },
935
- ])
936
- }
937
- }
938
-
939
925
  override toSvg(shape: TLArrowShape, ctx: SvgExportContext) {
940
926
  ctx.addExportDef(getFillDefForExport(shape.props.fill))
941
927
  const theme = getDefaultColorTheme(ctx)
@@ -944,13 +930,13 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
944
930
  return (
945
931
  <g transform={`scale(${scaleFactor})`}>
946
932
  <ArrowSvg shape={shape} shouldDisplayHandles={false} />
947
- <SvgTextLabel
933
+ <RichTextSVG
948
934
  fontSize={getArrowLabelFontSize(shape)}
949
935
  font={shape.props.font}
950
936
  align="middle"
951
937
  verticalAlign="middle"
952
- text={shape.props.text}
953
- labelColor={theme[shape.props.labelColor].solid}
938
+ labelColor={getColorValue(theme, shape.props.labelColor, 'solid')}
939
+ richText={shape.props.richText}
954
940
  bounds={getArrowLabelPosition(this.editor, shape)
955
941
  .box.clone()
956
942
  .expandBy(-ARROW_LABEL_PADDING * shape.props.scale)}
@@ -1031,6 +1017,7 @@ const ArrowSvg = track(function ArrowSvg({
1031
1017
  if (!geometry) return null
1032
1018
  const bounds = Box.ZeroFix(geometry.bounds)
1033
1019
  const bindings = getArrowBindings(editor, shape)
1020
+ const isEmpty = isEmptyRichText(shape.props.richText)
1034
1021
 
1035
1022
  if (!info?.isValid) return null
1036
1023
 
@@ -1081,7 +1068,7 @@ const ArrowSvg = track(function ArrowSvg({
1081
1068
  <clipPath id={clipPathId}>
1082
1069
  <ArrowClipPath
1083
1070
  radius={3.5 * shape.props.scale}
1084
- hasText={isEditing || shape.props.text.trim().length > 0}
1071
+ hasText={isEditing || !isEmpty}
1085
1072
  bounds={bounds}
1086
1073
  labelBounds={labelPosition.box}
1087
1074
  as={clipStartArrowhead && as ? as : ''}
@@ -1091,7 +1078,7 @@ const ArrowSvg = track(function ArrowSvg({
1091
1078
  </defs>
1092
1079
  <g
1093
1080
  fill="none"
1094
- stroke={theme[shape.props.color].solid}
1081
+ stroke={getColorValue(theme, shape.props.color, 'solid')}
1095
1082
  strokeWidth={strokeWidth}
1096
1083
  strokeLinejoin="round"
1097
1084
  strokeLinecap="round"
@@ -9,13 +9,17 @@ import {
9
9
  Polygon2d,
10
10
  Polyline2d,
11
11
  TLArrowShape,
12
+ TLShape,
12
13
  Vec,
13
14
  VecLike,
14
15
  clamp,
15
16
  createComputedCache,
16
17
  exhaustiveSwitchError,
17
18
  getChangedKeys,
19
+ pointInPolygon,
20
+ toRichText,
18
21
  } from '@tldraw/editor'
22
+ import { isEmptyRichText, renderHtmlFromRichTextForMeasurement } from '../../utils/text/richText'
19
23
  import {
20
24
  ARROW_LABEL_FONT_SIZES,
21
25
  ARROW_LABEL_PADDING,
@@ -59,14 +63,18 @@ const labelSizeCache = createComputedCache(
59
63
 
60
64
  const bodyGeom = getArrowBodyGeometry(editor, shape)
61
65
  // We use 'i' as a default label to measure against as a minimum width.
62
- const text = shape.props.text || 'i'
66
+ const isEmpty = isEmptyRichText(shape.props.richText)
67
+ const html = renderHtmlFromRichTextForMeasurement(
68
+ editor,
69
+ isEmpty ? toRichText('i') : shape.props.richText
70
+ )
63
71
 
64
72
  const bodyBounds = bodyGeom.bounds
65
73
 
66
74
  const fontSize = getArrowLabelFontSize(shape)
67
75
 
68
76
  // First we measure the text with no constraints
69
- const { w, h } = editor.textMeasure.measureText(text, {
77
+ const { w, h } = editor.textMeasure.measureHtml(html, {
70
78
  ...TEXT_PROPS,
71
79
  fontFamily: FONT_FAMILIES[shape.props.font],
72
80
  fontSize,
@@ -96,7 +104,7 @@ const labelSizeCache = createComputedCache(
96
104
  }
97
105
 
98
106
  if (shouldSquish) {
99
- const { w: squishedWidth, h: squishedHeight } = editor.textMeasure.measureText(text, {
107
+ const { w: squishedWidth, h: squishedHeight } = editor.textMeasure.measureHtml(html, {
100
108
  ...TEXT_PROPS,
101
109
  fontFamily: FONT_FAMILIES[shape.props.font],
102
110
  fontSize,
@@ -292,3 +300,15 @@ export function getArrowLabelDefaultPosition(editor: Editor, shape: TLArrowShape
292
300
  exhaustiveSwitchError(info, 'type')
293
301
  }
294
302
  }
303
+
304
+ /** @internal */
305
+ export function isOverArrowLabel(editor: Editor, shape: TLShape) {
306
+ if (!editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) return false
307
+
308
+ const pointInShapeSpace = editor.getPointInShapeSpace(shape, editor.inputs.currentPagePoint)
309
+ // How should we handle multiple labels? Do shapes ever have multiple labels?
310
+ const labelGeometry = editor.getShapeGeometry<Group2d>(shape).children[1]
311
+ // Knowing what we know about arrows... if the shape has no text in its label,
312
+ // then the label geometry should not be there.
313
+ return labelGeometry && pointInPolygon(pointInShapeSpace, labelGeometry.vertices)
314
+ }
@@ -94,7 +94,7 @@ export function updateArrowTargetState({
94
94
  const target = editor.getShapeAtPoint(pointInPageSpace, {
95
95
  hitInside: true,
96
96
  hitFrameInside: true,
97
- margin: arrowKind === 'elbow' ? 8 : 0,
97
+ margin: arrowKind === 'elbow' ? 8 : [8, 0],
98
98
  filter: (targetShape) => {
99
99
  return (
100
100
  !targetShape.isLocked &&
@@ -187,6 +187,7 @@ export function updateArrowTargetState({
187
187
  }
188
188
 
189
189
  const shouldSnapCenter = !isExact && precise && targetGeometryInTargetSpace.isClosed
190
+ // const shouldSnapEdges = !isExact && (precise || !targetGeometryInTargetSpace.isClosed)
190
191
  const shouldSnapEdges =
191
192
  !isExact && ((precise && arrowKind === 'elbow') || !targetGeometryInTargetSpace.isClosed)
192
193
  const shouldSnapEdgePoints =