@tldraw/editor 3.14.0-canary.d926f92ca8d6 → 3.14.0-canary.db789786fb06

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 (237) hide show
  1. package/dist-cjs/index.d.ts +212 -117
  2. package/dist-cjs/index.js +11 -8
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/config/TLSessionStateSnapshot.js +1 -12
  5. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +3 -3
  6. package/dist-cjs/lib/editor/Editor.js +131 -99
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
  9. package/dist-cjs/lib/editor/derivations/bindingsIndex.js +22 -22
  10. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  11. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +16 -16
  12. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  13. package/dist-cjs/lib/editor/managers/{ClickManager.js → ClickManager/ClickManager.js} +1 -1
  14. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +7 -0
  15. package/dist-cjs/lib/editor/managers/{EdgeScrollManager.js → EdgeScrollManager/EdgeScrollManager.js} +2 -2
  16. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +7 -0
  17. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +7 -0
  18. package/dist-cjs/lib/editor/managers/{FontManager.js → FontManager/FontManager.js} +4 -1
  19. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +7 -0
  20. package/dist-cjs/lib/editor/managers/{HistoryManager.js → HistoryManager/HistoryManager.js} +67 -7
  21. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +7 -0
  22. package/dist-cjs/lib/editor/managers/{ScribbleManager.js → ScribbleManager/ScribbleManager.js} +1 -1
  23. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +7 -0
  24. package/dist-cjs/lib/editor/managers/{TextManager.js → TextManager/TextManager.js} +73 -42
  25. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +7 -0
  26. package/dist-cjs/lib/editor/managers/{TickManager.js → TickManager/TickManager.js} +1 -1
  27. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +7 -0
  28. package/dist-cjs/lib/editor/managers/{UserPreferencesManager.js → UserPreferencesManager/UserPreferencesManager.js} +1 -1
  29. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +7 -0
  30. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +0 -10
  31. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
  33. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +1 -1
  34. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +10 -6
  35. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +3 -3
  36. package/dist-cjs/lib/editor/tools/StateNode.js +3 -3
  37. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  38. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  39. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  40. package/dist-cjs/lib/exports/getSvgJsx.js.map +1 -1
  41. package/dist-cjs/lib/hooks/useCanvasEvents.js +1 -2
  42. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  43. package/dist-cjs/lib/primitives/Box.js +33 -33
  44. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  45. package/dist-cjs/lib/primitives/Vec.js +13 -8
  46. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  47. package/dist-cjs/lib/primitives/geometry/Arc2d.js +41 -21
  48. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  49. package/dist-cjs/lib/primitives/geometry/Circle2d.js +11 -11
  50. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  51. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +13 -16
  52. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  53. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js +4 -4
  54. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
  55. package/dist-cjs/lib/primitives/geometry/Edge2d.js +14 -17
  56. package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
  57. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +10 -10
  58. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  59. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +6 -2
  60. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  61. package/dist-cjs/lib/primitives/geometry/Point2d.js +6 -6
  62. package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
  63. package/dist-cjs/lib/primitives/geometry/Polygon2d.js +3 -0
  64. package/dist-cjs/lib/primitives/geometry/Polygon2d.js.map +2 -2
  65. package/dist-cjs/lib/primitives/geometry/Polyline2d.js +8 -5
  66. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  67. package/dist-cjs/lib/primitives/geometry/Rectangle2d.js +22 -11
  68. package/dist-cjs/lib/primitives/geometry/Rectangle2d.js.map +2 -2
  69. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +22 -22
  70. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  71. package/dist-cjs/lib/utils/reorderShapes.js +11 -10
  72. package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
  73. package/dist-cjs/lib/utils/reparenting.js +232 -0
  74. package/dist-cjs/lib/utils/reparenting.js.map +7 -0
  75. package/dist-cjs/lib/utils/richText.js +7 -2
  76. package/dist-cjs/lib/utils/richText.js.map +2 -2
  77. package/dist-cjs/version.js +3 -3
  78. package/dist-cjs/version.js.map +1 -1
  79. package/dist-esm/index.d.mts +212 -117
  80. package/dist-esm/index.mjs +15 -8
  81. package/dist-esm/index.mjs.map +2 -2
  82. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +1 -1
  83. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  84. package/dist-esm/lib/editor/Editor.mjs +131 -99
  85. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  86. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
  87. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +22 -22
  88. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  89. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +16 -16
  90. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  91. package/dist-esm/lib/editor/managers/{ClickManager.mjs → ClickManager/ClickManager.mjs} +1 -1
  92. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +7 -0
  93. package/dist-esm/lib/editor/managers/{EdgeScrollManager.mjs → EdgeScrollManager/EdgeScrollManager.mjs} +2 -2
  94. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +7 -0
  95. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +7 -0
  96. package/dist-esm/lib/editor/managers/{FontManager.mjs → FontManager/FontManager.mjs} +4 -1
  97. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +7 -0
  98. package/dist-esm/lib/editor/managers/{HistoryManager.mjs → HistoryManager/HistoryManager.mjs} +63 -3
  99. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +7 -0
  100. package/dist-esm/lib/editor/managers/{ScribbleManager.mjs → ScribbleManager/ScribbleManager.mjs} +1 -1
  101. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +7 -0
  102. package/dist-esm/lib/editor/managers/{TextManager.mjs → TextManager/TextManager.mjs} +73 -42
  103. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +7 -0
  104. package/dist-esm/lib/editor/managers/{TickManager.mjs → TickManager/TickManager.mjs} +1 -1
  105. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +7 -0
  106. package/dist-esm/lib/editor/managers/{UserPreferencesManager.mjs → UserPreferencesManager/UserPreferencesManager.mjs} +1 -1
  107. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +7 -0
  108. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +0 -10
  109. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  110. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
  111. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +1 -1
  112. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +10 -6
  113. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +3 -3
  114. package/dist-esm/lib/editor/tools/StateNode.mjs +3 -3
  115. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  116. package/dist-esm/lib/exports/getSvgJsx.mjs.map +1 -1
  117. package/dist-esm/lib/hooks/useCanvasEvents.mjs +1 -2
  118. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  119. package/dist-esm/lib/primitives/Box.mjs +33 -33
  120. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  121. package/dist-esm/lib/primitives/Vec.mjs +13 -8
  122. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  123. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +41 -21
  124. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  125. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +11 -11
  126. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  127. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +13 -16
  128. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  129. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs +4 -4
  130. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
  131. package/dist-esm/lib/primitives/geometry/Edge2d.mjs +14 -17
  132. package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
  133. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +11 -11
  134. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  135. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +6 -2
  136. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  137. package/dist-esm/lib/primitives/geometry/Point2d.mjs +6 -6
  138. package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
  139. package/dist-esm/lib/primitives/geometry/Polygon2d.mjs +3 -0
  140. package/dist-esm/lib/primitives/geometry/Polygon2d.mjs.map +2 -2
  141. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs +8 -5
  142. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  143. package/dist-esm/lib/primitives/geometry/Rectangle2d.mjs +22 -11
  144. package/dist-esm/lib/primitives/geometry/Rectangle2d.mjs.map +2 -2
  145. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +22 -22
  146. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  147. package/dist-esm/lib/utils/reorderShapes.mjs +11 -10
  148. package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
  149. package/dist-esm/lib/utils/reparenting.mjs +216 -0
  150. package/dist-esm/lib/utils/reparenting.mjs.map +7 -0
  151. package/dist-esm/lib/utils/richText.mjs +8 -3
  152. package/dist-esm/lib/utils/richText.mjs.map +2 -2
  153. package/dist-esm/version.mjs +3 -3
  154. package/dist-esm/version.mjs.map +1 -1
  155. package/editor.css +442 -492
  156. package/package.json +8 -9
  157. package/src/index.ts +20 -7
  158. package/src/lib/config/TLSessionStateSnapshot.ts +1 -1
  159. package/src/lib/editor/Editor.test.ts +252 -3
  160. package/src/lib/editor/Editor.ts +149 -107
  161. package/src/lib/editor/bindings/BindingUtil.ts +6 -0
  162. package/src/lib/editor/derivations/bindingsIndex.ts +27 -26
  163. package/src/lib/editor/derivations/parentsToChildren.ts +28 -25
  164. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +442 -0
  165. package/src/lib/editor/managers/{ClickManager.ts → ClickManager/ClickManager.ts} +3 -3
  166. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +374 -0
  167. package/src/lib/editor/managers/{EdgeScrollManager.ts → EdgeScrollManager/EdgeScrollManager.ts} +3 -3
  168. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +455 -0
  169. package/src/lib/editor/managers/{FocusManager.ts → FocusManager/FocusManager.ts} +1 -1
  170. package/src/lib/editor/managers/FontManager/FontManager.test.ts +263 -0
  171. package/src/lib/editor/managers/{FontManager.ts → FontManager/FontManager.ts} +5 -2
  172. package/src/lib/editor/managers/{HistoryManager.test.ts → HistoryManager/HistoryManager.test.ts} +388 -1
  173. package/src/lib/editor/managers/{HistoryManager.ts → HistoryManager/HistoryManager.ts} +76 -3
  174. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +624 -0
  175. package/src/lib/editor/managers/{ScribbleManager.ts → ScribbleManager/ScribbleManager.ts} +2 -2
  176. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +485 -0
  177. package/src/lib/editor/managers/TextManager/TextManager.test.ts +407 -0
  178. package/src/lib/editor/managers/{TextManager.ts → TextManager/TextManager.ts} +119 -87
  179. package/src/lib/editor/managers/TickManager/TickManager.test.ts +314 -0
  180. package/src/lib/editor/managers/{TickManager.ts → TickManager/TickManager.ts} +2 -2
  181. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +591 -0
  182. package/src/lib/editor/managers/{UserPreferencesManager.ts → UserPreferencesManager/UserPreferencesManager.ts} +2 -2
  183. package/src/lib/editor/shapes/ShapeUtil.ts +48 -16
  184. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
  185. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +22 -17
  186. package/src/lib/editor/tools/StateNode.ts +3 -3
  187. package/src/lib/editor/types/emit-types.ts +4 -0
  188. package/src/lib/editor/types/external-content.ts +11 -2
  189. package/src/lib/exports/getSvgJsx.tsx +1 -1
  190. package/src/lib/hooks/useCanvasEvents.ts +0 -1
  191. package/src/lib/primitives/Box.test.ts +588 -7
  192. package/src/lib/primitives/Box.ts +33 -33
  193. package/src/lib/primitives/Vec.test.ts +2 -2
  194. package/src/lib/primitives/Vec.ts +13 -8
  195. package/src/lib/primitives/geometry/Arc2d.ts +42 -23
  196. package/src/lib/primitives/geometry/Circle2d.ts +12 -12
  197. package/src/lib/primitives/geometry/CubicBezier2d.test.ts +5 -0
  198. package/src/lib/primitives/geometry/CubicBezier2d.ts +13 -17
  199. package/src/lib/primitives/geometry/CubicSpline2d.ts +5 -5
  200. package/src/lib/primitives/geometry/Edge2d.ts +14 -18
  201. package/src/lib/primitives/geometry/Ellipse2d.ts +12 -13
  202. package/src/lib/primitives/geometry/Geometry2d.ts +7 -2
  203. package/src/lib/primitives/geometry/Point2d.ts +6 -6
  204. package/src/lib/primitives/geometry/Polygon2d.ts +4 -0
  205. package/src/lib/primitives/geometry/Polyline2d.ts +10 -7
  206. package/src/lib/primitives/geometry/Rectangle2d.ts +24 -11
  207. package/src/lib/primitives/geometry/Stadium2d.ts +22 -23
  208. package/src/lib/utils/reorderShapes.ts +10 -13
  209. package/src/lib/utils/reparenting.ts +383 -0
  210. package/src/lib/utils/richText.ts +10 -4
  211. package/src/version.ts +3 -3
  212. package/dist-cjs/lib/editor/managers/ClickManager.js.map +0 -7
  213. package/dist-cjs/lib/editor/managers/EdgeScrollManager.js.map +0 -7
  214. package/dist-cjs/lib/editor/managers/FocusManager.js.map +0 -7
  215. package/dist-cjs/lib/editor/managers/FontManager.js.map +0 -7
  216. package/dist-cjs/lib/editor/managers/HistoryManager.js.map +0 -7
  217. package/dist-cjs/lib/editor/managers/ScribbleManager.js.map +0 -7
  218. package/dist-cjs/lib/editor/managers/Stack.js +0 -82
  219. package/dist-cjs/lib/editor/managers/Stack.js.map +0 -7
  220. package/dist-cjs/lib/editor/managers/TextManager.js.map +0 -7
  221. package/dist-cjs/lib/editor/managers/TickManager.js.map +0 -7
  222. package/dist-cjs/lib/editor/managers/UserPreferencesManager.js.map +0 -7
  223. package/dist-esm/lib/editor/managers/ClickManager.mjs.map +0 -7
  224. package/dist-esm/lib/editor/managers/EdgeScrollManager.mjs.map +0 -7
  225. package/dist-esm/lib/editor/managers/FocusManager.mjs.map +0 -7
  226. package/dist-esm/lib/editor/managers/FontManager.mjs.map +0 -7
  227. package/dist-esm/lib/editor/managers/HistoryManager.mjs.map +0 -7
  228. package/dist-esm/lib/editor/managers/ScribbleManager.mjs.map +0 -7
  229. package/dist-esm/lib/editor/managers/Stack.mjs +0 -62
  230. package/dist-esm/lib/editor/managers/Stack.mjs.map +0 -7
  231. package/dist-esm/lib/editor/managers/TextManager.mjs.map +0 -7
  232. package/dist-esm/lib/editor/managers/TickManager.mjs.map +0 -7
  233. package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs.map +0 -7
  234. package/src/lib/editor/managers/ScribbleManager.test.ts +0 -32
  235. package/src/lib/editor/managers/Stack.ts +0 -71
  236. /package/dist-cjs/lib/editor/managers/{FocusManager.js → FocusManager/FocusManager.js} +0 -0
  237. /package/dist-esm/lib/editor/managers/{FocusManager.mjs → FocusManager/FocusManager.mjs} +0 -0
