@tldraw/editor 3.8.0-internal.a0a0d9e5162c → 3.8.0

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 (116) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/dist-cjs/index.d.ts +277 -64
  3. package/dist-cjs/index.js +15 -8
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +2 -5
  6. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  7. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
  8. package/dist-cjs/lib/config/createTLStore.js +4 -2
  9. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  10. package/dist-cjs/lib/editor/Editor.js +101 -24
  11. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  12. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
  13. package/dist-cjs/lib/editor/managers/TextManager.js +1 -0
  14. package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
  15. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +13 -0
  16. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  17. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js +66 -0
  18. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js.map +7 -0
  19. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  20. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  21. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  22. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  23. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  24. package/dist-cjs/lib/exports/exportToSvg.js.map +2 -2
  25. package/dist-cjs/lib/exports/getSvgAsImage.js +83 -0
  26. package/dist-cjs/lib/exports/getSvgAsImage.js.map +7 -0
  27. package/dist-cjs/lib/exports/getSvgJsx.js +16 -3
  28. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  29. package/dist-cjs/lib/hooks/useCanvasEvents.js +19 -8
  30. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  31. package/dist-cjs/lib/hooks/useDocumentEvents.js +1 -3
  32. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  33. package/dist-cjs/lib/hooks/useLocalStore.js +1 -1
  34. package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
  35. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -0
  36. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +3 -3
  37. package/dist-cjs/lib/options.js +2 -2
  38. package/dist-cjs/lib/options.js.map +2 -2
  39. package/dist-cjs/lib/utils/browserCanvasMaxSize.js +75 -0
  40. package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +7 -0
  41. package/dist-cjs/lib/utils/dom.js +6 -0
  42. package/dist-cjs/lib/utils/dom.js.map +2 -2
  43. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +3 -1
  44. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  45. package/dist-cjs/version.js +3 -3
  46. package/dist-cjs/version.js.map +1 -1
  47. package/dist-esm/index.d.mts +277 -64
  48. package/dist-esm/index.mjs +9 -1
  49. package/dist-esm/index.mjs.map +2 -2
  50. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +2 -5
  51. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  52. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  53. package/dist-esm/lib/config/createTLStore.mjs +4 -2
  54. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  55. package/dist-esm/lib/editor/Editor.mjs +101 -24
  56. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  57. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
  58. package/dist-esm/lib/editor/managers/TextManager.mjs +1 -0
  59. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  60. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +13 -0
  61. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  62. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs +46 -0
  63. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs.map +7 -0
  64. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  65. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  66. package/dist-esm/lib/exports/exportToSvg.mjs.map +2 -2
  67. package/dist-esm/lib/exports/getSvgAsImage.mjs +63 -0
  68. package/dist-esm/lib/exports/getSvgAsImage.mjs.map +7 -0
  69. package/dist-esm/lib/exports/getSvgJsx.mjs +16 -3
  70. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  71. package/dist-esm/lib/hooks/useCanvasEvents.mjs +19 -8
  72. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  73. package/dist-esm/lib/hooks/useDocumentEvents.mjs +2 -4
  74. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  75. package/dist-esm/lib/hooks/useLocalStore.mjs +1 -1
  76. package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
  77. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -0
  78. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +3 -3
  79. package/dist-esm/lib/options.mjs +2 -2
  80. package/dist-esm/lib/options.mjs.map +2 -2
  81. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +45 -0
  82. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +7 -0
  83. package/dist-esm/lib/utils/dom.mjs +6 -0
  84. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  85. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +3 -1
  86. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  87. package/dist-esm/version.mjs +3 -3
  88. package/dist-esm/version.mjs.map +1 -1
  89. package/editor.css +2 -1
  90. package/package.json +22 -20
  91. package/src/index.ts +22 -1
  92. package/src/lib/components/default-components/DefaultCanvas.tsx +2 -5
  93. package/src/lib/config/TLSessionStateSnapshot.ts +3 -1
  94. package/src/lib/config/createTLStore.ts +4 -2
  95. package/src/lib/editor/Editor.ts +151 -59
  96. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +4 -4
  97. package/src/lib/editor/managers/TextManager.ts +1 -0
  98. package/src/lib/editor/shapes/ShapeUtil.ts +49 -1
  99. package/src/lib/editor/shapes/shared/resizeScaled.ts +61 -0
  100. package/src/lib/editor/types/SvgExportContext.tsx +21 -0
  101. package/src/lib/editor/types/emit-types.ts +1 -0
  102. package/src/lib/editor/types/external-content.ts +104 -50
  103. package/src/lib/editor/types/misc-types.ts +55 -2
  104. package/src/lib/exports/StyleEmbedder.ts +1 -1
  105. package/src/lib/exports/exportToSvg.tsx +2 -2
  106. package/src/lib/exports/getSvgAsImage.ts +92 -0
  107. package/src/lib/exports/getSvgJsx.tsx +17 -2
  108. package/src/lib/hooks/useCanvasEvents.ts +20 -8
  109. package/src/lib/hooks/useDocumentEvents.ts +2 -11
  110. package/src/lib/hooks/useLocalStore.ts +1 -1
  111. package/src/lib/hooks/usePassThroughWheelEvents.ts +7 -0
  112. package/src/lib/options.ts +5 -2
  113. package/src/lib/utils/browserCanvasMaxSize.ts +65 -0
  114. package/src/lib/utils/dom.ts +12 -0
  115. package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -1
  116. package/src/version.ts +3 -3
