@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,21 +1,17 @@
1
- import { vi } from 'vitest'
2
1
  import { Editor } from '../../Editor'
3
2
  import { TextManager, TLMeasureTextSpanOpts } from './TextManager'
4
3
 
5
4
  // Create a simple mock DOM environment
6
5
  const mockElement = {
7
- classList: { add: vi.fn() },
6
+ classList: { add: jest.fn() },
8
7
  tabIndex: -1,
9
- cloneNode: vi.fn(),
8
+ cloneNode: jest.fn(),
10
9
  innerHTML: '',
11
10
  textContent: '',
12
- setAttribute: vi.fn(),
13
- style: {
14
- setProperty: vi.fn(),
15
- getPropertyValue: vi.fn(() => ''),
16
- },
11
+ setAttribute: jest.fn(),
12
+ style: { setProperty: jest.fn() },
17
13
  scrollWidth: 100,
18
- getBoundingClientRect: vi.fn(() => ({
14
+ getBoundingClientRect: jest.fn(() => ({
19
15
  width: 100,
20
16
  height: 20,
21
17
  left: 0,
@@ -23,44 +19,22 @@ const mockElement = {
23
19
  right: 100,
24
20
  bottom: 20,
25
21
  })),
26
- remove: vi.fn(),
27
- insertAdjacentElement: vi.fn(),
22
+ remove: jest.fn(),
23
+ insertAdjacentElement: jest.fn(),
28
24
  childNodes: [],
29
25
  }
30
26
 
31
27
  // Mock document.createElement to return our mock element
32
- const mockCreateElement = vi.fn(() => {
28
+ const mockCreateElement = jest.fn(() => {
33
29
  const element = { ...mockElement }
34
- element.cloneNode = vi.fn(() => ({ ...element }))
35
-
36
- // Make textContent and innerHTML reactive like real DOM elements
37
- let _textContent = ''
38
- let _innerHTML = ''
39
-
40
- Object.defineProperty(element, 'textContent', {
41
- get: () => _textContent,
42
- set: (value) => {
43
- _textContent = value || ''
44
- // When textContent is set, innerHTML should be the escaped version
45
- _innerHTML = _textContent
46
- },
47
- })
48
-
49
- Object.defineProperty(element, 'innerHTML', {
50
- get: () => _innerHTML,
51
- set: (value) => {
52
- _innerHTML = value || ''
53
- _textContent = _innerHTML // Simple approximation
54
- },
55
- })
56
-
30
+ element.cloneNode = jest.fn(() => ({ ...element }))
57
31
  return element
58
32
  })
59
33
 
60
34
  // Mock editor
61
35
  const mockEditor = {
62
- getContainer: vi.fn(() => ({
63
- appendChild: vi.fn(),
36
+ getContainer: jest.fn(() => ({
37
+ appendChild: jest.fn(),
64
38
  })),
65
39
  } as unknown as Editor
66
40
 
@@ -69,10 +43,10 @@ global.document = {
69
43
  createElement: mockCreateElement,
70
44
  } as any
71
45
 
72
- global.Range = vi.fn(() => ({
73
- setStart: vi.fn(),
74
- setEnd: vi.fn(),
75
- getClientRects: vi.fn(() => [
46
+ global.Range = jest.fn(() => ({
47
+ setStart: jest.fn(),
48
+ setEnd: jest.fn(),
49
+ getClientRects: jest.fn(() => [
76
50
  {
77
51
  width: 10,
78
52
  height: 16,
@@ -88,7 +62,7 @@ describe('TextManager', () => {
88
62
  let textManager: TextManager
89
63
 
90
64
  beforeEach(() => {
91
- vi.clearAllMocks()
65
+ jest.clearAllMocks()
92
66
  textManager = new TextManager(mockEditor)
93
67
  })
94
68
 
@@ -112,13 +86,13 @@ describe('TextManager', () => {
112
86
  }
113
87
 
114
88
  it('should call measureHtml with normalized text', () => {
115
- const spy = vi.spyOn(textManager, 'measureHtml')
89
+ const spy = jest.spyOn(textManager, 'measureHtml')
116
90
  textManager.measureText('Hello World', defaultOpts)
117
91
  expect(spy).toHaveBeenCalledWith('Hello World', defaultOpts)
118
92
  })
119
93
 
120
94
  it('should normalize line breaks', () => {
121
- const spy = vi.spyOn(textManager, 'measureHtml')
95
+ const spy = jest.spyOn(textManager, 'measureHtml')
122
96
  textManager.measureText('Hello\nWorld\r\nTest', defaultOpts)
123
97
  // The text should be normalized to use consistent line breaks
124
98
  expect(spy).toHaveBeenCalled()
@@ -273,7 +247,7 @@ describe('TextManager', () => {
273
247
 
274
248
  it('should return array of text spans for non-empty text', () => {
275
249
  // Mock measureElementTextNodeSpans to return some spans
276
- vi.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
250
+ jest.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
277
251
  spans: [
278
252
  {
279
253
  text: 'Hello World',
@@ -292,7 +266,7 @@ describe('TextManager', () => {
292
266
  })
293
267
 
294
268
  it('should handle wrap overflow', () => {
295
- vi.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
269
+ jest.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
296
270
  spans: [
297
271
  {
298
272
  text: 'Hello World',
@@ -310,7 +284,8 @@ describe('TextManager', () => {
310
284
 
311
285
  it('should handle truncate-ellipsis overflow', () => {
312
286
  // Mock the calls for ellipsis handling
313
- vi.spyOn(textManager, 'measureElementTextNodeSpans')
287
+ jest
288
+ .spyOn(textManager, 'measureElementTextNodeSpans')
314
289
  .mockReturnValueOnce({
315
290
  spans: [
316
291
  {
@@ -346,7 +321,7 @@ describe('TextManager', () => {
346
321
  })
347
322
 
348
323
  it('should handle truncate-clip overflow', () => {
349
- vi.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
324
+ jest.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
350
325
  spans: [
351
326
  {
352
327
  text: 'Hello Wo',
@@ -363,7 +338,7 @@ describe('TextManager', () => {
363
338
  })
364
339
 
365
340
  it('should handle different text alignments', () => {
366
- vi.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
341
+ jest.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
367
342
  spans: [
368
343
  {
369
344
  text: 'Test',
@@ -383,7 +358,7 @@ describe('TextManager', () => {
383
358
  })
384
359
 
385
360
  it('should handle custom font properties', () => {
386
- vi.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
361
+ jest.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
387
362
  spans: [
388
363
  {
389
364
  text: 'Test',
@@ -407,7 +382,7 @@ describe('TextManager', () => {
407
382
  })
408
383
 
409
384
  it('should handle other styles', () => {
410
- vi.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
385
+ jest.spyOn(textManager, 'measureElementTextNodeSpans').mockReturnValue({
411
386
  spans: [
412
387
  {
413
388
  text: 'Test',
@@ -1,29 +1,28 @@
1
- import { Mock, Mocked, vi } from 'vitest'
2
1
  import { Vec } from '../../../primitives/Vec'
3
2
  import { Editor } from '../../Editor'
4
3
  import { TickManager } from './TickManager'
5
4
 
6
5
  // Mock the Editor class
7
- vi.mock('../../Editor')
6
+ jest.mock('../../Editor')
8
7
 
9
8
  // Mock Date.now to control time
10
- const mockDateNow = vi.fn()
9
+ const mockDateNow = jest.fn()
11
10
  Date.now = mockDateNow
12
11
 
13
12
  // Mock requestAnimationFrame and cancelAnimationFrame
14
- const mockRequestAnimationFrame = vi.fn()
15
- const mockCancelAnimationFrame = vi.fn()
13
+ const mockRequestAnimationFrame = jest.fn()
14
+ const mockCancelAnimationFrame = jest.fn()
16
15
  global.requestAnimationFrame = mockRequestAnimationFrame
17
16
  global.cancelAnimationFrame = mockCancelAnimationFrame
18
17
 
19
18
  describe('TickManager', () => {
20
- let editor: Mocked<Editor>
19
+ let editor: jest.Mocked<Editor>
21
20
  let tickManager: TickManager
22
- let mockEmit: Mock
23
- let mockDisposablesAdd: Mock
21
+ let mockEmit: jest.Mock
22
+ let mockDisposablesAdd: jest.Mock
24
23
 
25
24
  beforeEach(() => {
26
- vi.clearAllMocks()
25
+ jest.clearAllMocks()
27
26
 
28
27
  // Reset time
29
28
  mockDateNow.mockReturnValue(1000)
@@ -38,8 +37,8 @@ describe('TickManager', () => {
38
37
 
39
38
  mockCancelAnimationFrame.mockImplementation(() => {})
40
39
 
41
- mockEmit = vi.fn()
42
- mockDisposablesAdd = vi.fn()
40
+ mockEmit = jest.fn()
41
+ mockDisposablesAdd = jest.fn()
43
42
 
44
43
  editor = {
45
44
  emit: mockEmit,
@@ -91,7 +90,7 @@ describe('TickManager', () => {
91
90
  })
92
91
 
93
92
  it('should cancel existing RAF before starting new one', () => {
94
- const mockCancel = vi.fn()
93
+ const mockCancel = jest.fn()
95
94
  tickManager.cancelRaf = mockCancel
96
95
 
97
96
  tickManager.start()
@@ -144,7 +143,7 @@ describe('TickManager', () => {
144
143
  })
145
144
 
146
145
  it('should update pointer velocity', () => {
147
- const updatePointerVelocitySpy = vi.spyOn(tickManager as any, 'updatePointerVelocity')
146
+ const updatePointerVelocitySpy = jest.spyOn(tickManager as any, 'updatePointerVelocity')
148
147
  tickManager.now = 1000
149
148
  mockDateNow.mockReturnValue(1016)
150
149
 
@@ -177,7 +176,7 @@ describe('TickManager', () => {
177
176
  })
178
177
 
179
178
  it('should cancel RAF if exists', () => {
180
- const mockCancel = vi.fn()
179
+ const mockCancel = jest.fn()
181
180
  tickManager.cancelRaf = mockCancel
182
181
 
183
182
  tickManager.dispose()
@@ -1,15 +1,17 @@
1
1
  import { atom } from '@tldraw/state'
2
- import { Mocked, vi } from 'vitest'
3
2
  import { TLUserPreferences, defaultUserPreferences } from '../../../config/TLUserPreferences'
4
3
  import { TLUser } from '../../../config/createTLUser'
5
4
  import { UserPreferencesManager } from './UserPreferencesManager'
6
5
 
7
6
  // Mock window.matchMedia
8
- const mockMatchMedia = vi.fn()
9
- window.matchMedia = mockMatchMedia
7
+ const mockMatchMedia = jest.fn()
8
+ Object.defineProperty(window, 'matchMedia', {
9
+ writable: true,
10
+ value: mockMatchMedia,
11
+ })
10
12
 
11
13
  describe('UserPreferencesManager', () => {
12
- let mockUser: Mocked<TLUser>
14
+ let mockUser: jest.Mocked<TLUser>
13
15
  let mockUserPreferences: TLUserPreferences
14
16
  let userPreferencesAtom: any
15
17
  let userPreferencesManager: UserPreferencesManager
@@ -22,8 +24,6 @@ describe('UserPreferencesManager', () => {
22
24
  color: '#FF802B',
23
25
  locale: 'en',
24
26
  animationSpeed: 1,
25
- areKeyboardShortcutsEnabled: true,
26
- showUiLabels: false,
27
27
  edgeScrollSpeed: 1,
28
28
  colorScheme: 'light',
29
29
  isSnapMode: false,
@@ -34,14 +34,14 @@ describe('UserPreferencesManager', () => {
34
34
  })
35
35
 
36
36
  beforeEach(() => {
37
- vi.clearAllMocks()
37
+ jest.clearAllMocks()
38
38
 
39
39
  mockUserPreferences = createMockUserPreferences()
40
40
  userPreferencesAtom = atom('userPreferences', mockUserPreferences)
41
41
 
42
42
  mockUser = {
43
43
  userPreferences: userPreferencesAtom,
44
- setUserPreferences: vi.fn((prefs) => {
44
+ setUserPreferences: jest.fn((prefs) => {
45
45
  userPreferencesAtom.set(prefs)
46
46
  }),
47
47
  }
@@ -49,8 +49,8 @@ describe('UserPreferencesManager', () => {
49
49
  // Default matchMedia mock - no dark mode preference
50
50
  mockMatchMedia.mockReturnValue({
51
51
  matches: false,
52
- addEventListener: vi.fn(),
53
- removeEventListener: vi.fn(),
52
+ addEventListener: jest.fn(),
53
+ removeEventListener: jest.fn(),
54
54
  })
55
55
  })
56
56
 
@@ -64,14 +64,17 @@ describe('UserPreferencesManager', () => {
64
64
  expect(userPreferencesManager.systemColorScheme.get()).toBe('light')
65
65
 
66
66
  // Restore matchMedia
67
- window.matchMedia = mockMatchMedia
67
+ Object.defineProperty(window, 'matchMedia', {
68
+ writable: true,
69
+ value: mockMatchMedia,
70
+ })
68
71
  })
69
72
 
70
73
  it('should initialize with light system color scheme when dark mode not preferred', () => {
71
74
  mockMatchMedia.mockReturnValue({
72
75
  matches: false,
73
- addEventListener: vi.fn(),
74
- removeEventListener: vi.fn(),
76
+ addEventListener: jest.fn(),
77
+ removeEventListener: jest.fn(),
75
78
  })
76
79
 
77
80
  userPreferencesManager = new UserPreferencesManager(mockUser, false)
@@ -82,8 +85,8 @@ describe('UserPreferencesManager', () => {
82
85
  it('should initialize with dark system color scheme when dark mode preferred', () => {
83
86
  mockMatchMedia.mockReturnValue({
84
87
  matches: true,
85
- addEventListener: vi.fn(),
86
- removeEventListener: vi.fn(),
88
+ addEventListener: jest.fn(),
89
+ removeEventListener: jest.fn(),
87
90
  })
88
91
 
89
92
  userPreferencesManager = new UserPreferencesManager(mockUser, false)
@@ -92,8 +95,8 @@ describe('UserPreferencesManager', () => {
92
95
  })
93
96
 
94
97
  it('should set up media query listener for color scheme changes', () => {
95
- const mockAddEventListener = vi.fn()
96
- const mockRemoveEventListener = vi.fn()
98
+ const mockAddEventListener = jest.fn()
99
+ const mockRemoveEventListener = jest.fn()
97
100
 
98
101
  mockMatchMedia.mockReturnValue({
99
102
  matches: false,
@@ -107,7 +110,7 @@ describe('UserPreferencesManager', () => {
107
110
  })
108
111
 
109
112
  it('should handle media query change events', () => {
110
- const mockAddEventListener = vi.fn()
113
+ const mockAddEventListener = jest.fn()
111
114
  let changeHandler: (e: MediaQueryListEvent) => void
112
115
 
113
116
  mockMatchMedia.mockReturnValue({
@@ -118,7 +121,7 @@ describe('UserPreferencesManager', () => {
118
121
  }
119
122
  mockAddEventListener(event, handler)
120
123
  },
121
- removeEventListener: vi.fn(),
124
+ removeEventListener: jest.fn(),
122
125
  })
123
126
 
124
127
  userPreferencesManager = new UserPreferencesManager(mockUser, false)
@@ -148,11 +151,11 @@ describe('UserPreferencesManager', () => {
148
151
 
149
152
  describe('dispose', () => {
150
153
  it('should remove media query listener on dispose', () => {
151
- const mockRemoveEventListener = vi.fn()
154
+ const mockRemoveEventListener = jest.fn()
152
155
 
153
156
  mockMatchMedia.mockReturnValue({
154
157
  matches: false,
155
- addEventListener: vi.fn(),
158
+ addEventListener: jest.fn(),
156
159
  removeEventListener: mockRemoveEventListener,
157
160
  })
158
161
 
@@ -165,8 +168,8 @@ describe('UserPreferencesManager', () => {
165
168
  it('should call all disposables', () => {
166
169
  userPreferencesManager = new UserPreferencesManager(mockUser, false)
167
170
 
168
- const mockDisposable1 = vi.fn()
169
- const mockDisposable2 = vi.fn()
171
+ const mockDisposable1 = jest.fn()
172
+ const mockDisposable2 = jest.fn()
170
173
 
171
174
  userPreferencesManager.disposables.add(mockDisposable1)
172
175
  userPreferencesManager.disposables.add(mockDisposable2)
@@ -226,8 +229,6 @@ describe('UserPreferencesManager', () => {
226
229
  locale: mockUserPreferences.locale,
227
230
  color: mockUserPreferences.color,
228
231
  animationSpeed: mockUserPreferences.animationSpeed,
229
- areKeyboardShortcutsEnabled: mockUserPreferences.areKeyboardShortcutsEnabled,
230
- showUiLabels: mockUserPreferences.showUiLabels,
231
232
  isSnapMode: mockUserPreferences.isSnapMode,
232
233
  colorScheme: mockUserPreferences.colorScheme,
233
234
  isDarkMode: false, // light mode
@@ -361,32 +362,6 @@ describe('UserPreferencesManager', () => {
361
362
  })
362
363
  })
363
364
 
364
- describe('getAreKeyboardShortcutsEnabled', () => {
365
- it('should return user keyboard shortcuts', () => {
366
- expect(userPreferencesManager.getAreKeyboardShortcutsEnabled()).toBe(
367
- mockUserPreferences.areKeyboardShortcutsEnabled
368
- )
369
- })
370
-
371
- it('should return default keyboard shortcuts when null', () => {
372
- userPreferencesAtom.set({ ...mockUserPreferences, areKeyboardShortcutsEnabled: null })
373
- expect(userPreferencesManager.getAreKeyboardShortcutsEnabled()).toBe(
374
- defaultUserPreferences.areKeyboardShortcutsEnabled
375
- )
376
- })
377
- })
378
-
379
- describe('getShowUiLabels', () => {
380
- it('should return user show ui labels setting', () => {
381
- expect(userPreferencesManager.getShowUiLabels()).toBe(mockUserPreferences.showUiLabels)
382
- })
383
-
384
- it('should return default show ui labels when null', () => {
385
- userPreferencesAtom.set({ ...mockUserPreferences, showUiLabels: null })
386
- expect(userPreferencesManager.getShowUiLabels()).toBe(defaultUserPreferences.showUiLabels)
387
- })
388
- })
389
-
390
365
  describe('getEdgeScrollSpeed', () => {
391
366
  it('should return user edge scroll speed', () => {
392
367
  expect(userPreferencesManager.getEdgeScrollSpeed()).toBe(
@@ -508,7 +483,6 @@ describe('UserPreferencesManager', () => {
508
483
  color: null,
509
484
  locale: null,
510
485
  animationSpeed: null,
511
- areKeyboardShortcutsEnabled: null,
512
486
  edgeScrollSpeed: null,
513
487
  isSnapMode: null,
514
488
  isWrapMode: null,
@@ -522,9 +496,6 @@ describe('UserPreferencesManager', () => {
522
496
  expect(userPreferencesManager.getColor()).toBe(defaultUserPreferences.color)
523
497
  expect(userPreferencesManager.getLocale()).toBe(defaultUserPreferences.locale)
524
498
  expect(userPreferencesManager.getAnimationSpeed()).toBe(defaultUserPreferences.animationSpeed)
525
- expect(userPreferencesManager.getAreKeyboardShortcutsEnabled()).toBe(
526
- defaultUserPreferences.areKeyboardShortcutsEnabled
527
- )
528
499
  expect(userPreferencesManager.getEdgeScrollSpeed()).toBe(
529
500
  defaultUserPreferences.edgeScrollSpeed
530
501
  )
@@ -13,7 +13,7 @@ export class UserPreferencesManager {
13
13
  private readonly user: TLUser,
14
14
  private readonly inferDarkMode: boolean
15
15
  ) {
16
- if (typeof window === 'undefined' || !window.matchMedia) return
16
+ if (typeof window === 'undefined' || !('matchMedia' in window)) return
17
17
 
18
18
  const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
19
19
  if (darkModeMediaQuery?.matches) {
@@ -43,13 +43,11 @@ export class UserPreferencesManager {
43
43
  locale: this.getLocale(),
44
44
  color: this.getColor(),
45
45
  animationSpeed: this.getAnimationSpeed(),
46
- areKeyboardShortcutsEnabled: this.getAreKeyboardShortcutsEnabled(),
47
46
  isSnapMode: this.getIsSnapMode(),
48
47
  colorScheme: this.user.userPreferences.get().colorScheme,
49
48
  isDarkMode: this.getIsDarkMode(),
50
49
  isWrapMode: this.getIsWrapMode(),
51
50
  isDynamicResizeMode: this.getIsDynamicResizeMode(),
52
- showUiLabels: this.getShowUiLabels(),
53
51
  }
54
52
  }
55
53
 
@@ -77,13 +75,6 @@ export class UserPreferencesManager {
77
75
  return this.user.userPreferences.get().animationSpeed ?? defaultUserPreferences.animationSpeed
78
76
  }
79
77
 
80
- @computed getAreKeyboardShortcutsEnabled() {
81
- return (
82
- this.user.userPreferences.get().areKeyboardShortcutsEnabled ??
83
- defaultUserPreferences.areKeyboardShortcutsEnabled
84
- )
85
- }
86
-
87
78
  @computed getId() {
88
79
  return this.user.userPreferences.get().id
89
80
  }
@@ -120,8 +111,4 @@ export class UserPreferencesManager {
120
111
  defaultUserPreferences.isPasteAtCursorMode
121
112
  )
122
113
  }
123
-
124
- @computed getShowUiLabels() {
125
- return this.user.userPreferences.get().showUiLabels ?? defaultUserPreferences.showUiLabels
126
- }
127
114
  }
@@ -584,15 +584,6 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
584
584
  */
585
585
  onResizeEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void
586
586
 
587
- /**
588
- * A callback called when a shape resize is cancelled.
589
- *
590
- * @param initial - The shape at the start of the resize.
591
- * @param current - The current shape.
592
- * @public
593
- */
594
- onResizeCancel?(initial: Shape, current: Shape): void
595
-
596
587
  /**
597
588
  * A callback called when a shape starts being translated.
598
589
  *
@@ -622,25 +613,6 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
622
613
  */
623
614
  onTranslateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void
624
615
 
625
- /**
626
- * A callback called when a shape translation is cancelled.
627
- *
628
- * @param initial - The shape at the start of the translation.
629
- * @param current - The current shape.
630
- * @public
631
- */
632
- onTranslateCancel?(initial: Shape, current: Shape): void
633
-
634
- /**
635
- * A callback called when a shape's handle starts being dragged.
636
- *
637
- * @param shape - The shape.
638
- * @param info - An object containing the handle and whether the handle is 'precise' or not.
639
- * @returns A change to apply to the shape, or void.
640
- * @public
641
- */
642
- onHandleDragStart?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void
643
-
644
616
  /**
645
617
  * A callback called when a shape's handle changes.
646
618
  *
@@ -651,25 +623,6 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
651
623
  */
652
624
  onHandleDrag?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void
653
625
 
654
- /**
655
- * A callback called when a shape's handle finishes being dragged.
656
- *
657
- * @param current - The current shape.
658
- * @param info - An object containing the handle and whether the handle is 'precise' or not.
659
- * @returns A change to apply to the shape, or void.
660
- * @public
661
- */
662
- onHandleDragEnd?(current: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void
663
-
664
- /**
665
- * A callback called when a shape's handle drag is cancelled.
666
- *
667
- * @param current - The current shape.
668
- * @param info - An object containing the handle and whether the handle is 'precise' or not.
669
- * @public
670
- */
671
- onHandleDragCancel?(current: Shape, info: TLHandleDragInfo<Shape>): void
672
-
673
626
  /**
674
627
  * A callback called when a shape starts being rotated.
675
628
  *
@@ -699,15 +652,6 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
699
652
  */
700
653
  onRotateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void
701
654
 
702
- /**
703
- * A callback called when a shape rotation is cancelled.
704
- *
705
- * @param initial - The shape at the start of the rotation.
706
- * @param current - The current shape.
707
- * @public
708
- */
709
- onRotateCancel?(initial: Shape, current: Shape): void
710
-
711
655
  /**
712
656
  * Not currently used.
713
657
  *
@@ -875,6 +819,5 @@ export interface TLResizeInfo<T extends TLShape> {
875
819
  export interface TLHandleDragInfo<T extends TLShape> {
876
820
  handle: TLHandle
877
821
  isPrecise: boolean
878
- isCreatingShape: boolean
879
822
  initial?: T | undefined
880
823
  }
@@ -62,7 +62,7 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
62
62
 
63
63
  this.parent = parent ?? ({} as any)
64
64
 
65
- if (parent) {
65
+ if (this.parent) {
66
66
  if (children && initial) {
67
67
  this.type = 'branch'
68
68
  this.initial = initial
@@ -238,32 +238,6 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
238
238
  this._currentToolIdMask.set(id)
239
239
  }
240
240
 
241
- /**
242
- * Add a child node to this state node.
243
- *
244
- * @public
245
- */
246
- addChild(childConstructor: TLStateNodeConstructor): this {
247
- if (this.type === 'leaf') {
248
- throw new Error('StateNode.addChild: cannot add child to a leaf node')
249
- }
250
-
251
- // Initialize children if it's undefined (for root nodes without static children)
252
- if (!this.children) {
253
- this.children = {}
254
- }
255
-
256
- const child = new childConstructor(this.editor, this)
257
-
258
- // Check if a child with this ID already exists
259
- if (this.children[child.id]) {
260
- throw new Error(`StateNode.addChild: a child with id '${child.id}' already exists`)
261
- }
262
-
263
- this.children[child.id] = child
264
- return this
265
- }
266
-
267
241
  onWheel?(info: TLWheelEventInfo): void
268
242
  onPointerDown?(info: TLPointerEventInfo): void
269
243
  onPointerMove?(info: TLPointerEventInfo): void