tldraw 3.15.0 → 3.16.0-canary.03deb7f8fe34

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 (374) hide show
  1. package/dist-cjs/index.d.ts +271 -9
  2. package/dist-cjs/index.js +28 -2
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
  5. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  6. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js +1 -0
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  9. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +25 -39
  10. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  11. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +16 -4
  12. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  13. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  14. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  16. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  17. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  18. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  19. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  20. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  21. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  22. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  23. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +12 -12
  24. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  25. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  26. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  27. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  28. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  30. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  31. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  32. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  33. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
  34. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
  35. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +20 -2
  36. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  37. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  38. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  40. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  41. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  42. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
  43. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
  44. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  45. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  46. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  47. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  48. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  49. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  50. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  51. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  52. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +43 -22
  53. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  54. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -15
  55. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  56. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +5 -0
  57. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  58. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +8 -0
  59. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  60. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +8 -0
  61. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  62. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +8 -0
  63. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  64. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  65. package/dist-cjs/lib/ui/TldrawUi.js +14 -0
  66. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  67. package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
  68. package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
  69. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  70. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  71. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  72. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  73. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +40 -0
  74. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  75. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +3 -3
  76. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  78. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  79. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  80. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  81. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
  82. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  83. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
  84. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  85. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  86. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  87. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  88. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  89. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
  90. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  91. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -140
  92. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  93. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
  94. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
  95. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
  96. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
  97. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  98. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  99. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  100. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  101. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  102. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  103. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
  104. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  105. package/dist-cjs/lib/ui/components/menu-items.js +6 -0
  106. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  107. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
  108. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
  109. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  110. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  111. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  112. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  113. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -0
  114. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  115. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +30 -7
  116. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  117. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +268 -0
  118. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
  119. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  120. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  121. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  122. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  123. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  124. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +153 -20
  125. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  126. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
  127. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
  128. package/dist-cjs/lib/ui/context/actions.js +29 -7
  129. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  130. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  131. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  132. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  133. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  134. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  135. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +7 -0
  136. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  137. package/dist-cjs/lib/ui/kbd-utils.js +2 -1
  138. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  139. package/dist-cjs/lib/ui/version.js +3 -3
  140. package/dist-cjs/lib/ui/version.js.map +1 -1
  141. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
  142. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  143. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +3 -2
  144. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  145. package/dist-esm/index.d.mts +271 -9
  146. package/dist-esm/index.mjs +44 -3
  147. package/dist-esm/index.mjs.map +2 -2
  148. package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
  149. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  150. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  151. package/dist-esm/lib/defaultExternalContentHandlers.mjs +1 -0
  152. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  153. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +28 -39
  154. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  155. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +19 -5
  156. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  157. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  158. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  159. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  160. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  161. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +3 -0
  162. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  163. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  164. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  165. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  166. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  167. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +13 -12
  168. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  169. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  170. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  171. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  172. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  173. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  174. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  175. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  176. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  177. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
  178. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
  179. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +21 -2
  180. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  181. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  182. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  183. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  184. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  185. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  186. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
  187. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
  188. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  189. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  190. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  191. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  192. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  193. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  194. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  195. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  196. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +43 -22
  197. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  198. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -15
  199. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  200. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +5 -0
  201. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  202. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +8 -0
  203. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  204. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +8 -0
  205. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  206. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +8 -0
  207. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  208. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  209. package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
  210. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  211. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
  212. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
  213. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  214. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  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 +40 -0
  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 +245 -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 +161 -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 +29 -7
  273. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  274. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  275. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  276. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  277. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  278. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +7 -0
  279. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  280. package/dist-esm/lib/ui/kbd-utils.mjs +2 -1
  281. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  282. package/dist-esm/lib/ui/version.mjs +3 -3
  283. package/dist-esm/lib/ui/version.mjs.map +1 -1
  284. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
  285. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  286. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +3 -2
  287. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  288. package/package.json +3 -3
  289. package/src/index.ts +32 -1
  290. package/src/lib/canvas/TldrawCropHandles.tsx +2 -0
  291. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  292. package/src/lib/defaultExternalContentHandlers.ts +2 -1
  293. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +5 -5
  294. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +29 -42
  295. package/src/lib/shapes/arrow/arrowLabel.ts +23 -3
  296. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -1
  297. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  298. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +3 -0
  299. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  300. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  301. package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -14
  302. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  303. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  304. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  305. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  306. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
  307. package/src/lib/shapes/line/LineShapeUtil.tsx +25 -3
  308. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  309. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  310. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  311. package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
  312. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  313. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  314. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  315. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  316. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +54 -30
  317. package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -24
  318. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +7 -0
  319. package/src/lib/tools/SelectTool/childStates/Resizing.ts +12 -1
  320. package/src/lib/tools/SelectTool/childStates/Rotating.ts +11 -0
  321. package/src/lib/tools/SelectTool/childStates/Translating.ts +11 -1
  322. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -0
  323. package/src/lib/ui/TldrawUi.tsx +17 -2
  324. package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
  325. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  326. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  327. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +32 -0
  328. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -4
  329. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  330. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  331. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
  332. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
  333. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  334. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  335. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
  336. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -107
  337. package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
  338. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
  339. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  340. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  341. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  342. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +17 -12
  343. package/src/lib/ui/components/menu-items.tsx +8 -0
  344. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
  345. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
  346. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  347. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +1 -0
  348. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +51 -12
  349. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +327 -0
  350. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  351. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  352. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  353. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +220 -19
  354. package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
  355. package/src/lib/ui/context/actions.tsx +29 -7
  356. package/src/lib/ui/context/events.tsx +4 -2
  357. package/src/lib/ui/hooks/menu-hooks.ts +1 -0
  358. package/src/lib/ui/hooks/useTools.tsx +140 -10
  359. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +7 -0
  360. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +7 -0
  361. package/src/lib/ui/kbd-utils.ts +2 -1
  362. package/src/lib/ui/version.ts +3 -3
  363. package/src/lib/ui.css +406 -292
  364. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +16 -2
  365. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
  366. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +24 -3
  367. package/src/lib/utils/tldr/buildFromV1Document.ts +2 -1
  368. package/src/test/EraserTool.test.ts +176 -6
  369. package/src/test/SelectTool.test.ts +37 -11
  370. package/src/test/arrows-megabus.test.tsx +12 -6
  371. package/src/test/commands/deletePage.test.ts +84 -1
  372. package/src/test/inner-outer-margin.test.ts +315 -0
  373. package/src/test/shapeutils.test.ts +394 -45
  374. package/tldraw.css +703 -603
