@tldraw/editor 4.2.2 → 4.2.3
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.
- package/dist-cjs/index.d.ts +155 -498
- package/dist-cjs/index.js +1 -6
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/ErrorBoundary.js.map +1 -1
- package/dist-cjs/lib/components/GeometryDebuggingView.js +17 -1
- package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +3 -3
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/constants.js +3 -1
- package/dist-cjs/lib/constants.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +286 -292
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +17 -18
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +3 -3
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js +3 -12
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +6 -5
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +22 -1
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +23 -31
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -3
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
- package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/exports/parseCss.js +1 -1
- package/dist-cjs/lib/exports/parseCss.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +9 -45
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/globals/menus.js +1 -1
- package/dist-cjs/lib/globals/menus.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +3 -4
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useCoarsePointer.js +29 -14
- package/dist-cjs/lib/hooks/useCoarsePointer.js.map +2 -2
- package/dist-cjs/lib/hooks/useEvent.js +1 -1
- package/dist-cjs/lib/hooks/useEvent.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
- package/dist-cjs/lib/hooks/useStateAttribute.js +1 -4
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +2 -2
- package/dist-cjs/lib/hooks/useTransform.js.map +1 -1
- package/dist-cjs/lib/hooks/useZoomCss.js +8 -4
- package/dist-cjs/lib/hooks/useZoomCss.js.map +2 -2
- package/dist-cjs/lib/options.js +1 -6
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +0 -3
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +0 -1
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/rotation.js +1 -1
- package/dist-cjs/lib/utils/rotation.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +155 -498
- package/dist-esm/index.mjs +2 -7
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/ErrorBoundary.mjs.map +1 -1
- package/dist-esm/lib/components/GeometryDebuggingView.mjs +17 -1
- package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +3 -3
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/constants.mjs +3 -1
- package/dist-esm/lib/constants.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +289 -293
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +17 -18
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +3 -3
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +4 -13
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +6 -5
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +22 -1
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +23 -31
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -3
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/exports/parseCss.mjs +1 -1
- package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +9 -45
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/globals/menus.mjs +1 -1
- package/dist-esm/lib/globals/menus.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +3 -4
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCoarsePointer.mjs +30 -15
- package/dist-esm/lib/hooks/useCoarsePointer.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEvent.mjs +1 -1
- package/dist-esm/lib/hooks/useEvent.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs +1 -1
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
- package/dist-esm/lib/hooks/useStateAttribute.mjs +1 -4
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +2 -2
- package/dist-esm/lib/hooks/useTransform.mjs.map +1 -1
- package/dist-esm/lib/hooks/useZoomCss.mjs +8 -4
- package/dist-esm/lib/hooks/useZoomCss.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +1 -6
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +0 -3
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +0 -1
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/rotation.mjs +1 -1
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +12 -14
- package/package.json +16 -18
- package/src/index.ts +1 -4
- package/src/lib/components/ErrorBoundary.tsx +1 -1
- package/src/lib/components/GeometryDebuggingView.tsx +19 -1
- package/src/lib/components/default-components/DefaultCanvas.tsx +3 -4
- package/src/lib/constants.ts +2 -0
- package/src/lib/editor/Editor.test.ts +10 -150
- package/src/lib/editor/Editor.ts +379 -459
- package/src/lib/editor/bindings/BindingUtil.ts +9 -15
- package/src/lib/editor/derivations/bindingsIndex.ts +2 -2
- package/src/lib/editor/derivations/notVisibleShapes.ts +23 -37
- package/src/lib/editor/derivations/parentsToChildren.ts +7 -18
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +31 -17
- package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +79 -129
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +6 -10
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +4 -14
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +4 -0
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +0 -12
- package/src/lib/editor/managers/SnapManager/SnapManager.ts +4 -4
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +107 -40
- package/src/lib/editor/managers/TickManager/TickManager.ts +32 -2
- package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +32 -72
- package/src/lib/editor/shapes/group/DashedOutlineBox.tsx +1 -1
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +3 -1
- package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +1 -2
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +6 -6
- package/src/lib/editor/types/emit-types.ts +1 -3
- package/src/lib/exports/getSvgJsx.test.ts +19 -10
- package/src/lib/exports/getSvgJsx.tsx +5 -2
- package/src/lib/exports/parseCss.test.ts +0 -1
- package/src/lib/exports/parseCss.ts +1 -1
- package/src/lib/globals/environment.ts +10 -65
- package/src/lib/globals/menus.ts +1 -1
- package/src/lib/hooks/useCanvasEvents.ts +3 -4
- package/src/lib/hooks/useCoarsePointer.ts +59 -16
- package/src/lib/hooks/useEvent.tsx +1 -1
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +1 -1
- package/src/lib/hooks/useGestureEvents.ts +2 -2
- package/src/lib/hooks/usePassThroughMouseOverEvents.ts +1 -1
- package/src/lib/hooks/usePassThroughWheelEvents.ts +1 -1
- package/src/lib/hooks/useScreenBounds.ts +1 -1
- package/src/lib/hooks/useStateAttribute.ts +1 -4
- package/src/lib/hooks/useTransform.ts +1 -1
- package/src/lib/hooks/useZoomCss.ts +8 -3
- package/src/lib/options.ts +0 -32
- package/src/lib/primitives/Box.ts +0 -9
- package/src/lib/primitives/geometry/Geometry2d.ts +0 -1
- package/src/lib/utils/reparenting.ts +5 -5
- package/src/lib/utils/rotation.ts +1 -1
- package/src/version.ts +3 -3
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +0 -591
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +0 -7
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +0 -573
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +0 -7
- package/src/lib/config/TLUserPreferences.test.ts +0 -40
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +0 -566
|
@@ -18,56 +18,8 @@ describe('EdgeScrollManager', () => {
|
|
|
18
18
|
}
|
|
19
19
|
>
|
|
20
20
|
let edgeScrollManager: EdgeScrollManager
|
|
21
|
-
let mockInputs: {
|
|
22
|
-
_currentScreenPoint: Vec
|
|
23
|
-
currentScreenPoint: Vec
|
|
24
|
-
getCurrentScreenPoint(): Vec
|
|
25
|
-
setCurrentScreenPoint(value: Vec): void
|
|
26
|
-
_isDragging: boolean
|
|
27
|
-
isDragging: boolean
|
|
28
|
-
getIsDragging(): boolean
|
|
29
|
-
setIsDragging(value: boolean): void
|
|
30
|
-
_isPanning: boolean
|
|
31
|
-
isPanning: boolean
|
|
32
|
-
getIsPanning(): boolean
|
|
33
|
-
setIsPanning(value: boolean): void
|
|
34
|
-
}
|
|
35
21
|
|
|
36
22
|
beforeEach(() => {
|
|
37
|
-
// Create a mock inputs object with writable properties and getters
|
|
38
|
-
mockInputs = {
|
|
39
|
-
_currentScreenPoint: new Vec(500, 300),
|
|
40
|
-
get currentScreenPoint() {
|
|
41
|
-
return this._currentScreenPoint
|
|
42
|
-
},
|
|
43
|
-
getCurrentScreenPoint() {
|
|
44
|
-
return this._currentScreenPoint
|
|
45
|
-
},
|
|
46
|
-
setCurrentScreenPoint(value: Vec) {
|
|
47
|
-
this._currentScreenPoint = value
|
|
48
|
-
},
|
|
49
|
-
_isDragging: true,
|
|
50
|
-
get isDragging() {
|
|
51
|
-
return this._isDragging
|
|
52
|
-
},
|
|
53
|
-
getIsDragging() {
|
|
54
|
-
return this._isDragging
|
|
55
|
-
},
|
|
56
|
-
setIsDragging(value: boolean) {
|
|
57
|
-
this._isDragging = value
|
|
58
|
-
},
|
|
59
|
-
_isPanning: false,
|
|
60
|
-
get isPanning() {
|
|
61
|
-
return this._isPanning
|
|
62
|
-
},
|
|
63
|
-
getIsPanning() {
|
|
64
|
-
return this._isPanning
|
|
65
|
-
},
|
|
66
|
-
setIsPanning(value: boolean) {
|
|
67
|
-
this._isPanning = value
|
|
68
|
-
},
|
|
69
|
-
}
|
|
70
|
-
|
|
71
23
|
editor = {
|
|
72
24
|
options: {
|
|
73
25
|
edgeScrollDelay: 200,
|
|
@@ -76,15 +28,22 @@ describe('EdgeScrollManager', () => {
|
|
|
76
28
|
edgeScrollDistance: 8,
|
|
77
29
|
coarsePointerWidth: 12,
|
|
78
30
|
},
|
|
79
|
-
inputs:
|
|
31
|
+
inputs: {
|
|
32
|
+
currentScreenPoint: new Vec(500, 300),
|
|
33
|
+
isDragging: true,
|
|
34
|
+
isPanning: false,
|
|
35
|
+
},
|
|
80
36
|
user: {
|
|
81
37
|
getEdgeScrollSpeed: vi.fn(() => 1),
|
|
82
38
|
},
|
|
83
39
|
getViewportScreenBounds: vi.fn(() => new Box(0, 0, 1000, 600)),
|
|
84
|
-
getInstanceState: vi.fn(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
40
|
+
getInstanceState: vi.fn(
|
|
41
|
+
() =>
|
|
42
|
+
({
|
|
43
|
+
isCoarsePointer: false,
|
|
44
|
+
insets: [false, false, false, false], // [top, right, bottom, left]
|
|
45
|
+
}) as any
|
|
46
|
+
),
|
|
88
47
|
getCameraOptions: vi.fn(() => ({
|
|
89
48
|
isLocked: false,
|
|
90
49
|
panSpeed: 1,
|
|
@@ -95,17 +54,9 @@ describe('EdgeScrollManager', () => {
|
|
|
95
54
|
getZoomLevel: vi.fn(() => 1),
|
|
96
55
|
getCamera: vi.fn(() => new Vec(0, 0, 1)),
|
|
97
56
|
setCamera: vi.fn(),
|
|
98
|
-
} as
|
|
99
|
-
Editor & {
|
|
100
|
-
user: { getEdgeScrollSpeed: Mock }
|
|
101
|
-
getCamera: Mock
|
|
102
|
-
getCameraOptions: Mock
|
|
103
|
-
getZoomLevel: Mock
|
|
104
|
-
getViewportScreenBounds: Mock
|
|
105
|
-
}
|
|
106
|
-
>
|
|
57
|
+
} as any
|
|
107
58
|
|
|
108
|
-
edgeScrollManager = new EdgeScrollManager(editor)
|
|
59
|
+
edgeScrollManager = new EdgeScrollManager(editor as any)
|
|
109
60
|
})
|
|
110
61
|
|
|
111
62
|
afterEach(() => {
|
|
@@ -116,45 +67,49 @@ describe('EdgeScrollManager', () => {
|
|
|
116
67
|
it('should initialize with editor reference', () => {
|
|
117
68
|
expect(edgeScrollManager.editor).toBe(editor)
|
|
118
69
|
})
|
|
70
|
+
|
|
71
|
+
it('should initialize edge scrolling state as false', () => {
|
|
72
|
+
// Access private properties for testing
|
|
73
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
74
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(-1)
|
|
75
|
+
})
|
|
119
76
|
})
|
|
120
77
|
|
|
121
78
|
describe('basic edge scrolling behavior', () => {
|
|
122
79
|
it('should not trigger edge scrolling when pointer is in center', () => {
|
|
123
|
-
|
|
80
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
124
81
|
|
|
125
82
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
126
83
|
|
|
84
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
127
85
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
128
86
|
})
|
|
129
87
|
|
|
130
88
|
it('should start edge scrolling when pointer is near edge', () => {
|
|
131
|
-
|
|
89
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
132
90
|
|
|
133
|
-
// Should not scroll immediately due to delay
|
|
134
91
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
135
|
-
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
136
92
|
|
|
137
|
-
|
|
138
|
-
edgeScrollManager.
|
|
139
|
-
expect(editor.setCamera).toHaveBeenCalled()
|
|
93
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
|
|
94
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(16)
|
|
140
95
|
})
|
|
141
96
|
|
|
142
97
|
it('should stop edge scrolling when pointer moves away from edge', () => {
|
|
143
|
-
// Start edge scrolling
|
|
144
|
-
|
|
145
|
-
edgeScrollManager.updateEdgeScrolling(
|
|
146
|
-
expect(
|
|
98
|
+
// Start edge scrolling
|
|
99
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
100
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
101
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
|
|
147
102
|
|
|
148
|
-
// Move pointer to center
|
|
149
|
-
editor.
|
|
150
|
-
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
103
|
+
// Move pointer to center
|
|
104
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
151
105
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
152
106
|
|
|
153
|
-
expect(
|
|
107
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
108
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
|
|
154
109
|
})
|
|
155
110
|
|
|
156
111
|
it('should respect edge scroll delay', () => {
|
|
157
|
-
|
|
112
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
158
113
|
|
|
159
114
|
// First update - should not scroll yet due to delay
|
|
160
115
|
edgeScrollManager.updateEdgeScrolling(100)
|
|
@@ -168,7 +123,7 @@ describe('EdgeScrollManager', () => {
|
|
|
168
123
|
|
|
169
124
|
describe('edge proximity detection', () => {
|
|
170
125
|
it('should detect left edge proximity', () => {
|
|
171
|
-
|
|
126
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
172
127
|
edgeScrollManager.updateEdgeScrolling(300) // Enough to trigger after delay
|
|
173
128
|
|
|
174
129
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -177,7 +132,7 @@ describe('EdgeScrollManager', () => {
|
|
|
177
132
|
})
|
|
178
133
|
|
|
179
134
|
it('should detect right edge proximity', () => {
|
|
180
|
-
|
|
135
|
+
editor.inputs.currentScreenPoint = new Vec(995, 300)
|
|
181
136
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
182
137
|
|
|
183
138
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -186,7 +141,7 @@ describe('EdgeScrollManager', () => {
|
|
|
186
141
|
})
|
|
187
142
|
|
|
188
143
|
it('should detect top edge proximity', () => {
|
|
189
|
-
|
|
144
|
+
editor.inputs.currentScreenPoint = new Vec(500, 5)
|
|
190
145
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
191
146
|
|
|
192
147
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -195,7 +150,7 @@ describe('EdgeScrollManager', () => {
|
|
|
195
150
|
})
|
|
196
151
|
|
|
197
152
|
it('should detect bottom edge proximity', () => {
|
|
198
|
-
|
|
153
|
+
editor.inputs.currentScreenPoint = new Vec(500, 595)
|
|
199
154
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
200
155
|
|
|
201
156
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -204,7 +159,7 @@ describe('EdgeScrollManager', () => {
|
|
|
204
159
|
})
|
|
205
160
|
|
|
206
161
|
it('should handle corner proximity (both x and y)', () => {
|
|
207
|
-
|
|
162
|
+
editor.inputs.currentScreenPoint = new Vec(5, 5)
|
|
208
163
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
209
164
|
|
|
210
165
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -217,11 +172,11 @@ describe('EdgeScrollManager', () => {
|
|
|
217
172
|
describe('coarse pointer handling', () => {
|
|
218
173
|
it('should account for coarse pointer width', () => {
|
|
219
174
|
editor.getInstanceState.mockReturnValue({
|
|
220
|
-
...editor.getInstanceState(),
|
|
221
175
|
isCoarsePointer: true,
|
|
222
176
|
insets: [false, false, false, false],
|
|
223
|
-
})
|
|
224
|
-
|
|
177
|
+
} as any)
|
|
178
|
+
|
|
179
|
+
editor.inputs.currentScreenPoint = new Vec(15, 300)
|
|
225
180
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
226
181
|
|
|
227
182
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -229,11 +184,11 @@ describe('EdgeScrollManager', () => {
|
|
|
229
184
|
|
|
230
185
|
it('should not trigger edge scrolling for fine pointer at same position', () => {
|
|
231
186
|
editor.getInstanceState.mockReturnValue({
|
|
232
|
-
...editor.getInstanceState(),
|
|
233
187
|
isCoarsePointer: false,
|
|
234
188
|
insets: [false, false, false, false],
|
|
235
|
-
})
|
|
236
|
-
|
|
189
|
+
} as any)
|
|
190
|
+
|
|
191
|
+
editor.inputs.currentScreenPoint = new Vec(15, 300)
|
|
237
192
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
238
193
|
|
|
239
194
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
@@ -242,8 +197,8 @@ describe('EdgeScrollManager', () => {
|
|
|
242
197
|
|
|
243
198
|
describe('camera movement conditions', () => {
|
|
244
199
|
it('should not move camera when not dragging', () => {
|
|
245
|
-
editor.inputs.
|
|
246
|
-
|
|
200
|
+
editor.inputs.isDragging = false
|
|
201
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
247
202
|
|
|
248
203
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
249
204
|
|
|
@@ -251,8 +206,8 @@ describe('EdgeScrollManager', () => {
|
|
|
251
206
|
})
|
|
252
207
|
|
|
253
208
|
it('should not move camera when panning', () => {
|
|
254
|
-
editor.inputs.
|
|
255
|
-
|
|
209
|
+
editor.inputs.isPanning = true
|
|
210
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
256
211
|
|
|
257
212
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
258
213
|
|
|
@@ -267,7 +222,7 @@ describe('EdgeScrollManager', () => {
|
|
|
267
222
|
zoomSteps: [1],
|
|
268
223
|
wheelBehavior: 'pan' as const,
|
|
269
224
|
})
|
|
270
|
-
|
|
225
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
271
226
|
|
|
272
227
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
273
228
|
|
|
@@ -278,7 +233,7 @@ describe('EdgeScrollManager', () => {
|
|
|
278
233
|
describe('camera movement calculation', () => {
|
|
279
234
|
it('should calculate scroll speed based on user preference', () => {
|
|
280
235
|
editor.user.getEdgeScrollSpeed.mockReturnValue(2)
|
|
281
|
-
|
|
236
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
282
237
|
|
|
283
238
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
284
239
|
|
|
@@ -289,7 +244,7 @@ describe('EdgeScrollManager', () => {
|
|
|
289
244
|
|
|
290
245
|
it('should apply screen size factor for small screens', () => {
|
|
291
246
|
editor.getViewportScreenBounds.mockReturnValue(new Box(0, 0, 800, 600))
|
|
292
|
-
|
|
247
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
293
248
|
|
|
294
249
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
295
250
|
|
|
@@ -298,7 +253,7 @@ describe('EdgeScrollManager', () => {
|
|
|
298
253
|
|
|
299
254
|
it('should adjust scroll speed based on zoom level', () => {
|
|
300
255
|
editor.getZoomLevel.mockReturnValue(2)
|
|
301
|
-
|
|
256
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
302
257
|
|
|
303
258
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
304
259
|
|
|
@@ -311,7 +266,7 @@ describe('EdgeScrollManager', () => {
|
|
|
311
266
|
it('should add scroll delta to current camera position', () => {
|
|
312
267
|
const currentCamera = new Vec(100, 200, 1)
|
|
313
268
|
editor.getCamera.mockReturnValue(currentCamera)
|
|
314
|
-
|
|
269
|
+
editor.inputs.currentScreenPoint = new Vec(5, 5)
|
|
315
270
|
|
|
316
271
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
317
272
|
|
|
@@ -325,14 +280,14 @@ describe('EdgeScrollManager', () => {
|
|
|
325
280
|
|
|
326
281
|
describe('proximity factor calculation', () => {
|
|
327
282
|
it('should return 0 when not near any edge', () => {
|
|
328
|
-
|
|
283
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
329
284
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
330
285
|
|
|
331
286
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
332
287
|
})
|
|
333
288
|
|
|
334
289
|
it('should cap proximity factor at 1', () => {
|
|
335
|
-
|
|
290
|
+
editor.inputs.currentScreenPoint = new Vec(0, 300)
|
|
336
291
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
337
292
|
|
|
338
293
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -342,20 +297,20 @@ describe('EdgeScrollManager', () => {
|
|
|
342
297
|
|
|
343
298
|
describe('edge cases and error handling', () => {
|
|
344
299
|
it('should handle negative elapsed time', () => {
|
|
345
|
-
|
|
300
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
346
301
|
|
|
347
302
|
expect(() => edgeScrollManager.updateEdgeScrolling(-16)).not.toThrow()
|
|
348
303
|
})
|
|
349
304
|
|
|
350
305
|
it('should handle very large elapsed time', () => {
|
|
351
|
-
|
|
306
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
352
307
|
|
|
353
308
|
expect(() => edgeScrollManager.updateEdgeScrolling(100000)).not.toThrow()
|
|
354
309
|
})
|
|
355
310
|
|
|
356
311
|
it('should handle zero user edge scroll speed', () => {
|
|
357
312
|
editor.user.getEdgeScrollSpeed.mockReturnValue(0)
|
|
358
|
-
|
|
313
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
359
314
|
|
|
360
315
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
361
316
|
|
|
@@ -367,7 +322,7 @@ describe('EdgeScrollManager', () => {
|
|
|
367
322
|
})
|
|
368
323
|
|
|
369
324
|
it('should handle extreme zoom levels', () => {
|
|
370
|
-
|
|
325
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
371
326
|
|
|
372
327
|
editor.getZoomLevel.mockReturnValue(0.01) // Very zoomed out
|
|
373
328
|
expect(() => edgeScrollManager.updateEdgeScrolling(300)).not.toThrow()
|
|
@@ -380,46 +335,41 @@ describe('EdgeScrollManager', () => {
|
|
|
380
335
|
describe('state transitions', () => {
|
|
381
336
|
it('should properly transition from not scrolling to scrolling', () => {
|
|
382
337
|
// Start with no edge scrolling
|
|
383
|
-
|
|
338
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
384
339
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
385
|
-
expect(
|
|
340
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
386
341
|
|
|
387
|
-
// Move to edge
|
|
388
|
-
|
|
342
|
+
// Move to edge
|
|
343
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
389
344
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
390
|
-
expect(
|
|
391
|
-
|
|
392
|
-
edgeScrollManager.updateEdgeScrolling(200)
|
|
393
|
-
expect(editor.setCamera).toHaveBeenCalled()
|
|
345
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
|
|
346
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(16)
|
|
394
347
|
})
|
|
395
348
|
|
|
396
349
|
it('should accumulate edge scroll duration over multiple updates', () => {
|
|
397
|
-
|
|
350
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
398
351
|
|
|
399
|
-
// First update - not enough time
|
|
400
352
|
edgeScrollManager.updateEdgeScrolling(50)
|
|
401
|
-
expect(
|
|
353
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(50)
|
|
402
354
|
|
|
403
|
-
|
|
404
|
-
edgeScrollManager.
|
|
405
|
-
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
355
|
+
edgeScrollManager.updateEdgeScrolling(30)
|
|
356
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(80)
|
|
406
357
|
|
|
407
|
-
|
|
408
|
-
edgeScrollManager.
|
|
409
|
-
expect(editor.setCamera).toHaveBeenCalled()
|
|
358
|
+
edgeScrollManager.updateEdgeScrolling(25)
|
|
359
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(105)
|
|
410
360
|
})
|
|
411
361
|
|
|
412
362
|
it('should reset duration when stopping edge scroll', () => {
|
|
413
363
|
// Start edge scrolling
|
|
414
|
-
|
|
415
|
-
edgeScrollManager.updateEdgeScrolling(
|
|
416
|
-
expect(
|
|
364
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
365
|
+
edgeScrollManager.updateEdgeScrolling(100)
|
|
366
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(100)
|
|
417
367
|
|
|
418
|
-
// Stop edge scrolling
|
|
419
|
-
editor.
|
|
420
|
-
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
368
|
+
// Stop edge scrolling
|
|
369
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
421
370
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
422
|
-
expect(
|
|
371
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
372
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
|
|
423
373
|
})
|
|
424
374
|
})
|
|
425
375
|
})
|
|
@@ -9,10 +9,6 @@ export class EdgeScrollManager {
|
|
|
9
9
|
private _isEdgeScrolling = false
|
|
10
10
|
private _edgeScrollDuration = -1
|
|
11
11
|
|
|
12
|
-
getIsEdgeScrolling() {
|
|
13
|
-
return this._isEdgeScrolling
|
|
14
|
-
}
|
|
15
|
-
|
|
16
12
|
/**
|
|
17
13
|
* Update the camera position when the mouse is close to the edge of the screen.
|
|
18
14
|
* Run this on every tick when in a state where edge scrolling is enabled.
|
|
@@ -85,7 +81,11 @@ export class EdgeScrollManager {
|
|
|
85
81
|
|
|
86
82
|
private getEdgeScroll() {
|
|
87
83
|
const { editor } = this
|
|
88
|
-
const {
|
|
84
|
+
const {
|
|
85
|
+
inputs: {
|
|
86
|
+
currentScreenPoint: { x, y },
|
|
87
|
+
},
|
|
88
|
+
} = editor
|
|
89
89
|
const screenBounds = editor.getViewportScreenBounds()
|
|
90
90
|
|
|
91
91
|
const {
|
|
@@ -107,11 +107,7 @@ export class EdgeScrollManager {
|
|
|
107
107
|
*/
|
|
108
108
|
private moveCameraWhenCloseToEdge(proximityFactor: { x: number; y: number }) {
|
|
109
109
|
const { editor } = this
|
|
110
|
-
if (
|
|
111
|
-
!editor.inputs.getIsDragging() ||
|
|
112
|
-
editor.inputs.getIsPanning() ||
|
|
113
|
-
editor.getCameraOptions().isLocked
|
|
114
|
-
)
|
|
110
|
+
if (!editor.inputs.isDragging || editor.inputs.isPanning || editor.getCameraOptions().isLocked)
|
|
115
111
|
return
|
|
116
112
|
|
|
117
113
|
if (proximityFactor.x === 0 && proximityFactor.y === 0) return
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { IndexKey } from '@tldraw/utils'
|
|
1
|
+
import { TLShape, TLShapeId, createShapeId } from '@tldraw/tlschema'
|
|
3
2
|
import { Mock, Mocked, vi } from 'vitest'
|
|
4
3
|
import { Editor } from '../../Editor'
|
|
5
4
|
import { FontManager, TLFontFace } from './FontManager'
|
|
@@ -42,21 +41,12 @@ describe('FontManager', () => {
|
|
|
42
41
|
x: 0,
|
|
43
42
|
y: 0,
|
|
44
43
|
rotation: 0,
|
|
45
|
-
index: 'a1' as
|
|
46
|
-
parentId: 'page:page' as
|
|
44
|
+
index: 'a1' as any,
|
|
45
|
+
parentId: 'page:page' as any,
|
|
47
46
|
opacity: 1,
|
|
48
47
|
isLocked: false,
|
|
49
48
|
meta: {},
|
|
50
|
-
props: {
|
|
51
|
-
color: 'black',
|
|
52
|
-
size: 'xl',
|
|
53
|
-
font: 'serif',
|
|
54
|
-
textAlign: 'middle',
|
|
55
|
-
w: 100,
|
|
56
|
-
richText: toRichText('❤️'),
|
|
57
|
-
scale: 2,
|
|
58
|
-
autoSize: true,
|
|
59
|
-
},
|
|
49
|
+
props: {},
|
|
60
50
|
typeName: 'shape' as const,
|
|
61
51
|
})
|
|
62
52
|
|
|
@@ -36,6 +36,10 @@ describe('ScribbleManager', () => {
|
|
|
36
36
|
expect(scribbleManager.scribbleItems.size).toBe(0)
|
|
37
37
|
expect(scribbleManager.state).toBe('paused')
|
|
38
38
|
})
|
|
39
|
+
|
|
40
|
+
it('should store reference to editor', () => {
|
|
41
|
+
expect((scribbleManager as any).editor).toBe(editor)
|
|
42
|
+
})
|
|
39
43
|
})
|
|
40
44
|
|
|
41
45
|
describe('addScribble', () => {
|
|
@@ -64,7 +64,6 @@ describe('SnapManager', () => {
|
|
|
64
64
|
beforeEach(() => {
|
|
65
65
|
editor = {
|
|
66
66
|
getZoomLevel: vi.fn(() => 1),
|
|
67
|
-
options: { snapThreshold: 8 },
|
|
68
67
|
getViewportPageBounds: vi.fn(() => new Box(0, 0, 1000, 1000)),
|
|
69
68
|
getSelectedShapeIds: vi.fn(() => []),
|
|
70
69
|
getSelectedShapes: vi.fn(() => []),
|
|
@@ -249,17 +248,6 @@ describe('SnapManager', () => {
|
|
|
249
248
|
editor.getZoomLevel.mockReturnValue(10)
|
|
250
249
|
expect(snapManager.getSnapThreshold()).toBe(0.8)
|
|
251
250
|
})
|
|
252
|
-
|
|
253
|
-
it('should use custom snap threshold when configured', () => {
|
|
254
|
-
;(editor as any).options = { snapThreshold: 16 }
|
|
255
|
-
editor.getZoomLevel.mockReturnValue(1)
|
|
256
|
-
const customSnapManager = new SnapManager(editor)
|
|
257
|
-
expect(customSnapManager.getSnapThreshold()).toBe(16)
|
|
258
|
-
|
|
259
|
-
editor.getZoomLevel.mockReturnValue(2)
|
|
260
|
-
const customSnapManager2 = new SnapManager(editor)
|
|
261
|
-
expect(customSnapManager2.getSnapThreshold()).toBe(8)
|
|
262
|
-
})
|
|
263
251
|
})
|
|
264
252
|
|
|
265
253
|
describe('getCurrentCommonAncestor', () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EMPTY_ARRAY, atom, computed } from '@tldraw/state'
|
|
2
|
-
import { TLParentId, TLShapeId, isShapeId } from '@tldraw/tlschema'
|
|
2
|
+
import { TLFrameShape, TLGroupShape, TLParentId, TLShapeId, isShapeId } from '@tldraw/tlschema'
|
|
3
3
|
import { Vec, VecLike } from '../../../primitives/Vec'
|
|
4
4
|
import type { Editor } from '../../Editor'
|
|
5
5
|
import { BoundsSnaps } from './BoundsSnaps'
|
|
@@ -58,7 +58,7 @@ export class SnapManager {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
@computed getSnapThreshold() {
|
|
61
|
-
return
|
|
61
|
+
return 8 / this.editor.getZoomLevel()
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// TODO: make this an incremental derivation
|
|
@@ -72,7 +72,7 @@ export class SnapManager {
|
|
|
72
72
|
const collectSnappableShapesFromParent = (parentId: TLParentId) => {
|
|
73
73
|
if (isShapeId(parentId)) {
|
|
74
74
|
const parent = editor.getShape(parentId)
|
|
75
|
-
if (parent && editor.isShapeOfType(parent, 'frame')) {
|
|
75
|
+
if (parent && editor.isShapeOfType<TLFrameShape>(parent, 'frame')) {
|
|
76
76
|
snappableShapes.add(parentId)
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -89,7 +89,7 @@ export class SnapManager {
|
|
|
89
89
|
const pageBounds = editor.getShapePageBounds(childId)
|
|
90
90
|
if (!(pageBounds && renderingBounds.includes(pageBounds))) continue
|
|
91
91
|
// Snap to children of groups but not group itself
|
|
92
|
-
if (editor.isShapeOfType(childShape, 'group')) {
|
|
92
|
+
if (editor.isShapeOfType<TLGroupShape>(childShape, 'group')) {
|
|
93
93
|
collectSnappableShapesFromParent(childId)
|
|
94
94
|
continue
|
|
95
95
|
}
|