@tldraw/editor 3.14.0-canary.eab0b2f83117 → 3.14.0-canary.ed47bf46edcd
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 +16 -122
- package/dist-cjs/index.js +1 -4
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +25 -81
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +1 -3
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +2 -3
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +10 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +6 -10
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +3 -3
- package/dist-cjs/lib/editor/tools/StateNode.js +3 -3
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -1
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +2 -6
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +6 -11
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +1 -1
- package/dist-cjs/lib/utils/dom.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 +16 -122
- package/dist-esm/index.mjs +1 -4
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +25 -81
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +1 -3
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +2 -3
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +10 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +6 -10
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +3 -3
- package/dist-esm/lib/editor/tools/StateNode.mjs +3 -3
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -1
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +2 -6
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +6 -11
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +1 -1
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +12 -34
- package/package.json +7 -7
- package/src/index.ts +0 -6
- package/src/lib/editor/Editor.ts +35 -100
- package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +1 -3
- package/src/lib/editor/managers/TextManager/TextManager.ts +2 -4
- package/src/lib/editor/shapes/ShapeUtil.ts +15 -47
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +17 -22
- package/src/lib/editor/tools/StateNode.ts +3 -3
- package/src/lib/editor/types/emit-types.ts +0 -4
- package/src/lib/editor/types/external-content.ts +2 -11
- package/src/lib/hooks/useCanvasEvents.ts +1 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +2 -7
- package/src/lib/primitives/geometry/Group2d.ts +5 -11
- package/src/lib/utils/dom.ts +1 -1
- package/src/version.ts +3 -3
- package/dist-cjs/lib/utils/reparenting.js +0 -232
- package/dist-cjs/lib/utils/reparenting.js.map +0 -7
- package/dist-esm/lib/utils/reparenting.mjs +0 -216
- package/dist-esm/lib/utils/reparenting.mjs.map +0 -7
- package/src/lib/utils/reparenting.ts +0 -383
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -2122,20 +2122,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2122
2122
|
return this.getShapesPageBounds(this.getSelectedShapeIds())
|
|
2123
2123
|
}
|
|
2124
2124
|
|
|
2125
|
-
/**
|
|
2126
|
-
* The bounds of the selection bounding box in the current page space.
|
|
2127
|
-
*
|
|
2128
|
-
* @readonly
|
|
2129
|
-
* @public
|
|
2130
|
-
*/
|
|
2131
|
-
getSelectionScreenBounds(): Box | undefined {
|
|
2132
|
-
const bounds = this.getSelectionPageBounds()
|
|
2133
|
-
if (!bounds) return undefined
|
|
2134
|
-
const { x, y } = this.pageToScreen(bounds.point)
|
|
2135
|
-
const zoom = this.getZoomLevel()
|
|
2136
|
-
return new Box(x, y, bounds.width * zoom, bounds.height * zoom)
|
|
2137
|
-
}
|
|
2138
|
-
|
|
2139
2125
|
/**
|
|
2140
2126
|
* @internal
|
|
2141
2127
|
*/
|
|
@@ -3662,7 +3648,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3662
3648
|
* @public
|
|
3663
3649
|
*/
|
|
3664
3650
|
updateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {
|
|
3665
|
-
if (
|
|
3651
|
+
if (screenBounds instanceof HTMLElement) {
|
|
3666
3652
|
const rect = screenBounds.getBoundingClientRect()
|
|
3667
3653
|
screenBounds = new Box(
|
|
3668
3654
|
rect.left || rect.x,
|
|
@@ -5528,7 +5514,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5528
5514
|
if (!id) return undefined
|
|
5529
5515
|
const freshShape = this.getShape(id)
|
|
5530
5516
|
if (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined
|
|
5531
|
-
return this.
|
|
5517
|
+
return this.store.get(freshShape.parentId)
|
|
5532
5518
|
}
|
|
5533
5519
|
|
|
5534
5520
|
/**
|
|
@@ -5711,10 +5697,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5711
5697
|
const newPoint = invertedParentTransform.applyToPoint(pagePoint)
|
|
5712
5698
|
const newRotation = pageTransform.rotation() - parentPageRotation
|
|
5713
5699
|
|
|
5714
|
-
if (shape.id === parentId) {
|
|
5715
|
-
throw Error('Attempted to reparent a shape to itself!')
|
|
5716
|
-
}
|
|
5717
|
-
|
|
5718
5700
|
changes.push({
|
|
5719
5701
|
id: shape.id,
|
|
5720
5702
|
type: shape.type,
|
|
@@ -5818,11 +5800,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5818
5800
|
return shapeIds
|
|
5819
5801
|
}
|
|
5820
5802
|
|
|
5821
|
-
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
5822
|
-
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5823
|
-
return this.getDraggingOverShape(point, droppingShapes)
|
|
5824
|
-
}
|
|
5825
|
-
|
|
5826
5803
|
/**
|
|
5827
5804
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
5828
5805
|
*
|
|
@@ -5833,33 +5810,35 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5833
5810
|
*
|
|
5834
5811
|
* @public
|
|
5835
5812
|
*/
|
|
5836
|
-
|
|
5837
|
-
//
|
|
5838
|
-
const
|
|
5839
|
-
|
|
5840
|
-
|
|
5813
|
+
getDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {
|
|
5814
|
+
// starting from the top...
|
|
5815
|
+
const currentPageShapesSorted = this.getCurrentPageShapesSorted()
|
|
5816
|
+
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
5817
|
+
const shape = currentPageShapesSorted[i]
|
|
5841
5818
|
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
!
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5819
|
+
if (
|
|
5820
|
+
// ignore hidden shapes
|
|
5821
|
+
this.isShapeHidden(shape) ||
|
|
5822
|
+
// don't allow dropping on selected shapes
|
|
5823
|
+
this.getSelectedShapeIds().includes(shape.id) ||
|
|
5824
|
+
// only allow shapes that can receive children
|
|
5825
|
+
!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||
|
|
5826
|
+
// don't allow dropping a shape on itself or one of it's children
|
|
5827
|
+
droppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))
|
|
5828
|
+
) {
|
|
5829
|
+
continue
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5832
|
+
// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is
|
|
5833
|
+
// partially clipped by its own parent frame
|
|
5834
|
+
const maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)
|
|
5852
5835
|
|
|
5853
|
-
for (const maybeDraggingOverShape of maybeDraggingOverShapes) {
|
|
5854
|
-
const shapeUtil = this.getShapeUtil(maybeDraggingOverShape)
|
|
5855
|
-
// Any shape that can handle any dragging interactions is a valid target
|
|
5856
5836
|
if (
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
shapeUtil.onDropShapesOver
|
|
5837
|
+
maskedPageBounds &&
|
|
5838
|
+
maskedPageBounds.containsPoint(point) &&
|
|
5839
|
+
this.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)
|
|
5861
5840
|
) {
|
|
5862
|
-
return
|
|
5841
|
+
return shape
|
|
5863
5842
|
}
|
|
5864
5843
|
}
|
|
5865
5844
|
}
|
|
@@ -6218,12 +6197,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6218
6197
|
*/
|
|
6219
6198
|
duplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {
|
|
6220
6199
|
this.run(() => {
|
|
6221
|
-
const
|
|
6200
|
+
const ids =
|
|
6222
6201
|
typeof shapes[0] === 'string'
|
|
6223
6202
|
? (shapes as TLShapeId[])
|
|
6224
6203
|
: (shapes as TLShape[]).map((s) => s.id)
|
|
6225
6204
|
|
|
6226
|
-
const ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids)
|
|
6227
6205
|
if (ids.length <= 0) return this
|
|
6228
6206
|
|
|
6229
6207
|
const initialIds = new Set(ids)
|
|
@@ -6303,7 +6281,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6303
6281
|
})
|
|
6304
6282
|
const shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)
|
|
6305
6283
|
|
|
6306
|
-
|
|
6284
|
+
const maxShapesReached =
|
|
6285
|
+
shapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage
|
|
6286
|
+
|
|
6287
|
+
if (maxShapesReached) {
|
|
6307
6288
|
alertMaxShapes(this)
|
|
6308
6289
|
return
|
|
6309
6290
|
}
|
|
@@ -7732,32 +7713,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7732
7713
|
return {}
|
|
7733
7714
|
}
|
|
7734
7715
|
|
|
7735
|
-
/**
|
|
7736
|
-
* Get whether the provided shape can be created.
|
|
7737
|
-
*
|
|
7738
|
-
* @param shape - The shape or shape IDs to check.
|
|
7739
|
-
*
|
|
7740
|
-
* @public
|
|
7741
|
-
*/
|
|
7742
|
-
canCreateShape<T extends TLUnknownShape>(
|
|
7743
|
-
shape: OptionalKeys<TLShapePartial<T>, 'id'> | T['id']
|
|
7744
|
-
): boolean {
|
|
7745
|
-
return this.canCreateShapes([shape])
|
|
7746
|
-
}
|
|
7747
|
-
|
|
7748
|
-
/**
|
|
7749
|
-
* Get whether the provided shapes can be created.
|
|
7750
|
-
*
|
|
7751
|
-
* @param shapes - The shapes or shape IDs to create.
|
|
7752
|
-
*
|
|
7753
|
-
* @public
|
|
7754
|
-
*/
|
|
7755
|
-
canCreateShapes<T extends TLUnknownShape>(
|
|
7756
|
-
shapes: (T['id'] | OptionalKeys<TLShapePartial<T>, 'id'>)[]
|
|
7757
|
-
): boolean {
|
|
7758
|
-
return shapes.length + this.getCurrentPageShapeIds().size <= this.options.maxShapesPerPage
|
|
7759
|
-
}
|
|
7760
|
-
|
|
7761
7716
|
/**
|
|
7762
7717
|
* Create a single shape.
|
|
7763
7718
|
*
|
|
@@ -7804,7 +7759,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7804
7759
|
if (maxShapesReached) {
|
|
7805
7760
|
// can't create more shapes than fit on the page
|
|
7806
7761
|
alertMaxShapes(this)
|
|
7807
|
-
// todo: throw an error here? Otherwise we'll need to check every time whether the shapes were actually created
|
|
7808
7762
|
return this
|
|
7809
7763
|
}
|
|
7810
7764
|
|
|
@@ -7837,10 +7791,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7837
7791
|
|
|
7838
7792
|
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
7839
7793
|
const parent = currentPageShapesSorted[i]
|
|
7840
|
-
const util = this.getShapeUtil(parent)
|
|
7841
7794
|
if (
|
|
7842
|
-
util.canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7843
7795
|
!this.isShapeHidden(parent) &&
|
|
7796
|
+
this.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7844
7797
|
this.isPointInShape(
|
|
7845
7798
|
parent,
|
|
7846
7799
|
// If no parent is provided, then we can treat the
|
|
@@ -7969,8 +7922,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7969
7922
|
}
|
|
7970
7923
|
})
|
|
7971
7924
|
|
|
7972
|
-
this.emit('created-shapes', shapeRecordsToCreate)
|
|
7973
|
-
this.emit('edit')
|
|
7974
7925
|
this.store.put(shapeRecordsToCreate)
|
|
7975
7926
|
})
|
|
7976
7927
|
|
|
@@ -8365,8 +8316,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8365
8316
|
updates.push(updated)
|
|
8366
8317
|
}
|
|
8367
8318
|
|
|
8368
|
-
this.emit('edited-shapes', updates)
|
|
8369
|
-
this.emit('edit')
|
|
8370
8319
|
this.store.put(updates)
|
|
8371
8320
|
})
|
|
8372
8321
|
}
|
|
@@ -8416,8 +8365,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8416
8365
|
})
|
|
8417
8366
|
}
|
|
8418
8367
|
|
|
8419
|
-
this.emit('deleted-shapes', [...allShapeIdsToDelete])
|
|
8420
|
-
this.emit('edit')
|
|
8421
8368
|
return this.run(() => this.store.remove([...allShapeIdsToDelete]))
|
|
8422
8369
|
}
|
|
8423
8370
|
|
|
@@ -8866,7 +8813,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8866
8813
|
} = {
|
|
8867
8814
|
text: null,
|
|
8868
8815
|
files: null,
|
|
8869
|
-
'file-replace': null,
|
|
8870
8816
|
embed: null,
|
|
8871
8817
|
'svg-text': null,
|
|
8872
8818
|
url: null,
|
|
@@ -8916,15 +8862,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8916
8862
|
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8917
8863
|
}
|
|
8918
8864
|
|
|
8919
|
-
/**
|
|
8920
|
-
* Handle replacing external content.
|
|
8921
|
-
*
|
|
8922
|
-
* @param info - Info about the external content.
|
|
8923
|
-
*/
|
|
8924
|
-
async replaceExternalContent<E>(info: TLExternalContent<E>): Promise<void> {
|
|
8925
|
-
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8926
|
-
}
|
|
8927
|
-
|
|
8928
8865
|
/**
|
|
8929
8866
|
* Get content that can be exported for the given shape ids.
|
|
8930
8867
|
*
|
|
@@ -9544,8 +9481,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9544
9481
|
previousPagePoint,
|
|
9545
9482
|
currentScreenPoint,
|
|
9546
9483
|
currentPagePoint,
|
|
9547
|
-
originScreenPoint,
|
|
9548
|
-
originPagePoint,
|
|
9549
9484
|
} = this.inputs
|
|
9550
9485
|
|
|
9551
9486
|
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
|
@@ -9574,8 +9509,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9574
9509
|
// Reset velocity on pointer down, or when a pinch starts or ends
|
|
9575
9510
|
if (info.name === 'pointer_down' || this.inputs.isPinching) {
|
|
9576
9511
|
pointerVelocity.set(0, 0)
|
|
9577
|
-
originScreenPoint.setTo(currentScreenPoint)
|
|
9578
|
-
originPagePoint.setTo(currentPagePoint)
|
|
9512
|
+
this.inputs.originScreenPoint.setTo(currentScreenPoint)
|
|
9513
|
+
this.inputs.originPagePoint.setTo(currentPagePoint)
|
|
9579
9514
|
}
|
|
9580
9515
|
|
|
9581
9516
|
// todo: We only have to do this if there are multiple users in the document
|
|
@@ -241,9 +241,7 @@ export class HistoryManager<R extends UnknownRecord> {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
bailToMark(id: string) {
|
|
244
|
-
|
|
245
|
-
this._undo({ pushToRedoStack: false, toMark: id })
|
|
246
|
-
}
|
|
244
|
+
this._undo({ pushToRedoStack: false, toMark: id })
|
|
247
245
|
|
|
248
246
|
return this
|
|
249
247
|
}
|
|
@@ -26,7 +26,6 @@ export interface TLMeasureTextOpts {
|
|
|
26
26
|
fontWeight: string
|
|
27
27
|
fontFamily: string
|
|
28
28
|
fontSize: number
|
|
29
|
-
/** This must be a number, e.g. 1.35, not a pixel value. */
|
|
30
29
|
lineHeight: number
|
|
31
30
|
/**
|
|
32
31
|
* When maxWidth is a number, the text will be wrapped to that maxWidth. When maxWidth
|
|
@@ -76,7 +75,6 @@ export class TextManager {
|
|
|
76
75
|
// we need to save the default styles so that we can restore them when we're done
|
|
77
76
|
// these must be the css names, not the js names for the styles
|
|
78
77
|
this.defaultStyles = {
|
|
79
|
-
'overflow-wrap': 'break-word',
|
|
80
78
|
'word-break': 'auto',
|
|
81
79
|
width: null,
|
|
82
80
|
height: null,
|
|
@@ -125,7 +123,7 @@ export class TextManager {
|
|
|
125
123
|
elm.style.setProperty('font-style', opts.fontStyle)
|
|
126
124
|
elm.style.setProperty('font-weight', opts.fontWeight)
|
|
127
125
|
elm.style.setProperty('font-size', opts.fontSize + 'px')
|
|
128
|
-
elm.style.setProperty('line-height', opts.lineHeight.
|
|
126
|
+
elm.style.setProperty('line-height', opts.lineHeight * opts.fontSize + 'px')
|
|
129
127
|
elm.style.setProperty('padding', opts.padding)
|
|
130
128
|
|
|
131
129
|
if (opts.maxWidth) {
|
|
@@ -289,7 +287,7 @@ export class TextManager {
|
|
|
289
287
|
elm.style.setProperty('font-style', opts.fontStyle)
|
|
290
288
|
elm.style.setProperty('font-weight', opts.fontWeight)
|
|
291
289
|
elm.style.setProperty('font-size', opts.fontSize + 'px')
|
|
292
|
-
elm.style.setProperty('line-height', opts.lineHeight.
|
|
290
|
+
elm.style.setProperty('line-height', opts.lineHeight * opts.fontSize + 'px')
|
|
293
291
|
|
|
294
292
|
const elementWidth = Math.ceil(opts.width - opts.padding * 2)
|
|
295
293
|
elm.style.setProperty('width', `${elementWidth}px`)
|
|
@@ -4,15 +4,12 @@ import { LegacyMigrations, MigrationSequence } from '@tldraw/store'
|
|
|
4
4
|
import {
|
|
5
5
|
RecordProps,
|
|
6
6
|
TLHandle,
|
|
7
|
-
TLParentId,
|
|
8
7
|
TLPropsMigrations,
|
|
9
8
|
TLShape,
|
|
10
9
|
TLShapeCrop,
|
|
11
|
-
TLShapeId,
|
|
12
10
|
TLShapePartial,
|
|
13
11
|
TLUnknownShape,
|
|
14
12
|
} from '@tldraw/tlschema'
|
|
15
|
-
import { IndexKey } from '@tldraw/utils'
|
|
16
13
|
import { ReactElement } from 'react'
|
|
17
14
|
import { Box, SelectionHandle } from '../../primitives/Box'
|
|
18
15
|
import { Vec } from '../../primitives/Vec'
|
|
@@ -390,6 +387,17 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
390
387
|
return false
|
|
391
388
|
}
|
|
392
389
|
|
|
390
|
+
/**
|
|
391
|
+
* Get whether the shape can receive children of a given type.
|
|
392
|
+
*
|
|
393
|
+
* @param shape - The shape type.
|
|
394
|
+
* @param shapes - The shapes that are being dropped.
|
|
395
|
+
* @public
|
|
396
|
+
*/
|
|
397
|
+
canDropShapes(_shape: Shape, _shapes: TLShape[]) {
|
|
398
|
+
return false
|
|
399
|
+
}
|
|
400
|
+
|
|
393
401
|
/**
|
|
394
402
|
* Get the shape as an SVG object.
|
|
395
403
|
*
|
|
@@ -509,16 +517,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
509
517
|
): Omit<TLShapePartial<Shape>, 'id' | 'type'> | undefined | void
|
|
510
518
|
|
|
511
519
|
/**
|
|
512
|
-
* A callback called when some other shapes are dragged
|
|
513
|
-
*
|
|
514
|
-
* @param shape - The shape.
|
|
515
|
-
* @param shapes - The shapes that are being dragged in.
|
|
516
|
-
* @public
|
|
517
|
-
*/
|
|
518
|
-
onDragShapesIn?(shape: Shape, shapes: TLShape[], info: TLDragShapesInInfo): void
|
|
519
|
-
|
|
520
|
-
/**
|
|
521
|
-
* A callback called when some other shapes are dragged over this one. This fires when the shapes are dragged over the shape for the first time (after the onDragShapesIn callback), and again on every update while the shapes are being dragged.
|
|
520
|
+
* A callback called when some other shapes are dragged over this one.
|
|
522
521
|
*
|
|
523
522
|
* @example
|
|
524
523
|
*
|
|
@@ -532,7 +531,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
532
531
|
* @param shapes - The shapes that are being dragged over this one.
|
|
533
532
|
* @public
|
|
534
533
|
*/
|
|
535
|
-
onDragShapesOver?(shape: Shape, shapes: TLShape[]
|
|
534
|
+
onDragShapesOver?(shape: Shape, shapes: TLShape[]): void
|
|
536
535
|
|
|
537
536
|
/**
|
|
538
537
|
* A callback called when some other shapes are dragged out of this one.
|
|
@@ -541,7 +540,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
541
540
|
* @param shapes - The shapes that are being dragged out.
|
|
542
541
|
* @public
|
|
543
542
|
*/
|
|
544
|
-
onDragShapesOut?(shape: Shape, shapes: TLShape[]
|
|
543
|
+
onDragShapesOut?(shape: Shape, shapes: TLShape[]): void
|
|
545
544
|
|
|
546
545
|
/**
|
|
547
546
|
* A callback called when some other shapes are dropped over this one.
|
|
@@ -550,7 +549,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
|
550
549
|
* @param shapes - The shapes that are being dropped over this one.
|
|
551
550
|
* @public
|
|
552
551
|
*/
|
|
553
|
-
onDropShapesOver?(shape: Shape, shapes: TLShape[]
|
|
552
|
+
onDropShapesOver?(shape: Shape, shapes: TLShape[]): void
|
|
554
553
|
|
|
555
554
|
/**
|
|
556
555
|
* A callback called when a shape starts being resized.
|
|
@@ -746,37 +745,6 @@ export interface TLCropInfo<T extends TLShape> {
|
|
|
746
745
|
crop: TLShapeCrop
|
|
747
746
|
uncroppedSize: { w: number; h: number }
|
|
748
747
|
initialShape: T
|
|
749
|
-
aspectRatioLocked?: boolean
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
/** @public */
|
|
753
|
-
export interface TLDragShapesInInfo {
|
|
754
|
-
initialDraggingOverShapeId: TLShapeId | null
|
|
755
|
-
prevDraggingOverShapeId: TLShapeId | null
|
|
756
|
-
initialParentIds: Map<TLShapeId, TLParentId>
|
|
757
|
-
initialIndices: Map<TLShapeId, IndexKey>
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
/** @public */
|
|
761
|
-
export interface TLDragShapesOverInfo {
|
|
762
|
-
initialDraggingOverShapeId: TLShapeId | null
|
|
763
|
-
initialParentIds: Map<TLShapeId, TLParentId>
|
|
764
|
-
initialIndices: Map<TLShapeId, IndexKey>
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
/** @public */
|
|
768
|
-
export interface TLDragShapesOutInfo {
|
|
769
|
-
nextDraggingOverShapeId: TLShapeId | null
|
|
770
|
-
initialDraggingOverShapeId: TLShapeId | null
|
|
771
|
-
initialParentIds: Map<TLShapeId, TLParentId>
|
|
772
|
-
initialIndices: Map<TLShapeId, IndexKey>
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
/** @public */
|
|
776
|
-
export interface TLDropShapesOverInfo {
|
|
777
|
-
initialDraggingOverShapeId: TLShapeId | null
|
|
778
|
-
initialParentIds: Map<TLShapeId, TLParentId>
|
|
779
|
-
initialIndices: Map<TLShapeId, IndexKey>
|
|
780
748
|
}
|
|
781
749
|
|
|
782
750
|
/**
|
|
@@ -11,33 +11,29 @@ export class Pointing extends StateNode {
|
|
|
11
11
|
static override id = 'pointing'
|
|
12
12
|
|
|
13
13
|
override onPointerMove(info: TLPointerEventInfo) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const { originPagePoint } = editor.inputs
|
|
14
|
+
if (this.editor.inputs.isDragging) {
|
|
15
|
+
const { originPagePoint } = this.editor.inputs
|
|
17
16
|
|
|
18
17
|
const shapeType = (this.parent as BaseBoxShapeTool)!.shapeType
|
|
19
18
|
|
|
20
19
|
const id = createShapeId()
|
|
21
20
|
|
|
22
|
-
const creatingMarkId = editor.markHistoryStoppingPoint(`creating_box:${id}`)
|
|
23
|
-
const newPoint = maybeSnapToGrid(originPagePoint, editor)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
const creatingMarkId = this.editor.markHistoryStoppingPoint(`creating_box:${id}`)
|
|
22
|
+
const newPoint = maybeSnapToGrid(originPagePoint, this.editor)
|
|
23
|
+
this.editor
|
|
24
|
+
.createShapes<TLBaseBoxShape>([
|
|
25
|
+
{
|
|
26
|
+
id,
|
|
27
|
+
type: shapeType,
|
|
28
|
+
x: newPoint.x,
|
|
29
|
+
y: newPoint.y,
|
|
30
|
+
props: {
|
|
31
|
+
w: 1,
|
|
32
|
+
h: 1,
|
|
33
|
+
},
|
|
35
34
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const shape = editor.getShape(id)
|
|
39
|
-
if (!shape) this.cancel()
|
|
40
|
-
editor.select(id)
|
|
35
|
+
])
|
|
36
|
+
.select(id)
|
|
41
37
|
|
|
42
38
|
const parent = this.parent as BaseBoxShapeTool
|
|
43
39
|
this.editor.setCurrentTool(
|
|
@@ -83,7 +79,6 @@ export class Pointing extends StateNode {
|
|
|
83
79
|
|
|
84
80
|
this.editor.markHistoryStoppingPoint(`creating_box:${id}`)
|
|
85
81
|
|
|
86
|
-
// Allow this to trigger the max shapes reached alert
|
|
87
82
|
// todo: add scale here when dynamic size is enabled (is this still needed?)
|
|
88
83
|
this.editor.createShapes<TLBaseBoxShape>([
|
|
89
84
|
{
|
|
@@ -206,15 +206,15 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
// todo: move this logic into transition
|
|
209
|
-
exit(info: any,
|
|
209
|
+
exit(info: any, from: string) {
|
|
210
210
|
if (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {
|
|
211
211
|
this.performanceTracker.stop()
|
|
212
212
|
}
|
|
213
213
|
this._isActive.set(false)
|
|
214
|
-
this.onExit?.(info,
|
|
214
|
+
this.onExit?.(info, from)
|
|
215
215
|
|
|
216
216
|
if (!this.getIsActive()) {
|
|
217
|
-
this.getCurrent()?.exit(info,
|
|
217
|
+
this.getCurrent()?.exit(info, from)
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
|
|
@@ -18,10 +18,6 @@ export interface TLEventMap {
|
|
|
18
18
|
frame: [number]
|
|
19
19
|
'select-all-text': [{ shapeId: TLShapeId }]
|
|
20
20
|
'place-caret': [{ shapeId: TLShapeId; point: { x: number; y: number } }]
|
|
21
|
-
'created-shapes': [TLRecord[]]
|
|
22
|
-
'edited-shapes': [TLRecord[]]
|
|
23
|
-
'deleted-shapes': [TLShapeId[]]
|
|
24
|
-
edit: []
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
/** @public */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TLAssetId
|
|
1
|
+
import { TLAssetId } from '@tldraw/tlschema'
|
|
2
2
|
import { VecLike } from '../../primitives/Vec'
|
|
3
3
|
import { TLContent } from './clipboard-types'
|
|
4
4
|
|
|
@@ -52,15 +52,7 @@ export interface TLTextExternalContent extends TLBaseExternalContent {
|
|
|
52
52
|
export interface TLFilesExternalContent extends TLBaseExternalContent {
|
|
53
53
|
type: 'files'
|
|
54
54
|
files: File[]
|
|
55
|
-
ignoreParent
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** @public */
|
|
59
|
-
export interface TLFileReplaceExternalContent extends TLBaseExternalContent {
|
|
60
|
-
type: 'file-replace'
|
|
61
|
-
file: File
|
|
62
|
-
shapeId: TLShapeId
|
|
63
|
-
isImage: boolean
|
|
55
|
+
ignoreParent: boolean
|
|
64
56
|
}
|
|
65
57
|
|
|
66
58
|
/** @public */
|
|
@@ -98,7 +90,6 @@ export interface TLExcalidrawExternalContent extends TLBaseExternalContent {
|
|
|
98
90
|
export type TLExternalContent<EmbedDefinition> =
|
|
99
91
|
| TLTextExternalContent
|
|
100
92
|
| TLFilesExternalContent
|
|
101
|
-
| TLFileReplaceExternalContent
|
|
102
93
|
| TLUrlExternalContent
|
|
103
94
|
| TLSvgTextExternalContent
|
|
104
95
|
| TLEmbedExternalContent<EmbedDefinition>
|
|
@@ -44,7 +44,6 @@ export const Geometry2dFilters: {
|
|
|
44
44
|
/** @public */
|
|
45
45
|
export interface TransformedGeometry2dOptions {
|
|
46
46
|
isLabel?: boolean
|
|
47
|
-
isEmptyLabel?: boolean
|
|
48
47
|
isInternal?: boolean
|
|
49
48
|
debugColor?: string
|
|
50
49
|
ignore?: boolean
|
|
@@ -58,24 +57,20 @@ export interface Geometry2dOptions extends TransformedGeometry2dOptions {
|
|
|
58
57
|
|
|
59
58
|
/** @public */
|
|
60
59
|
export abstract class Geometry2d {
|
|
61
|
-
// todo: consider making accessors for these too, so that they can be overridden in subclasses by geometries with more complex logic
|
|
62
60
|
isFilled = false
|
|
63
61
|
isClosed = true
|
|
64
62
|
isLabel = false
|
|
65
|
-
isEmptyLabel = false
|
|
66
63
|
isInternal = false
|
|
67
64
|
debugColor?: string
|
|
68
65
|
ignore?: boolean
|
|
69
66
|
|
|
70
67
|
constructor(opts: Geometry2dOptions) {
|
|
71
|
-
const { isLabel = false, isEmptyLabel = false, isInternal = false } = opts
|
|
72
68
|
this.isFilled = opts.isFilled
|
|
73
69
|
this.isClosed = opts.isClosed
|
|
70
|
+
this.isLabel = opts.isLabel ?? false
|
|
71
|
+
this.isInternal = opts.isInternal ?? false
|
|
74
72
|
this.debugColor = opts.debugColor
|
|
75
73
|
this.ignore = opts.ignore
|
|
76
|
-
this.isLabel = isLabel
|
|
77
|
-
this.isEmptyLabel = isEmptyLabel
|
|
78
|
-
this.isInternal = isInternal
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
isExcludedByFilter(filters?: Geometry2dFilters) {
|
|
@@ -17,20 +17,14 @@ export class Group2d extends Geometry2d {
|
|
|
17
17
|
) {
|
|
18
18
|
super({ ...config, isClosed: true, isFilled: false })
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.ignoredChildren.push(child)
|
|
26
|
-
} else {
|
|
27
|
-
this.children.push(child)
|
|
28
|
-
}
|
|
20
|
+
for (const child of config.children) {
|
|
21
|
+
if (child.ignore) {
|
|
22
|
+
this.ignoredChildren.push(child)
|
|
23
|
+
} else {
|
|
24
|
+
this.children.push(child)
|
|
29
25
|
}
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
addChildren(config.children)
|
|
33
|
-
|
|
34
28
|
if (this.children.length === 0) throw Error('Group2d must have at least one child')
|
|
35
29
|
}
|
|
36
30
|
|
package/src/lib/utils/dom.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { debugFlags, pointerCaptureTrackingObject } from './debug-flags'
|
|
|
18
18
|
|
|
19
19
|
/** @public */
|
|
20
20
|
export function loopToHtmlElement(elm: Element): HTMLElement {
|
|
21
|
-
if (elm
|
|
21
|
+
if (elm instanceof HTMLElement) return elm
|
|
22
22
|
if (elm.parentElement) return loopToHtmlElement(elm.parentElement)
|
|
23
23
|
else throw Error('Could not find a parent element of an HTML type!')
|
|
24
24
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '3.14.0-canary.
|
|
4
|
+
export const version = '3.14.0-canary.ed47bf46edcd'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-06-
|
|
8
|
-
patch: '2025-06-
|
|
7
|
+
minor: '2025-06-17T08:34:31.662Z',
|
|
8
|
+
patch: '2025-06-17T08:34:31.662Z',
|
|
9
9
|
}
|