@@ -1,4 +1,4 @@
1
- import { createShapeId, TLFrameShape, TLGeoShape } from '@tldraw/editor'
1
+ import { createShapeId, TLFrameShape, TLGeoShape, TLLineShape } from '@tldraw/editor'
2
2
  import { TestEditor } from './TestEditor'
3
3
 
4
4
  let editor: TestEditor
@@ -11,6 +11,8 @@ const ids = {
11
11
  frame1: createShapeId('frame1'),
12
12
  box1: createShapeId('box1'),
13
13
  box2: createShapeId('box2'),
14
+ line1: createShapeId('line1'),
15
+ page1: createShapeId('page1'),
14
16
  }
15
17
 
16
18
  beforeEach(() => {
@@ -56,34 +58,93 @@ describe('When interacting with a shape...', () => {
56
58
  // Set start / change / end events on only the geo shape
57
59
  const util = editor.getShapeUtil<TLFrameShape>('frame')
58
60
 
59
- const fnStart = jest.fn()
60
- util.onRotateStart = fnStart
61
+ const calls: string[] = []
62
+
63
+ util.onRotateStart = () => {
64
+ calls.push('start')
65
+ }
61
66
 
62
- const fnChange = jest.fn()
63
- util.onRotate = fnChange
67
+ util.onRotate = () => {
68
+ calls.push('change')
69
+ }
64
70
 
65
- const fnEnd = jest.fn()
66
- util.onRotateEnd = fnEnd
71
+ util.onRotateEnd = () => {
72
+ calls.push('end')
73
+ }
67
74
 
68
75
  editor.selectAll()
69
76
  expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
70
77
 
71
- editor
72
- .pointerDown(300, 300, {
73
- target: 'selection',
74
- handle: 'bottom_right_rotate',
75
- })
76
- .pointerMove(200, 200)
77
- .pointerUp(200, 200)
78
+ editor.pointerDown(300, 300, {
79
+ target: 'selection',
80
+ handle: 'bottom_right_rotate',
81
+ })
78
82
 
79
- // Once on start (for frame only)
80
- expect(fnStart).toHaveBeenCalledTimes(1)
83
+ // Should not have called any callbacks yet
84
+ expect(calls).toEqual([])
85
+
86
+ editor.pointerMove(200, 200)
81
87
 
82
- // Once on start, once during the move
83
- expect(fnChange).toHaveBeenCalledTimes(2)
88
+ // Should have called start once and change at least once now
89
+ expect(calls).toEqual(['start', 'change'])
84
90
 
85
- // Once on end
86
- expect(fnEnd).toHaveBeenCalledTimes(1)
91
+ editor.pointerMove(200, 210)
92
+
93
+ // Should have called start once and change multiple times
94
+ expect(calls).toEqual(['start', 'change', 'change'])
95
+
96
+ editor.pointerUp(200, 210)
97
+
98
+ // Should have called end once now
99
+ expect(calls).toEqual(['start', 'change', 'change', 'change', 'end'])
100
+ })
101
+
102
+ it('fires rotate cancel events', () => {
103
+ const util = editor.getShapeUtil<TLFrameShape>('frame')
104
+
105
+ const calls: string[] = []
106
+
107
+ util.onRotateStart = () => {
108
+ calls.push('start')
109
+ }
110
+
111
+ util.onRotate = () => {
112
+ calls.push('change')
113
+ }
114
+
115
+ util.onRotateEnd = () => {
116
+ calls.push('end')
117
+ }
118
+
119
+ util.onRotateCancel = () => {
120
+ calls.push('cancel')
121
+ }
122
+
123
+ editor.selectAll()
124
+ expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
125
+
126
+ editor.pointerDown(300, 300, {
127
+ target: 'selection',
128
+ handle: 'bottom_right_rotate',
129
+ })
130
+
131
+ // Should not have called any callbacks yet
132
+ expect(calls).toEqual([])
133
+
134
+ editor.pointerMove(200, 200)
135
+
136
+ // Should have called start once and change at least once now
137
+ expect(calls).toEqual(['start', 'change'])
138
+
139
+ editor.pointerMove(200, 210)
140
+
141
+ // Should have called start once and change multiple times
142
+ expect(calls).toEqual(['start', 'change', 'change'])
143
+
144
+ editor.cancel()
145
+
146
+ // Should have called cancel instead of end
147
+ expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
87
148
  })
88
149
 
89
150
  it('cleans up events', () => {
@@ -105,14 +166,19 @@ describe('When interacting with a shape...', () => {
105
166
  it('Fires resisizing events', () => {
106
167
  const util = editor.getShapeUtil<TLFrameShape>('frame')
107
168
 
108
- const fnStart = jest.fn()
109
- util.onResizeStart = fnStart
169
+ const calls: string[] = []
170
+
171
+ util.onResizeStart = () => {
172
+ calls.push('start')
173
+ }
110
174
 
111
- const fnChange = jest.fn()
112
- util.onResize = fnChange
175
+ util.onResize = () => {
176
+ calls.push('change')
177
+ }
113
178
 
114
- const fnEnd = jest.fn()
115
- util.onResizeEnd = fnEnd
179
+ util.onResizeEnd = () => {
180
+ calls.push('end')
181
+ }
116
182
 
117
183
  editor.selectAll()
118
184
  expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
@@ -123,48 +189,165 @@ describe('When interacting with a shape...', () => {
123
189
  })
124
190
 
125
191
  editor.expectToBeIn('select.pointing_resize_handle')
192
+
193
+ // Should not have called any callbacks yet
194
+ expect(calls).toEqual([])
195
+
126
196
  editor.pointerMove(200, 200)
127
197
  editor.expectToBeIn('select.resizing')
198
+
199
+ // Should have called start once and change at least once now
200
+ expect(calls).toEqual(['start', 'change'])
201
+
128
202
  editor.pointerMove(200, 210)
203
+
204
+ // Should have called start once and change multiple times
205
+ expect(calls).toEqual(['start', 'change', 'change'])
206
+
129
207
  editor.pointerUp(200, 210)
130
208
  editor.expectToBeIn('select.idle')
131
209
 
132
- // Once on start (for frame only)
133
- expect(fnStart).toHaveBeenCalledTimes(1)
210
+ // Should have called end once now
211
+ expect(calls).toEqual(['start', 'change', 'change', 'end'])
212
+ })
213
+
214
+ it('Fires resizing cancel events', () => {
215
+ const util = editor.getShapeUtil<TLFrameShape>('frame')
216
+
217
+ const calls: string[] = []
218
+
219
+ util.onResizeStart = () => {
220
+ calls.push('start')
221
+ }
134
222
 
135
- // Once on start, once during the resize
136
- expect(fnChange).toHaveBeenCalledTimes(2)
223
+ util.onResize = () => {
224
+ calls.push('change')
225
+ }
226
+
227
+ util.onResizeEnd = () => {
228
+ calls.push('end')
229
+ }
230
+
231
+ util.onResizeCancel = () => {
232
+ calls.push('cancel')
233
+ }
234
+
235
+ editor.selectAll()
236
+ expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
237
+
238
+ editor.pointerDown(300, 300, {
239
+ target: 'selection',
240
+ handle: 'bottom_right',
241
+ })
242
+
243
+ editor.expectToBeIn('select.pointing_resize_handle')
244
+
245
+ // Should not have called any callbacks yet
246
+ expect(calls).toEqual([])
247
+
248
+ editor.pointerMove(200, 200)
249
+ editor.expectToBeIn('select.resizing')
137
250
 
138
- // Once on end
139
- expect(fnEnd).toHaveBeenCalledTimes(1)
251
+ // Should have called start once and change at least once now
252
+ expect(calls).toEqual(['start', 'change'])
253
+
254
+ editor.pointerMove(200, 210)
255
+
256
+ // Should have called start once and change multiple times
257
+ expect(calls).toEqual(['start', 'change', 'change'])
258
+
259
+ editor.cancel()
260
+
261
+ // Should have called cancel instead of end
262
+ expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
140
263
  })
141
264
 
142
265
  it('Fires translating events', () => {
143
266
  const util = editor.getShapeUtil<TLFrameShape>('frame')
144
267
 
145
- const fnStart = jest.fn()
146
- util.onTranslateStart = fnStart
268
+ const calls: string[] = []
269
+
270
+ util.onTranslateStart = () => {
271
+ calls.push('start')
272
+ }
147
273
 
148
- const fnChange = jest.fn()
149
- util.onTranslate = fnChange
274
+ util.onTranslate = () => {
275
+ calls.push('change')
276
+ }
150
277
 
151
- const fnEnd = jest.fn()
152
- util.onTranslateEnd = fnEnd
278
+ util.onTranslateEnd = () => {
279
+ calls.push('end')
280
+ }
153
281
 
154
282
  editor.selectAll()
155
283
  expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
156
284
 
157
285
  // Translate the shapes...
158
- editor.pointerDown(50, 50, ids.box1).pointerMove(50, 40).pointerUp(50, 40)
286
+ editor.pointerDown(50, 50, ids.box1)
159
287
 
160
- // Once on start for frame
161
- expect(fnStart).toHaveBeenCalledTimes(1)
288
+ // Should not have called any callbacks yet
289
+ expect(calls).toEqual([])
290
+
291
+ editor.pointerMove(50, 40)
162
292
 
163
- // Once on start, once during the move
164
- expect(fnChange).toHaveBeenCalledTimes(2)
293
+ // Should have called start once and change at least once now
294
+ expect(calls).toEqual(['start', 'change'])
165
295
 
166
- // Once on end
167
- expect(fnEnd).toHaveBeenCalledTimes(1)
296
+ editor.pointerMove(50, 35)
297
+
298
+ // Should have called start once and change multiple times
299
+ expect(calls).toEqual(['start', 'change', 'change'])
300
+
301
+ editor.pointerUp(50, 35)
302
+
303
+ // Should have called end once now
304
+ expect(calls).toEqual(['start', 'change', 'change', 'change', 'end'])
305
+ })
306
+
307
+ it('Fires translating cancel events', () => {
308
+ const util = editor.getShapeUtil<TLFrameShape>('frame')
309
+
310
+ const calls: string[] = []
311
+
312
+ util.onTranslateStart = () => {
313
+ calls.push('start')
314
+ }
315
+
316
+ util.onTranslate = () => {
317
+ calls.push('change')
318
+ }
319
+
320
+ util.onTranslateEnd = () => {
321
+ calls.push('end')
322
+ }
323
+
324
+ util.onTranslateCancel = () => {
325
+ calls.push('cancel')
326
+ }
327
+
328
+ editor.selectAll()
329
+ expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
330
+
331
+ // Translate the shapes...
332
+ editor.pointerDown(50, 50, ids.box1)
333
+
334
+ // Should not have called any callbacks yet
335
+ expect(calls).toEqual([])
336
+
337
+ editor.pointerMove(50, 40)
338
+
339
+ // Should have called start once and change at least once now
340
+ expect(calls).toEqual(['start', 'change'])
341
+
342
+ editor.pointerMove(50, 35)
343
+
344
+ // Should have called start once and change multiple times
345
+ expect(calls).toEqual(['start', 'change', 'change'])
346
+
347
+ editor.cancel()
348
+
349
+ // Should have called cancel instead of end
350
+ expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
168
351
  })
169
352
 
170
353
  it('Uses the shape utils onClick handler', () => {
@@ -201,4 +384,170 @@ describe('When interacting with a shape...', () => {
201
384
  // it should not be selected.
202
385
  expect(editor.getSelectedShapeIds().length).toBe(0)
203
386
  })
387
+
388
+ it('Fires handle dragging events', () => {
389
+ const util = editor.getShapeUtil<TLLineShape>('line')
390
+
391
+ const calls: string[] = []
392
+
393
+ util.onHandleDragStart = () => {
394
+ calls.push('start')
395
+ }
396
+
397
+ util.onHandleDrag = () => {
398
+ calls.push('change')
399
+ }
400
+
401
+ util.onHandleDragEnd = () => {
402
+ calls.push('end')
403
+ }
404
+
405
+ util.onHandleDragCancel = () => {
406
+ calls.push('cancel')
407
+ }
408
+
409
+ // Create a line shape with handles
410
+ const lineShape: TLLineShape = {
411
+ id: ids.line1,
412
+ type: 'line',
413
+ typeName: 'shape',
414
+ parentId: ids.page1,
415
+ index: 'a1' as any,
416
+ x: 100,
417
+ y: 100,
418
+ rotation: 0,
419
+ isLocked: false,
420
+ opacity: 1,
421
+ meta: {},
422
+ props: {
423
+ dash: 'draw',
424
+ size: 'm',
425
+ color: 'black',
426
+ spline: 'line',
427
+ scale: 1,
428
+ points: {
429
+ a1: { id: 'a1', index: 'a1' as any, x: 0, y: 0 },
430
+ a2: { id: 'a2', index: 'a2' as any, x: 100, y: 100 },
431
+ },
432
+ },
433
+ }
434
+
435
+ editor.createShapes([lineShape])
436
+
437
+ // Get the handle point
438
+ const handlePagePoint = editor
439
+ .getShapePageTransform(lineShape.id)!
440
+ .applyToPoint(lineShape.props.points['a2'])
441
+
442
+ editor.pointerDown(handlePagePoint.x, handlePagePoint.y, {
443
+ target: 'handle',
444
+ shape: editor.getShape(lineShape.id)!,
445
+ handle: { id: 'a2', type: 'vertex', index: 'a2' as any, x: 100, y: 100 },
446
+ })
447
+
448
+ editor.expectToBeIn('select.pointing_handle')
449
+
450
+ // Should not have called any callbacks yet
451
+ expect(calls).toEqual([])
452
+
453
+ editor.pointerMove(handlePagePoint.x + 20, handlePagePoint.y + 20) // Larger move to trigger drag
454
+ editor.expectToBeIn('select.dragging_handle')
455
+
456
+ // Should have called start once and change at least once now
457
+ expect(calls).toEqual(['start', 'change'])
458
+
459
+ editor.pointerMove(150, 150)
460
+
461
+ // Should have called start once and change multiple times
462
+ expect(calls).toEqual(['start', 'change', 'change'])
463
+
464
+ editor.pointerUp(150, 150)
465
+ editor.expectToBeIn('select.idle')
466
+
467
+ // Should have called end once now
468
+ expect(calls).toEqual(['start', 'change', 'change', 'end'])
469
+ })
470
+
471
+ it('Fires handle dragging cancel events', () => {
472
+ const util = editor.getShapeUtil<TLLineShape>('line')
473
+
474
+ const calls: string[] = []
475
+
476
+ util.onHandleDragStart = () => {
477
+ calls.push('start')
478
+ }
479
+
480
+ util.onHandleDrag = () => {
481
+ calls.push('change')
482
+ }
483
+
484
+ util.onHandleDragEnd = () => {
485
+ calls.push('end')
486
+ }
487
+
488
+ util.onHandleDragCancel = () => {
489
+ calls.push('cancel')
490
+ }
491
+
492
+ // Create a line shape with handles
493
+ const lineShape: TLLineShape = {
494
+ id: ids.line1,
495
+ type: 'line',
496
+ typeName: 'shape',
497
+ parentId: ids.page1,
498
+ index: 'a1' as any,
499
+ x: 100,
500
+ y: 100,
501
+ rotation: 0,
502
+ isLocked: false,
503
+ opacity: 1,
504
+ meta: {},
505
+ props: {
506
+ dash: 'draw',
507
+ size: 'm',
508
+ color: 'black',
509
+ spline: 'line',
510
+ scale: 1,
511
+ points: {
512
+ a1: { id: 'a1', index: 'a1' as any, x: 0, y: 0 },
513
+ a2: { id: 'a2', index: 'a2' as any, x: 100, y: 100 },
514
+ },
515
+ },
516
+ }
517
+
518
+ editor.createShapes([lineShape])
519
+
520
+ // Get the handle point
521
+ const handlePagePoint = editor
522
+ .getShapePageTransform(lineShape.id)!
523
+ .applyToPoint(lineShape.props.points['a2'])
524
+
525
+ editor.pointerDown(handlePagePoint.x, handlePagePoint.y, {
526
+ target: 'handle',
527
+ shape: editor.getShape(lineShape.id)!,
528
+ handle: { id: 'a2', type: 'vertex', index: 'a2' as any, x: 100, y: 100 },
529
+ })
530
+
531
+ editor.expectToBeIn('select.pointing_handle')
532
+
533
+ // Should not have called any callbacks yet
534
+ expect(calls).toEqual([])
535
+
536
+ editor.pointerMove(handlePagePoint.x + 20, handlePagePoint.y + 20) // Larger move to trigger drag
537
+ editor.expectToBeIn('select.dragging_handle')
538
+
539
+ // Should have called start once and change at least once now
540
+ expect(calls).toEqual(['start', 'change'])
541
+
542
+ editor.pointerMove(150, 150)
543
+
544
+ // Should have called start once and change multiple times
545
+ expect(calls).toEqual(['start', 'change', 'change'])
546
+
547
+ editor.cancel()
548
+ editor.expectToBeIn('select.idle')
549
+
550
+ // Should have called cancel instead of end
551
+ expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
552
+ })
204
553
  })