@tldraw/editor 5.1.1 → 5.2.0-canary.0878dbd31f0d

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.
Files changed (117) hide show
  1. package/README.md +7 -1
  2. package/dist-cjs/index.d.ts +33 -50
  3. package/dist-cjs/index.js +3 -4
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +4 -1
  6. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +3 -3
  7. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js.map +2 -2
  9. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js +1 -1
  10. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js.map +3 -3
  11. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js.map +2 -2
  13. package/dist-cjs/lib/editor/Editor.js +57 -18
  14. package/dist-cjs/lib/editor/Editor.js.map +3 -3
  15. package/dist-cjs/lib/editor/derivations/bindingsIndex.js +2 -2
  16. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  17. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +2 -2
  18. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  19. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js +2 -2
  20. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js.map +2 -2
  21. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +8 -58
  22. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  23. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +3 -3
  24. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -2
  26. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +15 -2
  28. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  29. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js +79 -0
  30. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js.map +7 -0
  31. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  32. package/dist-cjs/lib/editor/types/event-types.js +0 -2
  33. package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
  34. package/dist-cjs/lib/hooks/usePresence.js.map +2 -2
  35. package/dist-cjs/lib/license/LicenseProvider.js +3 -1
  36. package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
  37. package/dist-cjs/lib/primitives/utils.js +2 -2
  38. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  39. package/dist-cjs/lib/utils/dom.js +5 -3
  40. package/dist-cjs/lib/utils/dom.js.map +2 -2
  41. package/dist-cjs/version.js +3 -3
  42. package/dist-cjs/version.js.map +1 -1
  43. package/dist-esm/index.d.mts +33 -50
  44. package/dist-esm/index.mjs +2 -6
  45. package/dist-esm/index.mjs.map +2 -2
  46. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +4 -1
  47. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +3 -3
  48. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs +2 -2
  49. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map +2 -2
  50. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs +1 -1
  51. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map +3 -3
  52. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs +2 -2
  53. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs.map +2 -2
  54. package/dist-esm/lib/editor/Editor.mjs +57 -18
  55. package/dist-esm/lib/editor/Editor.mjs.map +3 -3
  56. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +2 -2
  57. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  58. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +2 -2
  59. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  60. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs +2 -2
  61. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs.map +2 -2
  62. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +8 -58
  63. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  64. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +3 -3
  65. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
  66. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -2
  67. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  68. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +15 -2
  69. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  70. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs +59 -0
  71. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs.map +7 -0
  72. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  73. package/dist-esm/lib/editor/types/event-types.mjs +0 -2
  74. package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
  75. package/dist-esm/lib/hooks/usePresence.mjs.map +2 -2
  76. package/dist-esm/lib/license/LicenseProvider.mjs +3 -1
  77. package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
  78. package/dist-esm/lib/primitives/utils.mjs +2 -2
  79. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  80. package/dist-esm/lib/utils/dom.mjs +5 -3
  81. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  82. package/dist-esm/version.mjs +3 -3
  83. package/dist-esm/version.mjs.map +1 -1
  84. package/editor.css +2 -0
  85. package/package.json +8 -8
  86. package/src/index.ts +1 -5
  87. package/src/lib/components/default-components/DefaultErrorFallback.tsx +4 -1
  88. package/src/lib/components/default-components/DefaultLoadingScreen.tsx +1 -1
  89. package/src/lib/components/default-components/DefaultShapeErrorFallback.tsx +4 -3
  90. package/src/lib/components/default-components/DefaultSvgDefs.tsx +1 -1
  91. package/src/lib/editor/Editor.ts +92 -29
  92. package/src/lib/editor/derivations/bindingsIndex.ts +1 -1
  93. package/src/lib/editor/derivations/parentsToChildren.ts +1 -1
  94. package/src/lib/editor/derivations/shapeIdsInCurrentPage.ts +1 -1
  95. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +54 -74
  96. package/src/lib/editor/managers/ClickManager/ClickManager.ts +15 -65
  97. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts +43 -16
  98. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +8 -5
  99. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +4 -4
  100. package/src/lib/editor/managers/FocusManager/FocusManager.ts +1 -2
  101. package/src/lib/editor/managers/FontManager/FontManager.test.ts +13 -9
  102. package/src/lib/editor/managers/TextManager/TextManager.test.ts +16 -14
  103. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +12 -2
  104. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +27 -2
  105. package/src/lib/editor/overlays/strokeShapeIndicators.ts +86 -0
  106. package/src/lib/editor/tools/StateNode.ts +0 -2
  107. package/src/lib/editor/types/event-types.ts +2 -6
  108. package/src/lib/hooks/usePresence.ts +2 -2
  109. package/src/lib/license/LicenseProvider.tsx +3 -1
  110. package/src/lib/primitives/utils.ts +1 -1
  111. package/src/lib/utils/dom.ts +5 -3
  112. package/src/version.ts +3 -3
  113. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +0 -161
  114. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +0 -7
  115. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +0 -141
  116. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +0 -7
  117. package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +0 -216
