@tldraw/editor 3.16.0-next.f9f54ec051f3 → 3.16.0-next.fe14f1b4181f

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 (137) hide show
  1. package/dist-cjs/index.d.ts +110 -9
  2. package/dist-cjs/index.js +3 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +8 -2
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
  7. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  8. package/dist-cjs/lib/components/Shape.js +7 -10
  9. package/dist-cjs/lib/components/Shape.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +4 -23
  11. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
  13. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +1 -1
  14. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
  15. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
  17. package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
  18. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
  19. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  20. package/dist-cjs/lib/config/TLUserPreferences.js +9 -3
  21. package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
  22. package/dist-cjs/lib/editor/Editor.js +63 -24
  23. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  24. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +9 -4
  25. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  26. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +13 -0
  27. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  28. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  29. package/dist-cjs/lib/exports/getSvgJsx.js +35 -16
  30. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  31. package/dist-cjs/lib/hooks/useCanvasEvents.js +31 -25
  32. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  33. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -1
  34. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  35. package/dist-cjs/lib/{utils/nearestMultiple.js → hooks/useStateAttribute.js} +15 -14
  36. package/dist-cjs/lib/hooks/useStateAttribute.js.map +7 -0
  37. package/dist-cjs/lib/license/Watermark.js +6 -6
  38. package/dist-cjs/lib/license/Watermark.js.map +1 -1
  39. package/dist-cjs/lib/options.js +7 -0
  40. package/dist-cjs/lib/options.js.map +2 -2
  41. package/dist-cjs/lib/primitives/Box.js +3 -0
  42. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  43. package/dist-cjs/lib/utils/EditorAtom.js +45 -0
  44. package/dist-cjs/lib/utils/EditorAtom.js.map +7 -0
  45. package/dist-cjs/version.js +3 -3
  46. package/dist-cjs/version.js.map +1 -1
  47. package/dist-esm/index.d.mts +110 -9
  48. package/dist-esm/index.mjs +3 -1
  49. package/dist-esm/index.mjs.map +2 -2
  50. package/dist-esm/lib/TldrawEditor.mjs +8 -2
  51. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  52. package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
  53. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  54. package/dist-esm/lib/components/Shape.mjs +7 -10
  55. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  56. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +4 -23
  57. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  58. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
  59. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +1 -1
  60. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
  61. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  62. package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
  63. package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
  64. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
  65. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  66. package/dist-esm/lib/config/TLUserPreferences.mjs +9 -3
  67. package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
  68. package/dist-esm/lib/editor/Editor.mjs +63 -24
  69. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  70. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +9 -4
  71. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  72. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +13 -0
  73. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  74. package/dist-esm/lib/exports/getSvgJsx.mjs +36 -16
  75. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  76. package/dist-esm/lib/hooks/useCanvasEvents.mjs +32 -26
  77. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  78. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -1
  79. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  80. package/dist-esm/lib/hooks/useStateAttribute.mjs +15 -0
  81. package/dist-esm/lib/hooks/useStateAttribute.mjs.map +7 -0
  82. package/dist-esm/lib/license/Watermark.mjs +6 -6
  83. package/dist-esm/lib/license/Watermark.mjs.map +1 -1
  84. package/dist-esm/lib/options.mjs +7 -0
  85. package/dist-esm/lib/options.mjs.map +2 -2
  86. package/dist-esm/lib/primitives/Box.mjs +4 -1
  87. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  88. package/dist-esm/lib/utils/EditorAtom.mjs +25 -0
  89. package/dist-esm/lib/utils/EditorAtom.mjs.map +7 -0
  90. package/dist-esm/version.mjs +3 -3
  91. package/dist-esm/version.mjs.map +1 -1
  92. package/editor.css +301 -288
  93. package/package.json +14 -37
  94. package/src/index.ts +2 -0
  95. package/src/lib/TldrawEditor.tsx +13 -6
  96. package/src/lib/components/MenuClickCapture.tsx +0 -8
  97. package/src/lib/components/Shape.tsx +6 -12
  98. package/src/lib/components/default-components/DefaultCanvas.tsx +5 -22
  99. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
  100. package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
  101. package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
  102. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +5 -1
  103. package/src/lib/config/TLUserPreferences.ts +8 -1
  104. package/src/lib/editor/Editor.test.ts +12 -11
  105. package/src/lib/editor/Editor.ts +88 -47
  106. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
  107. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
  108. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
  109. package/src/lib/editor/managers/FontManager/FontManager.test.ts +24 -23
  110. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
  111. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
  112. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
  113. package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
  114. package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
  115. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +34 -26
  116. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +6 -1
  117. package/src/lib/editor/shapes/ShapeUtil.ts +14 -0
  118. package/src/lib/editor/types/misc-types.ts +54 -1
  119. package/src/lib/exports/getSvgJsx.test.ts +868 -0
  120. package/src/lib/exports/getSvgJsx.tsx +78 -21
  121. package/src/lib/hooks/useCanvasEvents.ts +45 -38
  122. package/src/lib/hooks/usePassThroughWheelEvents.ts +6 -1
  123. package/src/lib/hooks/useStateAttribute.ts +15 -0
  124. package/src/lib/license/LicenseManager.test.ts +3 -1
  125. package/src/lib/license/Watermark.test.tsx +2 -1
  126. package/src/lib/license/Watermark.tsx +6 -6
  127. package/src/lib/options.ts +8 -0
  128. package/src/lib/primitives/Box.test.ts +126 -0
  129. package/src/lib/primitives/Box.ts +10 -1
  130. package/src/lib/utils/EditorAtom.ts +37 -0
  131. package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
  132. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
  133. package/src/version.ts +3 -3
  134. package/dist-cjs/lib/utils/nearestMultiple.js.map +0 -7
  135. package/dist-esm/lib/utils/nearestMultiple.mjs +0 -14
  136. package/dist-esm/lib/utils/nearestMultiple.mjs.map +0 -7
  137. package/src/lib/utils/nearestMultiple.ts +0 -13
