@tldraw/editor 5.3.0-canary.fceaae5e9feb → 5.3.0-internal.c5c7f1d817d0

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 (61) hide show
  1. package/dist-cjs/index.d.ts +60 -2
  2. package/dist-cjs/index.js +4 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +6 -1
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/editor/Editor.js +72 -15
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +9 -0
  9. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  10. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +3 -0
  11. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  12. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +3 -0
  13. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  16. package/dist-cjs/lib/license/LicenseManager.js +62 -7
  17. package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
  18. package/dist-cjs/lib/license/useLicenseManagerState.js +7 -0
  19. package/dist-cjs/lib/license/useLicenseManagerState.js.map +2 -2
  20. package/dist-cjs/lib/options.js +2 -1
  21. package/dist-cjs/lib/options.js.map +2 -2
  22. package/dist-cjs/version.js +3 -3
  23. package/dist-cjs/version.js.map +1 -1
  24. package/dist-esm/index.d.mts +60 -2
  25. package/dist-esm/index.mjs +5 -2
  26. package/dist-esm/index.mjs.map +2 -2
  27. package/dist-esm/lib/TldrawEditor.mjs +6 -1
  28. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  29. package/dist-esm/lib/editor/Editor.mjs +72 -15
  30. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  31. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +9 -0
  32. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  33. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +3 -0
  34. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  35. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +3 -0
  36. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +2 -2
  37. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  38. package/dist-esm/lib/license/LicenseManager.mjs +63 -8
  39. package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
  40. package/dist-esm/lib/license/useLicenseManagerState.mjs +7 -0
  41. package/dist-esm/lib/license/useLicenseManagerState.mjs.map +2 -2
  42. package/dist-esm/lib/options.mjs +2 -1
  43. package/dist-esm/lib/options.mjs.map +2 -2
  44. package/dist-esm/version.mjs +3 -3
  45. package/dist-esm/version.mjs.map +1 -1
  46. package/editor.css +10 -0
  47. package/package.json +7 -7
  48. package/src/index.ts +3 -1
  49. package/src/lib/TldrawEditor.tsx +10 -1
  50. package/src/lib/editor/Editor.ts +111 -20
  51. package/src/lib/editor/managers/FontManager/FontManager.test.ts +66 -0
  52. package/src/lib/editor/managers/FontManager/FontManager.ts +14 -0
  53. package/src/lib/editor/managers/TextManager/TextManager.ts +3 -0
  54. package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +6 -1
  55. package/src/lib/editor/shapes/ShapeUtil.ts +24 -0
  56. package/src/lib/editor/types/emit-types.ts +1 -0
  57. package/src/lib/license/LicenseManager.test.ts +220 -29
  58. package/src/lib/license/LicenseManager.ts +107 -6
  59. package/src/lib/license/useLicenseManagerState.ts +17 -1
  60. package/src/lib/options.ts +3 -1
  61. package/src/version.ts +3 -3
