@tldraw/editor 3.15.0 → 3.16.0-canary.03deb7f8fe34
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 +181 -9
- package/dist-cjs/index.js +5 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +3 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +4 -26
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +1 -1
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +53 -0
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +7 -0
- package/dist-cjs/lib/config/TLUserPreferences.js +8 -2
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +100 -58
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +8 -3
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +1 -2
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +22 -20
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +2 -0
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/hooks/useStateAttribute.js +35 -0
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +7 -0
- package/dist-cjs/lib/license/Watermark.js +6 -6
- package/dist-cjs/lib/license/Watermark.js.map +1 -1
- package/dist-cjs/lib/options.js +1 -0
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/EditorAtom.js +45 -0
- package/dist-cjs/lib/utils/EditorAtom.js.map +7 -0
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +181 -9
- package/dist-esm/index.mjs +7 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +3 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +4 -26
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +1 -1
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +23 -0
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +7 -0
- package/dist-esm/lib/config/TLUserPreferences.mjs +8 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +100 -58
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +8 -3
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +23 -21
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -0
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useStateAttribute.mjs +15 -0
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +7 -0
- package/dist-esm/lib/license/Watermark.mjs +6 -6
- package/dist-esm/lib/license/Watermark.mjs.map +1 -1
- package/dist-esm/lib/options.mjs +1 -0
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/EditorAtom.mjs +25 -0
- package/dist-esm/lib/utils/EditorAtom.mjs.map +7 -0
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +297 -311
- package/package.json +7 -7
- package/src/index.ts +7 -0
- package/src/lib/TldrawEditor.tsx +7 -5
- package/src/lib/components/MenuClickCapture.tsx +0 -8
- package/src/lib/components/Shape.tsx +6 -21
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
- package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +5 -1
- package/src/lib/components/default-components/DefaultShapeWrapper.tsx +35 -0
- package/src/lib/config/TLUserPreferences.ts +7 -0
- package/src/lib/editor/Editor.ts +130 -81
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +13 -0
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +5 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +57 -0
- package/src/lib/editor/types/misc-types.ts +73 -1
- package/src/lib/exports/getSvgJsx.tsx +2 -2
- package/src/lib/hooks/useCanvasEvents.ts +36 -32
- package/src/lib/hooks/useEditorComponents.tsx +7 -1
- package/src/lib/hooks/useStateAttribute.ts +15 -0
- package/src/lib/license/Watermark.tsx +6 -6
- package/src/lib/options.ts +2 -0
- package/src/lib/utils/EditorAtom.ts +37 -0
- package/src/version.ts +3 -3
|
@@ -2323,28 +2323,11 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
2323
2323
|
{ history: "ignore" }
|
|
2324
2324
|
);
|
|
2325
2325
|
const { currentScreenPoint, currentPagePoint } = this.inputs;
|
|
2326
|
-
const { screenBounds } = this.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID);
|
|
2327
2326
|
if (currentScreenPoint.x / z - x !== currentPagePoint.x || currentScreenPoint.y / z - y !== currentPagePoint.y) {
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
// weird but true: we need to put the screen point back into client space
|
|
2333
|
-
point: import_Vec.Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),
|
|
2334
|
-
pointerId: import_constants.INTERNAL_POINTER_IDS.CAMERA_MOVE,
|
|
2335
|
-
ctrlKey: this.inputs.ctrlKey,
|
|
2336
|
-
altKey: this.inputs.altKey,
|
|
2337
|
-
shiftKey: this.inputs.shiftKey,
|
|
2338
|
-
metaKey: this.inputs.metaKey,
|
|
2339
|
-
accelKey: (0, import_keyboard.isAccelKey)(this.inputs),
|
|
2340
|
-
button: 0,
|
|
2341
|
-
isPen: this.getInstanceState().isPenMode ?? false
|
|
2342
|
-
};
|
|
2343
|
-
if (opts?.immediate) {
|
|
2344
|
-
this._flushEventForTick(event);
|
|
2345
|
-
} else {
|
|
2346
|
-
this.dispatch(event);
|
|
2347
|
-
}
|
|
2327
|
+
this.updatePointer({
|
|
2328
|
+
immediate: opts?.immediate,
|
|
2329
|
+
pointerId: import_constants.INTERNAL_POINTER_IDS.CAMERA_MOVE
|
|
2330
|
+
});
|
|
2348
2331
|
}
|
|
2349
2332
|
this._tickCameraState();
|
|
2350
2333
|
});
|
|
@@ -3313,19 +3296,24 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3313
3296
|
*/
|
|
3314
3297
|
deletePage(page) {
|
|
3315
3298
|
const id = typeof page === "string" ? page : page.id;
|
|
3316
|
-
this.run(
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3299
|
+
this.run(
|
|
3300
|
+
() => {
|
|
3301
|
+
if (this.getIsReadonly()) return;
|
|
3302
|
+
const pages = this.getPages();
|
|
3303
|
+
if (pages.length === 1) return;
|
|
3304
|
+
const deletedPage = this.getPage(id);
|
|
3305
|
+
if (!deletedPage) return;
|
|
3306
|
+
if (id === this.getCurrentPageId()) {
|
|
3307
|
+
const index = pages.findIndex((page2) => page2.id === id);
|
|
3308
|
+
const next = pages[index - 1] ?? pages[index + 1];
|
|
3309
|
+
this.setCurrentPage(next.id);
|
|
3310
|
+
}
|
|
3311
|
+
const shapes = this.getSortedChildIdsForParent(deletedPage.id);
|
|
3312
|
+
this.deleteShapes(shapes);
|
|
3313
|
+
this.store.remove([deletedPage.id]);
|
|
3314
|
+
},
|
|
3315
|
+
{ ignoreShapeLock: true }
|
|
3316
|
+
);
|
|
3329
3317
|
return this;
|
|
3330
3318
|
}
|
|
3331
3319
|
/**
|
|
@@ -3922,6 +3910,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3922
3910
|
hitInside = false,
|
|
3923
3911
|
hitFrameInside = false
|
|
3924
3912
|
} = opts;
|
|
3913
|
+
const [innerMargin, outerMargin] = Array.isArray(margin) ? margin : [margin, margin];
|
|
3925
3914
|
let inHollowSmallestArea = Infinity;
|
|
3926
3915
|
let inHollowSmallestAreaHit = null;
|
|
3927
3916
|
let inMarginClosestToEdgeDistance = Infinity;
|
|
@@ -3931,7 +3920,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3931
3920
|
return false;
|
|
3932
3921
|
const pageMask = this.getShapeMask(shape);
|
|
3933
3922
|
if (pageMask && !(0, import_utils2.pointInPolygon)(point, pageMask)) return false;
|
|
3934
|
-
if (filter
|
|
3923
|
+
if (filter && !filter(shape)) return false;
|
|
3935
3924
|
return true;
|
|
3936
3925
|
});
|
|
3937
3926
|
for (let i = shapesToCheck.length - 1; i >= 0; i--) {
|
|
@@ -3939,7 +3928,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3939
3928
|
const geometry = this.getShapeGeometry(shape);
|
|
3940
3929
|
const isGroup = geometry instanceof import_Group2d.Group2d;
|
|
3941
3930
|
const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
|
|
3942
|
-
if (this.isShapeOfType(shape, "frame") || this.isShapeOfType(shape, "
|
|
3931
|
+
if (this.isShapeOfType(shape, "frame") || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && this.getShapeUtil(shape).getText(shape)?.trim()) {
|
|
3943
3932
|
for (const childGeometry of geometry.children) {
|
|
3944
3933
|
if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
|
|
3945
3934
|
return shape;
|
|
@@ -3947,8 +3936,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3947
3936
|
}
|
|
3948
3937
|
}
|
|
3949
3938
|
if (this.isShapeOfType(shape, "frame")) {
|
|
3950
|
-
const distance2 = geometry.distanceToPoint(pointInShapeSpace,
|
|
3951
|
-
if (
|
|
3939
|
+
const distance2 = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside);
|
|
3940
|
+
if (hitFrameInside ? distance2 > 0 && distance2 <= outerMargin || distance2 <= 0 && distance2 > -innerMargin : distance2 > 0 && distance2 <= outerMargin) {
|
|
3952
3941
|
return inMarginClosestToEdgeHit || shape;
|
|
3953
3942
|
}
|
|
3954
3943
|
if (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {
|
|
@@ -3968,10 +3957,10 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3968
3957
|
}
|
|
3969
3958
|
distance = minDistance;
|
|
3970
3959
|
} else {
|
|
3971
|
-
if (
|
|
3960
|
+
if (outerMargin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
|
|
3972
3961
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside);
|
|
3973
3962
|
} else {
|
|
3974
|
-
if (geometry.bounds.containsPoint(pointInShapeSpace,
|
|
3963
|
+
if (geometry.bounds.containsPoint(pointInShapeSpace, outerMargin)) {
|
|
3975
3964
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside);
|
|
3976
3965
|
} else {
|
|
3977
3966
|
distance = Infinity;
|
|
@@ -3979,12 +3968,22 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3979
3968
|
}
|
|
3980
3969
|
}
|
|
3981
3970
|
if (geometry.isClosed) {
|
|
3982
|
-
if (distance <=
|
|
3971
|
+
if (distance <= outerMargin || hitInside && distance <= 0 && distance > -innerMargin) {
|
|
3983
3972
|
if (geometry.isFilled || isGroup && geometry.children[0].isFilled) {
|
|
3984
3973
|
return inMarginClosestToEdgeHit || shape;
|
|
3985
3974
|
} else {
|
|
3986
3975
|
if (this.getShapePageBounds(shape).contains(viewportPageBounds)) continue;
|
|
3987
|
-
if (
|
|
3976
|
+
if (hitInside ? (
|
|
3977
|
+
// On hitInside, the distance will be negative for hits inside
|
|
3978
|
+
// If the distance is positive, check against the outer margin
|
|
3979
|
+
distance > 0 && distance <= outerMargin || // If the distance is negative, check against the inner margin
|
|
3980
|
+
distance <= 0 && distance > -innerMargin
|
|
3981
|
+
) : (
|
|
3982
|
+
// If hitInside is false, then sadly _we do not know_ whether the
|
|
3983
|
+
// point is inside or outside of the shape, so we check against
|
|
3984
|
+
// the max of the two margins
|
|
3985
|
+
Math.abs(distance) <= Math.max(innerMargin, outerMargin)
|
|
3986
|
+
)) {
|
|
3988
3987
|
if (Math.abs(distance) < inMarginClosestToEdgeDistance) {
|
|
3989
3988
|
inMarginClosestToEdgeDistance = Math.abs(distance);
|
|
3990
3989
|
inMarginClosestToEdgeHit = shape;
|
|
@@ -5503,8 +5502,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
5503
5502
|
const shapesMovingTogether = [shape];
|
|
5504
5503
|
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5505
5504
|
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5506
|
-
type: "stretch"
|
|
5507
|
-
shapes: shapesToStretchFirstPass
|
|
5505
|
+
type: "stretch"
|
|
5508
5506
|
})) {
|
|
5509
5507
|
continue;
|
|
5510
5508
|
}
|
|
@@ -5829,21 +5827,24 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
5829
5827
|
}
|
|
5830
5828
|
if (!partial.parentId || !(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))) {
|
|
5831
5829
|
let parentId = this.getFocusedGroupId();
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
parent
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5830
|
+
const isPositioned = partial.x !== void 0 && partial.y !== void 0;
|
|
5831
|
+
if (isPositioned) {
|
|
5832
|
+
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
5833
|
+
const parent = currentPageShapesSorted[i];
|
|
5834
|
+
const util = this.getShapeUtil(parent);
|
|
5835
|
+
if (util.canReceiveNewChildrenOfType(parent, partial.type) && !this.isShapeHidden(parent) && this.isPointInShape(
|
|
5836
|
+
parent,
|
|
5837
|
+
// If no parent is provided, then we can treat the
|
|
5838
|
+
// shape's provided x/y as being in the page's space.
|
|
5839
|
+
{ x: partial.x ?? 0, y: partial.y ?? 0 },
|
|
5840
|
+
{
|
|
5841
|
+
margin: 0,
|
|
5842
|
+
hitInside: true
|
|
5843
|
+
}
|
|
5844
|
+
)) {
|
|
5845
|
+
parentId = parent.id;
|
|
5846
|
+
break;
|
|
5843
5847
|
}
|
|
5844
|
-
)) {
|
|
5845
|
-
parentId = parent.id;
|
|
5846
|
-
break;
|
|
5847
5848
|
}
|
|
5848
5849
|
}
|
|
5849
5850
|
const prevParentId = partial.parentId;
|
|
@@ -7028,6 +7029,47 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
7028
7029
|
this.dispatch({ type: "misc", name: "complete" });
|
|
7029
7030
|
return this;
|
|
7030
7031
|
}
|
|
7032
|
+
/**
|
|
7033
|
+
* Dispatch a pointer move event in the current position of the pointer. This is useful when
|
|
7034
|
+
* external circumstances have changed (e.g. the camera moved or a shape was moved) and you want
|
|
7035
|
+
* the current interaction to respond to that change.
|
|
7036
|
+
*
|
|
7037
|
+
* @example
|
|
7038
|
+
* ```ts
|
|
7039
|
+
* editor.updatePointer()
|
|
7040
|
+
* ```
|
|
7041
|
+
*
|
|
7042
|
+
* @param options - The options for updating the pointer.
|
|
7043
|
+
* @returns The editor instance.
|
|
7044
|
+
* @public
|
|
7045
|
+
*/
|
|
7046
|
+
updatePointer(options) {
|
|
7047
|
+
const event = {
|
|
7048
|
+
type: "pointer",
|
|
7049
|
+
target: "canvas",
|
|
7050
|
+
name: "pointer_move",
|
|
7051
|
+
point: options?.point ?? // weird but true: what `inputs` calls screen-space is actually viewport space. so
|
|
7052
|
+
// we need to convert back into true screen space first. we should fix this...
|
|
7053
|
+
import_Vec.Vec.Add(
|
|
7054
|
+
this.inputs.currentScreenPoint,
|
|
7055
|
+
this.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID).screenBounds
|
|
7056
|
+
),
|
|
7057
|
+
pointerId: options?.pointerId ?? 0,
|
|
7058
|
+
button: options?.button ?? 0,
|
|
7059
|
+
isPen: options?.isPen ?? this.inputs.isPen,
|
|
7060
|
+
shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
|
|
7061
|
+
altKey: options?.altKey ?? this.inputs.altKey,
|
|
7062
|
+
ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
|
|
7063
|
+
metaKey: options?.metaKey ?? this.inputs.metaKey,
|
|
7064
|
+
accelKey: options?.accelKey ?? (0, import_keyboard.isAccelKey)(this.inputs)
|
|
7065
|
+
};
|
|
7066
|
+
if (options?.immediate) {
|
|
7067
|
+
this._flushEventForTick(event);
|
|
7068
|
+
} else {
|
|
7069
|
+
this.dispatch(event);
|
|
7070
|
+
}
|
|
7071
|
+
return this;
|
|
7072
|
+
}
|
|
7031
7073
|
/**
|
|
7032
7074
|
* Puts the editor into focused mode.
|
|
7033
7075
|
*
|