@@ -87,6 +87,7 @@ var import_defaultBindings = require("../config/defaultBindings");
87
87
  var import_defaultShapes = require("../config/defaultShapes");
88
88
  var import_constants = require("../constants");
89
89
  var import_exportToSvg = require("../exports/exportToSvg");
90
+ var import_getSvgAsImage = require("../exports/getSvgAsImage");
90
91
  var import_environment = require("../globals/environment");
91
92
  var import_menus = require("../globals/menus");
92
93
  var import_time = require("../globals/time");
@@ -305,7 +306,9 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
305
306
  files: null,
306
307
  embed: null,
307
308
  "svg-text": null,
308
- url: null
309
+ url: null,
310
+ tldraw: null,
311
+ excalidraw: null
309
312
  });
310
313
  /* --------------------- Events --------------------- */
311
314
  /**
@@ -812,6 +815,10 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
812
815
  (0, import_utils.assert)(shapeUtil, `No shape util found for type "${type}"`);
813
816
  return shapeUtil;
814
817
  }
818
+ hasShapeUtil(arg) {
819
+ const type = typeof arg === "string" ? arg : arg.type;
820
+ return (0, import_utils.hasOwnProperty)(this.shapeUtils, type);
821
+ }
815
822
  getBindingUtil(arg) {
816
823
  const type = typeof arg === "string" ? arg : arg.type;
817
824
  const bindingUtil = (0, import_utils.getOwnProperty)(this.bindingUtils, type);
@@ -1038,9 +1045,20 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1038
1045
  },
1039
1046
  extras: {
1040
1047
  activeStateNode: this.root.getPath(),
1041
- selectedShapes: this.getSelectedShapes(),
1048
+ selectedShapes: this.getSelectedShapes().map((s) => {
1049
+ const { props, ...rest } = s;
1050
+ const { text: _text, richText: _richText, ...restProps } = props;
1051
+ return {
1052
+ ...rest,
1053
+ props: restProps
1054
+ };
1055
+ }),
1056
+ selectionCount: this.getSelectedShapes().length,
1042
1057
  editingShape: editingShapeId ? this.getShape(editingShapeId) : void 0,
1043
- inputs: this.inputs
1058
+ inputs: this.inputs,
1059
+ pageState: this.getCurrentPageState(),
1060
+ instanceState: this.getInstanceState(),
1061
+ collaboratorCount: this.getCollaboratorsOnCurrentPage().length
1044
1062
  }
1045
1063
  };
1046
1064
  } catch {
@@ -1148,8 +1166,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1148
1166
  *
1149
1167
  * @example
1150
1168
  * ```ts
1151
- * state.getStateDescendant('select')
1152
- * state.getStateDescendant('select.brushing')
1169
+ * editor.getStateDescendant('select')
1170
+ * editor.getStateDescendant('select.brushing')
1153
1171
  * ```
1154
1172
  *
1155
1173
  * @param path - The descendant's path of state ids, separated by periods.
@@ -1203,7 +1221,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
1203
1221
  if (partial.isChangingStyle === true) {
1204
1222
  this._isChangingStyleTimeout = this.timers.setTimeout(() => {
1205
1223
  this._updateInstanceState({ isChangingStyle: false }, { history: "ignore" });
1206
- }, 2e3);
1224
+ }, 1e3);
1207
1225
  }
1208
1226
  }
1209
1227
  return this;
@@ -3154,11 +3172,14 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
3154
3172
  if (!assetId) return null;
3155
3173
  const asset = this.getAsset(assetId);
3156
3174
  if (!asset) return null;
3157
- const { screenScale = 1, shouldResolveToOriginal = false } = context;
3175
+ const {
3176
+ screenScale = 1,
3177
+ shouldResolveToOriginal = false,
3178
+ dpr = this.getInstanceState().devicePixelRatio
3179
+ } = context;
3158
3180
  const zoomStepFunction = (zoom) => Math.pow(2, Math.ceil(Math.log2(zoom)));
3159
- const steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale));
3181
+ const steppedScreenScale = zoomStepFunction(screenScale);
3160
3182
  const networkEffectiveType = "connection" in navigator ? navigator.connection.effectiveType : null;
3161
- const dpr = this.getInstanceState().devicePixelRatio;
3162
3183
  return await this.store.props.assets.resolve(asset, {
3163
3184
  screenScale: screenScale || 1,
3164
3185
  steppedScreenScale,
@@ -5079,6 +5100,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5079
5100
  scale = new import_Vec.Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
5080
5101
  }
5081
5102
  }
5103
+ let didResize = false;
5082
5104
  if (util.onResize && util.canResize(initialShape)) {
5083
5105
  const newPagePoint = this._scalePagePoint(
5084
5106
  import_Mat.Mat.applyToPoint(pageTransform, new import_Vec.Vec(0, 0)),
@@ -5103,24 +5125,28 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5103
5125
  util.onResizeStart?.(initialShape) ?? void 0
5104
5126
  );
5105
5127
  }
5128
+ const resizedShape = util.onResize(
5129
+ { ...initialShape, x, y },
5130
+ {
5131
+ newPoint: newLocalPoint,
5132
+ handle: opts.dragHandle ?? "bottom_right",
5133
+ // don't set isSingle to true for children
5134
+ mode: opts.mode ?? "scale_shape",
5135
+ scaleX: myScale.x,
5136
+ scaleY: myScale.y,
5137
+ initialBounds,
5138
+ initialShape
5139
+ }
5140
+ );
5141
+ if (resizedShape) {
5142
+ didResize = true;
5143
+ }
5106
5144
  workingShape = applyPartialToRecordWithProps(workingShape, {
5107
5145
  id,
5108
5146
  type: initialShape.type,
5109
5147
  x: newLocalPoint.x,
5110
5148
  y: newLocalPoint.y,
5111
- ...util.onResize(
5112
- { ...initialShape, x, y },
5113
- {
5114
- newPoint: newLocalPoint,
5115
- handle: opts.dragHandle ?? "bottom_right",
5116
- // don't set isSingle to true for children
5117
- mode: opts.mode ?? "scale_shape",
5118
- scaleX: myScale.x,
5119
- scaleY: myScale.y,
5120
- initialBounds,
5121
- initialShape
5122
- }
5123
- )
5149
+ ...resizedShape
5124
5150
  });
5125
5151
  if (!opts.skipStartAndEndCallbacks) {
5126
5152
  workingShape = applyPartialToRecordWithProps(
@@ -5129,7 +5155,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
5129
5155
  );
5130
5156
  }
5131
5157
  this.updateShapes([workingShape]);
5132
- } else {
5158
+ }
5159
+ if (!didResize) {
5133
5160
  const initialPageCenter = import_Mat.Mat.applyToPoint(pageTransform, initialBounds.center);
5134
5161
  const newPageCenter = this._scalePagePoint(
5135
5162
  initialPageCenter,
@@ -6276,7 +6303,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
6276
6303
  * @public
6277
6304
  */
