@tldraw/editor 5.3.0-canary.ec4b74d7eb64 → 5.3.0-canary.f8a4bdc003b1

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 (41) hide show
  1. package/dist-cjs/index.d.ts +37 -1
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/editor/Editor.js +17 -5
  4. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  5. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +9 -0
  6. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  7. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +3 -0
  8. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  9. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/license/LicenseManager.js +14 -5
  11. package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
  12. package/dist-cjs/lib/options.js +2 -1
  13. package/dist-cjs/lib/options.js.map +2 -2
  14. package/dist-cjs/version.js +3 -3
  15. package/dist-cjs/version.js.map +1 -1
  16. package/dist-esm/index.d.mts +37 -1
  17. package/dist-esm/index.mjs +1 -1
  18. package/dist-esm/lib/editor/Editor.mjs +17 -5
  19. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  20. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +9 -0
  21. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  22. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +3 -0
  23. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  24. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  25. package/dist-esm/lib/license/LicenseManager.mjs +14 -5
  26. package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
  27. package/dist-esm/lib/options.mjs +2 -1
  28. package/dist-esm/lib/options.mjs.map +2 -2
  29. package/dist-esm/version.mjs +3 -3
  30. package/dist-esm/version.mjs.map +1 -1
  31. package/editor.css +10 -0
  32. package/package.json +7 -7
  33. package/src/lib/editor/Editor.ts +32 -5
  34. package/src/lib/editor/managers/FontManager/FontManager.test.ts +66 -0
  35. package/src/lib/editor/managers/FontManager/FontManager.ts +14 -0
  36. package/src/lib/editor/managers/TextManager/TextManager.ts +3 -0
  37. package/src/lib/editor/shapes/ShapeUtil.ts +24 -0
  38. package/src/lib/license/LicenseManager.test.ts +99 -29
  39. package/src/lib/license/LicenseManager.ts +16 -4
  40. package/src/lib/options.ts +3 -1
  41. package/src/version.ts +3 -3
@@ -1007,6 +1007,7 @@ export declare const defaultTldrawOptions: {
1007
1007
  readonly cameraSlideFriction: 0.09;
1008
1008
  readonly coarseDragDistanceSquared: 36;
1009
1009
  readonly coarseHandleRadius: 20;
1010
+ readonly coarseHitTestMargin: 4;
1010
1011
  readonly coarsePointerWidth: 12;
1011
1012
  readonly collaboratorCheckIntervalMs: 1200;
1012
1013
  readonly collaboratorIdleTimeoutMs: 3000;
@@ -1046,7 +1047,7 @@ export declare const defaultTldrawOptions: {
1046
1047
  readonly step: 1;
1047
1048
  }];
1048
1049
  readonly handleRadius: 12;
1049
- readonly hitTestMargin: 8;
1050
+ readonly hitTestMargin: 3;
1050
1051
  readonly laserDelayMs: 1200;
1051
1052
  readonly laserFadeoutMs: 500;
1052
1053
  readonly longPressDurationMs: 500;
