@tldraw/editor 5.4.0-canary.587f42e00c65 → 5.4.0-canary.5a084792df77

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 (51) hide show
  1. package/dist-cjs/index.js +1 -1
  2. package/dist-cjs/lib/editor/Editor.js +39 -62
  3. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  4. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +3 -3
  5. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  6. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +1 -1
  7. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  8. package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -0
  9. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  10. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +1 -0
  11. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  12. package/dist-cjs/lib/hooks/usePeerIds.js +2 -1
  13. package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
  14. package/dist-cjs/lib/utils/deepLinks.js +5 -1
  15. package/dist-cjs/lib/utils/deepLinks.js.map +2 -2
  16. package/dist-cjs/lib/utils/sync/alerts.js +1 -1
  17. package/dist-cjs/lib/utils/sync/alerts.js.map +1 -1
  18. package/dist-cjs/version.js +3 -3
  19. package/dist-cjs/version.js.map +1 -1
  20. package/dist-esm/index.mjs +1 -1
  21. package/dist-esm/lib/editor/Editor.mjs +40 -62
  22. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  23. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +3 -3
  24. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  25. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +1 -1
  26. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  27. package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -0
  28. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  29. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +1 -0
  30. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  31. package/dist-esm/lib/hooks/usePeerIds.mjs +2 -1
  32. package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
  33. package/dist-esm/lib/utils/deepLinks.mjs +5 -1
  34. package/dist-esm/lib/utils/deepLinks.mjs.map +2 -2
  35. package/dist-esm/lib/utils/sync/alerts.mjs +1 -1
  36. package/dist-esm/lib/utils/sync/alerts.mjs.map +1 -1
  37. package/dist-esm/version.mjs +3 -3
  38. package/dist-esm/version.mjs.map +1 -1
  39. package/package.json +7 -7
  40. package/src/lib/editor/Editor.ts +70 -87
  41. package/src/lib/editor/managers/ClickManager/ClickManager.ts +5 -3
  42. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +4 -1
  43. package/src/lib/hooks/useCanvasEvents.ts +2 -0
  44. package/src/lib/hooks/usePassThroughWheelEvents.ts +3 -0
  45. package/src/lib/hooks/usePeerIds.ts +2 -1
  46. package/src/lib/test/useCanvasEvents.test.tsx +74 -0
  47. package/src/lib/test/usePassThroughWheelEvents.test.tsx +25 -2
  48. package/src/lib/utils/deepLinks.test.ts +15 -0
  49. package/src/lib/utils/deepLinks.ts +7 -1
  50. package/src/lib/utils/sync/alerts.ts +1 -1
  51. package/src/version.ts +3 -3
package/dist-cjs/index.js CHANGED
@@ -392,7 +392,7 @@ var import_uniq = require("./lib/utils/uniq");
392
392
  var import_defaultThemes2 = require("./lib/editor/managers/ThemeManager/defaultThemes");
393
393
  (0, import_utils.registerTldrawLibraryVersion)(
394
394
  "@tldraw/editor",
395
- "5.4.0-canary.587f42e00c65",
395
+ "5.4.0-canary.5a084792df77",
396
396
  "cjs"
397
397
  );
398
398
  //# sourceMappingURL=index.js.map
@@ -257,6 +257,10 @@ class Editor extends import_eventemitter3.default {
257
257
  if (!nextPageState) nextPageState = { ...prevPageState };
258
258
  nextPageState.editingShapeId = null;
259
259
  }
260
+ if (prevPageState.croppingShapeId && shapesNoLongerInPage.has(prevPageState.croppingShapeId)) {
261
+ if (!nextPageState) nextPageState = { ...prevPageState };
262
+ nextPageState.croppingShapeId = null;
263
+ }
260
264
  const hintingShapeIds = prevPageState.hintingShapeIds.filter(
261
265
  (id) => !shapesNoLongerInPage.has(id)
262
266
  );