@@ -2152,7 +2152,7 @@ class Editor extends import_eventemitter3.default {
2152
2152
  return baseCamera;
2153
2153
  }
2154
2154
  _getFollowingPresence(targetUserId) {
2155
- const visited = [this.user.getId()];
2155
+ const visited = [this.user.getRecordId()];
2156
2156
  const collaborators = this.getCollaborators();
2157
2157
  let leaderPresence = null;
2158
2158
  while (targetUserId && !visited.includes(targetUserId)) {
@@ -2340,6 +2340,11 @@ class Editor extends import_eventemitter3.default {
2340
2340
  getConstrainedCamera(point, opts) {
2341
2341
  const currentCamera = this.getCamera();
2342
2342
  let { x, y, z = currentCamera.z } = point;
2343
+ const preserveFocalPoint = (current, requested, rz, z2) => {
2344
+ const cz = currentCamera.z;
2345
+ if (rz === cz) return current;
2346
+ return current + (requested - current) * (1 / z2 - 1 / cz) / (1 / rz - 1 / cz);
2347
+ };
2343
2348
  if (!opts?.force) {
2344
2349
  const cameraOptions = this.getCameraOptions();
2345
2350
  const zoomMin = cameraOptions.zoomSteps[0];
@@ -2359,14 +2364,10 @@ class Editor extends import_eventemitter3.default {
2359
2364
  z = this.getInitialZoom();
2360
2365
  }
2361
2366
  if (z < minZ || z > maxZ) {
2362
- const { x: cx, y: cy, z: cz } = currentCamera;
2363
- const cxA = -cx + vsb.w / cz / 2;
2364
- const cyA = -cy + vsb.h / cz / 2;
2367
+ const rz = z;
2365
2368
  z = (0, import_utils2.clamp)(z, minZ, maxZ);
2366
- const cxB = -cx + vsb.w / z / 2;
2367
- const cyB = -cy + vsb.h / z / 2;
2368
- x = cx + cxB - cxA;
2369
- y = cy + cyB - cyA;
2369
+ x = preserveFocalPoint(currentCamera.x, x, rz, z);
2370
+ y = preserveFocalPoint(currentCamera.y, y, rz, z);
2370
2371
  }
2371
2372
  const minX = px / z - bounds.x;
2372
2373
  const minY = py / z - bounds.y;
@@ -2435,10 +2436,10 @@ class Editor extends import_eventemitter3.default {
2435
2436
  }
2436
2437
  } else {
2437
2438
  if (z > zoomMax || z < zoomMin) {
2438
- const { x: cx, y: cy, z: cz } = currentCamera;
2439
+ const rz = z;
2439
2440
  z = (0, import_utils2.clamp)(z, zoomMin, zoomMax);
2440
- x = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2);
2441
- y = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2);
2441
+ x = preserveFocalPoint(currentCamera.x, x, rz, z);
2442
+ y = preserveFocalPoint(currentCamera.y, y, rz, z);
2442
2443
  }
2443
2444
  }
2444
2445
  }
@@ -2861,14 +2862,25 @@ class Editor extends import_eventemitter3.default {
2861
2862
  this.off("stop-camera-animation", cancel);
2862
2863
  };
2863
2864
  this.once("stop-camera-animation", cancel);
2865
+ const dirZ = direction.z ?? 0;
2864
2866
  const moveCamera = (elapsed) => {
2865
2867
  const { x: cx, y: cy, z: cz } = this.getCamera();
2866
- const movementVec = import_Vec.Vec.Mul(direction, currentSpeed * elapsed / cz);
2868
+ const dx = direction.x * (currentSpeed * elapsed) / cz;
2869
+ const dy = direction.y * (currentSpeed * elapsed) / cz;
2870
+ let newCx = cx + dx;
2871
+ let newCy = cy + dy;
2872
+ let newCz = cz;
2873
+ if (dirZ !== 0) {
2874
+ newCz = cz * (1 + dirZ * currentSpeed * elapsed);
2875
+ const center = this.getViewportScreenCenter();
2876
+ newCx += center.x / newCz - center.x / cz;
2877
+ newCy += center.y / newCz - center.y / cz;
2878
+ }
2867
2879
  currentSpeed *= 1 - friction;
2868
2880
  if (currentSpeed < speedThreshold) {
2869
2881
  cancel();
2870
2882
  } else {
2871
- this._setCamera(new import_Vec.Vec(cx + movementVec.x, cy + movementVec.y, cz));
2883
+ this._setCamera(new import_Vec.Vec(newCx, newCy, newCz));
2872
2884
  }
2873
2885
  };
2874
2886
  this.on("tick", moveCamera);
@@ -3188,7 +3200,7 @@ class Editor extends import_eventemitter3.default {
3188
3200
  */
3189
3201
  startFollowingUser(userId) {
3190
3202
  this.stopFollowingUser();
3191
- const thisUserId = this.user.getId();
3203
+ const thisUserId = this.user.getExternalId();
3192
3204
  if (!thisUserId) {
3193
3205
  console.warn("You should set the userId for the current instance before following a user");
3194
3206
  }
@@ -7834,6 +7846,15 @@ class Editor extends import_eventemitter3.default {
7834
7846
  _didPinch = false;
7835
7847
  /** @internal */
7836
7848
  _selectedShapeIdsAtPointerDown = [];
7849
+ /**
7850
+ * Whether `_selectedShapeIdsAtPointerDown` holds a pre-gesture selection
7851
+ * captured by a `pointer_down` (the touch path) that a following pinch
7852
+ * should restore. False when no pointer_down preceded the pinch (the
7853
+ * Safari trackpad path uses gesture events), in which case `pinch_start`
7854
+ * captures the live selection instead.
7855
+ * @internal
7856
+ */
7857
+ _didCaptureSelectionAtPointerDown = false;
7837
7858
  /** @internal */
7838
7859
  _longPressTimeout = -1;
7839
7860
  /** @internal */
@@ -7966,10 +7987,15 @@ class Editor extends import_eventemitter3.default {
7966
7987
  case "pinch_start": {
7967
7988
  if (inputs.getIsPinching()) return;
7968
7989
  if (!inputs.getIsEditing()) {
7969
- this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
7990
+ if (!this._didCaptureSelectionAtPointerDown) {
7991
+ this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
7992
+ }
7970
7993
  this._didPinch = true;
7971
7994
  inputs.setIsPinching(true);
7972
7995
  this.interrupt();
7996
+ if (this._didCaptureSelectionAtPointerDown) {
7997
+ this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
7998
+ }
7973
7999
  }
7974
8000
  this.emit("event", info);
7975
8001
  return;
@@ -8009,6 +8035,7 @@ class Editor extends import_eventemitter3.default {
8009
8035
  const { _selectedShapeIdsAtPointerDown: shapesToReselect } = this;
8010
8036
  this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
8011
8037
  this._selectedShapeIdsAtPointerDown = [];
8038
+ this._didCaptureSelectionAtPointerDown = false;
8012
8039
  if (this._didPinch) {
8013
8040
  this._didPinch = false;
8014
8041
  if (shapesToReselect.length > 0) {
@@ -8102,7 +8129,10 @@ class Editor extends import_eventemitter3.default {
8102
8129
  });
8103
8130
  }, this.options.longPressDurationMs);
8104
8131
  }
8105
- this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
8132
+ if (!this._didCaptureSelectionAtPointerDown) {
8133
+ this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
8134
+ this._didCaptureSelectionAtPointerDown = true;
8135
+ }
8106
8136
  if (info.button === import_constants.LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId;
8107
8137
  inputs.buttons.add(info.button);
8108
8138
  inputs.setIsPointing(true);
@@ -8178,6 +8208,7 @@ class Editor extends import_eventemitter3.default {
8178
8208
  if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
8179
8209
  this.inputs.setIsRightPointing(false);
8180
8210
  this._selectedShapeIdsAtPointerDown = [];
8211
+ this._didCaptureSelectionAtPointerDown = false;
8181
8212
  break;
8182
8213
  }
8183
8214
  this.inputs.setIsRightPointing(false);
@@ -8212,14 +8243,21 @@ class Editor extends import_eventemitter3.default {
8212
8243
  this.setCursor({ type: this._prevCursor, rotation: 0 });
8213
8244
  }
8214
8245
  if (slideSpeed > 0) {
8215
- this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8246
+ this.slideCamera({
8247
+ speed: slideSpeed,
8248
+ direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
8249
+ });
8216
8250
  }
8217
8251
  this._selectedShapeIdsAtPointerDown = [];
8252
+ this._didCaptureSelectionAtPointerDown = false;
8218
8253
  return this;
8219
8254
  }
8220
8255
  }
8221
8256
  if (slideSpeed > 0) {
8222
- this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8257
+ this.slideCamera({
8258
+ speed: slideSpeed,
8259
+ direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
8260
+ });
8223
8261
  }
8224
8262
  } else {
8225
8263
  if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
@@ -8228,6 +8266,7 @@ class Editor extends import_eventemitter3.default {
8228
8266
  }
8229
8267
  }
8230
8268
  this._selectedShapeIdsAtPointerDown = [];
8269
+ this._didCaptureSelectionAtPointerDown = false;
8231
8270
  break;
8232
8271
  }
8233
8272
  }