@@ -3910,6 +3910,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3910
3910
  hitInside = false,
3911
3911
  hitFrameInside = false
3912
3912
  } = opts;
3913
+ const [innerMargin, outerMargin] = Array.isArray(margin) ? margin : [margin, margin];
3913
3914
  let inHollowSmallestArea = Infinity;
3914
3915
  let inHollowSmallestAreaHit = null;
3915
3916
  let inMarginClosestToEdgeDistance = Infinity;
@@ -3919,7 +3920,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3919
3920
  return false;
3920
3921
  const pageMask = this.getShapeMask(shape);
3921
3922
  if (pageMask && !(0, import_utils2.pointInPolygon)(point, pageMask)) return false;
3922
- if (filter) return filter(shape);
3923
+ if (filter && !filter(shape)) return false;
3923
3924
  return true;
3924
3925
  });
3925
3926
  for (let i = shapesToCheck.length - 1; i >= 0; i--) {
@@ -3935,8 +3936,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3935
3936
  }
3936
3937
  }
3937
3938
  if (this.isShapeOfType(shape, "frame")) {
3938
- const distance2 = geometry.distanceToPoint(pointInShapeSpace, hitInside);
3939
- if (Math.abs(distance2) <= margin) {
3939
+ const distance2 = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside);
3940
+ if (hitFrameInside ? distance2 > 0 && distance2 <= outerMargin || distance2 <= 0 && distance2 > -innerMargin : distance2 > 0 && distance2 <= outerMargin) {
3940
3941
  return inMarginClosestToEdgeHit || shape;
3941
3942
  }
3942
3943
  if (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {
@@ -3956,10 +3957,10 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3956
3957
  }
3957
3958
  distance = minDistance;
3958
3959
  } else {
3959
- if (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
3960
+ if (outerMargin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
3960
3961
  distance = geometry.distanceToPoint(pointInShapeSpace, hitInside);
3961
3962
  } else {
3962
- if (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {
3963
+ if (geometry.bounds.containsPoint(pointInShapeSpace, outerMargin)) {
3963
3964
  distance = geometry.distanceToPoint(pointInShapeSpace, hitInside);
3964
3965
  } else {
3965
3966
  distance = Infinity;
@@ -3967,12 +3968,22 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3967
3968
  }
3968
3969
  }
3969
3970
  if (geometry.isClosed) {
3970
- if (distance <= margin) {
3971
+ if (distance <= outerMargin || hitInside && distance <= 0 && distance > -innerMargin) {
3971
3972
  if (geometry.isFilled || isGroup && geometry.children[0].isFilled) {
3972
3973
  return inMarginClosestToEdgeHit || shape;
3973
3974
  } else {
3974
3975
  if (this.getShapePageBounds(shape).contains(viewportPageBounds)) continue;
3975
- if (Math.abs(distance) < margin) {
3976
+ if (hitInside ? (
3977
+ // On hitInside, the distance will be negative for hits inside
3978
+ // If the distance is positive, check against the outer margin
3979
+ distance > 0 && distance <= outerMargin || // If the distance is negative, check against the inner margin
3980
+ distance <= 0 && distance > -innerMargin
3981
+ ) : (
3982
+ // If hitInside is false, then sadly _we do not know_ whether the
3983
+ // point is inside or outside of the shape, so we check against
3984
+ // the max of the two margins
3985
+ Math.abs(distance) <= Math.max(innerMargin, outerMargin)
3986
+ )) {
3976
3987
  if (Math.abs(distance) < inMarginClosestToEdgeDistance) {
3977
3988
  inMarginClosestToEdgeDistance = Math.abs(distance);
3978
3989
  inMarginClosestToEdgeHit = shape;
@@ -4737,7 +4748,16 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
4737
4748
  }
4738
4749
  this.createShapes(shapesToCreate);
4739
4750
  this.createBindings(bindingsToCreate);
4740
- this.setSelectedShapes((0, import_utils.compact)(ids.map((id) => shapeIds.get(id))));
4751
+ this.setSelectedShapes(
4752
+ (0, import_utils.compact)(
4753
+ ids.map((oldId) => {
4754
+ const newId = shapeIds.get(oldId);
4755
+ if (!newId) return null;
4756
+ if (!this.getShape(newId)) return null;
4757
+ return newId;
4758
+ })
4759
+ )
4760
+ );
4741
4761
  if (offset !== void 0) {
4742
4762
  const selectionPageBounds = this.getSelectionPageBounds();
4743
4763
  const viewportPageBounds = this.getViewportPageBounds();
@@ -5491,8 +5511,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5491
5511
  const shapesMovingTogether = [shape];
5492
5512
  const boundsOfShapesMovingTogether = [shapePageBounds];
5493
5513
  if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
5494
- type: "stretch",
5495
- shapes: shapesToStretchFirstPass
5514
+ type: "stretch"
5496
5515
  })) {
5497
5516
  continue;
5498
5517
  }
@@ -5817,21 +5836,24 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5817
5836
  }
5818
5837
  if (!partial.parentId || !(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))) {
5819
5838
  let parentId = this.getFocusedGroupId();
5820
- for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
5821
- const parent = currentPageShapesSorted[i];
5822
- const util = this.getShapeUtil(parent);
5823
- if (util.canReceiveNewChildrenOfType(parent, partial.type) && !this.isShapeHidden(parent) && this.isPointInShape(
5824
- parent,
5825
- // If no parent is provided, then we can treat the
5826
- // shape's provided x/y as being in the page's space.
5827
- { x: partial.x ?? 0, y: partial.y ?? 0 },
5828
- {
5829
- margin: 0,
5830
- hitInside: true
5839
+ const isPositioned = partial.x !== void 0 && partial.y !== void 0;
5840
+ if (isPositioned) {
5841
+ for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
5842
+ const parent = currentPageShapesSorted[i];
5843
+ const util = this.getShapeUtil(parent);
5844
+ if (util.canReceiveNewChildrenOfType(parent, partial.type) && !this.isShapeHidden(parent) && this.isPointInShape(
5845
+ parent,
5846
+ // If no parent is provided, then we can treat the
5847
+ // shape's provided x/y as being in the page's space.
5848
+ { x: partial.x ?? 0, y: partial.y ?? 0 },
5849
+ {
5850
+ margin: 0,
5851
+ hitInside: true
5852
+ }
5853
+ )) {
5854
+ parentId = parent.id;
5855
+ break;
5831
5856
  }
5832
- )) {
5833
- parentId = parent.id;
5834
- break;
5835
5857
  }
5836
5858
  }
5837
5859
  const prevParentId = partial.parentId;
@@ -6920,6 +6942,23 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
6920
6942
  }
6921
6943
  }
6922
6944
  }
6945
+ /**
6946
+ * Get an exported image of the given shapes as a data URL.
6947
+ *
6948
+ * @param shapes - The shapes (or shape ids) to export.
6949
+ * @param opts - Options for the export.
6950
+ *
6951
+ * @returns A data URL of the image.
6952
+ * @public
6953
+ */
6954
+ async toImageDataUrl(shapes, opts = {}) {
6955
+ const { blob, width, height } = await this.toImage(shapes, opts);
6956
+ return {
6957
+ url: await import_utils.FileHelpers.blobToDataUrl(blob),
6958
+ width,
6959
+ height
6960
+ };
6961
+ }
6923
6962
  /**
6924
6963
  * Update the input points from a pointer, pinch, or wheel event.
6925
6964
  *