tldraw 3.15.0 → 3.16.0-canary.01f62b6d4455

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