tldraw 3.16.0-next.282b7be564ae → 3.16.0-next.2f9d39693e4c

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 (291) hide show
  1. package/dist-cjs/index.d.ts +224 -102
  2. package/dist-cjs/index.js +33 -14
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  9. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  10. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +6 -0
  11. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -0
  13. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  15. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  16. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  17. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +0 -2
  18. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  19. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  20. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  21. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  22. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  23. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  24. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  25. package/dist-cjs/lib/ui/TldrawUi.js +13 -12
  26. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  27. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  28. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  29. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  30. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  31. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
  32. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  33. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  34. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  35. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  36. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  37. package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
  38. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  39. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  40. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  41. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  42. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  43. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +24 -21
  44. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  45. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  46. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  47. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
  48. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  49. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
  50. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  51. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  52. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  53. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
  54. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  55. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +10 -1
  56. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  57. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +17 -4
  58. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  59. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -0
  60. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  61. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +37 -36
  62. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  63. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +2 -1
  64. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  65. package/dist-cjs/lib/ui/context/actions.js +23 -10
  66. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  67. package/dist-cjs/lib/ui/context/components.js +2 -0
  68. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  69. package/dist-cjs/lib/ui/context/events.js.map +1 -1
  70. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  71. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  72. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  73. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  74. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  75. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
  76. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  77. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  78. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  79. package/dist-cjs/lib/ui/version.js +3 -3
  80. package/dist-cjs/lib/ui/version.js.map +1 -1
  81. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  82. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  83. package/dist-cjs/lib/utils/export/export.js +0 -20
  84. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  85. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  86. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  87. package/dist-esm/index.d.mts +224 -102
  88. package/dist-esm/index.mjs +61 -29
  89. package/dist-esm/index.mjs.map +2 -2
  90. package/dist-esm/lib/Tldraw.mjs +14 -4
  91. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  92. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  93. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  94. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  95. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  96. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +6 -0
  97. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  98. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -0
  99. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  100. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  101. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  102. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  103. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +0 -2
  104. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  105. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  106. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  107. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  108. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  109. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  110. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  111. package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
  112. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  113. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  114. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  115. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  116. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  117. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
  118. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  119. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  120. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  121. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  122. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  123. package/dist-esm/lib/ui/components/{primitives/TldrawUiButtonPicker.mjs → StylePanel/StylePanelButtonPicker.mjs} +54 -43
  124. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  125. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  126. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  127. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  128. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  129. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +21 -18
  130. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  131. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  132. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  133. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
  134. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  135. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
  136. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  137. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  138. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  139. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
  140. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  141. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +10 -1
  142. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  143. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +17 -4
  144. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  145. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +2 -0
  146. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  147. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +37 -36
  148. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  149. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -1
  150. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  151. package/dist-esm/lib/ui/context/actions.mjs +23 -10
  152. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  153. package/dist-esm/lib/ui/context/components.mjs +2 -0
  154. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  155. package/dist-esm/lib/ui/context/events.mjs.map +1 -1
  156. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  157. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  158. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  159. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  160. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
  161. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  162. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  163. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  164. package/dist-esm/lib/ui/version.mjs +3 -3
  165. package/dist-esm/lib/ui/version.mjs.map +1 -1
  166. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  167. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  168. package/dist-esm/lib/utils/export/export.mjs +0 -20
  169. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  170. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  171. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  172. package/package.json +11 -34
  173. package/src/index.ts +44 -22
  174. package/src/lib/Tldraw.tsx +15 -2
  175. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  176. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  177. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  178. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
  179. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  180. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  181. package/src/lib/shapes/frame/FrameShapeUtil.tsx +8 -0
  182. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -0
  183. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  184. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  185. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  186. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  187. package/src/lib/shapes/shared/useEditablePlainText.ts +0 -6
  188. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  189. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  190. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  191. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  192. package/src/lib/ui/TldrawUi.tsx +16 -10
  193. package/src/lib/ui/assetUrls.ts +13 -10
  194. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  195. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
  196. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  197. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  198. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +63 -50
  199. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  200. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  201. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  202. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  203. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
  204. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
  205. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  206. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
  207. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +6 -1
  208. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +50 -30
  209. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +3 -0
  210. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +29 -21
  211. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +3 -2
  212. package/src/lib/ui/context/actions.tsx +23 -10
  213. package/src/lib/ui/context/components.tsx +3 -0
  214. package/src/lib/ui/context/events.tsx +1 -1
  215. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  216. package/src/lib/ui/hooks/useTools.tsx +1 -1
  217. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  218. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
  219. package/src/lib/ui/kbd-utils.ts +10 -3
  220. package/src/lib/ui/version.ts +3 -3
  221. package/src/lib/ui.css +19 -2
  222. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  223. package/src/lib/utils/export/copyAs.ts +1 -24
  224. package/src/lib/utils/export/export.ts +0 -36
  225. package/src/lib/utils/export/exportAs.ts +1 -32
  226. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  227. package/src/test/A11y.test.tsx +3 -2
  228. package/src/test/ClickManager.test.ts +7 -6
  229. package/src/test/Editor.test.tsx +20 -19
  230. package/src/test/EraserTool.test.ts +184 -13
  231. package/src/test/HandTool.test.ts +10 -9
  232. package/src/test/HighlightShape.test.ts +2 -1
  233. package/src/test/SelectTool.test.ts +3 -2
  234. package/src/test/TLUserPreferences.test.ts +4 -3
  235. package/src/test/TestEditor.ts +13 -15
  236. package/src/test/TldrawEditor.test.tsx +11 -10
  237. package/src/test/ZoomTool.test.ts +7 -6
  238. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  239. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  240. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  241. package/src/test/arrows-megabus.test.tsx +5 -4
  242. package/src/test/bindings.test.tsx +24 -37
  243. package/src/test/bookmark-shapes.test.ts +1 -8
  244. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  245. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  246. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  247. package/src/test/commands/alignShapes.test.tsx +25 -24
  248. package/src/test/commands/animationSpeed.test.ts +2 -1
  249. package/src/test/commands/centerOnPoint.test.ts +3 -2
  250. package/src/test/commands/clipboard.test.ts +3 -2
  251. package/src/test/commands/createShapes.test.ts +2 -1
  252. package/src/test/commands/deleteShapes.test.ts +2 -1
  253. package/src/test/commands/distributeShapes.test.tsx +11 -10
  254. package/src/test/commands/getSvgString.test.ts +2 -1
  255. package/src/test/commands/packShapes.test.ts +5 -4
  256. package/src/test/commands/resizeShape.test.ts +2 -1
  257. package/src/test/commands/rotateShapes.test.ts +7 -6
  258. package/src/test/commands/setCamera.test.ts +4 -3
  259. package/src/test/commands/setCurrentPage.test.ts +3 -2
  260. package/src/test/commands/stackShapes.test.ts +11 -10
  261. package/src/test/commands/stretch.test.tsx +13 -12
  262. package/src/test/createDeepLink.test.tsx +2 -1
  263. package/src/test/cropping.test.ts +3 -2
  264. package/src/test/custom-clipping.test.ts +436 -0
  265. package/src/test/drawing.test.ts +2 -1
  266. package/src/test/flipShapes.test.ts +4 -3
  267. package/src/test/frames.test.ts +25 -24
  268. package/src/test/getCulledShapes.test.tsx +3 -2
  269. package/src/test/groups.test.tsx +1 -1
  270. package/src/test/handleDeepLink.test.tsx +2 -1
  271. package/src/test/maxShapes.test.ts +3 -2
  272. package/src/test/modifiers.test.ts +5 -4
  273. package/src/test/navigation.test.ts +12 -11
  274. package/src/test/panning.test.ts +2 -1
  275. package/src/test/perf/perf.test.ts +2 -1
  276. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  277. package/src/test/resizing.test.ts +39 -38
  278. package/src/test/select.test.tsx +4 -3
  279. package/src/test/selection-omnibus.test.ts +11 -10
  280. package/src/test/shapeutils.test.ts +4 -3
  281. package/src/test/translating.test.ts +9 -8
  282. package/tldraw.css +27 -2
  283. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  284. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  285. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  286. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  287. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  288. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  289. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  290. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  291. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -8,13 +8,14 @@ import {
8
8
  createShapeId,
9
9
  toRichText,
10
10
  } from '@tldraw/editor'
