@tldraw/editor 3.16.0-internal.51e99e128bd4 → 3.16.0-internal.a478398270c6

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 (217) hide show
  1. package/dist-cjs/index.d.ts +16 -217
  2. package/dist-cjs/index.js +1 -8
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +1 -3
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/MenuClickCapture.js +5 -0
  7. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  8. package/dist-cjs/lib/components/SVGContainer.js +1 -1
  9. package/dist-cjs/lib/components/SVGContainer.js.map +2 -2
  10. package/dist-cjs/lib/components/Shape.js +26 -4
  11. package/dist-cjs/lib/components/Shape.js.map +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultBrush.js +1 -1
  13. package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
  15. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +2 -2
  17. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
  18. package/dist-cjs/lib/components/default-components/DefaultCursor.js +1 -1
  19. package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +2 -2
  20. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
  21. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  22. package/dist-cjs/lib/components/default-components/DefaultGrid.js +1 -1
  23. package/dist-cjs/lib/components/default-components/DefaultGrid.js.map +2 -2
  24. package/dist-cjs/lib/components/default-components/DefaultHandles.js +1 -1
  25. package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +2 -2
  26. package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
  27. package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
  28. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -9
  29. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  30. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +1 -1
  31. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +2 -2
  32. package/dist-cjs/lib/components/default-components/DefaultSpinner.js +15 -27
  33. package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +3 -3
  34. package/dist-cjs/lib/config/TLUserPreferences.js +3 -15
  35. package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
  36. package/dist-cjs/lib/editor/Editor.js +67 -134
  37. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  38. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +4 -14
  39. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  40. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  41. package/dist-cjs/lib/editor/tools/StateNode.js +1 -20
  42. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  43. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  44. package/dist-cjs/lib/exports/getSvgJsx.js +2 -1
  45. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  46. package/dist-cjs/lib/hooks/useCanvasEvents.js +20 -24
  47. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  48. package/dist-cjs/lib/hooks/useEditor.js +4 -1
  49. package/dist-cjs/lib/hooks/useEditor.js.map +2 -2
  50. package/dist-cjs/lib/hooks/useEditorComponents.js +0 -2
  51. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  52. package/dist-cjs/lib/license/Watermark.js +8 -8
  53. package/dist-cjs/lib/license/Watermark.js.map +2 -2
  54. package/dist-cjs/lib/options.js +0 -7
  55. package/dist-cjs/lib/options.js.map +2 -2
  56. package/dist-cjs/lib/primitives/geometry/Arc2d.js +1 -1
  57. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  58. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
  59. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  60. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -3
  61. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  62. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -1
  63. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  64. package/dist-cjs/lib/primitives/geometry/geometry-constants.js +2 -2
  65. package/dist-cjs/lib/primitives/geometry/geometry-constants.js.map +2 -2
  66. package/dist-cjs/lib/primitives/intersect.js +4 -4
  67. package/dist-cjs/lib/primitives/intersect.js.map +2 -2
  68. package/dist-cjs/lib/primitives/utils.js +0 -4
  69. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  70. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +1 -0
  71. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  72. package/dist-cjs/version.js +3 -3
  73. package/dist-cjs/version.js.map +1 -1
  74. package/dist-esm/index.d.mts +16 -217
  75. package/dist-esm/index.mjs +2 -16
  76. package/dist-esm/index.mjs.map +2 -2
  77. package/dist-esm/lib/TldrawEditor.mjs +1 -3
  78. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  79. package/dist-esm/lib/components/MenuClickCapture.mjs +5 -0
  80. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  81. package/dist-esm/lib/components/SVGContainer.mjs +1 -1
  82. package/dist-esm/lib/components/SVGContainer.mjs.map +2 -2
  83. package/dist-esm/lib/components/Shape.mjs +26 -4
  84. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  85. package/dist-esm/lib/components/default-components/DefaultBrush.mjs +1 -1
  86. package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
  87. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
  88. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  89. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +2 -2
  90. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
  91. package/dist-esm/lib/components/default-components/DefaultCursor.mjs +1 -1
  92. package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +2 -2
  93. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
  94. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  95. package/dist-esm/lib/components/default-components/DefaultGrid.mjs +1 -1
  96. package/dist-esm/lib/components/default-components/DefaultGrid.mjs.map +2 -2
  97. package/dist-esm/lib/components/default-components/DefaultHandles.mjs +1 -1
  98. package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +2 -2
  99. package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
  100. package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
  101. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -9
  102. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  103. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +1 -1
  104. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +2 -2
  105. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +15 -17
  106. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
  107. package/dist-esm/lib/config/TLUserPreferences.mjs +3 -15
  108. package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
  109. package/dist-esm/lib/editor/Editor.mjs +67 -134
  110. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  111. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +4 -14
  112. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  113. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  114. package/dist-esm/lib/editor/tools/StateNode.mjs +1 -20
  115. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  116. package/dist-esm/lib/exports/getSvgJsx.mjs +2 -2
  117. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  118. package/dist-esm/lib/hooks/useCanvasEvents.mjs +21 -25
  119. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  120. package/dist-esm/lib/hooks/useEditor.mjs +4 -1
  121. package/dist-esm/lib/hooks/useEditor.mjs.map +2 -2
  122. package/dist-esm/lib/hooks/useEditorComponents.mjs +0 -4
  123. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  124. package/dist-esm/lib/license/Watermark.mjs +8 -8
  125. package/dist-esm/lib/license/Watermark.mjs.map +2 -2
  126. package/dist-esm/lib/options.mjs +0 -7
  127. package/dist-esm/lib/options.mjs.map +2 -2
  128. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  129. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  130. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +2 -2
  131. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  132. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -3
  133. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  134. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +2 -2
  135. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  136. package/dist-esm/lib/primitives/geometry/geometry-constants.mjs +2 -2
  137. package/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map +2 -2
  138. package/dist-esm/lib/primitives/intersect.mjs +5 -5
  139. package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
  140. package/dist-esm/lib/primitives/utils.mjs +0 -4
  141. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  142. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +1 -0
  143. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  144. package/dist-esm/version.mjs +3 -3
  145. package/dist-esm/version.mjs.map +1 -1
  146. package/editor.css +313 -312
  147. package/package.json +38 -16
  148. package/src/index.ts +1 -15
  149. package/src/lib/TldrawEditor.tsx +5 -7
  150. package/src/lib/components/MenuClickCapture.tsx +8 -0
  151. package/src/lib/components/SVGContainer.tsx +1 -1
  152. package/src/lib/components/Shape.tsx +21 -6
  153. package/src/lib/components/default-components/DefaultBrush.tsx +1 -1
  154. package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
  155. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +2 -2
  156. package/src/lib/components/default-components/DefaultCursor.tsx +1 -1
  157. package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
  158. package/src/lib/components/default-components/DefaultGrid.tsx +1 -1
  159. package/src/lib/components/default-components/DefaultHandles.tsx +1 -5
  160. package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
  161. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +2 -6
  162. package/src/lib/components/default-components/DefaultSnapIndictor.tsx +1 -1
  163. package/src/lib/components/default-components/DefaultSpinner.tsx +12 -12
  164. package/src/lib/config/TLUserPreferences.ts +1 -15
  165. package/src/lib/editor/Editor.test.ts +8 -416
  166. package/src/lib/editor/Editor.ts +92 -177
  167. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +14 -15
  168. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +15 -16
  169. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +48 -49
  170. package/src/lib/editor/managers/FontManager/FontManager.test.ts +23 -24
  171. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +6 -7
  172. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +11 -12
  173. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +50 -57
  174. package/src/lib/editor/managers/TextManager/TextManager.test.ts +26 -51
  175. package/src/lib/editor/managers/TickManager/TickManager.test.ts +13 -14
  176. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +26 -55
  177. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +1 -14
  178. package/src/lib/editor/shapes/ShapeUtil.ts +0 -57
  179. package/src/lib/editor/tools/StateNode.ts +1 -27
  180. package/src/lib/editor/types/misc-types.ts +1 -73
  181. package/src/lib/exports/getSvgJsx.tsx +2 -2
  182. package/src/lib/hooks/useCanvasEvents.ts +32 -39
  183. package/src/lib/hooks/useEditor.tsx +5 -6
  184. package/src/lib/hooks/useEditorComponents.tsx +2 -8
  185. package/src/lib/license/LicenseManager.test.ts +1 -3
  186. package/src/lib/license/Watermark.test.tsx +1 -2
  187. package/src/lib/license/Watermark.tsx +8 -8
  188. package/src/lib/options.ts +0 -8
  189. package/src/lib/primitives/geometry/Arc2d.ts +2 -2
  190. package/src/lib/primitives/geometry/Circle2d.ts +2 -2
  191. package/src/lib/primitives/geometry/CubicBezier2d.ts +1 -4
  192. package/src/lib/primitives/geometry/Ellipse2d.ts +2 -2
  193. package/src/lib/primitives/geometry/geometry-constants.ts +1 -2
  194. package/src/lib/primitives/intersect.ts +5 -12
  195. package/src/lib/primitives/utils.ts +0 -11
  196. package/src/lib/test/currentToolIdMask.test.ts +49 -0
  197. package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -2
  198. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
  199. package/src/lib/utils/sync/TLLocalSyncClient.ts +1 -0
  200. package/src/version.ts +3 -3
  201. package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +0 -53
  202. package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +0 -7
  203. package/dist-cjs/lib/hooks/useStateAttribute.js +0 -35
  204. package/dist-cjs/lib/hooks/useStateAttribute.js.map +0 -7
  205. package/dist-cjs/lib/utils/EditorAtom.js +0 -45
  206. package/dist-cjs/lib/utils/EditorAtom.js.map +0 -7
  207. package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +0 -23
  208. package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +0 -7
  209. package/dist-esm/lib/hooks/useStateAttribute.mjs +0 -15
  210. package/dist-esm/lib/hooks/useStateAttribute.mjs.map +0 -7
  211. package/dist-esm/lib/utils/EditorAtom.mjs +0 -25
  212. package/dist-esm/lib/utils/EditorAtom.mjs.map +0 -7
  213. package/src/lib/components/default-components/DefaultShapeWrapper.tsx +0 -35
  214. package/src/lib/editor/tools/StateNode.test.ts +0 -285
  215. package/src/lib/hooks/useStateAttribute.ts +0 -15
  216. package/src/lib/primitives/intersect.test.ts +0 -946
  217. package/src/lib/utils/EditorAtom.ts +0 -37