@@ -0,0 +1,374 @@
1
+ import { Box } from '../../../primitives/Box'
2
+ import { Vec } from '../../../primitives/Vec'
3
+ import { Editor } from '../../Editor'
4
+ import { EdgeScrollManager } from './EdgeScrollManager'
5
+
6
+ // Mock the Editor class
7
+ jest.mock('../../Editor')
8
+
9
+ describe('EdgeScrollManager', () => {
10
+ let editor: jest.Mocked<
11
+ Editor & {
12
+ user: { getEdgeScrollSpeed: jest.Mock }
13
+ getCamera: jest.Mock
14
+ getCameraOptions: jest.Mock
15
+ getZoomLevel: jest.Mock
16
+ getViewportScreenBounds: jest.Mock
17
+ }
18
+ >
19
+ let edgeScrollManager: EdgeScrollManager
20
+
21
+ beforeEach(() => {
22
+ editor = {
23
+ options: {
24
+ edgeScrollDelay: 200,
25
+ edgeScrollEaseDuration: 200,
26
+ edgeScrollSpeed: 25,
27
+ edgeScrollDistance: 8,
28
+ coarsePointerWidth: 12,
29
+ },
30
+ inputs: {
31
+ currentScreenPoint: new Vec(500, 300),
32
+ isDragging: true,
33
+ isPanning: false,
34
+ },
35
+ user: {
36
+ getEdgeScrollSpeed: jest.fn(() => 1),
37
+ },
38
+ getViewportScreenBounds: jest.fn(() => new Box(0, 0, 1000, 600)),
39
+ getInstanceState: jest.fn(
40
+ () =>
41
+ ({
42
+ isCoarsePointer: false,
43
+ insets: [false, false, false, false], // [top, right, bottom, left]
44
+ }) as any
45
+ ),
46
+ getCameraOptions: jest.fn(() => ({
47
+ isLocked: false,
48
+ panSpeed: 1,
49
+ zoomSpeed: 1,
50
+ zoomSteps: [1],
51
+ wheelBehavior: 'pan' as const,
52
+ })),
53
+ getZoomLevel: jest.fn(() => 1),
54
+ getCamera: jest.fn(() => new Vec(0, 0, 1)),
55
+ setCamera: jest.fn(),
56
+ } as any
57
+
58
+ edgeScrollManager = new EdgeScrollManager(editor as any)
59
+ })
60
+
61
+ afterEach(() => {
62
+ jest.clearAllMocks()
63
+ })
64
+
65
+ describe('constructor and initialization', () => {
66
+ it('should initialize with editor reference', () => {
67
+ expect(edgeScrollManager.editor).toBe(editor)
68
+ })
69
+
70
+ it('should initialize edge scrolling state as false', () => {
71
+ // Access private properties for testing
72
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
73
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(-1)
74
+ })
75
+ })
76
+
77
+ describe('basic edge scrolling behavior', () => {
78
+ it('should not trigger edge scrolling when pointer is in center', () => {
79
+ editor.inputs.currentScreenPoint = new Vec(500, 300)
80
+
81
+ edgeScrollManager.updateEdgeScrolling(16)
82
+
83
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
84
+ expect(editor.setCamera).not.toHaveBeenCalled()
85
+ })
86
+
87
+ it('should start edge scrolling when pointer is near edge', () => {
88
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
89
+
90
+ edgeScrollManager.updateEdgeScrolling(16)
91
+
92
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
93
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(16)
94
+ })
95
+
96
+ it('should stop edge scrolling when pointer moves away from edge', () => {
97
+ // Start edge scrolling
98
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
99
+ edgeScrollManager.updateEdgeScrolling(16)
100
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
101
+
102
+ // Move pointer to center
103
+ editor.inputs.currentScreenPoint = new Vec(500, 300)
104
+ edgeScrollManager.updateEdgeScrolling(16)
105
+
106
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
107
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
108
+ })
109
+
110
+ it('should respect edge scroll delay', () => {
111
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
112
+
113
+ // First update - should not scroll yet due to delay
114
+ edgeScrollManager.updateEdgeScrolling(100)
115
+ expect(editor.setCamera).not.toHaveBeenCalled()
116
+
117
+ // Second update - should trigger scrolling after delay
118
+ edgeScrollManager.updateEdgeScrolling(150)
119
+ expect(editor.setCamera).toHaveBeenCalled()
120
+ })
121
+ })
122
+
123
+ describe('edge proximity detection', () => {
124
+ it('should detect left edge proximity', () => {
125
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
126
+ edgeScrollManager.updateEdgeScrolling(300) // Enough to trigger after delay
127
+
128
+ expect(editor.setCamera).toHaveBeenCalled()
129
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
130
+ expect(callArgs.x).toBeGreaterThan(0) // Should scroll right when near left edge
131
+ })
132
+
133
+ it('should detect right edge proximity', () => {
134
+ editor.inputs.currentScreenPoint = new Vec(995, 300)
135
+ edgeScrollManager.updateEdgeScrolling(300)
136
+
137
+ expect(editor.setCamera).toHaveBeenCalled()
138
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
139
+ expect(callArgs.x).toBeLessThan(0) // Should scroll left when near right edge
140
+ })
141
+
142
+ it('should detect top edge proximity', () => {
143
+ editor.inputs.currentScreenPoint = new Vec(500, 5)
144
+ edgeScrollManager.updateEdgeScrolling(300)
145
+
146
+ expect(editor.setCamera).toHaveBeenCalled()
147
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
148
+ expect(callArgs.y).toBeGreaterThan(0) // Should scroll down when near top edge
149
+ })
150
+
151
+ it('should detect bottom edge proximity', () => {
152
+ editor.inputs.currentScreenPoint = new Vec(500, 595)
153
+ edgeScrollManager.updateEdgeScrolling(300)
154
+
155
+ expect(editor.setCamera).toHaveBeenCalled()
156
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
157
+ expect(callArgs.y).toBeLessThan(0) // Should scroll up when near bottom edge
158
+ })
159
+
160
+ it('should handle corner proximity (both x and y)', () => {
161
+ editor.inputs.currentScreenPoint = new Vec(5, 5)
162
+ edgeScrollManager.updateEdgeScrolling(300)
163
+
164
+ expect(editor.setCamera).toHaveBeenCalled()
165
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
166
+ expect(callArgs.x).toBeGreaterThan(0) // Should scroll right
167
+ expect(callArgs.y).toBeGreaterThan(0) // Should scroll down
168
+ })
169
+ })
170
+
171
+ describe('coarse pointer handling', () => {
172
+ it('should account for coarse pointer width', () => {
173
+ editor.getInstanceState.mockReturnValue({
174
+ isCoarsePointer: true,
175
+ insets: [false, false, false, false],
176
+ } as any)
177
+
178
+ editor.inputs.currentScreenPoint = new Vec(15, 300)
179
+ edgeScrollManager.updateEdgeScrolling(300)
180
+
181
+ expect(editor.setCamera).toHaveBeenCalled()
182
+ })
183
+
184
+ it('should not trigger edge scrolling for fine pointer at same position', () => {
185
+ editor.getInstanceState.mockReturnValue({
186
+ isCoarsePointer: false,
187
+ insets: [false, false, false, false],
188
+ } as any)
189
+
190
+ editor.inputs.currentScreenPoint = new Vec(15, 300)
191
+ edgeScrollManager.updateEdgeScrolling(300)
192
+
193
+ expect(editor.setCamera).not.toHaveBeenCalled()
194
+ })
195
+ })
196
+
197
+ describe('camera movement conditions', () => {
198
+ it('should not move camera when not dragging', () => {
199
+ editor.inputs.isDragging = false
200
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
201
+
202
+ edgeScrollManager.updateEdgeScrolling(300)
203
+
204
+ expect(editor.setCamera).not.toHaveBeenCalled()
205
+ })
206
+
207
+ it('should not move camera when panning', () => {
208
+ editor.inputs.isPanning = true
209
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
210
+
211
+ edgeScrollManager.updateEdgeScrolling(300)
212
+
213
+ expect(editor.setCamera).not.toHaveBeenCalled()
214
+ })
215
+
216
+ it('should not move camera when camera is locked', () => {
217
+ editor.getCameraOptions.mockReturnValue({
218
+ isLocked: true,
219
+ panSpeed: 1,
220
+ zoomSpeed: 1,
221
+ zoomSteps: [1],
222
+ wheelBehavior: 'pan' as const,
223
+ })
224
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
225
+
226
+ edgeScrollManager.updateEdgeScrolling(300)
227
+
228
+ expect(editor.setCamera).not.toHaveBeenCalled()
229
+ })
230
+ })
231
+
232
+ describe('camera movement calculation', () => {
233
+ it('should calculate scroll speed based on user preference', () => {
234
+ editor.user.getEdgeScrollSpeed.mockReturnValue(2)
235
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
236
+
237
+ edgeScrollManager.updateEdgeScrolling(300)
238
+
239
+ expect(editor.setCamera).toHaveBeenCalled()
240
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
241
+ expect(callArgs.x).toBeGreaterThan(0) // Should scroll when user speed is > 0
242
+ })
243
+
244
+ it('should apply screen size factor for small screens', () => {
245
+ editor.getViewportScreenBounds.mockReturnValue(new Box(0, 0, 800, 600))
246
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
247
+
248
+ edgeScrollManager.updateEdgeScrolling(300)
249
+
250
+ expect(editor.setCamera).toHaveBeenCalled()
251
+ })
252
+
253
+ it('should adjust scroll speed based on zoom level', () => {
254
+ editor.getZoomLevel.mockReturnValue(2)
255
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
256
+
257
+ edgeScrollManager.updateEdgeScrolling(300)
258
+
259
+ expect(editor.setCamera).toHaveBeenCalled()
260
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
261
+ // Higher zoom should result in smaller camera movement
262
+ expect(Math.abs(callArgs.x)).toBeLessThan(25)
263
+ })
264
+
265
+ it('should add scroll delta to current camera position', () => {
266
+ const currentCamera = new Vec(100, 200, 1)
267
+ editor.getCamera.mockReturnValue(currentCamera)
268
+ editor.inputs.currentScreenPoint = new Vec(5, 5)
269
+
270
+ edgeScrollManager.updateEdgeScrolling(300)
271
+
272
+ expect(editor.setCamera).toHaveBeenCalled()
273
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
274
+ expect(callArgs.x).toBeGreaterThan(100) // Should be added to current position
275
+ expect(callArgs.y).toBeGreaterThan(200) // Should be added to current position
276
+ expect(callArgs.z).toBe(1) // Z should remain unchanged
277
+ })
278
+ })
279
+
280
+ describe('proximity factor calculation', () => {
281
+ it('should return 0 when not near any edge', () => {
282
+ editor.inputs.currentScreenPoint = new Vec(500, 300)
283
+ edgeScrollManager.updateEdgeScrolling(16)
284
+
285
+ expect(editor.setCamera).not.toHaveBeenCalled()
286
+ })
287
+
288
+ it('should cap proximity factor at 1', () => {
289
+ editor.inputs.currentScreenPoint = new Vec(0, 300)
290
+ edgeScrollManager.updateEdgeScrolling(300)
291
+
292
+ expect(editor.setCamera).toHaveBeenCalled()
293
+ // The proximity factor should be capped, so movement shouldn't be infinite
294
+ })
295
+ })
296
+
297
+ describe('edge cases and error handling', () => {
298
+ it('should handle negative elapsed time', () => {
299
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
300
+
301
+ expect(() => edgeScrollManager.updateEdgeScrolling(-16)).not.toThrow()
302
+ })
303
+
304
+ it('should handle very large elapsed time', () => {
305
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
306
+
307
+ expect(() => edgeScrollManager.updateEdgeScrolling(100000)).not.toThrow()
308
+ })
309
+
310
+ it('should handle zero user edge scroll speed', () => {
311
+ editor.user.getEdgeScrollSpeed.mockReturnValue(0)
312
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
313
+
314
+ edgeScrollManager.updateEdgeScrolling(300)
315
+
316
+ if (editor.setCamera.mock.calls.length > 0) {
317
+ const callArgs = editor.setCamera.mock.calls[0][0] as Vec
318
+ expect(callArgs.x).toBe(0)
319
+ expect(callArgs.y).toBe(0)
320
+ }
321
+ })
322
+
323
+ it('should handle extreme zoom levels', () => {
324
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
325
+
326
+ editor.getZoomLevel.mockReturnValue(0.01) // Very zoomed out
327
+ expect(() => edgeScrollManager.updateEdgeScrolling(300)).not.toThrow()
328
+
329
+ editor.getZoomLevel.mockReturnValue(100) // Very zoomed in
330
+ expect(() => edgeScrollManager.updateEdgeScrolling(300)).not.toThrow()
331
+ })
332
+ })
333
+
334
+ describe('state transitions', () => {
335
+ it('should properly transition from not scrolling to scrolling', () => {
336
+ // Start with no edge scrolling
337
+ editor.inputs.currentScreenPoint = new Vec(500, 300)
338
+ edgeScrollManager.updateEdgeScrolling(16)
339
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
340
+
341
+ // Move to edge
342
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
343
+ edgeScrollManager.updateEdgeScrolling(16)
344
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
345
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(16)
346
+ })
347
+
348
+ it('should accumulate edge scroll duration over multiple updates', () => {
349
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
350
+
351
+ edgeScrollManager.updateEdgeScrolling(50)
352
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(50)
353
+
354
+ edgeScrollManager.updateEdgeScrolling(30)
355
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(80)
356
+
357
+ edgeScrollManager.updateEdgeScrolling(25)
358
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(105)
359
+ })
360
+
361
+ it('should reset duration when stopping edge scroll', () => {
362
+ // Start edge scrolling
363
+ editor.inputs.currentScreenPoint = new Vec(5, 300)
364
+ edgeScrollManager.updateEdgeScrolling(100)
365
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(100)
366
+
367
+ // Stop edge scrolling
368
+ editor.inputs.currentScreenPoint = new Vec(500, 300)
369
+ edgeScrollManager.updateEdgeScrolling(16)
370
+ expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
371
+ expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
372
+ })
373
+ })
374
+ })
@@ -1,6 +1,6 @@
1
- import { Vec } from '../../primitives/Vec'
2
- import { EASINGS } from '../../primitives/easings'
3
- import { Editor } from '../Editor'
1
+ import { Vec } from '../../../primitives/Vec'
2
+ import { EASINGS } from '../../../primitives/easings'
3
+ import { Editor } from '../../Editor'
4
4
 
5
5
  /** @public */
6
6
  export class EdgeScrollManager {