tldraw 3.15.0 → 3.16.0-canary.0e0fb8bde89d
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 +101 -5
- package/dist-cjs/index.js +12 -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/components/primitives/menus/TldrawUiMenuItem.js +149 -1
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.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 +2 -2
- package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +76 -9
- package/dist-cjs/lib/ui/hooks/useTools.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 +101 -5
- package/dist-esm/index.mjs +18 -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/components/primitives/menus/TldrawUiMenuItem.mjs +157 -3
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.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 +2 -2
- package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +83 -10
- package/dist-esm/lib/ui/hooks/useTools.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 +11 -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 -1
- 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/components/primitives/menus/TldrawUiMenuItem.tsx +213 -2
- package/src/lib/ui/context/actions.tsx +14 -7
- package/src/lib/ui/context/events.tsx +3 -2
- package/src/lib/ui/hooks/menu-hooks.ts +1 -0
- package/src/lib/ui/hooks/useTools.tsx +118 -10
- 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
|
@@ -405,7 +405,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
|
|
|
405
405
|
...inCommon,
|
|
406
406
|
type: 'arrow',
|
|
407
407
|
props: {
|
|
408
|
-
|
|
408
|
+
richText: toRichText(v1Shape.label ?? ''),
|
|
409
409
|
color: getV2Color(v1Shape.style.color),
|
|
410
410
|
labelColor: getV2Color(v1Shape.style.color),
|
|
411
411
|
size: getV2Size(v1Shape.style.size),
|
|
@@ -562,6 +562,7 @@ export function buildFromV1Document(editor: Editor, _document: unknown) {
|
|
|
562
562
|
y: point.y,
|
|
563
563
|
},
|
|
564
564
|
isPrecise: point.x !== 0.5 || point.y !== 0.5,
|
|
565
|
+
isCreatingShape: true,
|
|
565
566
|
})
|
|
566
567
|
|
|
567
568
|
if (change) {
|
|
@@ -275,17 +275,27 @@ describe('PointingLabel', () => {
|
|
|
275
275
|
type: 'arrow',
|
|
276
276
|
x: 100,
|
|
277
277
|
y: 100,
|
|
278
|
-
props: {
|
|
278
|
+
props: {
|
|
279
|
+
richText: toRichText('Test Label'),
|
|
280
|
+
start: { x: 0, y: 0 },
|
|
281
|
+
end: { x: 100, y: 0 },
|
|
282
|
+
},
|
|
279
283
|
},
|
|
280
284
|
])
|
|
281
|
-
const shape = editor.getShape(ids.arrow1)
|
|
282
|
-
|
|
285
|
+
const shape = editor.getShape(ids.arrow1)!
|
|
286
|
+
// First select the shape so it's already selected
|
|
287
|
+
editor.select(shape.id)
|
|
288
|
+
|
|
289
|
+
// Click at the middle of the arrow where the label would be and drag to move the label
|
|
290
|
+
editor.pointerDown(150, 100, {
|
|
283
291
|
target: 'shape',
|
|
284
292
|
shape,
|
|
285
293
|
})
|
|
286
|
-
editor.pointerMove(
|
|
294
|
+
editor.pointerMove(160, 100)
|
|
287
295
|
editor.expectToBeIn('select.pointing_arrow_label')
|
|
288
296
|
|
|
297
|
+
// Continue dragging to actually move the label, then it should go to idle
|
|
298
|
+
editor.pointerMove(170, 100)
|
|
289
299
|
editor.pointerUp()
|
|
290
300
|
editor.expectToBeIn('select.idle')
|
|
291
301
|
})
|
|
@@ -297,16 +307,21 @@ describe('PointingLabel', () => {
|
|
|
297
307
|
type: 'arrow',
|
|
298
308
|
x: 100,
|
|
299
309
|
y: 100,
|
|
300
|
-
props: {
|
|
310
|
+
props: {
|
|
311
|
+
richText: toRichText('Test Label'),
|
|
312
|
+
start: { x: 0, y: 0 },
|
|
313
|
+
end: { x: 100, y: 0 },
|
|
314
|
+
},
|
|
301
315
|
},
|
|
302
316
|
])
|
|
303
317
|
const shape = editor.getShape(ids.arrow1)
|
|
304
318
|
|
|
305
|
-
|
|
319
|
+
// Click at the middle of the arrow where the label would be
|
|
320
|
+
editor.pointerDown(150, 100, {
|
|
306
321
|
target: 'shape',
|
|
307
322
|
shape,
|
|
308
323
|
})
|
|
309
|
-
editor.pointerMove(
|
|
324
|
+
editor.pointerMove(160, 100)
|
|
310
325
|
editor.expectToBeIn('select.pointing_arrow_label')
|
|
311
326
|
editor.cancel()
|
|
312
327
|
editor.expectToBeIn('select.idle')
|
|
@@ -314,14 +329,25 @@ describe('PointingLabel', () => {
|
|
|
314
329
|
|
|
315
330
|
it('Doesnt go into pointing_arrow_label mode if not selecting the arrow shape', () => {
|
|
316
331
|
editor.createShapes<TLArrowShape>([
|
|
317
|
-
{
|
|
332
|
+
{
|
|
333
|
+
id: ids.arrow1,
|
|
334
|
+
type: 'arrow',
|
|
335
|
+
x: 100,
|
|
336
|
+
y: 100,
|
|
337
|
+
props: {
|
|
338
|
+
richText: toRichText(''), // Empty label
|
|
339
|
+
start: { x: 0, y: 0 },
|
|
340
|
+
end: { x: 100, y: 0 },
|
|
341
|
+
},
|
|
342
|
+
},
|
|
318
343
|
])
|
|
319
|
-
const shape = editor.getShape(ids.arrow1)
|
|
320
|
-
|
|
344
|
+
const shape = editor.getShape(ids.arrow1)!
|
|
345
|
+
// Click anywhere on the arrow - since there's no label, it should go to translating
|
|
346
|
+
editor.pointerDown(150, 100, {
|
|
321
347
|
target: 'shape',
|
|
322
348
|
shape,
|
|
323
349
|
})
|
|
324
|
-
editor.pointerMove(
|
|
350
|
+
editor.pointerMove(155, 105)
|
|
325
351
|
editor.expectToBeIn('select.translating')
|
|
326
352
|
|
|
327
353
|
editor.pointerUp()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PageRecordType } from '@tldraw/editor'
|
|
1
|
+
import { PageRecordType, createShapeId } from '@tldraw/editor'
|
|
2
2
|
import { TestEditor } from '../TestEditor'
|
|
3
3
|
|
|
4
4
|
let editor: TestEditor
|
|
@@ -76,4 +76,87 @@ describe('deletePage', () => {
|
|
|
76
76
|
expect(editor.getCurrentPageId()).not.toBe(currentPageId)
|
|
77
77
|
expect(editor.getCurrentPageId()).toBe(editor.getPages()[0].id)
|
|
78
78
|
})
|
|
79
|
+
|
|
80
|
+
it('deletes all shapes that belong to the deleted page', () => {
|
|
81
|
+
// Create a second page
|
|
82
|
+
const page2Id = PageRecordType.createId('page2')
|
|
83
|
+
editor.createPage({ name: 'Page 2', id: page2Id })
|
|
84
|
+
|
|
85
|
+
// Switch to the second page
|
|
86
|
+
editor.setCurrentPage(page2Id)
|
|
87
|
+
|
|
88
|
+
// Add some shapes to the second page
|
|
89
|
+
const shape1Id = createShapeId('shape1')
|
|
90
|
+
const shape2Id = createShapeId('shape2')
|
|
91
|
+
const shape3Id = createShapeId('shape3')
|
|
92
|
+
|
|
93
|
+
editor.createShape({ id: shape1Id, type: 'text', x: 100, y: 100 })
|
|
94
|
+
editor.createShape({ id: shape2Id, type: 'geo', x: 200, y: 200, props: { geo: 'rectangle' } })
|
|
95
|
+
editor.createShape({ id: shape3Id, type: 'geo', x: 300, y: 300, props: { geo: 'ellipse' } })
|
|
96
|
+
|
|
97
|
+
// Verify shapes were created and belong to the second page
|
|
98
|
+
expect(editor.getShape(shape1Id)).toBeDefined()
|
|
99
|
+
expect(editor.getShape(shape2Id)).toBeDefined()
|
|
100
|
+
expect(editor.getShape(shape3Id)).toBeDefined()
|
|
101
|
+
expect(editor.getShape(shape1Id)?.parentId).toBe(page2Id)
|
|
102
|
+
expect(editor.getShape(shape2Id)?.parentId).toBe(page2Id)
|
|
103
|
+
expect(editor.getShape(shape3Id)?.parentId).toBe(page2Id)
|
|
104
|
+
|
|
105
|
+
// Delete the second page
|
|
106
|
+
editor.deletePage(page2Id)
|
|
107
|
+
|
|
108
|
+
// Verify the page was deleted
|
|
109
|
+
expect(editor.getPages().length).toBe(1)
|
|
110
|
+
expect(editor.getPages()[0].id).not.toBe(page2Id)
|
|
111
|
+
|
|
112
|
+
// Verify all shapes that belonged to the deleted page were also deleted
|
|
113
|
+
expect(editor.getShape(shape1Id)).toBeUndefined()
|
|
114
|
+
expect(editor.getShape(shape2Id)).toBeUndefined()
|
|
115
|
+
expect(editor.getShape(shape3Id)).toBeUndefined()
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('deletes locked shapes that belong to the deleted page', () => {
|
|
119
|
+
// Create a second page
|
|
120
|
+
const page2Id = PageRecordType.createId('page2')
|
|
121
|
+
editor.createPage({ name: 'Page 2', id: page2Id })
|
|
122
|
+
|
|
123
|
+
// Switch to the second page
|
|
124
|
+
editor.setCurrentPage(page2Id)
|
|
125
|
+
|
|
126
|
+
// Add some shapes to the second page
|
|
127
|
+
const shape1Id = createShapeId('shape1')
|
|
128
|
+
const shape2Id = createShapeId('shape2')
|
|
129
|
+
const shape3Id = createShapeId('shape3')
|
|
130
|
+
|
|
131
|
+
editor.createShape({ id: shape1Id, type: 'text', x: 100, y: 100 })
|
|
132
|
+
editor.createShape({ id: shape2Id, type: 'geo', x: 200, y: 200, props: { geo: 'rectangle' } })
|
|
133
|
+
editor.createShape({ id: shape3Id, type: 'geo', x: 300, y: 300, props: { geo: 'ellipse' } })
|
|
134
|
+
|
|
135
|
+
// Lock some of the shapes
|
|
136
|
+
editor.updateShape({ id: shape1Id, type: 'text', isLocked: true })
|
|
137
|
+
editor.updateShape({ id: shape2Id, type: 'geo', isLocked: true })
|
|
138
|
+
|
|
139
|
+
// Verify shapes were created and belong to the second page
|
|
140
|
+
expect(editor.getShape(shape1Id)).toBeDefined()
|
|
141
|
+
expect(editor.getShape(shape2Id)).toBeDefined()
|
|
142
|
+
expect(editor.getShape(shape3Id)).toBeDefined()
|
|
143
|
+
expect(editor.getShape(shape1Id)?.parentId).toBe(page2Id)
|
|
144
|
+
expect(editor.getShape(shape2Id)?.parentId).toBe(page2Id)
|
|
145
|
+
expect(editor.getShape(shape3Id)?.parentId).toBe(page2Id)
|
|
146
|
+
expect(editor.getShape(shape1Id)?.isLocked).toBe(true)
|
|
147
|
+
expect(editor.getShape(shape2Id)?.isLocked).toBe(true)
|
|
148
|
+
expect(editor.getShape(shape3Id)?.isLocked).toBe(false)
|
|
149
|
+
|
|
150
|
+
// Delete the second page
|
|
151
|
+
editor.deletePage(page2Id)
|
|
152
|
+
|
|
153
|
+
// Verify the page was deleted
|
|
154
|
+
expect(editor.getPages().length).toBe(1)
|
|
155
|
+
expect(editor.getPages()[0].id).not.toBe(page2Id)
|
|
156
|
+
|
|
157
|
+
// Verify all shapes that belonged to the deleted page were also deleted, including locked ones
|
|
158
|
+
expect(editor.getShape(shape1Id)).toBeUndefined()
|
|
159
|
+
expect(editor.getShape(shape2Id)).toBeUndefined()
|
|
160
|
+
expect(editor.getShape(shape3Id)).toBeUndefined()
|
|
161
|
+
})
|
|
79
162
|
})
|