6278
6305
  async getSvgElement(shapes, opts = {}) {
6279
- const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
6306
+ const ids = shapes.length === 0 ? this.getCurrentPageShapeIdsSorted() : typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
6280
6307
  if (ids.length === 0) return void 0;
6281
6308
  return (0, import_exportToSvg.exportToSvg)(this, ids, opts);
6282
6309
  }
@@ -6306,6 +6333,55 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
6306
6333
  if (!result) return void 0;
6307
6334
  return result.svg;
6308
6335
  }
6336
+ /**
6337
+ * Get an exported image of the given shapes.
6338
+ *
6339
+ * @param shapes - The shapes (or shape ids) to export.
6340
+ * @param opts - Options for the export.
6341
+ *
6342
+ * @returns A blob of the image.
6343
+ * @public
6344
+ */
6345
+ async toImage(shapes, opts = {}) {
6346
+ const withDefaults = {
6347
+ format: "png",
6348
+ scale: 1,
6349
+ pixelRatio: opts.format === "svg" ? void 0 : 2,
6350
+ ...opts
6351
+ };
6352
+ const result = await this.getSvgString(shapes, withDefaults);
6353
+ if (!result) throw new Error("Could not create SVG");
6354
+ switch (withDefaults.format) {
6355
+ case "svg":
6356
+ return {
6357
+ blob: new Blob([result.svg], { type: "text/plain" }),
6358
+ width: result.width,
6359
+ height: result.height
6360
+ };
6361
+ case "jpeg":
6362
+ case "png":
6363
+ case "webp": {
6364
+ const blob = await (0, import_getSvgAsImage.getSvgAsImage)(result.svg, {
6365
+ type: withDefaults.format,
6366
+ quality: withDefaults.quality,
6367
+ pixelRatio: withDefaults.pixelRatio,
6368
+ width: result.width,
6369
+ height: result.height
6370
+ });
6371
+ if (!blob) {
6372
+ throw new Error("Could not construct image.");
6373
+ }
6374
+ return {
6375
+ blob,
6376
+ width: result.width,
6377
+ height: result.height
6378
+ };
6379
+ }
6380
+ default: {
6381
+ (0, import_utils.exhaustiveSwitchError)(withDefaults.format);
6382
+ }
6383
+ }
6384
+ }
6309
6385
  /**
6310
6386
  * Update the input points from a pointer, pinch, or wheel event.
6311
6387
  *
@@ -6799,6 +6875,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
6799
6875
  }
6800
6876
  _flushEventForTick(info) {
6801
6877
  if (this.getCrashingError()) return this;
6878
+ this.emit("before-event", info);
6802
6879
  const { inputs } = this;
6803
6880
  const { type } = info;
6804
6881
  if (info.type === "misc") {