@tldraw/editor 5.3.2 → 5.4.0-canary.02cd0bd3b597
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 +94 -52
- package/dist-cjs/index.js +3 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +86 -26
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js +7 -3
- package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +6 -3
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +6 -3
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/globals/editors.js +57 -0
- package/dist-cjs/lib/globals/editors.js.map +7 -0
- package/dist-cjs/lib/hooks/useViewportHeight.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +63 -21
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/utils/normalizeWheel.js +2 -0
- package/dist-cjs/lib/utils/normalizeWheel.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 +94 -52
- package/dist-esm/index.mjs +3 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +86 -26
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs +7 -3
- package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +7 -4
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +6 -3
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/globals/editors.mjs +37 -0
- package/dist-esm/lib/globals/editors.mjs.map +7 -0
- package/dist-esm/lib/hooks/useViewportHeight.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +63 -21
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/utils/normalizeWheel.mjs +2 -0
- package/dist-esm/lib/utils/normalizeWheel.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +2 -0
- package/src/lib/editor/Editor.ts +126 -37
- package/src/lib/editor/derivations/shapeIdsInCurrentPage.ts +7 -3
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +42 -0
- package/src/lib/editor/managers/TextManager/TextManager.ts +10 -8
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +13 -0
- package/src/lib/editor/managers/TickManager/TickManager.ts +9 -3
- package/src/lib/globals/editors.test.ts +76 -0
- package/src/lib/globals/editors.ts +53 -0
- package/src/lib/hooks/useViewportHeight.ts +9 -1
- package/src/lib/primitives/geometry/Group2d.ts +63 -27
- package/src/lib/utils/normalizeWheel.test.ts +39 -0
- package/src/lib/utils/normalizeWheel.ts +6 -0
- package/src/version.ts +3 -3
|
@@ -53,6 +53,7 @@ var import_constants = require("../constants");
|
|
|
53
53
|
var import_domUtils = require("../exports/domUtils");
|
|
54
54
|
var import_exportToSvg = require("../exports/exportToSvg");
|
|
55
55
|
var import_getSvgAsImage = require("../exports/getSvgAsImage");
|
|
56
|
+
var import_editors = require("../globals/editors");
|
|
56
57
|
var import_menus = require("../globals/menus");
|
|
57
58
|
var import_time = require("../globals/time");
|
|
58
59
|
var import_options = require("../options");
|
|
@@ -571,9 +572,11 @@ class Editor extends import_eventemitter3.default {
|
|
|
571
572
|
this.on("tick", this._flushEventsForTick);
|
|
572
573
|
this.on("mount", () => {
|
|
573
574
|
this._isMounted.set(true);
|
|
575
|
+
(0, import_editors.registerMountedEditor)(this);
|
|
574
576
|
});
|
|
575
577
|
this.on("unmount", () => {
|
|
576
578
|
this._isMounted.set(false);
|
|
579
|
+
(0, import_editors.unregisterMountedEditor)(this);
|
|
577
580
|
});
|
|
578
581
|
this.timers.requestAnimationFrame(() => {
|
|
579
582
|
this._tickManager.start();
|
|
@@ -815,6 +818,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
815
818
|
if (this._isMounted.get()) {
|
|
816
819
|
this.emit("unmount");
|
|
817
820
|
}
|
|
821
|
+
(0, import_editors.unregisterMountedEditor)(this);
|
|
818
822
|
this.stopCameraAnimation();
|
|
819
823
|
if (this.getInstanceState().followingUserId) {
|
|
820
824
|
this.stopFollowingUser();
|
|
@@ -4306,17 +4310,16 @@ class Editor extends import_eventemitter3.default {
|
|
|
4306
4310
|
let inMarginClosestToEdgeHit = null;
|
|
4307
4311
|
const searchMargin = Math.max(innerMargin, outerMargin, this.getHitTestMargin());
|
|
4308
4312
|
const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin);
|
|
4309
|
-
const shapesToCheck =
|
|
4310
|
-
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
|
|
4311
|
-
if (shape.isLocked && !hitLocked || this.isShapeHidden(shape) || this.isShapeOfType(shape, "group"))
|
|
4312
|
-
return false;
|
|
4313
|
-
const pageMask = this.getShapeMask(shape);
|
|
4314
|
-
if (pageMask && !(0, import_utils2.pointInPolygon)(point, pageMask)) return false;
|
|
4315
|
-
if (filter && !filter(shape)) return false;
|
|
4316
|
-
return true;
|
|
4317
|
-
});
|
|
4313
|
+
const shapesToCheck = opts.renderingOnly ? this.getCurrentPageRenderingShapesSorted() : this.getCurrentPageShapesSorted();
|
|
4318
4314
|
for (let i = shapesToCheck.length - 1; i >= 0; i--) {
|
|
4319
4315
|
const shape = shapesToCheck[i];
|
|
4316
|
+
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) continue;
|
|
4317
|
+
if (shape.isLocked && !hitLocked || this.isShapeHidden(shape) || this.isShapeOfType(shape, "group")) {
|
|
4318
|
+
continue;
|
|
4319
|
+
}
|
|
4320
|
+
const pageMask = this.getShapeMask(shape);
|
|
4321
|
+
if (pageMask && !(0, import_utils2.pointInPolygon)(point, pageMask)) continue;
|
|
4322
|
+
if (filter && !filter(shape)) continue;
|
|
4320
4323
|
const geometry = this.getShapeGeometry(shape);
|
|
4321
4324
|
const isGroup = geometry instanceof import_Group2d.Group2d;
|
|
4322
4325
|
const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
|
|
@@ -4421,11 +4424,15 @@ class Editor extends import_eventemitter3.default {
|
|
|
4421
4424
|
getShapesAtPoint(point, opts = {}) {
|
|
4422
4425
|
const margin = opts.margin ?? 0;
|
|
4423
4426
|
const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, margin);
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4427
|
+
const sorted = this.getCurrentPageShapesSorted();
|
|
4428
|
+
const result = [];
|
|
4429
|
+
for (let i = sorted.length - 1; i >= 0; i--) {
|
|
4430
|
+
const shape = sorted[i];
|
|
4431
|
+
if (this.isShapeHidden(shape)) continue;
|
|
4432
|
+
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) continue;
|
|
4433
|
+
if (this.isPointInShape(shape, point, opts)) result.push(shape);
|
|
4434
|
+
}
|
|
4435
|
+
return result;
|
|
4429
4436
|
}
|
|
4430
4437
|
/**
|
|
4431
4438
|
* Get shape IDs within the given bounds.
|
|
@@ -5721,6 +5728,9 @@ class Editor extends import_eventemitter3.default {
|
|
|
5721
5728
|
*/
|
|
5722
5729
|
alignShapes(shapes, operation) {
|
|
5723
5730
|
if (this.getIsReadonly()) return this;
|
|
5731
|
+
if (operation === "center") {
|
|
5732
|
+
return this.alignShapes(shapes, "center-horizontal").alignShapes(shapes, "center-vertical");
|
|
5733
|
+
}
|
|
5724
5734
|
const { clusters: shapeClustersToAlign, allBounds } = this.getShapeClusters(shapes, "align");
|
|
5725
5735
|
if (shapeClustersToAlign.length < 2) return this;
|
|
5726
5736
|
const commonBounds = import_Box.Box.Common(allBounds);
|
|
@@ -7866,7 +7876,8 @@ class Editor extends import_eventemitter3.default {
|
|
|
7866
7876
|
_prevCursor = "default";
|
|
7867
7877
|
/** @internal */
|
|
7868
7878
|
_shiftKeyTimeout = -1;
|
|
7869
|
-
|
|
7879
|
+
_releaseShiftKey() {
|
|
7880
|
+
this._shiftKeyTimeout = -1;
|
|
7870
7881
|
this.inputs.setShiftKey(false);
|
|
7871
7882
|
this.dispatch({
|
|
7872
7883
|
type: "keyboard",
|
|
@@ -7882,7 +7893,8 @@ class Editor extends import_eventemitter3.default {
|
|
|
7882
7893
|
}
|
|
7883
7894
|
/** @internal */
|
|
7884
7895
|
_altKeyTimeout = -1;
|
|
7885
|
-
|
|
7896
|
+
_releaseAltKey() {
|
|
7897
|
+
this._altKeyTimeout = -1;
|
|
7886
7898
|
this.inputs.setAltKey(false);
|
|
7887
7899
|
this.dispatch({
|
|
7888
7900
|
type: "keyboard",
|
|
@@ -7898,7 +7910,8 @@ class Editor extends import_eventemitter3.default {
|
|
|
7898
7910
|
}
|
|
7899
7911
|
/** @internal */
|
|
7900
7912
|
_ctrlKeyTimeout = -1;
|
|
7901
|
-
|
|
7913
|
+
_releaseCtrlKey() {
|
|
7914
|
+
this._ctrlKeyTimeout = -1;
|
|
7902
7915
|
this.inputs.setCtrlKey(false);
|
|
7903
7916
|
this.dispatch({
|
|
7904
7917
|
type: "keyboard",
|
|
@@ -7914,7 +7927,8 @@ class Editor extends import_eventemitter3.default {
|
|
|
7914
7927
|
}
|
|
7915
7928
|
/** @internal */
|
|
7916
7929
|
_metaKeyTimeout = -1;
|
|
7917
|
-
|
|
7930
|
+
_releaseMetaKey() {
|
|
7931
|
+
this._metaKeyTimeout = -1;
|
|
7918
7932
|
this.inputs.setMetaKey(false);
|
|
7919
7933
|
this.dispatch({
|
|
7920
7934
|
type: "keyboard",
|
|
@@ -7928,6 +7942,51 @@ class Editor extends import_eventemitter3.default {
|
|
|
7928
7942
|
code: "MetaLeft"
|
|
7929
7943
|
});
|
|
7930
7944
|
}
|
|
7945
|
+
/**
|
|
7946
|
+
* Flush any modifier still sitting in its 150ms release-debounce window, so a new
|
|
7947
|
+
* interaction (a pointer down) starts with correct modifier state instead of a
|
|
7948
|
+
* just-released key still being counted as held. A pending timer is exactly
|
|
7949
|
+
* "released but still counted as held"; a genuinely-held modifier has no timer
|
|
7950
|
+
* (-1) and is left alone.
|
|
7951
|
+
*
|
|
7952
|
+
* Each modifier is released through the same path its timer would have taken
|
|
7953
|
+
* (`_releaseShiftKey` and friends), which dispatches the synthetic `key_up` so
|
|
7954
|
+
* stale codes (e.g. `ShiftLeft`) leave `inputs.keys` and tool `onKeyUp` handlers run.
|
|
7955
|
+
* We clear every pending modifier atom and timer *first*, then dispatch: a synthetic
|
|
7956
|
+
* `key_up` reports all currently-held modifiers, so releasing them one at a time
|
|
7957
|
+
* would make each event re-confirm the not-yet-released ones and cancel their flush.
|
|
7958
|
+
* @internal
|
|
7959
|
+
*/
|
|
7960
|
+
_releaseDebouncedModifiers() {
|
|
7961
|
+
const releaseShift = this._shiftKeyTimeout !== -1;
|
|
7962
|
+
const releaseAlt = this._altKeyTimeout !== -1;
|
|
7963
|
+
const releaseCtrl = this._ctrlKeyTimeout !== -1;
|
|
7964
|
+
const releaseMeta = this._metaKeyTimeout !== -1;
|
|
7965
|
+
if (releaseShift) {
|
|
7966
|
+
clearTimeout(this._shiftKeyTimeout);
|
|
7967
|
+
this._shiftKeyTimeout = -1;
|
|
7968
|
+
this.inputs.setShiftKey(false);
|
|
7969
|
+
}
|
|
7970
|
+
if (releaseAlt) {
|
|
7971
|
+
clearTimeout(this._altKeyTimeout);
|
|
7972
|
+
this._altKeyTimeout = -1;
|
|
7973
|
+
this.inputs.setAltKey(false);
|
|
7974
|
+
}
|
|
7975
|
+
if (releaseCtrl) {
|
|
7976
|
+
clearTimeout(this._ctrlKeyTimeout);
|
|
7977
|
+
this._ctrlKeyTimeout = -1;
|
|
7978
|
+
this.inputs.setCtrlKey(false);
|
|
7979
|
+
}
|
|
7980
|
+
if (releaseMeta) {
|
|
7981
|
+
clearTimeout(this._metaKeyTimeout);
|
|
7982
|
+
this._metaKeyTimeout = -1;
|
|
7983
|
+
this.inputs.setMetaKey(false);
|
|
7984
|
+
}
|
|
7985
|
+
if (releaseShift) this._releaseShiftKey();
|
|
7986
|
+
if (releaseAlt) this._releaseAltKey();
|
|
7987
|
+
if (releaseCtrl) this._releaseCtrlKey();
|
|
7988
|
+
if (releaseMeta) this._releaseMetaKey();
|
|
7989
|
+
}
|
|
7931
7990
|
/** @internal */
|
|
7932
7991
|
_restoreToolId = "select";
|
|
7933
7992
|
/** @internal */
|
|
@@ -8037,28 +8096,28 @@ class Editor extends import_eventemitter3.default {
|
|
|
8037
8096
|
this._shiftKeyTimeout = -1;
|
|
8038
8097
|
inputs.setShiftKey(true);
|
|
8039
8098
|
} else if (!info.shiftKey && inputs.getShiftKey() && this._shiftKeyTimeout === -1) {
|
|
8040
|
-
this._shiftKeyTimeout = this.timers.setTimeout(this.
|
|
8099
|
+
this._shiftKeyTimeout = this.timers.setTimeout(this._releaseShiftKey, 150);
|
|
8041
8100
|
}
|
|
8042
8101
|
if (info.altKey) {
|
|
8043
8102
|
clearTimeout(this._altKeyTimeout);
|
|
8044
8103
|
this._altKeyTimeout = -1;
|
|
8045
8104
|
inputs.setAltKey(true);
|
|
8046
8105
|
} else if (!info.altKey && inputs.getAltKey() && this._altKeyTimeout === -1) {
|
|
8047
|
-
this._altKeyTimeout = this.timers.setTimeout(this.
|
|
8106
|
+
this._altKeyTimeout = this.timers.setTimeout(this._releaseAltKey, 150);
|
|
8048
8107
|
}
|
|
8049
8108
|
if (info.ctrlKey) {
|
|
8050
8109
|
clearTimeout(this._ctrlKeyTimeout);
|
|
8051
8110
|
this._ctrlKeyTimeout = -1;
|
|
8052
8111
|
inputs.setCtrlKey(true);
|
|
8053
8112
|
} else if (!info.ctrlKey && inputs.getCtrlKey() && this._ctrlKeyTimeout === -1) {
|
|
8054
|
-
this._ctrlKeyTimeout = this.timers.setTimeout(this.
|
|
8113
|
+
this._ctrlKeyTimeout = this.timers.setTimeout(this._releaseCtrlKey, 150);
|
|
8055
8114
|
}
|
|
8056
8115
|
if (info.metaKey && info.name !== "key_up") {
|
|
8057
8116
|
clearTimeout(this._metaKeyTimeout);
|
|
8058
8117
|
this._metaKeyTimeout = -1;
|
|
8059
8118
|
inputs.setMetaKey(true);
|
|
8060
8119
|
} else if (!info.metaKey && inputs.getMetaKey() && this._metaKeyTimeout === -1) {
|
|
8061
|
-
this._metaKeyTimeout = this.timers.setTimeout(this.
|
|
8120
|
+
this._metaKeyTimeout = this.timers.setTimeout(this._releaseMetaKey, 150);
|
|
8062
8121
|
}
|
|
8063
8122
|
if (!inputs.getIsPointing()) {
|
|
8064
8123
|
inputs.setIsDragging(false);
|
|
@@ -8203,6 +8262,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8203
8262
|
switch (info.name) {
|
|
8204
8263
|
case "pointer_down": {
|
|
8205
8264
|
if (isPenMode && !isPen) return;
|
|
8265
|
+
this._releaseDebouncedModifiers();
|
|
8206
8266
|
if (!this.inputs.getIsPanning()) {
|
|
8207
8267
|
this._longPressTimeout = this.timers.setTimeout(() => {
|
|
8208
8268
|
const vsb = this.getViewportScreenBounds();
|
|
@@ -8685,16 +8745,16 @@ __decorateClass([
|
|
|
8685
8745
|
], Editor.prototype, "getIsReadonly", 1);
|
|
8686
8746
|
__decorateClass([
|
|
8687
8747
|
import_utils.bind
|
|
8688
|
-
], Editor.prototype, "
|
|
8748
|
+
], Editor.prototype, "_releaseShiftKey", 1);
|
|
8689
8749
|
__decorateClass([
|
|
8690
8750
|
import_utils.bind
|
|
8691
|
-
], Editor.prototype, "
|
|
8751
|
+
], Editor.prototype, "_releaseAltKey", 1);
|
|
8692
8752
|
__decorateClass([
|
|
8693
8753
|
import_utils.bind
|
|
8694
|
-
], Editor.prototype, "
|
|
8754
|
+
], Editor.prototype, "_releaseCtrlKey", 1);
|
|
8695
8755
|
__decorateClass([
|
|
8696
8756
|
import_utils.bind
|
|
8697
|
-
], Editor.prototype, "
|
|
8757
|
+
], Editor.prototype, "_releaseMetaKey", 1);
|
|
8698
8758
|
function alertMaxShapes(editor, pageId = editor.getCurrentPageId()) {
|
|
8699
8759
|
const name = editor.getPage(pageId).name;
|
|
8700
8760
|
editor.emit("max-shapes", { name, pageId, count: editor.options.maxShapesPerPage });
|