@@ -273,12 +273,27 @@ class Editor extends import_eventemitter3.default {
273
273
  let deletedBindings = /* @__PURE__ */ new Map();
274
274
  const deletedShapeIds = /* @__PURE__ */ new Set();
275
275
  const invalidParents = /* @__PURE__ */ new Set();
276
+ const createdShapes = /* @__PURE__ */ new Set();
276
277
  let invalidBindingTypes = /* @__PURE__ */ new Set();
277
278
  this.disposables.add(
278
279
  this.sideEffects.registerOperationCompleteHandler(() => {
280
+ const deletedIds = deletedShapeIds.size ? new Set(deletedShapeIds) : null;
279
281
  deletedShapeIds.clear();
282
+ if (deletedIds) {
283
+ const updates = (0, import_utils.compact)(
284
+ this.getPageStates().map((pageState) => {
285
+ return cleanupInstancePageState(pageState, deletedIds);
286
+ })
287
+ );
288
+ if (updates.length) {
289
+ this.store.put(updates);
290
+ }
291
+ }
292
+ const justCreatedShapeIds = new Set(createdShapes);
293
+ createdShapes.clear();
280
294
  for (const parentId of invalidParents) {
281
295
  invalidParents.delete(parentId);
296
+ if (justCreatedShapeIds.has(parentId)) continue;
282
297
  const parent = this.getShape(parentId);
283
298
  if (!parent) continue;
284
299
  const util = this.getShapeUtil(parent);
@@ -308,6 +323,12 @@ class Editor extends import_eventemitter3.default {
308
323
  this.disposables.add(
309
324
  this.sideEffects.register({
310
325
  shape: {
326
+ afterCreate: (shape) => {
327
+ createdShapes.add(shape.id);
328
+ if (shape.parentId && (0, import_tlschema.isShapeId)(shape.parentId)) {
329
+ invalidParents.add(shape.parentId);
330
+ }
331
+ },
311
332
  afterChange: (shapeBefore, shapeAfter) => {
312
333
  for (const binding of this.getBindingsInvolvingShape(shapeAfter)) {
313
334
  invalidBindingTypes.add(binding.type);
@@ -397,15 +418,6 @@ class Editor extends import_eventemitter3.default {
397
418
  if (deleteBindingIds.length) {
398
419
  this.deleteBindings(deleteBindingIds);
399
420
  }
400
- const deletedIds = /* @__PURE__ */ new Set([shape.id]);
401
- const updates = (0, import_utils.compact)(
402
- this.getPageStates().map((pageState) => {
403
- return cleanupInstancePageState(pageState, deletedIds);
404
- })
405
- );
406
- if (updates.length) {
407
- this.store.put(updates);
408
- }
409
421
  }
410
422
  },
411
423
  binding: {
@@ -482,6 +494,9 @@ class Editor extends import_eventemitter3.default {
482
494
  },
483
495
  instance_page_state: {
484
496
  afterChange: (prev, next) => {
497
+ if (prev?.focusedGroupId !== next?.focusedGroupId) {
498
+ this.cancelDoubleClick();
499
+ }
485
500
  if (prev?.selectedShapeIds !== next?.selectedShapeIds) {
486
501
  const filtered = next.selectedShapeIds.filter((id) => {
487
502
  let parentId = this.getShape(id)?.parentId;
@@ -554,6 +569,12 @@ class Editor extends import_eventemitter3.default {
554
569
  this.stopFollowingUser();
555
570
  }
556
571
  this.on("tick", this._flushEventsForTick);
572
+ this.on("mount", () => {
573
+ this._isMounted.set(true);
574
+ });
575
+ this.on("unmount", () => {
576
+ this._isMounted.set(false);
577
+ });
557
578
  this.timers.requestAnimationFrame(() => {
558
579
  this._tickManager.start();
559
580
  });
@@ -648,6 +669,10 @@ class Editor extends import_eventemitter3.default {
648
669
  * @public
649
670
  */
650
671
  isDisposed = false;
672
+ _isMounted = (0, import_state.atom)("isMounted", false);
673
+ getIsMounted() {
674
+ return this._isMounted.get();
675
+ }
651
676
  /**
652
677
  * A manager for the editor's tick events.
653
678
  *
@@ -779,6 +804,9 @@ class Editor extends import_eventemitter3.default {
779
804
  * @public
780
805
  */
781
806
  dispose() {
807
+ if (this._isMounted.get()) {
808
+ this.emit("unmount");
809
+ }
782
810
  this.stopCameraAnimation();
783
811
  if (this.getInstanceState().followingUserId) {
784
812
  this.stopFollowingUser();
@@ -4215,6 +4243,11 @@ class Editor extends import_eventemitter3.default {
4215
4243
  });
4216
4244
  return commonBounds;
4217
4245
  }
4246
+ getHitTestMargin() {
4247
+ const { hitTestMargin, coarseHitTestMargin } = this.options;
4248
+ const margin = this.getInstanceState().isCoarsePointer ? coarseHitTestMargin : hitTestMargin;
4249
+ return margin / this.getZoomLevel();
4250
+ }
4218
4251
  /**
4219
4252
  * Get the top-most selected shape at the given point, ignoring groups.
4220
4253
  *
@@ -4224,7 +4257,21 @@ class Editor extends import_eventemitter3.default {
4224
4257
  */
4225
4258
  getSelectedShapeAtPoint(point) {
4226
4259
  const selectedShapeIds = this.getSelectedShapeIds();
4227
- return this.getCurrentPageShapesSorted().filter((shape) => shape.type !== "group" && selectedShapeIds.includes(shape.id)).reverse().find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }));
4260
+ const margin = this.options.hitTestMargin / this.getZoomLevel();
4261
+ const sortedShapes = this.getCurrentPageShapesSorted();
4262
+ for (let i = sortedShapes.length - 1; i >= 0; i--) {
4263
+ const shape = sortedShapes[i];
4264
+ if (shape.type === "group") continue;
4265
+ if (!selectedShapeIds.includes(shape.id)) continue;
4266
+ if (this.getShapeGeometry(shape).hitTestPoint(
4267
+ this.getPointInShapeSpace(shape, point),
4268
+ margin,
4269
+ true
4270
+ )) {
4271
+ return shape;
4272
+ }
4273
+ }
4274
+ return void 0;
4228
4275
  }
4229
4276
  /**
4230
4277
  * Get the shape at the current point.
@@ -4235,7 +4282,6 @@ class Editor extends import_eventemitter3.default {
4235
4282
  * @returns The shape at the given point, or undefined if there is no shape at the point.
4236
4283
  */
4237
4284
  getShapeAtPoint(point, opts = {}) {
4238
- const zoomLevel = this.getZoomLevel();
4239
4285
  const viewportPageBounds = this.getViewportPageBounds();
4240
4286
  const {
4241
4287
  filter,
@@ -4250,7 +4296,7 @@ class Editor extends import_eventemitter3.default {
4250
4296
  let inHollowSmallestAreaHit = null;
4251
4297
  let inMarginClosestToEdgeDistance = Infinity;
4252
4298
  let inMarginClosestToEdgeHit = null;
4253
- const searchMargin = Math.max(innerMargin, outerMargin, this.options.hitTestMargin / zoomLevel);
4299
+ const searchMargin = Math.max(innerMargin, outerMargin, this.getHitTestMargin());
4254
4300
  const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin);
4255
4301
  const shapesToCheck = (opts.renderingOnly ? this.getCurrentPageRenderingShapesSorted() : this.getCurrentPageShapesSorted()).filter((shape) => {
4256
4302
  if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
@@ -4341,7 +4387,7 @@ class Editor extends import_eventemitter3.default {
4341
4387
  }
4342
4388
  }
4343
4389
  } else {
4344
- if (distance < this.options.hitTestMargin / zoomLevel) {
4390
+ if (distance < this.getHitTestMargin()) {
4345
4391
  return shape;
4346
4392
  }
4347
4393
  }
@@ -5125,7 +5171,9 @@ class Editor extends import_eventemitter3.default {
5125
5171
  const index = (0, import_utils.getIndexBetween)(originalShape.index, siblingAbove?.index);
5126
5172
  shape.index = index;
5127
5173
  });
5128
- const shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape);
5174
+ const shapesToCreate = shapesToCreateWithOriginals.map(({ shape, originalShape }) => {
5175
+ return this.getShapeUtil(shape).onBeforeDuplicate?.(originalShape, shape) ?? shape;
5176
+ });
5129
5177
  if (!this.canCreateShapes(shapesToCreate)) {
5130
5178
  alertMaxShapes(this);
5131
5179
  return;
@@ -7151,7 +7199,10 @@ class Editor extends import_eventemitter3.default {
7151
7199
  const rootShapes = [];
7152
7200
  const newShapes = shapes.map((oldShape) => {
7153
7201
  const newId = shapeIdMap.get(oldShape.id);
7154
- const newShape = { ...oldShape, id: newId };
7202
+ let newShape = { ...oldShape, id: newId };
7203
+ if (!preserveIds) {
7204
+ newShape = this.getShapeUtil(newShape).onBeforeDuplicate?.(oldShape, newShape) ?? newShape;
7205
+ }
7155
7206
  if (rootShapeIds.includes(oldShape.id)) {
7156
7207
  newShape.parentId = currentPageId;
7157
7208
  rootShapes.push(newShape);
@@ -8417,6 +8468,9 @@ class Editor extends import_eventemitter3.default {
8417
8468
  __decorateClass([
8418
8469
  import_state.computed
8419
8470
  ], Editor.prototype, "getIsShapeHiddenCache", 1);
8471
+ __decorateClass([
8472
+ import_state.computed
8473
+ ], Editor.prototype, "getIsMounted", 1);
8420
8474
  __decorateClass([
8421
8475
  import_state.computed
8422
8476
  ], Editor.prototype, "canUndo", 1);
@@ -8591,6 +8645,9 @@ __decorateClass([
8591
8645
  __decorateClass([
8592
8646
  import_state.computed
8593
8647
  ], Editor.prototype, "getCurrentPageBounds", 1);
8648
+ __decorateClass([
8649
+ import_state.computed
8650
+ ], Editor.prototype, "getHitTestMargin", 1);
8594
8651
  __decorateClass([
8595
8652
  import_state.computed
8596
8653
  ], Editor.prototype, "getCurrentPageShapes", 1);