@@ -1,59 +1,58 @@
1
- import { Mock, Mocked, vi } from 'vitest'
2
1
  import { Editor } from '../../Editor'
3
2
  import { FocusManager } from './FocusManager'
4
3
 
5
4
  // Mock the Editor class
6
- vi.mock('../../Editor')
5
+ jest.mock('../../Editor')
7
6
 
8
7
  describe('FocusManager', () => {
9
- let editor: Mocked<
8
+ let editor: jest.Mocked<
10
9
  Editor & {
11
10
  sideEffects: {
12
- registerAfterChangeHandler: Mock
11
+ registerAfterChangeHandler: jest.Mock
13
12
  }
14
- getInstanceState: Mock
15
- updateInstanceState: Mock
16
- getContainer: Mock
17
- isIn: Mock
18
- getSelectedShapeIds: Mock
19
- complete: Mock
13
+ getInstanceState: jest.Mock
14
+ updateInstanceState: jest.Mock
15
+ getContainer: jest.Mock
16
+ isIn: jest.Mock
17
+ getSelectedShapeIds: jest.Mock
18
+ complete: jest.Mock
20
19
  }
21
20
  >
22
21
  let focusManager: FocusManager
23
22
  let mockContainer: HTMLElement
24
- let mockDispose: Mock
23
+ let mockDispose: jest.Mock
25
24
  let originalAddEventListener: typeof document.body.addEventListener
26
25
  let originalRemoveEventListener: typeof document.body.removeEventListener
27
26
 
28
27
  beforeEach(() => {
29
28
  // Create mock container element
30
29
  mockContainer = document.createElement('div')
31
- mockContainer.focus = vi.fn()
32
- mockContainer.blur = vi.fn()
33
- vi.spyOn(mockContainer.classList, 'add')
34
- vi.spyOn(mockContainer.classList, 'remove')
30
+ mockContainer.focus = jest.fn()
31
+ mockContainer.blur = jest.fn()
32
+ jest.spyOn(mockContainer.classList, 'add')
33
+ jest.spyOn(mockContainer.classList, 'remove')
35
34
 
36
35
  // Create mock dispose function
37
- mockDispose = vi.fn()
36
+ mockDispose = jest.fn()
38
37
 
39
38
  // Mock editor
40
39
  editor = {
41
40
  sideEffects: {
42
- registerAfterChangeHandler: vi.fn(() => mockDispose),
41
+ registerAfterChangeHandler: jest.fn(() => mockDispose),
43
42
  },
44
- getInstanceState: vi.fn(() => ({ isFocused: false })),
45
- updateInstanceState: vi.fn(),
46
- getContainer: vi.fn(() => mockContainer),
47
- isIn: vi.fn(() => false),
48
- getSelectedShapeIds: vi.fn(() => []),
49
- complete: vi.fn(),
43
+ getInstanceState: jest.fn(() => ({ isFocused: false })),
44
+ updateInstanceState: jest.fn(),
45
+ getContainer: jest.fn(() => mockContainer),
46
+ isIn: jest.fn(() => false),
47
+ getSelectedShapeIds: jest.fn(() => []),
48
+ complete: jest.fn(),
50
49
  } as any
51
50
 
52
51
  // Mock document.body event listeners
53
52
  originalAddEventListener = document.body.addEventListener
54
53
  originalRemoveEventListener = document.body.removeEventListener
55
- document.body.addEventListener = vi.fn()
56
- document.body.removeEventListener = vi.fn()
54
+ document.body.addEventListener = jest.fn()
55
+ document.body.removeEventListener = jest.fn()
57
56
  })
58
57
 
59
58
  afterEach(() => {
@@ -66,7 +65,7 @@ describe('FocusManager', () => {
66
65
  focusManager.dispose()
67
66
  }
68
67
 
69
- vi.clearAllMocks()
68
+ jest.clearAllMocks()
70
69
  })
71
70
 
72
71
  describe('constructor', () => {
@@ -132,7 +131,7 @@ describe('FocusManager', () => {
132
131
  const handler = handlerCall[1]
133
132
 
134
133
  // Clear previous calls
135
- vi.clearAllMocks()
134
+ jest.clearAllMocks()
136
135
 
137
136
  // Simulate focus state change
138
137
  const prev = { isFocused: false }
@@ -150,7 +149,7 @@ describe('FocusManager', () => {
150
149
  const handlerCall = editor.sideEffects.registerAfterChangeHandler.mock.calls[0]
151
150
  const handler = handlerCall[1]
152
151
 
153
- vi.clearAllMocks()
152
+ jest.clearAllMocks()
154
153
 
155
154
  // Simulate no focus state change
156
155
  const prev = { isFocused: true }
@@ -171,7 +170,7 @@ describe('FocusManager', () => {
171
170
  // Get the handler before clearing mocks
172
171
  const handlerCall = editor.sideEffects.registerAfterChangeHandler.mock.calls[0]
173
172
  handler = handlerCall[1]
174
- vi.clearAllMocks()
173
+ jest.clearAllMocks()
175
174
  })
176
175
 
177
176
  it('should add focused class when editor is focused', () => {
@@ -206,11 +205,11 @@ describe('FocusManager', () => {
206
205
  focusManager = new FocusManager(editor)
207
206
 
208
207
  // Get the keydown handler that was registered
209
- const addEventListenerCalls = (document.body.addEventListener as Mock).mock.calls
210
- const keydownCall = addEventListenerCalls.find((call: any) => call[0] === 'keydown')
211
- keydownHandler = keydownCall![1]
208
+ const addEventListenerCalls = (document.body.addEventListener as jest.Mock).mock.calls
209
+ const keydownCall = addEventListenerCalls.find((call) => call[0] === 'keydown')
210
+ keydownHandler = keydownCall[1]
212
211
 
213
- vi.clearAllMocks()
212
+ jest.clearAllMocks()
214
213
  })
215
214
 
216
215
  it('should remove no-focus-ring class on Tab key', () => {
@@ -284,11 +283,11 @@ describe('FocusManager', () => {
284
283
  focusManager = new FocusManager(editor)
285
284
 
286
285
  // Get the mousedown handler that was registered
287
- const addEventListenerCalls = (document.body.addEventListener as Mock).mock.calls
288
- const mousedownCall = addEventListenerCalls.find((call: any) => call[0] === 'mousedown')
289
- mousedownHandler = mousedownCall![1]
286
+ const addEventListenerCalls = (document.body.addEventListener as jest.Mock).mock.calls
287
+ const mousedownCall = addEventListenerCalls.find((call) => call[0] === 'mousedown')
288
+ mousedownHandler = mousedownCall[1]
290
289
 
291
- vi.clearAllMocks()
290
+ jest.clearAllMocks()
292
291
  })
293
292
 
294
293
  it('should add no-focus-ring class on mouse down', () => {
@@ -327,7 +326,7 @@ describe('FocusManager', () => {
327
326
  it('should complete before bluring', () => {
328
327
  const callOrder: string[] = []
329
328
  editor.complete.mockImplementation(() => callOrder.push('complete'))
330
- mockContainer.blur = vi.fn(() => callOrder.push('blur'))
329
+ mockContainer.blur = jest.fn(() => callOrder.push('blur'))
331
330
 
332
331
  focusManager.blur()
333
332
 
@@ -338,7 +337,7 @@ describe('FocusManager', () => {
338
337
  describe('dispose', () => {
339
338
  beforeEach(() => {
340
339
  focusManager = new FocusManager(editor)
341
- vi.clearAllMocks()
340
+ jest.clearAllMocks()
342
341
  })
343
342
 
344
343
  it('should remove keyboard event listener', () => {
@@ -377,7 +376,7 @@ describe('FocusManager', () => {
377
376
  const handlerCall = editor.sideEffects.registerAfterChangeHandler.mock.calls[0]
378
377
  const handler = handlerCall[1]
379
378
 
380
- vi.clearAllMocks()
379
+ jest.clearAllMocks()
381
380
 
382
381
  // Rapid focus changes
383
382
  editor.getInstanceState.mockReturnValue({ isFocused: true })
@@ -395,9 +394,9 @@ describe('FocusManager', () => {
395
394
 
396
395
  it('should handle keyboard navigation while editing', () => {
397
396
  focusManager = new FocusManager(editor)
398
- const addEventListenerCalls = (document.body.addEventListener as Mock).mock.calls
399
- const keydownCall = addEventListenerCalls.find((call: any) => call[0] === 'keydown')
400
- const keydownHandler = keydownCall![1]
397
+ const addEventListenerCalls = (document.body.addEventListener as jest.Mock).mock.calls
398
+ const keydownCall = addEventListenerCalls.find((call) => call[0] === 'keydown')
399
+ const keydownHandler = keydownCall[1]
401
400
 
402
401
  editor.isIn.mockReturnValue(true) // Editing mode
403
402
 
@@ -410,15 +409,15 @@ describe('FocusManager', () => {
410
409
 
411
410
  it('should handle mouse and keyboard interaction sequence', () => {
412
411
  focusManager = new FocusManager(editor)
413
- const addEventListenerCalls = (document.body.addEventListener as Mock).mock.calls
412
+ const addEventListenerCalls = (document.body.addEventListener as jest.Mock).mock.calls
414
413
 
415
- const mousedownCall = addEventListenerCalls.find((call: any) => call[0] === 'mousedown')
416
- const keydownCall = addEventListenerCalls.find((call: any) => call[0] === 'keydown')
414
+ const mousedownCall = addEventListenerCalls.find((call) => call[0] === 'mousedown')
415
+ const keydownCall = addEventListenerCalls.find((call) => call[0] === 'keydown')
417
416
 
418
- const mousedownHandler = mousedownCall![1]
419
- const keydownHandler = keydownCall![1]
417
+ const mousedownHandler = mousedownCall[1]
418
+ const keydownHandler = keydownCall[1]
420
419
 
421
- vi.clearAllMocks()
420
+ jest.clearAllMocks()
422
421
 
423
422
  // Mouse down adds no-focus-ring
424
423
  mousedownHandler()
@@ -1,31 +1,30 @@
1
1
  import { TLShape, TLShapeId, createShapeId } from '@tldraw/tlschema'
2
- import { Mock, Mocked, vi } from 'vitest'
3
2
  import { Editor } from '../../Editor'
4
3
  import { FontManager, TLFontFace } from './FontManager'
5
4
 
6
5
  // Mock the Editor class
7
- vi.mock('../../Editor')
6
+ jest.mock('../../Editor')
8
7
 
9
8
  // Mock globals
10
- global.FontFace = vi.fn().mockImplementation((family, src, descriptors) => ({
9
+ global.FontFace = jest.fn().mockImplementation((family, src, descriptors) => ({
11
10
  family,
12
11
  src,
13
12
  ...descriptors,
14
- load: vi.fn(() => Promise.resolve()),
13
+ load: jest.fn(() => Promise.resolve()),
15
14
  }))
16
15
 
17
16
  Object.defineProperty(global.document, 'fonts', {
18
17
  value: {
19
- add: vi.fn(),
20
- [Symbol.iterator]: vi.fn(() => [].values()),
18
+ add: jest.fn(),
19
+ [Symbol.iterator]: jest.fn(() => [].values()),
21
20
  },
22
21
  configurable: true,
23
22
  })
24
23
 
25
- global.queueMicrotask = vi.fn((fn) => Promise.resolve().then(fn))
24
+ global.queueMicrotask = jest.fn((fn) => Promise.resolve().then(fn))
26
25
 
27
26
  describe('FontManager', () => {
28
- let editor: Mocked<Editor>
27
+ let editor: jest.Mocked<Editor>
29
28
  let fontManager: FontManager
30
29
  let mockAssetUrls: { [key: string]: string }
31
30
 
@@ -51,30 +50,30 @@ describe('FontManager', () => {
51
50
  })
52
51
 
53
52
  beforeEach(() => {
54
- vi.clearAllMocks()
53
+ jest.clearAllMocks()
55
54
 
56
55
  mockAssetUrls = {
57
56
  'test-font.woff2': 'https://example.com/fonts/test-font.woff2',
58
57
  }
59
58
 
60
59
  const mockShapeUtil = {
61
- getFontFaces: vi.fn(() => []),
60
+ getFontFaces: jest.fn(() => []),
62
61
  }
63
62
 
64
63
  const mockStore = {
65
- createComputedCache: vi.fn(() => ({
66
- get: vi.fn(() => []),
64
+ createComputedCache: jest.fn(() => ({
65
+ get: jest.fn(() => []),
67
66
  })),
68
- createCache: vi.fn(() => ({
69
- get: vi.fn(() => ({ get: vi.fn(() => []) })),
67
+ createCache: jest.fn(() => ({
68
+ get: jest.fn(() => ({ get: jest.fn(() => []) })),
70
69
  })),
71
70
  }
72
71
 
73
72
  editor = {
74
73
  store: mockStore,
75
- getShapeUtil: vi.fn(() => mockShapeUtil),
76
- getCurrentPageShapeIds: vi.fn(() => new Set()),
77
- getShape: vi.fn(),
74
+ getShapeUtil: jest.fn(() => mockShapeUtil),
75
+ getCurrentPageShapeIds: jest.fn(() => new Set()),
76
+ getShape: jest.fn(),
78
77
  isDisposed: false,
79
78
  } as any
80
79
 
@@ -128,7 +127,7 @@ describe('FontManager', () => {
128
127
  const shapes = shapeIds.map(createMockShape)
129
128
 
130
129
  editor.getCurrentPageShapeIds.mockReturnValue(new Set(shapeIds))
131
- editor.getShape.mockImplementation((id: any) => shapes.find((s) => s.id === id))
130
+ editor.getShape.mockImplementation((id) => shapes.find((s) => s.id === id))
132
131
 
133
132
  await expect(fontManager.loadRequiredFontsForCurrentPage(3)).resolves.toBeUndefined()
134
133
  })
@@ -151,12 +150,12 @@ describe('FontManager', () => {
151
150
  const font = createMockFont()
152
151
  const error = new Error('Font load failed')
153
152
 
154
- ;(global.FontFace as Mock).mockReturnValue({
153
+ ;(global.FontFace as jest.Mock).mockReturnValue({
155
154
  family: font.family,
156
- load: vi.fn(() => Promise.reject(error)),
155
+ load: jest.fn(() => Promise.reject(error)),
157
156
  })
158
157
 
159
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
158
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation()
160
159
 
161
160
  await fontManager.ensureFontIsLoaded(font)
162
161
 
@@ -199,7 +198,7 @@ describe('FontManager', () => {
199
198
 
200
199
  fontManager.requestFonts(fonts)
201
200
 
202
- const callback = (queueMicrotask as Mock).mock.calls[0][0]
201
+ const callback = (queueMicrotask as jest.Mock).mock.calls[0][0]
203
202
  expect(() => callback()).not.toThrow()
204
203
  })
205
204
  })
@@ -214,7 +213,7 @@ describe('FontManager', () => {
214
213
  src: url("mock-data-url");
215
214
  }`
216
215
 
217
- vi.spyOn(fontManager, 'toEmbeddedCssDeclaration').mockResolvedValue(mockCssDeclaration)
216
+ jest.spyOn(fontManager, 'toEmbeddedCssDeclaration').mockResolvedValue(mockCssDeclaration)
218
217
 
219
218
  const result = await fontManager.toEmbeddedCssDeclaration(font)
220
219
 
@@ -228,7 +227,7 @@ describe('FontManager', () => {
228
227
  const font = createMockFont()
229
228
 
230
229
  // Simple spy to verify the method is called
231
- const spy = vi.spyOn(fontManager, 'toEmbeddedCssDeclaration').mockResolvedValue('mock-css')
230
+ const spy = jest.spyOn(fontManager, 'toEmbeddedCssDeclaration').mockResolvedValue('mock-css')
232
231
 
233
232
  await fontManager.toEmbeddedCssDeclaration(font)
234
233
 
@@ -1,5 +1,4 @@
1
1
  import { BaseRecord, RecordId, Store, StoreSchema, createRecordType } from '@tldraw/store'
2
- import { vi } from 'vitest'
3
2
  import { TLHistoryBatchOptions } from '../../types/history-types'
4
3
  import { HistoryManager } from './HistoryManager'
5
4
 
@@ -490,7 +489,7 @@ describe('HistoryManager constructor and lifecycle', () => {
490
489
  })
491
490
 
492
491
  it('should initialize with optional annotateError callback', () => {
493
- const mockAnnotateError = vi.fn()
492
+ const mockAnnotateError = jest.fn()
494
493
  const manager = new HistoryManager({ store, annotateError: mockAnnotateError })
495
494
  expect(manager).toBeDefined()
496
495
  })
@@ -504,7 +503,7 @@ describe('HistoryManager constructor and lifecycle', () => {
504
503
  })
505
504
 
506
505
  it('should handle errors in batch operations with annotateError', () => {
507
- const mockAnnotateError = vi.fn()
506
+ const mockAnnotateError = jest.fn()
508
507
  const manager = new HistoryManager({ store, annotateError: mockAnnotateError })
509
508
 
510
509
  const errorFn = () => {
@@ -516,7 +515,7 @@ describe('HistoryManager constructor and lifecycle', () => {
516
515
  })
517
516
 
518
517
  it('should handle nested batch error scenarios', () => {
519
- const mockAnnotateError = vi.fn()
518
+ const mockAnnotateError = jest.fn()
520
519
  const manager = new HistoryManager({ store, annotateError: mockAnnotateError })
521
520
 
522
521
  const nestedErrorFn = () => {
@@ -696,7 +695,7 @@ describe('HistoryManager error scenarios and edge cases', () => {
696
695
  describe('squashToMark error handling', () => {
697
696
  it('should handle non-existent mark gracefully', () => {
698
697
  store.update(ids.a, (s) => ({ ...s, value: 1 }))
699
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
698
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation()
700
699
 
701
700
  manager.squashToMark('non-existent-mark')
702
701
 
@@ -708,7 +707,7 @@ describe('HistoryManager error scenarios and edge cases', () => {
708
707
  })
709
708
 
710
709
  it('should handle empty stack when squashing', () => {
711
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
710
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation()
712
711
 
713
712
  manager.squashToMark('non-existent')
714
713
 
@@ -781,7 +780,7 @@ describe('HistoryManager error scenarios and edge cases', () => {
781
780
  })
782
781
 
783
782
  it('should maintain batch state correctly during errors', () => {
784
- const mockAnnotateError = vi.fn()
783
+ const mockAnnotateError = jest.fn()
785
784
  const errorManager = new HistoryManager({ store, annotateError: mockAnnotateError })
786
785
 
787
786
  try {
@@ -1,34 +1,33 @@
1
1
  import { TLScribble } from '@tldraw/tlschema'
2
- import { Mock, Mocked, vi } from 'vitest'
3
2
  import { Editor } from '../../Editor'
4
3
  import { ScribbleItem, ScribbleManager } from './ScribbleManager'
5
4
 
6
5
  // Mock the Editor class
7
- vi.mock('../../Editor')
8
- vi.mock('@tldraw/utils', () => ({
9
- uniqueId: vi.fn(() => 'test-id'),
6
+ jest.mock('../../Editor')
7
+ jest.mock('@tldraw/utils', () => ({
8
+ uniqueId: jest.fn(() => 'test-id'),
10
9
  }))
11
10
 
12
11
  describe('ScribbleManager', () => {
13
- let editor: Mocked<Editor>
12
+ let editor: jest.Mocked<Editor>
14
13
  let scribbleManager: ScribbleManager
15
- let mockUniqueId: Mock
14
+ let mockUniqueId: jest.Mock
16
15
 
17
- beforeEach(async () => {
16
+ beforeEach(() => {
18
17
  editor = {
19
- updateInstanceState: vi.fn(),
20
- run: vi.fn((fn) => fn()),
18
+ updateInstanceState: jest.fn(),
19
+ run: jest.fn((fn) => fn()),
21
20
  } as any
22
21
 
23
- const { uniqueId } = await vi.importMock('@tldraw/utils')
24
- mockUniqueId = uniqueId as Mock
22
+ const { uniqueId } = jest.requireMock('@tldraw/utils')
23
+ mockUniqueId = uniqueId
25
24
  mockUniqueId.mockReturnValue('test-id')
26
25
 
27
26
  scribbleManager = new ScribbleManager(editor)
28
27
  })
29
28
 
30
29
  afterEach(() => {
31
- vi.clearAllMocks()
30
+ jest.clearAllMocks()
32
31
  })
33
32
 
34
33
  describe('constructor and initialization', () => {
@@ -1,12 +1,4 @@
1
- import {
2
- TLFrameShape,
3
- TLGroupShape,
4
- TLPageId,
5
- TLShape,
6
- TLShapeId,
7
- createShapeId,
8
- } from '@tldraw/tlschema'
9
- import { Mocked, vi } from 'vitest'
1
+ import { TLFrameShape, TLGroupShape, TLPageId, TLShapeId, createShapeId } from '@tldraw/tlschema'
10
2
  import { Box } from '../../../primitives/Box'
11
3
  import { Vec } from '../../../primitives/Vec'
12
4
  import { Editor } from '../../Editor'
@@ -15,33 +7,32 @@ import { HandleSnaps } from './HandleSnaps'
15
7
  import { GapsSnapIndicator, PointsSnapIndicator, SnapManager } from './SnapManager'
16
8
 
17
9
  // Mock the Editor class
18
- vi.mock('../../Editor')
19
- vi.mock('./BoundsSnaps')
20
- vi.mock('./HandleSnaps')
10
+ jest.mock('../../Editor')
11
+ jest.mock('./BoundsSnaps')
12
+ jest.mock('./HandleSnaps')
21
13
 
22
14
  describe('SnapManager', () => {
23
- let editor: Mocked<Editor>
15
+ let editor: jest.Mocked<Editor>
24
16
  let snapManager: SnapManager
25
17
 
26
18
  const createMockShape = (
27
19
  id: TLShapeId,
28
20
  type: string = 'geo',
29
21
  parentId: TLShapeId | string = 'page:page'
30
- ) =>
31
- ({
32
- id,
33
- type,
34
- parentId,
35
- x: 0,
36
- y: 0,
37
- rotation: 0,
38
- index: 'a1' as const,
39
- opacity: 1,
40
- isLocked: false,
41
- meta: {},
42
- props: {},
43
- typeName: 'shape' as const,
44
- }) as TLShape
22
+ ) => ({
23
+ id,
24
+ type,
25
+ parentId,
26
+ x: 0,
27
+ y: 0,
28
+ rotation: 0,
29
+ index: 'a1' as const,
30
+ opacity: 1,
31
+ isLocked: false,
32
+ meta: {},
33
+ props: {},
34
+ typeName: 'shape' as const,
35
+ })
45
36
 
46
37
  const createMockFrameShape = (id: TLShapeId): TLFrameShape =>
47
38
  ({
@@ -63,26 +54,26 @@ describe('SnapManager', () => {
63
54
 
64
55
  beforeEach(() => {
65
56
  editor = {
66
- getZoomLevel: vi.fn(() => 1),
67
- getViewportPageBounds: vi.fn(() => new Box(0, 0, 1000, 1000)),
68
- getSelectedShapeIds: vi.fn(() => []),
69
- getSelectedShapes: vi.fn(() => []),
70
- findCommonAncestor: vi.fn(() => createShapeId('page')),
71
- getCurrentPageId: vi.fn(() => 'page:page' as TLPageId),
72
- getSortedChildIdsForParent: vi.fn(() => []),
73
- getShape: vi.fn(),
74
- getShapeUtil: vi.fn(() => ({
75
- canSnap: vi.fn(() => true),
57
+ getZoomLevel: jest.fn(() => 1),
58
+ getViewportPageBounds: jest.fn(() => new Box(0, 0, 1000, 1000)),
59
+ getSelectedShapeIds: jest.fn(() => []),
60
+ getSelectedShapes: jest.fn(() => []),
61
+ findCommonAncestor: jest.fn(() => createShapeId('page')),
62
+ getCurrentPageId: jest.fn(() => 'page:page' as TLPageId),
63
+ getSortedChildIdsForParent: jest.fn(() => []),
64
+ getShape: jest.fn(),
65
+ getShapeUtil: jest.fn(() => ({
66
+ canSnap: jest.fn(() => true),
76
67
  })),
77
- getShapePageBounds: vi.fn(),
78
- isShapeOfType: vi.fn(),
68
+ getShapePageBounds: jest.fn(),
69
+ isShapeOfType: jest.fn(),
79
70
  } as any
80
71
 
81
72
  snapManager = new SnapManager(editor)
82
73
  })
83
74
 
84
75
  afterEach(() => {
85
- vi.clearAllMocks()
76
+ jest.clearAllMocks()
86
77
  })
87
78
 
88
79
  describe('constructor and initialization', () => {
@@ -313,7 +304,7 @@ describe('SnapManager', () => {
313
304
  editor.getSortedChildIdsForParent.mockReturnValue([shapeId])
314
305
  editor.getShape.mockReturnValue(shape as any)
315
306
  editor.getShapeUtil.mockReturnValue({
316
- canSnap: vi.fn(() => false),
307
+ canSnap: jest.fn(() => false),
317
308
  } as any)
318
309
 
319
310
  const result = snapManager.getSnappableShapes()
@@ -338,7 +329,7 @@ describe('SnapManager', () => {
338
329
  const frameShape = createMockFrameShape(frameId)
339
330
 
340
331
  editor.getSortedChildIdsForParent.mockReturnValue([frameId])
341
- editor.getShape.mockReturnValue(frameShape)
332
+ editor.getShape.mockReturnValue(frameShape as any)
342
333
  editor.isShapeOfType.mockImplementation((_shape, type) => type === 'frame')
343
334
  editor.getShapePageBounds.mockReturnValue(new Box(10, 10, 50, 50))
344
335
 
@@ -357,12 +348,14 @@ describe('SnapManager', () => {
357
348
  .mockReturnValueOnce([childId]) // Inside group
358
349
 
359
350
  editor.getShape.mockImplementation((id) => {
360
- if (id === groupId) return groupShape
361
- if (id === childId) return childShape
351
+ if (id === groupId) return groupShape as any
352
+ if (id === childId) return childShape as any
362
353
  return undefined
363
354
  })
364
355
 
365
- editor.isShapeOfType.mockImplementation((shape: any, type) => shape && shape.type === type)
356
+ editor.isShapeOfType.mockImplementation(
357
+ (shape, type) => shape && (shape as any).type === type
358
+ )
366
359
 
367
360
  editor.getShapePageBounds.mockReturnValue(new Box(10, 10, 50, 50))
368
361
 
@@ -379,26 +372,26 @@ describe('SnapManager', () => {
379
372
 
380
373
  // Override the getCurrentCommonAncestor mock for this specific test
381
374
  const originalGetCurrentCommonAncestor = snapManager.getCurrentCommonAncestor
382
- vi.spyOn(snapManager, 'getCurrentCommonAncestor').mockReturnValue(parentFrameId)
375
+ jest.spyOn(snapManager, 'getCurrentCommonAncestor').mockReturnValue(parentFrameId)
383
376
 
384
377
  editor.getSortedChildIdsForParent.mockReturnValueOnce([childFrameId]) // Children of parent frame
385
378
 
386
- editor.getShape.mockImplementation((id: any) => {
379
+ editor.getShape.mockImplementation((id) => {
387
380
  if (id === parentFrameId) return parentFrame as any
388
381
  if (id === childFrameId) return childFrame as any
389
382
  return undefined
390
383
  })
391
384
 
392
- editor.isShapeOfType.mockImplementation((shape: any, type: any) => type === 'frame')
385
+ editor.isShapeOfType.mockImplementation((shape, type) => type === 'frame')
393
386
  editor.getShapePageBounds.mockReturnValue(new Box(10, 10, 50, 50))
394
387
 
395
388
  const result = snapManager.getSnappableShapes()
396
389
  expect(result.has(childFrameId)).toBe(true)
397
390
 
398
391
  // Restore original method
399
- vi.spyOn(snapManager, 'getCurrentCommonAncestor').mockImplementation(
400
- originalGetCurrentCommonAncestor
401
- )
392
+ jest
393
+ .spyOn(snapManager, 'getCurrentCommonAncestor')
394
+ .mockImplementation(originalGetCurrentCommonAncestor)
402
395
  })
403
396
 
404
397
  it('should handle missing shape bounds gracefully', () => {
@@ -429,7 +422,7 @@ describe('SnapManager', () => {
429
422
 
430
423
  // Override the getCurrentCommonAncestor mock for this specific test
431
424
  const originalGetCurrentCommonAncestor = snapManager.getCurrentCommonAncestor
432
- vi.spyOn(snapManager, 'getCurrentCommonAncestor').mockReturnValue(undefined)
425
+ jest.spyOn(snapManager, 'getCurrentCommonAncestor').mockReturnValue(undefined)
433
426
 
434
427
  editor.getCurrentPageId.mockReturnValue('page:current' as TLPageId)
435
428
  editor.getSortedChildIdsForParent.mockReturnValue([shapeId])
@@ -440,9 +433,9 @@ describe('SnapManager', () => {
440
433
  expect(editor.getSortedChildIdsForParent).toHaveBeenCalledWith('page:current')
441
434
 
442
435
  // Restore original method
443
- vi.spyOn(snapManager, 'getCurrentCommonAncestor').mockImplementation(
444
- originalGetCurrentCommonAncestor
445
- )
436
+ jest
437
+ .spyOn(snapManager, 'getCurrentCommonAncestor')
438
+ .mockImplementation(originalGetCurrentCommonAncestor)
446
439
  })
447
440
  })
448
441
 
@@ -477,7 +470,7 @@ describe('SnapManager', () => {
477
470
 
478
471
  // Test with second set of shapes
479
472
  editor.getSortedChildIdsForParent.mockReturnValue([shapeId1, shapeId2])
480
- editor.getShape.mockImplementation((id: any) => {
473
+ editor.getShape.mockImplementation((id) => {
481
474
  if (id === shapeId1) return createMockShape(shapeId1) as any
482
475
  if (id === shapeId2) return createMockShape(shapeId2) as any
483
476
  return undefined