@tldraw/editor 3.12.1 → 3.13.0-canary.064d79cae9fb
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/CHANGELOG.md +0 -20
- package/dist-cjs/index.d.ts +30 -14
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/TldrawEditor.js +2 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +12 -8
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +27 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +14 -12
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +17 -11
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +46 -28
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js +12 -3
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +3 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +16 -15
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +8 -1
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/areShapesContentEqual.js +25 -0
- package/dist-cjs/lib/utils/areShapesContentEqual.js.map +7 -0
- package/dist-cjs/lib/utils/dom.js +3 -3
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/nearestMultiple.js +34 -0
- package/dist-cjs/lib/utils/nearestMultiple.js.map +7 -0
- package/dist-cjs/lib/utils/rotation.js +5 -5
- package/dist-cjs/lib/utils/rotation.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +30 -14
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/TldrawEditor.mjs +2 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +12 -8
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +27 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +14 -12
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +17 -11
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +46 -28
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +12 -3
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +3 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +16 -15
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +8 -1
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/areShapesContentEqual.mjs +5 -0
- package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +7 -0
- package/dist-esm/lib/utils/dom.mjs +3 -3
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/nearestMultiple.mjs +14 -0
- package/dist-esm/lib/utils/nearestMultiple.mjs.map +7 -0
- package/dist-esm/lib/utils/rotation.mjs +5 -5
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +11 -0
- package/package.json +7 -7
- package/src/lib/TldrawEditor.tsx +6 -1
- package/src/lib/components/Shape.tsx +14 -10
- package/src/lib/components/default-components/DefaultCanvas.tsx +32 -2
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +25 -14
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +17 -8
- package/src/lib/components/default-components/DefaultSpinner.tsx +1 -1
- package/src/lib/editor/Editor.ts +43 -27
- package/src/lib/editor/shapes/ShapeUtil.ts +13 -1
- package/src/lib/exports/getSvgJsx.tsx +16 -7
- package/src/lib/hooks/useDocumentEvents.ts +7 -2
- package/src/lib/hooks/useEditorComponents.tsx +32 -28
- package/src/lib/license/LicenseManager.test.ts +40 -0
- package/src/lib/license/LicenseManager.ts +13 -1
- package/src/lib/options.ts +4 -0
- package/src/lib/utils/areShapesContentEqual.ts +4 -0
- package/src/lib/utils/dom.ts +4 -4
- package/src/lib/utils/nearestMultiple.ts +13 -0
- package/src/lib/utils/rotation.ts +8 -6
- package/src/version.ts +3 -3
|
@@ -132,6 +132,7 @@ import { Group2d } from "../primitives/geometry/Group2d.mjs";
|
|
|
132
132
|
import { intersectPolygonPolygon } from "../primitives/intersect.mjs";
|
|
133
133
|
import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from "../primitives/utils.mjs";
|
|
134
134
|
import { SharedStyleMap } from "../utils/SharedStylesMap.mjs";
|
|
135
|
+
import { areShapesContentEqual } from "../utils/areShapesContentEqual.mjs";
|
|
135
136
|
import { dataUrlToFile } from "../utils/assets.mjs";
|
|
136
137
|
import { debugFlags } from "../utils/debug-flags.mjs";
|
|
137
138
|
import {
|
|
@@ -1381,8 +1382,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1381
1382
|
return this.getCurrentPageState().selectedShapeIds;
|
|
1382
1383
|
}
|
|
1383
1384
|
getSelectedShapes() {
|
|
1384
|
-
|
|
1385
|
-
return compact(selectedShapeIds.map((id) => this.store.get(id)));
|
|
1385
|
+
return compact(this.getSelectedShapeIds().map((id) => this.store.get(id)));
|
|
1386
1386
|
}
|
|
1387
1387
|
/**
|
|
1388
1388
|
* Select one or more shapes.
|
|
@@ -1984,12 +1984,22 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1984
1984
|
}
|
|
1985
1985
|
return baseCamera;
|
|
1986
1986
|
}
|
|
1987
|
+
_getFollowingPresence(targetUserId) {
|
|
1988
|
+
const visited = [this.user.getId()];
|
|
1989
|
+
const collaborators = this.getCollaborators();
|
|
1990
|
+
let leaderPresence = null;
|
|
1991
|
+
while (targetUserId && !visited.includes(targetUserId)) {
|
|
1992
|
+
leaderPresence = collaborators.find((c) => c.userId === targetUserId) ?? null;
|
|
1993
|
+
targetUserId = leaderPresence?.followingUserId ?? null;
|
|
1994
|
+
if (leaderPresence) {
|
|
1995
|
+
visited.push(leaderPresence.userId);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
return leaderPresence;
|
|
1999
|
+
}
|
|
1987
2000
|
getViewportPageBoundsForFollowing() {
|
|
1988
|
-
const
|
|
1989
|
-
if (!
|
|
1990
|
-
const leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId);
|
|
1991
|
-
if (!leaderPresence) return null;
|
|
1992
|
-
if (!leaderPresence.camera || !leaderPresence.screenBounds) return null;
|
|
2001
|
+
const leaderPresence = this._getFollowingPresence(this.getInstanceState().followingUserId);
|
|
2002
|
+
if (!leaderPresence?.camera || !leaderPresence?.screenBounds) return null;
|
|
1993
2003
|
const { w: lw, h: lh } = leaderPresence.screenBounds;
|
|
1994
2004
|
const { x: lx, y: ly, z: lz } = leaderPresence.camera;
|
|
1995
2005
|
const theirViewport = new Box(-lx, -ly, lw / lz, lh / lz);
|
|
@@ -2896,34 +2906,30 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2896
2906
|
*/
|
|
2897
2907
|
startFollowingUser(userId) {
|
|
2898
2908
|
this.stopFollowingUser();
|
|
2899
|
-
const leaderPresences = this._getCollaboratorsQuery().get().filter((p) => p.userId === userId);
|
|
2900
|
-
if (!leaderPresences.length) {
|
|
2901
|
-
console.warn("User not found");
|
|
2902
|
-
return this;
|
|
2903
|
-
}
|
|
2904
2909
|
const thisUserId = this.user.getId();
|
|
2905
2910
|
if (!thisUserId) {
|
|
2906
2911
|
console.warn("You should set the userId for the current instance before following a user");
|
|
2907
2912
|
}
|
|
2908
|
-
|
|
2913
|
+
const leaderPresence = this._getFollowingPresence(userId);
|
|
2914
|
+
if (!leaderPresence) {
|
|
2909
2915
|
return this;
|
|
2910
2916
|
}
|
|
2911
2917
|
const latestLeaderPresence = computed("latestLeaderPresence", () => {
|
|
2912
|
-
return this.
|
|
2918
|
+
return this._getFollowingPresence(userId);
|
|
2913
2919
|
});
|
|
2914
2920
|
transact(() => {
|
|
2915
2921
|
this.updateInstanceState({ followingUserId: userId }, { history: "ignore" });
|
|
2916
2922
|
const dispose = react("update current page", () => {
|
|
2917
|
-
const
|
|
2918
|
-
if (!
|
|
2923
|
+
const leaderPresence2 = latestLeaderPresence.get();
|
|
2924
|
+
if (!leaderPresence2) {
|
|
2919
2925
|
this.stopFollowingUser();
|
|
2920
2926
|
return;
|
|
2921
2927
|
}
|
|
2922
|
-
if (
|
|
2928
|
+
if (leaderPresence2.currentPageId !== this.getCurrentPageId() && this.getPage(leaderPresence2.currentPageId)) {
|
|
2923
2929
|
this.run(
|
|
2924
2930
|
() => {
|
|
2925
2931
|
this.store.put([
|
|
2926
|
-
{ ...this.getInstanceState(), currentPageId:
|
|
2932
|
+
{ ...this.getInstanceState(), currentPageId: leaderPresence2.currentPageId }
|
|
2927
2933
|
]);
|
|
2928
2934
|
this._isLockedOnFollowingUser.set(true);
|
|
2929
2935
|
},
|
|
@@ -2938,8 +2944,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2938
2944
|
this.off("stop-following", cancel);
|
|
2939
2945
|
};
|
|
2940
2946
|
const moveTowardsUser = () => {
|
|
2941
|
-
const
|
|
2942
|
-
if (!
|
|
2947
|
+
const leaderPresence2 = latestLeaderPresence.get();
|
|
2948
|
+
if (!leaderPresence2) {
|
|
2943
2949
|
this.stopFollowingUser();
|
|
2944
2950
|
return;
|
|
2945
2951
|
}
|
|
@@ -3468,7 +3474,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3468
3474
|
this.fonts.trackFontsForShape(shape2);
|
|
3469
3475
|
return this.getShapeUtil(shape2).getGeometry(shape2, opts);
|
|
3470
3476
|
},
|
|
3471
|
-
{ areRecordsEqual:
|
|
3477
|
+
{ areRecordsEqual: areShapesContentEqual }
|
|
3472
3478
|
);
|
|
3473
3479
|
}
|
|
3474
3480
|
return this._shapeGeometryCaches[context].get(
|
|
@@ -3511,9 +3517,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3511
3517
|
);
|
|
3512
3518
|
}
|
|
3513
3519
|
_getShapeHandlesCache() {
|
|
3514
|
-
return this.store.createComputedCache(
|
|
3515
|
-
|
|
3516
|
-
|
|
3520
|
+
return this.store.createComputedCache(
|
|
3521
|
+
"handles",
|
|
3522
|
+
(shape) => {
|
|
3523
|
+
return this.getShapeUtil(shape).getHandles?.(shape);
|
|
3524
|
+
},
|
|
3525
|
+
{
|
|
3526
|
+
areRecordsEqual: areShapesContentEqual
|
|
3527
|
+
}
|
|
3528
|
+
);
|
|
3517
3529
|
}
|
|
3518
3530
|
/**
|
|
3519
3531
|
* Get the handles (if any) for a shape.
|
|
@@ -4397,9 +4409,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4397
4409
|
}
|
|
4398
4410
|
_getBindingsIndexCache() {
|
|
4399
4411
|
const index = bindingsIndex(this);
|
|
4400
|
-
return this.store.createComputedCache(
|
|
4401
|
-
|
|
4402
|
-
|
|
4412
|
+
return this.store.createComputedCache(
|
|
4413
|
+
"bindingsIndex",
|
|
4414
|
+
(shape) => {
|
|
4415
|
+
return index.get().get(shape.id);
|
|
4416
|
+
},
|
|
4417
|
+
// we can ignore the shape equality check here because the index is
|
|
4418
|
+
// computed incrementally based on what bindings are in the store
|
|
4419
|
+
{ areRecordsEqual: () => true }
|
|
4420
|
+
);
|
|
4403
4421
|
}
|
|
4404
4422
|
/**
|
|
4405
4423
|
* Get a binding from the store by its ID if it exists.
|
|
@@ -7474,7 +7492,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
7474
7492
|
const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
|
|
7475
7493
|
const { x: dx, y: dy, z: dz = 0 } = info.delta;
|
|
7476
7494
|
let behavior = wheelBehavior;
|
|
7477
|
-
if (
|
|
7495
|
+
if (info.ctrlKey) behavior = wheelBehavior === "pan" ? "zoom" : "pan";
|
|
7478
7496
|
switch (behavior) {
|
|
7479
7497
|
case "zoom": {
|
|
7480
7498
|
const { x, y } = this.inputs.currentScreenPoint;
|