tldraw 3.15.0 → 3.16.0-next.c30b1b5e551a
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 +69 -4
- package/dist-cjs/index.js +11 -2
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +1 -0
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +22 -36
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js +16 -4
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +15 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +43 -22
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -15
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +5 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +8 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +8 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +8 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +40 -0
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +14 -7
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/kbd-utils.js +2 -1
- package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +3 -2
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
- package/dist-esm/index.d.mts +69 -4
- package/dist-esm/index.mjs +16 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +1 -0
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +24 -36
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +19 -5
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +3 -0
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +15 -1
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +43 -22
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -15
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +5 -0
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +8 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +8 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +8 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +40 -0
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +1 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +14 -7
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +1 -1
- package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/kbd-utils.mjs +2 -1
- package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +3 -2
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
- package/package.json +3 -3
- package/src/index.ts +9 -1
- package/src/lib/canvas/TldrawCropHandles.tsx +2 -0
- package/src/lib/defaultExternalContentHandlers.ts +2 -1
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +5 -5
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +25 -39
- package/src/lib/shapes/arrow/arrowLabel.ts +23 -3
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +3 -0
- package/src/lib/shapes/line/LineShapeUtil.tsx +19 -2
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +54 -30
- package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -24
- package/src/lib/tools/SelectTool/childStates/PointingShape.ts +7 -0
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +12 -1
- package/src/lib/tools/SelectTool/childStates/Rotating.ts +11 -0
- package/src/lib/tools/SelectTool/childStates/Translating.ts +11 -0
- package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -0
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +32 -0
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +3 -1
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +1 -0
- package/src/lib/ui/context/actions.tsx +14 -7
- package/src/lib/ui/context/events.tsx +2 -2
- package/src/lib/ui/hooks/menu-hooks.ts +1 -0
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +4 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -0
- package/src/lib/ui/kbd-utils.ts +2 -1
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +16 -2
- package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
- package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +24 -3
- package/src/lib/utils/tldr/buildFromV1Document.ts +2 -1
- package/src/test/SelectTool.test.ts +37 -11
- package/src/test/commands/deletePage.test.ts +84 -1
- package/src/test/shapeutils.test.ts +394 -45
- package/tldraw.css +4 -23
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createShapeId, TLFrameShape, TLGeoShape } from '@tldraw/editor'
|
|
1
|
+
import { createShapeId, TLFrameShape, TLGeoShape, TLLineShape } from '@tldraw/editor'
|
|
2
2
|
import { TestEditor } from './TestEditor'
|
|
3
3
|
|
|
4
4
|
let editor: TestEditor
|
|
@@ -11,6 +11,8 @@ const ids = {
|
|
|
11
11
|
frame1: createShapeId('frame1'),
|
|
12
12
|
box1: createShapeId('box1'),
|
|
13
13
|
box2: createShapeId('box2'),
|
|
14
|
+
line1: createShapeId('line1'),
|
|
15
|
+
page1: createShapeId('page1'),
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
beforeEach(() => {
|
|
@@ -56,34 +58,93 @@ describe('When interacting with a shape...', () => {
|
|
|
56
58
|
// Set start / change / end events on only the geo shape
|
|
57
59
|
const util = editor.getShapeUtil<TLFrameShape>('frame')
|
|
58
60
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
+
const calls: string[] = []
|
|
62
|
+
|
|
63
|
+
util.onRotateStart = () => {
|
|
64
|
+
calls.push('start')
|
|
65
|
+
}
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
util.onRotate = () => {
|
|
68
|
+
calls.push('change')
|
|
69
|
+
}
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
util.onRotateEnd = () => {
|
|
72
|
+
calls.push('end')
|
|
73
|
+
}
|
|
67
74
|
|
|
68
75
|
editor.selectAll()
|
|
69
76
|
expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
|
|
70
77
|
|
|
71
|
-
editor
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})
|
|
76
|
-
.pointerMove(200, 200)
|
|
77
|
-
.pointerUp(200, 200)
|
|
78
|
+
editor.pointerDown(300, 300, {
|
|
79
|
+
target: 'selection',
|
|
80
|
+
handle: 'bottom_right_rotate',
|
|
81
|
+
})
|
|
78
82
|
|
|
79
|
-
//
|
|
80
|
-
expect(
|
|
83
|
+
// Should not have called any callbacks yet
|
|
84
|
+
expect(calls).toEqual([])
|
|
85
|
+
|
|
86
|
+
editor.pointerMove(200, 200)
|
|
81
87
|
|
|
82
|
-
//
|
|
83
|
-
expect(
|
|
88
|
+
// Should have called start once and change at least once now
|
|
89
|
+
expect(calls).toEqual(['start', 'change'])
|
|
84
90
|
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
editor.pointerMove(200, 210)
|
|
92
|
+
|
|
93
|
+
// Should have called start once and change multiple times
|
|
94
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
95
|
+
|
|
96
|
+
editor.pointerUp(200, 210)
|
|
97
|
+
|
|
98
|
+
// Should have called end once now
|
|
99
|
+
expect(calls).toEqual(['start', 'change', 'change', 'change', 'end'])
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('fires rotate cancel events', () => {
|
|
103
|
+
const util = editor.getShapeUtil<TLFrameShape>('frame')
|
|
104
|
+
|
|
105
|
+
const calls: string[] = []
|
|
106
|
+
|
|
107
|
+
util.onRotateStart = () => {
|
|
108
|
+
calls.push('start')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
util.onRotate = () => {
|
|
112
|
+
calls.push('change')
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
util.onRotateEnd = () => {
|
|
116
|
+
calls.push('end')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
util.onRotateCancel = () => {
|
|
120
|
+
calls.push('cancel')
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
editor.selectAll()
|
|
124
|
+
expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
|
|
125
|
+
|
|
126
|
+
editor.pointerDown(300, 300, {
|
|
127
|
+
target: 'selection',
|
|
128
|
+
handle: 'bottom_right_rotate',
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
// Should not have called any callbacks yet
|
|
132
|
+
expect(calls).toEqual([])
|
|
133
|
+
|
|
134
|
+
editor.pointerMove(200, 200)
|
|
135
|
+
|
|
136
|
+
// Should have called start once and change at least once now
|
|
137
|
+
expect(calls).toEqual(['start', 'change'])
|
|
138
|
+
|
|
139
|
+
editor.pointerMove(200, 210)
|
|
140
|
+
|
|
141
|
+
// Should have called start once and change multiple times
|
|
142
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
143
|
+
|
|
144
|
+
editor.cancel()
|
|
145
|
+
|
|
146
|
+
// Should have called cancel instead of end
|
|
147
|
+
expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
|
|
87
148
|
})
|
|
88
149
|
|
|
89
150
|
it('cleans up events', () => {
|
|
@@ -105,14 +166,19 @@ describe('When interacting with a shape...', () => {
|
|
|
105
166
|
it('Fires resisizing events', () => {
|
|
106
167
|
const util = editor.getShapeUtil<TLFrameShape>('frame')
|
|
107
168
|
|
|
108
|
-
const
|
|
109
|
-
|
|
169
|
+
const calls: string[] = []
|
|
170
|
+
|
|
171
|
+
util.onResizeStart = () => {
|
|
172
|
+
calls.push('start')
|
|
173
|
+
}
|
|
110
174
|
|
|
111
|
-
|
|
112
|
-
|
|
175
|
+
util.onResize = () => {
|
|
176
|
+
calls.push('change')
|
|
177
|
+
}
|
|
113
178
|
|
|
114
|
-
|
|
115
|
-
|
|
179
|
+
util.onResizeEnd = () => {
|
|
180
|
+
calls.push('end')
|
|
181
|
+
}
|
|
116
182
|
|
|
117
183
|
editor.selectAll()
|
|
118
184
|
expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
|
|
@@ -123,48 +189,165 @@ describe('When interacting with a shape...', () => {
|
|
|
123
189
|
})
|
|
124
190
|
|
|
125
191
|
editor.expectToBeIn('select.pointing_resize_handle')
|
|
192
|
+
|
|
193
|
+
// Should not have called any callbacks yet
|
|
194
|
+
expect(calls).toEqual([])
|
|
195
|
+
|
|
126
196
|
editor.pointerMove(200, 200)
|
|
127
197
|
editor.expectToBeIn('select.resizing')
|
|
198
|
+
|
|
199
|
+
// Should have called start once and change at least once now
|
|
200
|
+
expect(calls).toEqual(['start', 'change'])
|
|
201
|
+
|
|
128
202
|
editor.pointerMove(200, 210)
|
|
203
|
+
|
|
204
|
+
// Should have called start once and change multiple times
|
|
205
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
206
|
+
|
|
129
207
|
editor.pointerUp(200, 210)
|
|
130
208
|
editor.expectToBeIn('select.idle')
|
|
131
209
|
|
|
132
|
-
//
|
|
133
|
-
expect(
|
|
210
|
+
// Should have called end once now
|
|
211
|
+
expect(calls).toEqual(['start', 'change', 'change', 'end'])
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
it('Fires resizing cancel events', () => {
|
|
215
|
+
const util = editor.getShapeUtil<TLFrameShape>('frame')
|
|
216
|
+
|
|
217
|
+
const calls: string[] = []
|
|
218
|
+
|
|
219
|
+
util.onResizeStart = () => {
|
|
220
|
+
calls.push('start')
|
|
221
|
+
}
|
|
134
222
|
|
|
135
|
-
|
|
136
|
-
|
|
223
|
+
util.onResize = () => {
|
|
224
|
+
calls.push('change')
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
util.onResizeEnd = () => {
|
|
228
|
+
calls.push('end')
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
util.onResizeCancel = () => {
|
|
232
|
+
calls.push('cancel')
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
editor.selectAll()
|
|
236
|
+
expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
|
|
237
|
+
|
|
238
|
+
editor.pointerDown(300, 300, {
|
|
239
|
+
target: 'selection',
|
|
240
|
+
handle: 'bottom_right',
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
editor.expectToBeIn('select.pointing_resize_handle')
|
|
244
|
+
|
|
245
|
+
// Should not have called any callbacks yet
|
|
246
|
+
expect(calls).toEqual([])
|
|
247
|
+
|
|
248
|
+
editor.pointerMove(200, 200)
|
|
249
|
+
editor.expectToBeIn('select.resizing')
|
|
137
250
|
|
|
138
|
-
//
|
|
139
|
-
expect(
|
|
251
|
+
// Should have called start once and change at least once now
|
|
252
|
+
expect(calls).toEqual(['start', 'change'])
|
|
253
|
+
|
|
254
|
+
editor.pointerMove(200, 210)
|
|
255
|
+
|
|
256
|
+
// Should have called start once and change multiple times
|
|
257
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
258
|
+
|
|
259
|
+
editor.cancel()
|
|
260
|
+
|
|
261
|
+
// Should have called cancel instead of end
|
|
262
|
+
expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
|
|
140
263
|
})
|
|
141
264
|
|
|
142
265
|
it('Fires translating events', () => {
|
|
143
266
|
const util = editor.getShapeUtil<TLFrameShape>('frame')
|
|
144
267
|
|
|
145
|
-
const
|
|
146
|
-
|
|
268
|
+
const calls: string[] = []
|
|
269
|
+
|
|
270
|
+
util.onTranslateStart = () => {
|
|
271
|
+
calls.push('start')
|
|
272
|
+
}
|
|
147
273
|
|
|
148
|
-
|
|
149
|
-
|
|
274
|
+
util.onTranslate = () => {
|
|
275
|
+
calls.push('change')
|
|
276
|
+
}
|
|
150
277
|
|
|
151
|
-
|
|
152
|
-
|
|
278
|
+
util.onTranslateEnd = () => {
|
|
279
|
+
calls.push('end')
|
|
280
|
+
}
|
|
153
281
|
|
|
154
282
|
editor.selectAll()
|
|
155
283
|
expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
|
|
156
284
|
|
|
157
285
|
// Translate the shapes...
|
|
158
|
-
editor.pointerDown(50, 50, ids.box1)
|
|
286
|
+
editor.pointerDown(50, 50, ids.box1)
|
|
159
287
|
|
|
160
|
-
//
|
|
161
|
-
expect(
|
|
288
|
+
// Should not have called any callbacks yet
|
|
289
|
+
expect(calls).toEqual([])
|
|
290
|
+
|
|
291
|
+
editor.pointerMove(50, 40)
|
|
162
292
|
|
|
163
|
-
//
|
|
164
|
-
expect(
|
|
293
|
+
// Should have called start once and change at least once now
|
|
294
|
+
expect(calls).toEqual(['start', 'change'])
|
|
165
295
|
|
|
166
|
-
|
|
167
|
-
|
|
296
|
+
editor.pointerMove(50, 35)
|
|
297
|
+
|
|
298
|
+
// Should have called start once and change multiple times
|
|
299
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
300
|
+
|
|
301
|
+
editor.pointerUp(50, 35)
|
|
302
|
+
|
|
303
|
+
// Should have called end once now
|
|
304
|
+
expect(calls).toEqual(['start', 'change', 'change', 'change', 'end'])
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it('Fires translating cancel events', () => {
|
|
308
|
+
const util = editor.getShapeUtil<TLFrameShape>('frame')
|
|
309
|
+
|
|
310
|
+
const calls: string[] = []
|
|
311
|
+
|
|
312
|
+
util.onTranslateStart = () => {
|
|
313
|
+
calls.push('start')
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
util.onTranslate = () => {
|
|
317
|
+
calls.push('change')
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
util.onTranslateEnd = () => {
|
|
321
|
+
calls.push('end')
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
util.onTranslateCancel = () => {
|
|
325
|
+
calls.push('cancel')
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
editor.selectAll()
|
|
329
|
+
expect(editor.getSelectedShapeIds()).toMatchObject([ids.frame1, ids.box1])
|
|
330
|
+
|
|
331
|
+
// Translate the shapes...
|
|
332
|
+
editor.pointerDown(50, 50, ids.box1)
|
|
333
|
+
|
|
334
|
+
// Should not have called any callbacks yet
|
|
335
|
+
expect(calls).toEqual([])
|
|
336
|
+
|
|
337
|
+
editor.pointerMove(50, 40)
|
|
338
|
+
|
|
339
|
+
// Should have called start once and change at least once now
|
|
340
|
+
expect(calls).toEqual(['start', 'change'])
|
|
341
|
+
|
|
342
|
+
editor.pointerMove(50, 35)
|
|
343
|
+
|
|
344
|
+
// Should have called start once and change multiple times
|
|
345
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
346
|
+
|
|
347
|
+
editor.cancel()
|
|
348
|
+
|
|
349
|
+
// Should have called cancel instead of end
|
|
350
|
+
expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
|
|
168
351
|
})
|
|
169
352
|
|
|
170
353
|
it('Uses the shape utils onClick handler', () => {
|
|
@@ -201,4 +384,170 @@ describe('When interacting with a shape...', () => {
|
|
|
201
384
|
// it should not be selected.
|
|
202
385
|
expect(editor.getSelectedShapeIds().length).toBe(0)
|
|
203
386
|
})
|
|
387
|
+
|
|
388
|
+
it('Fires handle dragging events', () => {
|
|
389
|
+
const util = editor.getShapeUtil<TLLineShape>('line')
|
|
390
|
+
|
|
391
|
+
const calls: string[] = []
|
|
392
|
+
|
|
393
|
+
util.onHandleDragStart = () => {
|
|
394
|
+
calls.push('start')
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
util.onHandleDrag = () => {
|
|
398
|
+
calls.push('change')
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
util.onHandleDragEnd = () => {
|
|
402
|
+
calls.push('end')
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
util.onHandleDragCancel = () => {
|
|
406
|
+
calls.push('cancel')
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Create a line shape with handles
|
|
410
|
+
const lineShape: TLLineShape = {
|
|
411
|
+
id: ids.line1,
|
|
412
|
+
type: 'line',
|
|
413
|
+
typeName: 'shape',
|
|
414
|
+
parentId: ids.page1,
|
|
415
|
+
index: 'a1' as any,
|
|
416
|
+
x: 100,
|
|
417
|
+
y: 100,
|
|
418
|
+
rotation: 0,
|
|
419
|
+
isLocked: false,
|
|
420
|
+
opacity: 1,
|
|
421
|
+
meta: {},
|
|
422
|
+
props: {
|
|
423
|
+
dash: 'draw',
|
|
424
|
+
size: 'm',
|
|
425
|
+
color: 'black',
|
|
426
|
+
spline: 'line',
|
|
427
|
+
scale: 1,
|
|
428
|
+
points: {
|
|
429
|
+
a1: { id: 'a1', index: 'a1' as any, x: 0, y: 0 },
|
|
430
|
+
a2: { id: 'a2', index: 'a2' as any, x: 100, y: 100 },
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
editor.createShapes([lineShape])
|
|
436
|
+
|
|
437
|
+
// Get the handle point
|
|
438
|
+
const handlePagePoint = editor
|
|
439
|
+
.getShapePageTransform(lineShape.id)!
|
|
440
|
+
.applyToPoint(lineShape.props.points['a2'])
|
|
441
|
+
|
|
442
|
+
editor.pointerDown(handlePagePoint.x, handlePagePoint.y, {
|
|
443
|
+
target: 'handle',
|
|
444
|
+
shape: editor.getShape(lineShape.id)!,
|
|
445
|
+
handle: { id: 'a2', type: 'vertex', index: 'a2' as any, x: 100, y: 100 },
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
editor.expectToBeIn('select.pointing_handle')
|
|
449
|
+
|
|
450
|
+
// Should not have called any callbacks yet
|
|
451
|
+
expect(calls).toEqual([])
|
|
452
|
+
|
|
453
|
+
editor.pointerMove(handlePagePoint.x + 20, handlePagePoint.y + 20) // Larger move to trigger drag
|
|
454
|
+
editor.expectToBeIn('select.dragging_handle')
|
|
455
|
+
|
|
456
|
+
// Should have called start once and change at least once now
|
|
457
|
+
expect(calls).toEqual(['start', 'change'])
|
|
458
|
+
|
|
459
|
+
editor.pointerMove(150, 150)
|
|
460
|
+
|
|
461
|
+
// Should have called start once and change multiple times
|
|
462
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
463
|
+
|
|
464
|
+
editor.pointerUp(150, 150)
|
|
465
|
+
editor.expectToBeIn('select.idle')
|
|
466
|
+
|
|
467
|
+
// Should have called end once now
|
|
468
|
+
expect(calls).toEqual(['start', 'change', 'change', 'end'])
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
it('Fires handle dragging cancel events', () => {
|
|
472
|
+
const util = editor.getShapeUtil<TLLineShape>('line')
|
|
473
|
+
|
|
474
|
+
const calls: string[] = []
|
|
475
|
+
|
|
476
|
+
util.onHandleDragStart = () => {
|
|
477
|
+
calls.push('start')
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
util.onHandleDrag = () => {
|
|
481
|
+
calls.push('change')
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
util.onHandleDragEnd = () => {
|
|
485
|
+
calls.push('end')
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
util.onHandleDragCancel = () => {
|
|
489
|
+
calls.push('cancel')
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Create a line shape with handles
|
|
493
|
+
const lineShape: TLLineShape = {
|
|
494
|
+
id: ids.line1,
|
|
495
|
+
type: 'line',
|
|
496
|
+
typeName: 'shape',
|
|
497
|
+
parentId: ids.page1,
|
|
498
|
+
index: 'a1' as any,
|
|
499
|
+
x: 100,
|
|
500
|
+
y: 100,
|
|
501
|
+
rotation: 0,
|
|
502
|
+
isLocked: false,
|
|
503
|
+
opacity: 1,
|
|
504
|
+
meta: {},
|
|
505
|
+
props: {
|
|
506
|
+
dash: 'draw',
|
|
507
|
+
size: 'm',
|
|
508
|
+
color: 'black',
|
|
509
|
+
spline: 'line',
|
|
510
|
+
scale: 1,
|
|
511
|
+
points: {
|
|
512
|
+
a1: { id: 'a1', index: 'a1' as any, x: 0, y: 0 },
|
|
513
|
+
a2: { id: 'a2', index: 'a2' as any, x: 100, y: 100 },
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
editor.createShapes([lineShape])
|
|
519
|
+
|
|
520
|
+
// Get the handle point
|
|
521
|
+
const handlePagePoint = editor
|
|
522
|
+
.getShapePageTransform(lineShape.id)!
|
|
523
|
+
.applyToPoint(lineShape.props.points['a2'])
|
|
524
|
+
|
|
525
|
+
editor.pointerDown(handlePagePoint.x, handlePagePoint.y, {
|
|
526
|
+
target: 'handle',
|
|
527
|
+
shape: editor.getShape(lineShape.id)!,
|
|
528
|
+
handle: { id: 'a2', type: 'vertex', index: 'a2' as any, x: 100, y: 100 },
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
editor.expectToBeIn('select.pointing_handle')
|
|
532
|
+
|
|
533
|
+
// Should not have called any callbacks yet
|
|
534
|
+
expect(calls).toEqual([])
|
|
535
|
+
|
|
536
|
+
editor.pointerMove(handlePagePoint.x + 20, handlePagePoint.y + 20) // Larger move to trigger drag
|
|
537
|
+
editor.expectToBeIn('select.dragging_handle')
|
|
538
|
+
|
|
539
|
+
// Should have called start once and change at least once now
|
|
540
|
+
expect(calls).toEqual(['start', 'change'])
|
|
541
|
+
|
|
542
|
+
editor.pointerMove(150, 150)
|
|
543
|
+
|
|
544
|
+
// Should have called start once and change multiple times
|
|
545
|
+
expect(calls).toEqual(['start', 'change', 'change'])
|
|
546
|
+
|
|
547
|
+
editor.cancel()
|
|
548
|
+
editor.expectToBeIn('select.idle')
|
|
549
|
+
|
|
550
|
+
// Should have called cancel instead of end
|
|
551
|
+
expect(calls).toEqual(['start', 'change', 'change', 'cancel'])
|
|
552
|
+
})
|
|
204
553
|
})
|
package/tldraw.css
CHANGED
|
@@ -778,8 +778,7 @@ input,
|
|
|
778
778
|
position: static;
|
|
779
779
|
}
|
|
780
780
|
|
|
781
|
-
.tl-text-wrapper[data-isediting='false'] .tl-text-input
|
|
782
|
-
.tl-arrow-label[data-isediting='false'] .tl-text-input {
|
|
781
|
+
.tl-text-wrapper[data-isediting='false'] .tl-text-input {
|
|
783
782
|
opacity: 0;
|
|
784
783
|
cursor: var(--tl-cursor-default);
|
|
785
784
|
}
|
|
@@ -1192,7 +1191,7 @@ input,
|
|
|
1192
1191
|
|
|
1193
1192
|
/* --------------------- Arrow shape -------------------- */
|
|
1194
1193
|
|
|
1195
|
-
.tl-arrow-label {
|
|
1194
|
+
.tl-shape[data-shape-type='arrow'] .tl-text-label {
|
|
1196
1195
|
position: absolute;
|
|
1197
1196
|
top: -1px;
|
|
1198
1197
|
left: -1px;
|
|
@@ -1207,33 +1206,15 @@ input,
|
|
|
1207
1206
|
text-shadow: var(--tl-text-outline);
|
|
1208
1207
|
}
|
|
1209
1208
|
|
|
1210
|
-
.tl-
|
|
1211
|
-
opacity: 0;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
.tl-arrow-label__inner {
|
|
1209
|
+
.tl-shape[data-shape-type='arrow'] .tl-text-label__inner {
|
|
1215
1210
|
border-radius: var(--radius-1);
|
|
1216
1211
|
box-sizing: content-box;
|
|
1217
|
-
position: relative;
|
|
1218
1212
|
height: max-content;
|
|
1219
1213
|
width: max-content;
|
|
1220
|
-
pointer-events: none;
|
|
1221
|
-
display: flex;
|
|
1222
|
-
justify-content: center;
|
|
1223
|
-
align-items: center;
|
|
1224
1214
|
}
|
|
1225
1215
|
|
|
1226
|
-
.tl-arrow
|
|
1227
|
-
position: relative;
|
|
1216
|
+
.tl-shape[data-shape-type='arrow'] .tl-text {
|
|
1228
1217
|
height: max-content;
|
|
1229
|
-
padding: inherit;
|
|
1230
|
-
overflow: visible;
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
.tl-arrow-label textarea {
|
|
1234
|
-
padding: inherit;
|
|
1235
|
-
/* Don't allow textarea to be zero width */
|
|
1236
|
-
min-width: 4px;
|
|
1237
1218
|
}
|
|
1238
1219
|
|
|
1239
1220
|
.tl-arrow-hint {
|