11
+ import { vi } from 'vitest'
11
12
  import { getArrowBindings } from '../lib/shapes/arrow/shared'
12
13
  import { DEFAULT_FRAME_PADDING, fitFrameToContent, removeFrame } from '../lib/utils/frames/frames'
13
14
  import { TestEditor } from './TestEditor'
14
15
 
15
16
  let editor: TestEditor
16
17
 
17
- jest.useFakeTimers()
18
+ vi.useFakeTimers()
18
19
 
19
20
  beforeEach(() => {
20
21
  editor = new TestEditor()
@@ -335,7 +336,7 @@ describe('frame shapes', () => {
335
336
  // move to the center of the frame
336
337
  editor.pointerMove(100, 100)
337
338
 
338
- jest.advanceTimersByTime(300)
339
+ vi.advanceTimersByTime(300)
339
340
 
340
341
  // Expect the shape to be inside the frame
341
342
  expect(editor.getOnlySelectedShape()!.id).toBe(ids.boxA)
@@ -343,13 +344,13 @@ describe('frame shapes', () => {
343
344
 
344
345
  // Move out of the frame
345
346
  editor.pointerMove(275, 275)
346
- jest.advanceTimersByTime(250)
347
+ vi.advanceTimersByTime(250)
347
348
 
348
349
  expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.getCurrentPageId())
349
350
 
350
351
  // Move back into the frame
351
352
  editor.pointerMove(150, 150)
352
- jest.advanceTimersByTime(250)
353
+ vi.advanceTimersByTime(250)
353
354
 
354
355
  // Expect the shape to be inside the frame again
355
356
  expect(editor.getOnlySelectedShape()!.parentId).toBe(frameId)
@@ -384,7 +385,7 @@ describe('frame shapes', () => {
384
385
 
385
386
  editor.setCurrentTool('select').select(box1.id).pointerDown(127, 127).pointerMove(132, 127)
386
387
 
387
- jest.advanceTimersByTime(250)
388
+ vi.advanceTimersByTime(250)
388
389
 
389
390
  expect(editor.getOnlySelectedShape()!.id).toBe(box1.id)
390
391
  if (editor.getShape(box1)?.parentId !== frame.id) {
@@ -403,14 +404,14 @@ describe('frame shapes', () => {
403
404
  editor.pointerMove(175, 175)
404
405
  expect(editor.getOnlySelectedShape()!.parentId).toBe(frame.id)
405
406
 
406
- jest.advanceTimersByTime(250)
407
+ vi.advanceTimersByTime(250)
407
408
  expect(editor.getOnlySelectedShape()!.parentId).toBe(frame.id)
408
409
 
409
410
  // Let's try that
410
411
  editor.pointerMove(1750, 1750)
411
- jest.advanceTimersByTime(200)
412
+ vi.advanceTimersByTime(200)
412
413
  editor.pointerMove(175, 175)
413
- jest.advanceTimersByTime(200)
414
+ vi.advanceTimersByTime(200)
414
415
 
415
416
  // yay
416
417
  expect(editor.getHintingShapeIds()).toHaveLength(1)
@@ -958,7 +959,7 @@ describe('When dragging a shape inside a group inside a frame', () => {
958
959
  editor.pointerMove(150, 150).pointerDown(150, 150).pointerMove(140, 140)
959
960
 
960
961
  expect(editor.getOnlySelectedShapeId()).toBe(ids.box1)
961
- jest.advanceTimersByTime(300)
962
+ vi.advanceTimersByTime(300)
962
963
 
963
964
  expect(editor.getShape(ids.box1)!.parentId).toBe(ids.group1)
964
965
  })
@@ -973,7 +974,7 @@ it('Drags into a frame', () => {
973
974
  editor.pointerDown(550, 550)
974
975
  editor.pointerMove(250, 250)
975
976
 
976
- jest.advanceTimersByTime(200)
977
+ vi.advanceTimersByTime(200)
977
978
 
978
979
  expect(editor.getShape(box1)!.parentId).toBe(frame.id)
979
980
  })
@@ -992,7 +993,7 @@ it('Allows dragging grouped shapes into frames if every shape in the group is in
992
993
  editor.pointerDown(1100, 1100)
993
994
  editor.pointerMove(250, 250)
994
995
 
995
- jest.advanceTimersByTime(250)
996
+ vi.advanceTimersByTime(250)
996
997
 
997
998
  expect(editor.getHintingShapeIds()).toMatchObject([frame.id])
998
999
 
@@ -1068,7 +1069,7 @@ describe('When dragging a shape', () => {
1068
1069
  editor.pointerMove(30, 50)
1069
1070
  editor.pointerUp(30, 50)
1070
1071
  const parent = editor.getShape(rectId)?.parentId
1071
- jest.advanceTimersByTime(200)
1072
+ vi.advanceTimersByTime(200)
1072
1073
  expect(parent).toBe(frameId)
1073
1074
  })
1074
1075
 
@@ -1185,7 +1186,7 @@ describe('Unparenting behavior', () => {
1185
1186
  // expect(editor.getShape(rect.id)!.parentId).toBe(frame.id)
1186
1187
  // editor.pointerDown(90, 50)
1187
1188
  // editor.pointerMove(110, 50)
1188
- // jest.advanceTimersByTime(200)
1189
+ // vi.advanceTimersByTime(200)
1189
1190
  // expect(editor.getShape(rect.id)!.parentId).toBe(editor.getCurrentPageId())
1190
1191
  // editor.pointerUp(110, 50)
1191
1192
  // expect(editor.getShape(rect.id)!.parentId).toBe(editor.getCurrentPageId())
@@ -1199,7 +1200,7 @@ describe('Unparenting behavior', () => {
1199
1200
  expect(editor.getShape(rect.id)!.parentId).toBe(frame.id)
1200
1201
  editor.pointerDown(90, 50)
1201
1202
  editor.pointerMove(110, 50)
1202
- jest.advanceTimersByTime(200)
1203
+ vi.advanceTimersByTime(200)
1203
1204
  expect(editor.getShape(rect.id)!.parentId).toBe(editor.getCurrentPageId())
1204
1205
  editor.pointerUp(110, 50)
1205
1206
  expect(editor.getShape(rect.id)!.parentId).toBe(editor.getCurrentPageId())
@@ -1299,7 +1300,7 @@ describe('Unparenting behavior', () => {
1299
1300
  expect(editor.getShape(triangle.id)!.parentId).toBe(frame.id)
1300
1301
 
1301
1302
  // But after a delay, the triangle is reparented because it's not overlapping
1302
- jest.advanceTimersByTime(200)
1303
+ vi.advanceTimersByTime(200)
1303
1304
  expect(editor.getShape(triangle.id)!.parentId).toBe(editor.getCurrentPageId())
1304
1305
 
1305
1306
  editor.pointerMove(50, 50)
@@ -1308,7 +1309,7 @@ describe('Unparenting behavior', () => {
1308
1309
  expect(editor.getShape(triangle.id)!.parentId).toBe(editor.getCurrentPageId())
1309
1310
 
1310
1311
  // But after a delay, the triangle is reparented because it's overlapping
1311
- jest.advanceTimersByTime(200)
1312
+ vi.advanceTimersByTime(200)
1312
1313
  expect(editor.getShape(triangle.id)!.parentId).toBe(frame.id)
1313
1314
  })
1314
1315
 
@@ -1348,12 +1349,12 @@ describe('Unparenting behavior', () => {
1348
1349
  expect(editor.isIn('select.translating')).toBe(true)
1349
1350
 
1350
1351
  // Wait for reparenting to happen
1351
- jest.advanceTimersByTime(250)
1352
+ vi.advanceTimersByTime(250)
1352
1353
  expect(editor.getShape(largeRect.id)!.parentId).toBe(frameId)
1353
1354
 
1354
1355
  // The large rectangle should now be reparented to the frame, even though the frame covers it
1355
1356
  editor.pointerUp(250, 250)
1356
- jest.advanceTimersByTime(250)
1357
+ vi.advanceTimersByTime(250)
1357
1358
  }
1358
1359
 
1359
1360
  // When the shape has no fill and an empty label, it should fall out of the frame
@@ -1503,7 +1504,7 @@ describe('When dragging groups or shapes within a group', () => {
1503
1504
  editor.pointerDown(1100, 1100)
1504
1505
  editor.pointerMove(250, 250)
1505
1506
 
1506
- jest.advanceTimersByTime(200)
1507
+ vi.advanceTimersByTime(200)
1507
1508
 
1508
1509
  expect(editor.getShape(group)!.parentId).toBe(frame.id)
1509
1510
  })
@@ -1526,14 +1527,14 @@ describe('When dragging groups or shapes within a group', () => {
1526
1527
  editor.select(rect1ID)
1527
1528
  editor.pointerDown(15, 15)
1528
1529
  editor.pointerMove(100, 100)
1529
- jest.advanceTimersByTime(200)
1530
+ vi.advanceTimersByTime(200)
1530
1531
 
1531
1532
  expect(editor.getShape(rect1ID)?.parentId).toBe(group.id)
1532
1533
  expect(editor.getShape(rect2ID)?.parentId).toBe(group.id)
1533
1534
  expect(group.parentId).toBe(frame.id)
1534
1535
 
1535
1536
  editor.pointerUp(100, 100)
1536
- jest.advanceTimersByTime(200)
1537
+ vi.advanceTimersByTime(200)
1537
1538
 
1538
1539
  expect(editor.getShape(rect1ID)?.parentId).toBe(group.id)
1539
1540
  expect(editor.getShape(rect2ID)?.parentId).toBe(group.id)
@@ -1558,7 +1559,7 @@ describe('When dragging groups or shapes within a group', () => {
1558
1559
  editor.pointerDown(15, 15)
1559
1560
  editor.pointerMove(200, 200)
1560
1561
 
1561
- jest.advanceTimersByTime(200)
1562
+ vi.advanceTimersByTime(200)
1562
1563
  expect(editor.getShape(rect1ID)?.parentId).toBe(group.id)
1563
1564
  expect(editor.getShape(rect2ID)?.parentId).toBe(group.id)
1564
1565
  expect(editor.getShape(group.id)?.parentId).toBe(editor.getCurrentPageId())
@@ -1587,7 +1588,7 @@ describe('When dragging groups or shapes within a group', () => {
1587
1588
  editor.pointerDown(15, 15)
1588
1589
  editor.pointerMove(200, 200)
1589
1590
 
1590
- jest.advanceTimersByTime(200)
1591
+ vi.advanceTimersByTime(200)
1591
1592
  expect(editor.getShape(rect1ID)?.parentId).toBe(group.id)
1592
1593
  expect(editor.getShape(rect2ID)?.parentId).toBe(group.id)
1593
1594
  expect(editor.getShape(group.id)?.parentId).toBe(editor.getCurrentPageId())
@@ -1638,7 +1639,7 @@ describe('When dragging groups or shapes within a group', () => {
1638
1639
  editor.pointerDown(215, 215)
1639
1640
  editor.pointerMove(15, 15)
1640
1641
 
1641
- jest.advanceTimersByTime(200)
1642
+ vi.advanceTimersByTime(200)
1642
1643
  expect(editor.getShape(rect1ID)?.parentId).toBe(group.id)
1643
1644
  expect(editor.getShape(rect2ID)?.parentId).toBe(group.id)
1644
1645
  expect(editor.getShape(group.id)?.parentId).toBe(frameID)
@@ -1,4 +1,5 @@
1
1
  import { Box, TLShapeId, createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from './TestEditor'
3
4
  import { TL } from './test-jsx'
4
5
 
@@ -28,13 +29,13 @@ it('lists shapes in viewport', () => {
28
29
 
29
30
  // Move the camera 201 pixels to the right and 201 pixels down
30
31
  editor.pan({ x: -201, y: -201 })
31
- jest.advanceTimersByTime(500)
32
+ vi.advanceTimersByTime(500)
32
33
 
33
34
  // A is now outside of the viewport, like D
34
35
  expect(editor.getCulledShapes()).toStrictEqual(new Set([ids.A, ids.D]))
35
36
 
36
37
  editor.pan({ x: -900, y: -900 })
37
- jest.advanceTimersByTime(500)
38
+ vi.advanceTimersByTime(500)
38
39
  // Now all shapes are outside of the viewport, except for D (which is clipped)
39
40
  expect(editor.getCulledShapes()).toStrictEqual(new Set([ids.A, ids.B, ids.C]))
40
41
 
@@ -1070,7 +1070,7 @@ describe('the select tool', () => {
1070
1070
  // that we're doing hit testing manually—we'll catch that it was inside a shape
1071
1071
 
1072
1072
  // editor.keyUp('Shift')
1073
- // jest.advanceTimersByTime(200)
1073
+ // vi.advanceTimersByTime(200)
1074
1074
 
1075
1075
  // expect(editor.selectedShapeIds.includes(ids.boxA)).toBe(false)
1076
1076
  // expect(editor.selectedShapeIds.includes(ids.boxB)).toBe(true)
@@ -1,8 +1,9 @@
1
1
  import { PageRecordType, TLDeepLink, createDeepLinkString, createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from './TestEditor'
3
4
  import { TL } from './test-jsx'
4
5
 
5
- jest.useFakeTimers()
6
+ vi.useFakeTimers()
6
7
 
7
8
  let editor: TestEditor
8
9
 
@@ -1,4 +1,5 @@
1
1
  import { createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from './TestEditor'
3
4
 
4
5
  let editor: TestEditor
@@ -82,7 +83,7 @@ describe('Maximum shapes behavior', () => {
82
83
  })
83
84
 
84
85
  it('should emit max-shapes event when limit is reached', () => {
85
- const maxShapesHandler = jest.fn()
86
+ const maxShapesHandler = vi.fn()
86
87
  editor.addListener('max-shapes', maxShapesHandler)
87
88
 
88
89
  // Set up the note tool
@@ -282,7 +283,7 @@ describe('Maximum shapes behavior', () => {
282
283
  expect(editor.getCurrentPageShapeIds().size).toBe(5)
283
284
 
284
285
  // Try to create one more shape
285
- const maxShapesHandler = jest.fn()
286
+ const maxShapesHandler = vi.fn()
286
287
  editor.addListener('max-shapes', maxShapesHandler)
287
288
 
288
289
  const extraShapeId = createShapeId('extra-shape')
@@ -1,3 +1,4 @@
1
+ import { vi } from 'vitest'
1
2
  import { TestEditor } from './TestEditor'
2
3
 
3
4
  let editor: TestEditor
@@ -6,14 +7,14 @@ beforeEach(() => {
6
7
  editor = new TestEditor()
7
8
  })
8
9
 
9
- jest.useFakeTimers()
10
+ vi.useFakeTimers()
10
11
 
11
12
  it('Shift Key', () => {
12
13
  editor.pointerDown(0, 0)
13
14
  editor.pointerMove(100, 100, { shiftKey: true })
14
15
  editor.pointerMove(100, 100, { shiftKey: false })
15
16
  expect(editor.inputs.shiftKey).toBe(true)
16
- jest.advanceTimersByTime(200)
17
+ vi.advanceTimersByTime(200)
17
18
  expect(editor.inputs.shiftKey).toBe(false)
18
19
  })
19
20
 
@@ -22,7 +23,7 @@ it('Alt Key', () => {
22
23
  editor.pointerMove(100, 100, { altKey: true })
23
24
  editor.pointerMove(100, 100, { altKey: false })
24
25
  expect(editor.inputs.altKey).toBe(true)
25
- jest.advanceTimersByTime(200)
26
+ vi.advanceTimersByTime(200)
26
27
  expect(editor.inputs.altKey).toBe(false)
27
28
  })
28
29
 
@@ -31,6 +32,6 @@ it('Ctrl Key', () => {
31
32
  editor.pointerMove(100, 100, { ctrlKey: true })
32
33
  editor.pointerMove(100, 100, { ctrlKey: false })
33
34
  expect(editor.inputs.ctrlKey).toBe(true)
34
- jest.advanceTimersByTime(200)
35
+ vi.advanceTimersByTime(200)
35
36
  expect(editor.inputs.ctrlKey).toBe(false)
36
37
  })
@@ -1,4 +1,5 @@
1
1
  import { createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from './TestEditor'
3
4
 
4
5
  let editor: TestEditor
@@ -54,7 +55,7 @@ describe('Shape navigation', () => {
54
55
  ])
55
56
 
56
57
  // Mock canTabTo to return false for the second shape
57
- jest.spyOn(editor.getShapeUtil('geo'), 'canTabTo').mockImplementation((shape) => {
58
+ vi.spyOn(editor.getShapeUtil('geo'), 'canTabTo').mockImplementation((shape) => {
58
59
  return shape.id !== ids.box2
59
60
  })
60
61
 
@@ -100,7 +101,7 @@ describe('Shape navigation', () => {
100
101
  editor.select(ids.box1)
101
102
 
102
103
  // Spy on zoomToSelectionIfOffscreen method
103
- const zoomSpy = jest.spyOn(editor, 'zoomToSelectionIfOffscreen')
104
+ const zoomSpy = vi.spyOn(editor, 'zoomToSelectionIfOffscreen')
104
105
 
105
106
  // Navigate to next shape (offscreen)
106
107
  editor.selectAdjacentShape('next')
@@ -119,7 +120,7 @@ describe('Shape navigation', () => {
119
120
  ])
120
121
 
121
122
  // Mock a culled shape (not rendered)
122
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
123
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
123
124
  // Return normal bounds for box1, null for box2 as if it's culled/not rendered
124
125
  if (shape?.id === ids.box2) {
125
126
  // Still return bounds, but pretend it was calculated even though shape is culled
@@ -150,7 +151,7 @@ describe('Shape navigation', () => {
150
151
  ])
151
152
 
152
153
  // Setup shape centers for the test
153
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
154
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
154
155
  if (shape?.id === ids.boxA) {
155
156
  return { center: { x: 10, y: 110 } } as any
156
157
  }
@@ -182,7 +183,7 @@ describe('Shape navigation', () => {
182
183
  ])
183
184
 
184
185
  // Setup shape centers for the test
185
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
186
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
186
187
  if (shape?.id === ids.center) {
187
188
  return { center: { x: 100, y: 100 } } as any
188
189
  }
@@ -219,7 +220,7 @@ describe('Shape navigation', () => {
219
220
  ])
220
221
 
221
222
  // Setup shape centers
222
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
223
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
223
224
  if (shape?.id === ids.center) return { center: { x: 200, y: 200 } } as any
224
225
  if (shape?.id === ids.right) return { center: { x: 300, y: 200 } } as any
225
226
  if (shape?.id === ids.left) return { center: { x: 100, y: 200 } } as any
@@ -258,7 +259,7 @@ describe('Shape navigation', () => {
258
259
  ])
259
260
 
260
261
  // Setup shape centers
261
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
262
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
262
263
  if (shape?.id === ids.center) return { center: { x: 200, y: 200 } } as any
263
264
  if (shape?.id === ids.nearRight) return { center: { x: 250, y: 200 } } as any
264
265
  if (shape?.id === ids.farRight) return { center: { x: 350, y: 200 } } as any
@@ -284,7 +285,7 @@ describe('Shape navigation', () => {
284
285
  ])
285
286
 
286
287
  // Setup shape centers
287
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
288
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
288
289
  if (shape?.id === ids.box1) return { center: { x: 50, y: 50 } } as any
289
290
  if (shape?.id === ids.box2) return { center: { x: 150, y: 50 } } as any
290
291
  if (shape?.id === ids.box3) return { center: { x: 150, y: 150 } } as any
@@ -485,7 +486,7 @@ describe('Shape navigation', () => {
485
486
  ])
486
487
 
487
488
  // Setup shape centers for consistent testing
488
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
489
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
489
490
  const positions = {
490
491
  [ids.box1]: { x: 25, y: 115 },
491
492
  [ids.box2]: { x: 65, y: 115 },
@@ -612,7 +613,7 @@ describe('Shape navigation', () => {
612
613
  ])
613
614
 
614
615
  // Setup shape centers for consistent testing
615
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
616
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
616
617
  const positions = {
617
618
  [ids.box1]: { x: 115, y: 25 },
618
619
  [ids.box2]: { x: 115, y: 65 },
@@ -1006,7 +1007,7 @@ describe('Shape navigation', () => {
1006
1007
  ])
1007
1008
 
1008
1009
  // Setup shape centers
1009
- jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
1010
+ vi.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
1010
1011
  if (shape?.id === ids.row1Shape1) return { center: { x: 50, y: 50 } } as any
1011
1012
  if (shape?.id === ids.row1Shape2) return { center: { x: 150, y: 50 } } as any
1012
1013
  if (shape?.id === ids.row1Shape3) return { center: { x: 250, y: 50 } } as any
@@ -1,6 +1,7 @@
1
+ import { vi } from 'vitest'
1
2
  import { TestEditor } from './TestEditor'
2
3
 
3
- jest.useFakeTimers()
4
+ vi.useFakeTimers()
4
5
 
5
6
  let editor: TestEditor
6
7
 
@@ -1,10 +1,11 @@
1
1
  import { TLShapePartial, Vec, createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from '../TestEditor'
3
4
  import { PerformanceMeasurer } from './PerformanceMeasurer'
4
5
 
5
6
  let editor = new TestEditor()
6
7
 
7
- jest.useRealTimers()
8
+ vi.useRealTimers()
8
9
 
9
10
  describe.skip('Example perf tests', () => {
10
11
  it('measures Editor.createShape vs Editor.createShapes', () => {
@@ -1,8 +1,9 @@
1
1
  import { PageRecordType, Vec, createShapeId } from '@tldraw/editor'
2
+ import { vi } from 'vitest'
2
3
  import { TestEditor } from './TestEditor'
3
4
  import { TL } from './test-jsx'
4
5
 
5
- jest.useFakeTimers()
6
+ vi.useFakeTimers()
6
7
 
7
8
  let editor: TestEditor
8
9
 
@@ -20,20 +21,20 @@ beforeEach(() => {
20
21
  test('it creates a listener that updates the current url', async () => {
21
22
  const unlisten = editor.registerDeepLinkListener()
22
23
 
23
- jest.advanceTimersByTime(1000)
24
+ vi.advanceTimersByTime(1000)
24
25
  expect(window.location.href).toMatchInlineSnapshot(`"http://localhost/test?d=v0.0.1080.720.page"`)
25
26
 
26
27
  const pageId = PageRecordType.createId('foo')
27
28
  editor.createPage({ id: pageId })
28
29
  editor.setCurrentPage(pageId)
29
30
 
30
- jest.advanceTimersByTime(1000)
31
+ vi.advanceTimersByTime(1000)
31
32
 
32
33
  expect(window.location.href).toMatchInlineSnapshot(`"http://localhost/test?d=v0.0.1080.720.foo"`)
33
34
 
34
35
  editor.pan({ x: 100, y: 100 })
35
36
 
36
- jest.advanceTimersByTime(1000)
37
+ vi.advanceTimersByTime(1000)
37
38
 
38
39
  expect(window.location.href).toMatchInlineSnapshot(
39
40
  `"http://localhost/test?d=v-100.-100.1080.720.foo"`
@@ -43,7 +44,7 @@ test('it creates a listener that updates the current url', async () => {
43
44
 
44
45
  editor.pan({ x: 500, y: 500 })
45
46
 
46
- jest.advanceTimersByTime(1000)
47
+ vi.advanceTimersByTime(1000)
47
48
 
48
49
  expect(window.location.href).toMatchInlineSnapshot(
49
50
  `"http://localhost/test?d=v-100.-100.1080.720.foo"`
@@ -75,7 +76,7 @@ test('it allows specifying a page target', async () => {
75
76
  param: 'foo',
76
77
  })
77
78
 
78
- jest.advanceTimersByTime(1000)
79
+ vi.advanceTimersByTime(1000)
79
80
 
80
81
  // no shapes yet
81
82
  expect(window.location.href).toMatchInlineSnapshot(`"http://localhost/test?foo=ppage"`)
@@ -87,19 +88,19 @@ test('it allows specifying a page target', async () => {
87
88
  <TL.geo id={boxB} x={1000} y={1000} w={100} h={100} />,
88
89
  ])
89
90
 
90
- jest.advanceTimersByTime(1000)
91
+ vi.advanceTimersByTime(1000)
91
92
  expect(window.location.href).toMatchInlineSnapshot(`"http://localhost/test?foo=sa"`)
92
93
 
93
94
  editor.pan({ x: -1000, y: -1000 })
94
95
 
95
- jest.advanceTimersByTime(1000)
96
+ vi.advanceTimersByTime(1000)
96
97
  expect(window.location.href).toMatchInlineSnapshot(`"http://localhost/test?foo=sb"`)
97
98
 
98
99
  unlisten()
99
100
 
100
101
  editor.pan({ x: 1000, y: 1000 })
101
102
 
102
- jest.advanceTimersByTime(1000)
103
+ vi.advanceTimersByTime(1000)
103
104
  expect(window.location.href).toMatchInlineSnapshot(`"http://localhost/test?foo=sb"`)
104
105
  expect(getNearestShape().id).toBe(boxA)
105
106
  })
@@ -15,12 +15,13 @@ import {
15
15
  rotateSelectionHandle,
16
16
  toRichText,
17
17
  } from '@tldraw/editor'
18
+ import { vi } from 'vitest'
18
19
  import { NoteShapeUtil } from '../lib/shapes/note/NoteShapeUtil'
19
20
  import { TestEditor } from './TestEditor'
20
21
  import { getSnapLines } from './getSnapLines'
21
22
  import { roundedBox } from './roundedBox'
22
23
 
23
- jest.useFakeTimers()
24
+ vi.useFakeTimers()
24
25
 
25
26
  const ORDERED_ROTATE_CORNERS: TLSelectionHandle[] = [
26
27
  'top_left_rotate',
@@ -544,7 +545,7 @@ describe('Reisizing a selection of multiple shapes', () => {
544
545
  // └──────────────────O
545
546
 
546
547
  editor.pointerMove(15, 8, { altKey: false, shiftKey: true })
547
- jest.advanceTimersByTime(200)
548
+ vi.advanceTimersByTime(200)
548
549
 
549
550
  expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
550
551
  expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 5, h: 5 })
@@ -593,7 +594,7 @@ describe('Reisizing a selection of multiple shapes', () => {
593
594
  editor.pointerDown(30, 20, { target: 'selection', handle: 'top_left_rotate' })
594
595
  editor.pointerMove(20, 20, { shiftKey: true })
595
596
  editor.pointerUp(20, 20, { shiftKey: false })
596
- jest.advanceTimersByTime(200)
597
+ vi.advanceTimersByTime(200)
597
598
 
598
599
  expect(editor.getShape(ids.boxB)!.rotation).toBeCloseTo(canonicalizeRotation(-PI / 2))
599
600
 
@@ -740,7 +741,7 @@ describe('Reisizing a selection of multiple shapes', () => {
740
741
  // └──────────────────O
741
742
 
742
743
  editor.pointerMove(15, 8, { altKey: false, shiftKey: true })
743
- jest.advanceTimersByTime(200)
744
+ vi.advanceTimersByTime(200)
744
745
 
745
746
  expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
746
747
  expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 5, h: 5 })
@@ -2364,7 +2365,7 @@ describe('snapping while resizing a shape that has been rotated by multiples of
2364
2365
  .select(ids.boxX)
2365
2366
  .pointerDown(100, 70, { target: 'selection', handle: 'top' })
2366
2367
  .pointerMove(121, 70, { ctrlKey: true, shiftKey: false })
2367
- jest.advanceTimersByTime(200)
2368
+ vi.advanceTimersByTime(200)
2368
2369
 
2369
2370
  expect(editor.getShapePageBounds(ids.boxX)!).toMatchObject({
2370
2371
  x: 40,
@@ -2432,7 +2433,7 @@ describe('snapping while resizing a shape that has been rotated by multiples of
2432
2433
  .select(ids.boxX)
2433
2434
  .pointerDown(70, 40, { target: 'selection', handle: 'bottom' })
2434
2435
  .pointerMove(70, 18, { ctrlKey: true, shiftKey: false })
2435
- jest.advanceTimersByTime(200)
2436
+ vi.advanceTimersByTime(200)
2436
2437
 
2437
2438
  expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(40)
2438
2439
  expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(20)
@@ -2564,7 +2565,7 @@ describe('snapping while resizing a shape that has been rotated by multiples of
2564
2565
  .select(ids.boxX)
2565
2566
  .pointerDown(100, 70, { target: 'selection', handle: 'right' })
2566
2567
  .pointerMove(121, 70, { ctrlKey: true, shiftKey: false })
2567
- jest.advanceTimersByTime(200)
2568
+ vi.advanceTimersByTime(200)
2568
2569
 
2569
2570
  expect(editor.getShapePageBounds(ids.boxX)!.x).toBeCloseTo(40)
2570
2571
  expect(editor.getShapePageBounds(ids.boxX)!.y).toBeCloseTo(40)
@@ -3824,36 +3825,36 @@ describe('shapes that have do not resize', () => {
3824
3825
  // })
3825
3826
  // })
3826
3827
 
3827
- describe('bugs', () => {
3828
- // it('resizing a zero width shape', () => {
3829
- // // Draw shapes can no longer have zero width / height
3830
- // const shapeId = createShapeId()
3831
- // app
3832
- // .createShapes([
3833
- // {
3834
- // id: shapeId,
3835
- // type: 'draw',
3836
- // x: 0,
3837
- // y: 0,
3838
- // props: {
3839
- // segments: [
3840
- // {
3841
- // type: 'straight',
3842
- // points: [
3843
- // { x: 0, y: 0 },
3844
- // { x: 0, y: 100 },
3845
- // ],
3846
- // },
3847
- // ],
3848
- // },
3849
- // },
3850
- // ])
3851
- // .select(shapeId)
3852
- // expect(editor.selectionRotatedBounds!.width).toBe(0)
3853
- // editor.pointerDown(0, 100, { target: 'selection', handle: 'bottom_right' }).pointerMove(10, 110)
3854
- // expect(editor.selectionRotatedBounds!.width).toBe(0)
3855
- // })
3856
- })
3828
+ // describe('bugs', () => {
3829
+ // it('resizing a zero width shape', () => {
3830
+ // // Draw shapes can no longer have zero width / height
3831
+ // const shapeId = createShapeId()
3832
+ // app
3833
+ // .createShapes([
3834
+ // {
3835
+ // id: shapeId,
3836
+ // type: 'draw',
3837
+ // x: 0,
3838
+ // y: 0,
3839
+ // props: {
3840
+ // segments: [
3841
+ // {
3842
+ // type: 'straight',
3843
+ // points: [
3844
+ // { x: 0, y: 0 },
3845
+ // { x: 0, y: 100 },
3846
+ // ],
3847
+ // },
3848
+ // ],
3849
+ // },
3850
+ // },
3851
+ // ])
3852
+ // .select(shapeId)
3853
+ // expect(editor.selectionRotatedBounds!.width).toBe(0)
3854
+ // editor.pointerDown(0, 100, { target: 'selection', handle: 'bottom_right' }).pointerMove(10, 110)
3855
+ // expect(editor.selectionRotatedBounds!.width).toBe(0)
3856
+ // })
3857
+ // })
3857
3858
 
3858
3859
  it('uses the cross cursor when create resizing', () => {
3859
3860
  editor.setCurrentTool('geo')
@@ -3942,7 +3943,7 @@ describe('When resizing near the edges of the screen', () => {
3942
3943
  handle: 'top_left',
3943
3944
  })
3944
3945
  .pointerMove(-1, -1) // into the edge scrolling distance
3945
- jest.advanceTimersByTime(1000)
3946
+ vi.advanceTimersByTime(1000)
3946
3947
  const after = editor.getShape<TLGeoShape>(ids.boxA)!
3947
3948
  expect(after.x).toBeLessThan(before.x)
3948
3949
  expect(after.y).toBeLessThan(before.y)