@@ -3101,6 +3102,17 @@ export declare class Editor extends EventEmitter<TLEventMap> {
3101
3102
  * @public
3102
3103
  */
3103
3104
  getCurrentPageBounds(): Box | undefined;
3105
+ /**
3106
+ * Get the hit-test margin in page space—the distance in page units within which a pointer is
3107
+ * considered to be touching a shape. This resolves to {@link TldrawOptions.hitTestMargin} (or
3108
+ * {@link TldrawOptions.coarseHitTestMargin} when using a coarse pointer) divided by the current
3109
+ * zoom level, so it stays a constant distance in screen space.
3110
+ *
3111
+ * @returns The hit-test margin in page space.
3112
+ *
3113
+ * @public
3114
+ */
3115
+ getHitTestMargin(): number;
3104
3116
  /**
3105
3117
  * Get the top-most selected shape at the given point, ignoring groups.
3106
3118
  *
@@ -6781,6 +6793,29 @@ export declare abstract class ShapeUtil<Shape extends TLShape = TLShape> {
6781
6793
  * @public
6782
6794
  */
6783
6795
  onBeforeCreate?(next: Shape): Shape | void;
6796
+ /**
6797
+ * A callback called when a shape is reproduced from an existing shape, either by duplicating
6798
+ * ({@link Editor.duplicateShapes}) or by pasting/putting content onto the page
6799
+ * ({@link Editor.putContentOntoCurrentPage}). This provides a last chance to modify the copy
6800
+ * before it's created — for example, to re-stamp attribution so the copy is credited to the
6801
+ * current user rather than the original author. It is not called when content is put with
6802
+ * `preserveIds` (e.g. {@link Editor.moveShapesToPage}), since the shape keeps its identity
6803
+ * and no copy is made.
6804
+ *
6805
+ * @example
6806
+ *
6807
+ * ```ts
6808
+ * onBeforeDuplicate = (source, duplicate) => {
6809
+ * return { ...duplicate, props: { ...duplicate.props, editedBy: this.editor.getAttributionUserId() } }
6810
+ * }
6811
+ * ```
6812
+ *
6813
+ * @param source - The shape being copied from.
6814
+ * @param duplicate - The new copy (with its own id), before it's created.
6815
+ * @returns The next shape or void.
6816
+ * @public
6817
+ */
6818
+ onBeforeDuplicate?(source: Shape, duplicate: Shape): Shape | void;
6784
6819
  /**
6785
6820
  * A callback called just before a shape is updated. This method provides a last chance to modify
6786
6821
  * the updated shape.
@@ -8047,6 +8082,7 @@ export declare interface TldrawOptions {
8047
8082
  readonly collaboratorCheckIntervalMs: number;
8048
8083
  readonly cameraMovingTimeoutMs: number;
8049
8084
  readonly hitTestMargin: number;
8085
+ readonly coarseHitTestMargin: number;
8050
8086
  readonly edgeScrollDelay: number;
8051
8087
  readonly edgeScrollEaseDuration: number;
8052
8088
  readonly edgeScrollSpeed: number;
package/dist-cjs/index.js CHANGED
@@ -379,7 +379,7 @@ var import_uniq = require("./lib/utils/uniq");
379
379
  var import_defaultThemes2 = require("./lib/editor/managers/ThemeManager/defaultThemes");
380
380
  (0, import_utils.registerTldrawLibraryVersion)(
381
381
  "@tldraw/editor",
382
- "5.3.0-canary.ec4b74d7eb64",
382
+ "5.3.0-canary.f8a4bdc003b1",
383
383
  "cjs"
384
384
  );
385
385
  //# sourceMappingURL=index.js.map
@@ -4243,6 +4243,11 @@ class Editor extends import_eventemitter3.default {
4243
4243
  });
4244
4244
  return commonBounds;
4245
4245
  }
4246
+ getHitTestMargin() {
4247
+ const { hitTestMargin, coarseHitTestMargin } = this.options;
4248
+ const margin = this.getInstanceState().isCoarsePointer ? coarseHitTestMargin : hitTestMargin;
4249
+ return margin / this.getZoomLevel();
4250
+ }
4246
4251
  /**
4247
4252
  * Get the top-most selected shape at the given point, ignoring groups.
4248
4253
  *
@@ -4277,7 +4282,6 @@ class Editor extends import_eventemitter3.default {
4277
4282
  * @returns The shape at the given point, or undefined if there is no shape at the point.
4278
4283
  */
4279
4284
  getShapeAtPoint(point, opts = {}) {
4280
- const zoomLevel = this.getZoomLevel();
4281
4285
  const viewportPageBounds = this.getViewportPageBounds();
4282
4286
  const {
4283
4287
  filter,
@@ -4292,7 +4296,7 @@ class Editor extends import_eventemitter3.default {
4292
4296
  let inHollowSmallestAreaHit = null;
4293
4297
  let inMarginClosestToEdgeDistance = Infinity;
4294
4298
  let inMarginClosestToEdgeHit = null;
4295
- const searchMargin = Math.max(innerMargin, outerMargin, this.options.hitTestMargin / zoomLevel);
4299
+ const searchMargin = Math.max(innerMargin, outerMargin, this.getHitTestMargin());
4296
4300
  const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin);
4297
4301
  const shapesToCheck = (opts.renderingOnly ? this.getCurrentPageRenderingShapesSorted() : this.getCurrentPageShapesSorted()).filter((shape) => {
4298
4302
  if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
@@ -4383,7 +4387,7 @@ class Editor extends import_eventemitter3.default {
4383
4387
  }
4384
4388
  }
4385
4389
  } else {
4386
- if (distance < this.options.hitTestMargin / zoomLevel) {
4390
+ if (distance < this.getHitTestMargin()) {
4387
4391
  return shape;
4388
4392
  }
4389
4393
  }
@@ -5167,7 +5171,9 @@ class Editor extends import_eventemitter3.default {
5167
5171
  const index = (0, import_utils.getIndexBetween)(originalShape.index, siblingAbove?.index);
5168
5172
  shape.index = index;
5169
5173
  });
5170
- const shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape);
5174
+ const shapesToCreate = shapesToCreateWithOriginals.map(({ shape, originalShape }) => {
5175
+ return this.getShapeUtil(shape).onBeforeDuplicate?.(originalShape, shape) ?? shape;
5176
+ });
5171
5177
  if (!this.canCreateShapes(shapesToCreate)) {
5172
5178
  alertMaxShapes(this);
5173
5179
  return;
@@ -7193,7 +7199,10 @@ class Editor extends import_eventemitter3.default {
7193
7199
  const rootShapes = [];
7194
7200
  const newShapes = shapes.map((oldShape) => {
7195
7201
  const newId = shapeIdMap.get(oldShape.id);
7196
- const newShape = { ...oldShape, id: newId };
7202
+ let newShape = { ...oldShape, id: newId };
7203
+ if (!preserveIds) {
7204
+ newShape = this.getShapeUtil(newShape).onBeforeDuplicate?.(oldShape, newShape) ?? newShape;
7205
+ }
7197
7206
  if (rootShapeIds.includes(oldShape.id)) {
7198
7207
  newShape.parentId = currentPageId;
7199
7208
  rootShapes.push(newShape);
@@ -8636,6 +8645,9 @@ __decorateClass([
8636
8645
  __decorateClass([
8637
8646
  import_state.computed
8638
8647
  ], Editor.prototype, "getCurrentPageBounds", 1);
8648
+ __decorateClass([
8649
+ import_state.computed
8650
+ ], Editor.prototype, "getHitTestMargin", 1);
8639
8651
  __decorateClass([
8640
8652
  import_state.computed
8641
8653
  ], Editor.prototype, "getCurrentPageShapes", 1);