@@ -1959,42 +1963,28 @@ class Editor extends import_eventemitter3.default {
1959
1963
  */
1960
1964
  setEditingShape(shape) {
1961
1965
  const id = typeof shape === "string" ? shape : shape?.id ?? null;
1962
- if (!id) {
1966
+ if (id && !this.canEditShape(id)) return this;
1967
+ this.run(() => {
1968
+ const prevEditingShapeId = this.getEditingShapeId();
1969
+ if (prevEditingShapeId) {
1970
+ const prevEditingShape = this.getShape(prevEditingShapeId);
1971
+ if (prevEditingShape) {
1972
+ this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1973
+ }
1974
+ }
1963
1975
  this.run(
1964
1976
  () => {
1965
- const prevEditingShapeId = this.getEditingShapeId();
1966
- if (prevEditingShapeId) {
1967
- const prevEditingShape = this.getShape(prevEditingShapeId);
1968
- if (prevEditingShape) {
1969
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1970
- }
1971
- }
1972
1977
  this._updateCurrentPageState({ editingShapeId: null });
1973
1978
  this._currentRichTextEditor.set(null);
1979
+ if (!id) return;
1980
+ this.select(id);
1981
+ this._updateCurrentPageState({ editingShapeId: id });
1982
+ const nextEditingShape = this.getShape(id);
1983
+ this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
1974
1984
  },
1975
1985
  { history: "ignore" }
1976
1986
  );
1977
- return this;
1978
- }
1979
- if (!this.canEditShape(id)) return this;
1980
- this.run(
1981
- () => {
1982
- const prevEditingShapeId = this.getEditingShapeId();
1983
- if (prevEditingShapeId) {
1984
- const prevEditingShape = this.getShape(prevEditingShapeId);
1985
- if (prevEditingShape) {
1986
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1987
- }
1988
- }
1989
- this._updateCurrentPageState({ editingShapeId: null });
1990
- this._currentRichTextEditor.set(null);
1991
- this.select(id);
1992
- this._updateCurrentPageState({ editingShapeId: id });
1993
- const nextEditingShape = this.getShape(id);
1994
- this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
1995
- },
1996
- { history: "ignore" }
1997
- );
1987
+ });
1998
1988
  return this;
1999
1989
  }
2000
1990
  // Rich text editor
@@ -2100,19 +2090,12 @@ class Editor extends import_eventemitter3.default {
2100
2090
  * @public
2101
2091
  */
2102
2092
  setErasingShapes(shapes) {
2103
- const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
2093
+ const ids = typeof shapes[0] === "string" ? shapes.slice() : shapes.map((shape) => shape.id);
2104
2094
  ids.sort();
2105
2095
  const erasingShapeIds = this.getErasingShapeIds();
2106
2096
  this.run(
2107
2097
  () => {
2108
- if (ids.length === erasingShapeIds.length) {
2109
- for (let i = 0; i < ids.length; i++) {
2110
- if (ids[i] !== erasingShapeIds[i]) {
2111
- this._updateCurrentPageState({ erasingShapeIds: ids });
2112
- break;
2113
- }
2114
- }
2115
- } else {
2098
+ if (!(0, import_utils.areArraysShallowEqual)(ids, erasingShapeIds)) {
2116
2099
  this._updateCurrentPageState({ erasingShapeIds: ids });
2117
2100
  }
2118
2101
  },
@@ -2145,6 +2128,7 @@ class Editor extends import_eventemitter3.default {
2145
2128
  if (!_shape) return false;
2146
2129
  const util = this.getShapeUtil(_shape);
2147
2130
  if (!util.canCrop(_shape)) return false;
2131
+ if (this.getIsReadonly()) return false;
2148
2132
  if (this.isShapeOrAncestorLocked(_shape)) return false;
2149
2133
  return true;
2150
2134
  }
@@ -2354,7 +2338,7 @@ class Editor extends import_eventemitter3.default {
2354
2338
  ...this._cameraOptions.__unsafe__getWithoutCapture(),
2355
2339
  ...opts
2356
2340
  });
2357
- if (next.zoomSteps?.length < 1) next.zoomSteps = [1];
2341
+ if (!next.zoomSteps || next.zoomSteps.length < 1) next.zoomSteps = [1];
2358
2342
  this._cameraOptions.set(next);
2359
2343
  this.setCamera(this.getCamera());
2360
2344
  return this;
@@ -2375,8 +2359,8 @@ class Editor extends import_eventemitter3.default {
2375
2359
  const vsb = this.getViewportScreenBounds();
2376
2360
  if (cameraOptions.constraints) {
2377
2361
  const { constraints } = cameraOptions;
2378
- const py = Math.min(constraints.padding.y, vsb.w / 2);
2379
- const px = Math.min(constraints.padding.x, vsb.h / 2);
2362
+ const px = Math.min(constraints.padding.x, vsb.w / 2);
2363
+ const py = Math.min(constraints.padding.y, vsb.h / 2);
2380
2364
  const bounds = import_Box.Box.From(cameraOptions.constraints.bounds);
2381
2365
  const zx = (vsb.w - px * 2) / bounds.w;
2382
2366
  const zy = (vsb.h - py * 2) / bounds.h;
@@ -2415,12 +2399,12 @@ class Editor extends import_eventemitter3.default {
2415
2399
  break;
2416
2400
  }
2417
2401
  case "inside": {
2418
- if (z < zx) x = (0, import_utils2.clamp)(x, minX, (vsb.w - px) / z - bounds.w);
2402
+ if (z < zx) x = (0, import_utils2.clamp)(x, minX, (vsb.w - px) / z - bounds.w - bounds.x);
2419
2403
  else x = (0, import_utils2.clamp)(x, minX + freeW, minX);
2420
2404
  break;
2421
2405
  }
2422
2406
  case "outside": {
2423
- x = (0, import_utils2.clamp)(x, px / z - bounds.w, (vsb.w - px) / z);
2407
+ x = (0, import_utils2.clamp)(x, px / z - bounds.w - bounds.x, (vsb.w - px) / z - bounds.x);
2424
2408
  break;
2425
2409
  }
2426
2410
  case "free": {
@@ -2441,12 +2425,12 @@ class Editor extends import_eventemitter3.default {
2441
2425
  break;
2442
2426
  }
2443
2427
  case "inside": {
2444
- if (z < zy) y = (0, import_utils2.clamp)(y, minY, (vsb.h - py) / z - bounds.h);
2428
+ if (z < zy) y = (0, import_utils2.clamp)(y, minY, (vsb.h - py) / z - bounds.h - bounds.y);
2445
2429
  else y = (0, import_utils2.clamp)(y, minY + freeH, minY);
2446
2430
  break;
2447
2431
  }
2448
2432
  case "outside": {
2449
- y = (0, import_utils2.clamp)(y, py / z - bounds.h, (vsb.h - py) / z);
2433
+ y = (0, import_utils2.clamp)(y, py / z - bounds.h - bounds.y, (vsb.h - py) / z - bounds.y);
2450
2434
  break;
2451
2435
  }
2452
2436
  case "free": {
@@ -4058,7 +4042,9 @@ class Editor extends import_eventemitter3.default {
4058
4042
  if (pageMask) {
4059
4043
  if (pageMask.length === 0) return void 0;
4060
4044
  const { corners } = pageBounds;
4061
- if (corners.every((p, i) => p && import_Vec.Vec.Equals(p, pageMask[i]))) return pageBounds.clone();
4045
+ if (pageMask.length === corners.length && corners.every((p, i) => import_Vec.Vec.Equals(p, pageMask[i]))) {
4046
+ return pageBounds.clone();
4047
+ }
4062
4048
  const intersection = (0, import_intersect.intersectPolygonPolygon)(pageMask, corners);
4063
4049
  if (!intersection) return;
4064
4050
  return import_Box.Box.FromPoints(intersection);
@@ -4297,7 +4283,7 @@ class Editor extends import_eventemitter3.default {
4297
4283
  const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
4298
4284
  const shapeUtil = this.getShapeUtil(shape);
4299
4285
  const isShapeFrameLike = this.isShapeFrameLike(shape);
4300
- if (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim()) {
4286
+ if (isGroup && (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim())) {
4301
4287
  for (const childGeometry of geometry.children) {
4302
4288
  if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
4303
4289
  return shape;
@@ -5220,26 +5206,17 @@ class Editor extends import_eventemitter3.default {
5220
5206
  toggleLock(shapes) {
5221
5207
  const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
5222
5208
  if (this.getIsReadonly() || ids.length === 0) return this;
5223
- let allLocked = true, allUnlocked = true;
5209
+ let allLocked = true;
5224
5210
  const shapesToToggle = [];
5225
5211
  for (const id of ids) {
5226
5212
  const shape = this.getShape(id);
5227
5213
  if (shape) {
5228
5214
  shapesToToggle.push(shape);
5229
- if (shape.isLocked) {
5230
- allUnlocked = false;
5231
- } else {
5232
- allLocked = false;
5233
- }
5215
+ if (!shape.isLocked) allLocked = false;
5234
5216
  }
5235
5217
  }
5236
5218
  this.run(() => {
5237
- if (allUnlocked) {
5238
- this.updateShapes(
5239
- shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
5240
- );
5241
- this.setSelectedShapes([]);
5242
- } else if (allLocked) {
5219
+ if (allLocked) {
5243
5220
  this.updateShapes(
5244
5221
  shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))
5245
5222
  );
@@ -5247,6 +5224,7 @@ class Editor extends import_eventemitter3.default {
5247
5224
  this.updateShapes(
5248
5225
  shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
5249
5226
  );
5227
+ this.setSelectedShapes([]);
5250
5228
  }
5251
5229
  });
5252
5230
  return this;
@@ -8728,10 +8706,9 @@ function withIsolatedShapes(editor, shapeIds, callback) {
8728
8706
  }
8729
8707
  function getCameraFitXFitY(editor, cameraOptions) {
8730
8708
  if (!cameraOptions.constraints) throw Error("Should have constraints here");
8731
- const {
8732
- padding: { x: px, y: py }
8733
- } = cameraOptions.constraints;
8734
8709
  const vsb = editor.getViewportScreenBounds();
8710
+ const px = Math.min(cameraOptions.constraints.padding.x, vsb.w / 2);
8711
+ const py = Math.min(cameraOptions.constraints.padding.y, vsb.h / 2);
8735
8712
  const bounds = import_Box.Box.From(cameraOptions.constraints.bounds);
8736
8713
  const zx = (vsb.w - px * 2) / bounds.w;
8737
8714
  const zy = (vsb.h - py * 2) / bounds.h;