@tldraw/editor 3.8.0-canary.c5f3975feaab → 3.8.0-canary.c738f8c4d6db

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 (115) hide show
  1. package/dist-cjs/index.d.ts +277 -64
  2. package/dist-cjs/index.js +15 -8
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +2 -5
  5. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  6. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
  7. package/dist-cjs/lib/config/createTLStore.js +4 -2
  8. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  9. package/dist-cjs/lib/editor/Editor.js +101 -24
  10. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  11. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
  12. package/dist-cjs/lib/editor/managers/TextManager.js +1 -0
  13. package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
  14. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +13 -0
  15. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js +66 -0
  17. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js.map +7 -0
  18. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  19. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  20. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  21. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  22. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  23. package/dist-cjs/lib/exports/exportToSvg.js.map +2 -2
  24. package/dist-cjs/lib/exports/getSvgAsImage.js +83 -0
  25. package/dist-cjs/lib/exports/getSvgAsImage.js.map +7 -0
  26. package/dist-cjs/lib/exports/getSvgJsx.js +16 -3
  27. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  28. package/dist-cjs/lib/hooks/useCanvasEvents.js +19 -8
  29. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  30. package/dist-cjs/lib/hooks/useDocumentEvents.js +1 -3
  31. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  32. package/dist-cjs/lib/hooks/useLocalStore.js +1 -1
  33. package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
  34. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -0
  35. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +3 -3
  36. package/dist-cjs/lib/options.js +2 -2
  37. package/dist-cjs/lib/options.js.map +2 -2
  38. package/dist-cjs/lib/utils/browserCanvasMaxSize.js +75 -0
  39. package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +7 -0
  40. package/dist-cjs/lib/utils/dom.js +6 -0
  41. package/dist-cjs/lib/utils/dom.js.map +2 -2
  42. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +3 -1
  43. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  44. package/dist-cjs/version.js +3 -3
  45. package/dist-cjs/version.js.map +1 -1
  46. package/dist-esm/index.d.mts +277 -64
  47. package/dist-esm/index.mjs +9 -1
  48. package/dist-esm/index.mjs.map +2 -2
  49. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +2 -5
  50. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  51. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  52. package/dist-esm/lib/config/createTLStore.mjs +4 -2
  53. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  54. package/dist-esm/lib/editor/Editor.mjs +101 -24
  55. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  56. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
  57. package/dist-esm/lib/editor/managers/TextManager.mjs +1 -0
  58. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  59. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +13 -0
  60. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  61. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs +46 -0
  62. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs.map +7 -0
  63. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  64. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  65. package/dist-esm/lib/exports/exportToSvg.mjs.map +2 -2
  66. package/dist-esm/lib/exports/getSvgAsImage.mjs +63 -0
  67. package/dist-esm/lib/exports/getSvgAsImage.mjs.map +7 -0
  68. package/dist-esm/lib/exports/getSvgJsx.mjs +16 -3
  69. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  70. package/dist-esm/lib/hooks/useCanvasEvents.mjs +19 -8
  71. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  72. package/dist-esm/lib/hooks/useDocumentEvents.mjs +2 -4
  73. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  74. package/dist-esm/lib/hooks/useLocalStore.mjs +1 -1
  75. package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
  76. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -0
  77. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +3 -3
  78. package/dist-esm/lib/options.mjs +2 -2
  79. package/dist-esm/lib/options.mjs.map +2 -2
  80. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +45 -0
  81. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +7 -0
  82. package/dist-esm/lib/utils/dom.mjs +6 -0
  83. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  84. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +3 -1
  85. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  86. package/dist-esm/version.mjs +3 -3
  87. package/dist-esm/version.mjs.map +1 -1
  88. package/editor.css +2 -1
  89. package/package.json +22 -20
  90. package/src/index.ts +22 -1
  91. package/src/lib/components/default-components/DefaultCanvas.tsx +2 -5
  92. package/src/lib/config/TLSessionStateSnapshot.ts +3 -1
  93. package/src/lib/config/createTLStore.ts +4 -2
  94. package/src/lib/editor/Editor.ts +151 -59
  95. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +4 -4
  96. package/src/lib/editor/managers/TextManager.ts +1 -0
  97. package/src/lib/editor/shapes/ShapeUtil.ts +49 -1
  98. package/src/lib/editor/shapes/shared/resizeScaled.ts +61 -0
  99. package/src/lib/editor/types/SvgExportContext.tsx +21 -0
  100. package/src/lib/editor/types/emit-types.ts +1 -0
  101. package/src/lib/editor/types/external-content.ts +104 -50
  102. package/src/lib/editor/types/misc-types.ts +55 -2
  103. package/src/lib/exports/StyleEmbedder.ts +1 -1
  104. package/src/lib/exports/exportToSvg.tsx +2 -2
  105. package/src/lib/exports/getSvgAsImage.ts +92 -0
  106. package/src/lib/exports/getSvgJsx.tsx +17 -2
  107. package/src/lib/hooks/useCanvasEvents.ts +20 -8
  108. package/src/lib/hooks/useDocumentEvents.ts +2 -11
  109. package/src/lib/hooks/useLocalStore.ts +1 -1
  110. package/src/lib/hooks/usePassThroughWheelEvents.ts +7 -0
  111. package/src/lib/options.ts +5 -2
  112. package/src/lib/utils/browserCanvasMaxSize.ts +65 -0
  113. package/src/lib/utils/dom.ts +12 -0
  114. package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -1
  115. package/src/version.ts +3 -3
@@ -111,6 +111,7 @@ import {
111
111
  ZOOM_TO_FIT_PADDING
112
112
  } from "../constants.mjs";
113
113
  import { exportToSvg } from "../exports/exportToSvg.mjs";
114
+ import { getSvgAsImage } from "../exports/getSvgAsImage.mjs";
114
115
  import { tlenv } from "../globals/environment.mjs";
115
116
  import { tlmenus } from "../globals/menus.mjs";
116
117
  import { tltime } from "../globals/time.mjs";
@@ -331,7 +332,9 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
331
332
  files: null,
332
333
  embed: null,
333
334
  "svg-text": null,
334
- url: null
335
+ url: null,
336
+ tldraw: null,
337
+ excalidraw: null
335
338
  });
336
339
  /* --------------------- Events --------------------- */
337
340
  /**
@@ -838,6 +841,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
838
841
  assert(shapeUtil, `No shape util found for type "${type}"`);
839
842
  return shapeUtil;
840
843
  }
844
+ hasShapeUtil(arg) {
845
+ const type = typeof arg === "string" ? arg : arg.type;
846
+ return hasOwnProperty(this.shapeUtils, type);
847
+ }
841
848
  getBindingUtil(arg) {
842
849
  const type = typeof arg === "string" ? arg : arg.type;
843
850
  const bindingUtil = getOwnProperty(this.bindingUtils, type);
@@ -1064,9 +1071,20 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1064
1071
  },
1065
1072
  extras: {
1066
1073
  activeStateNode: this.root.getPath(),
1067
- selectedShapes: this.getSelectedShapes(),
1074
+ selectedShapes: this.getSelectedShapes().map((s) => {
1075
+ const { props, ...rest } = s;
1076
+ const { text: _text, richText: _richText, ...restProps } = props;
1077
+ return {
1078
+ ...rest,
1079
+ props: restProps
1080
+ };
1081
+ }),
1082
+ selectionCount: this.getSelectedShapes().length,
1068
1083
  editingShape: editingShapeId ? this.getShape(editingShapeId) : void 0,
1069
- inputs: this.inputs
1084
+ inputs: this.inputs,
1085
+ pageState: this.getCurrentPageState(),
1086
+ instanceState: this.getInstanceState(),
1087
+ collaboratorCount: this.getCollaboratorsOnCurrentPage().length
1070
1088
  }
1071
1089
  };
1072
1090
  } catch {
@@ -1174,8 +1192,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1174
1192
  *
1175
1193
  * @example
1176
1194
  * ```ts
1177
- * state.getStateDescendant('select')
1178
- * state.getStateDescendant('select.brushing')
1195
+ * editor.getStateDescendant('select')
1196
+ * editor.getStateDescendant('select.brushing')
1179
1197
  * ```
1180
1198
  *
1181
1199
  * @param path - The descendant's path of state ids, separated by periods.
@@ -1229,7 +1247,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1229
1247
  if (partial.isChangingStyle === true) {
1230
1248
  this._isChangingStyleTimeout = this.timers.setTimeout(() => {
1231
1249
  this._updateInstanceState({ isChangingStyle: false }, { history: "ignore" });
1232
- }, 2e3);
1250
+ }, 1e3);
1233
1251
  }
1234
1252
  }
1235
1253
  return this;
@@ -3180,11 +3198,14 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3180
3198
  if (!assetId) return null;
3181
3199
  const asset = this.getAsset(assetId);
3182
3200
  if (!asset) return null;
3183
- const { screenScale = 1, shouldResolveToOriginal = false } = context;
3201
+ const {
3202
+ screenScale = 1,
3203
+ shouldResolveToOriginal = false,
3204
+ dpr = this.getInstanceState().devicePixelRatio
3205
+ } = context;
3184
3206
  const zoomStepFunction = (zoom) => Math.pow(2, Math.ceil(Math.log2(zoom)));
3185
- const steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale));
3207
+ const steppedScreenScale = zoomStepFunction(screenScale);
3186
3208
  const networkEffectiveType = "connection" in navigator ? navigator.connection.effectiveType : null;
3187
- const dpr = this.getInstanceState().devicePixelRatio;
3188
3209
  return await this.store.props.assets.resolve(asset, {
3189
3210
  screenScale: screenScale || 1,
3190
3211
  steppedScreenScale,
@@ -5105,6 +5126,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5105
5126
  scale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
5106
5127
  }
5107
5128
  }
5129
+ let didResize = false;
5108
5130
  if (util.onResize && util.canResize(initialShape)) {
5109
5131
  const newPagePoint = this._scalePagePoint(
5110
5132
  Mat.applyToPoint(pageTransform, new Vec(0, 0)),
@@ -5129,24 +5151,28 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5129
5151
  util.onResizeStart?.(initialShape) ?? void 0
5130
5152
  );
5131
5153
  }
5154
+ const resizedShape = util.onResize(
5155
+ { ...initialShape, x, y },
5156
+ {
5157
+ newPoint: newLocalPoint,
5158
+ handle: opts.dragHandle ?? "bottom_right",
5159
+ // don't set isSingle to true for children
5160
+ mode: opts.mode ?? "scale_shape",
5161
+ scaleX: myScale.x,
5162
+ scaleY: myScale.y,
5163
+ initialBounds,
5164
+ initialShape
5165
+ }
5166
+ );
5167
+ if (resizedShape) {
5168
+ didResize = true;
5169
+ }
5132
5170
  workingShape = applyPartialToRecordWithProps(workingShape, {
5133
5171
  id,
5134
5172
  type: initialShape.type,
5135
5173
  x: newLocalPoint.x,
5136
5174
  y: newLocalPoint.y,
5137
- ...util.onResize(
5138
- { ...initialShape, x, y },
5139
- {
5140
- newPoint: newLocalPoint,
5141
- handle: opts.dragHandle ?? "bottom_right",
5142
- // don't set isSingle to true for children
5143
- mode: opts.mode ?? "scale_shape",
5144
- scaleX: myScale.x,
5145
- scaleY: myScale.y,
5146
- initialBounds,
5147
- initialShape
5148
- }
5149
- )
5175
+ ...resizedShape
5150
5176
  });
5151
5177
  if (!opts.skipStartAndEndCallbacks) {
5152
5178
  workingShape = applyPartialToRecordWithProps(
@@ -5155,7 +5181,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5155
5181
  );
5156
5182
  }
5157
5183
  this.updateShapes([workingShape]);
5158
- } else {
5184
+ }
5185
+ if (!didResize) {
5159
5186
  const initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center);
5160
5187
  const newPageCenter = this._scalePagePoint(
5161
5188
  initialPageCenter,
@@ -6302,7 +6329,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6302
6329
  * @public
6303
6330
  */
6304
6331
  async getSvgElement(shapes, opts = {}) {
6305
- const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
6332
+ const ids = shapes.length === 0 ? this.getCurrentPageShapeIdsSorted() : typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
6306
6333
  if (ids.length === 0) return void 0;
6307
6334
  return exportToSvg(this, ids, opts);
6308
6335
  }
@@ -6332,6 +6359,55 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6332
6359
  if (!result) return void 0;
6333
6360
  return result.svg;
6334
6361
  }
6362
+ /**
6363
+ * Get an exported image of the given shapes.
6364
+ *
6365
+ * @param shapes - The shapes (or shape ids) to export.
6366
+ * @param opts - Options for the export.
6367
+ *
6368
+ * @returns A blob of the image.
6369
+ * @public
6370
+ */
6371
+ async toImage(shapes, opts = {}) {
6372
+ const withDefaults = {
6373
+ format: "png",
6374
+ scale: 1,
6375
+ pixelRatio: opts.format === "svg" ? void 0 : 2,
6376
+ ...opts
6377
+ };
6378
+ const result = await this.getSvgString(shapes, withDefaults);
6379
+ if (!result) throw new Error("Could not create SVG");
6380
+ switch (withDefaults.format) {
6381
+ case "svg":
6382
+ return {
6383
+ blob: new Blob([result.svg], { type: "text/plain" }),
6384
+ width: result.width,
6385
+ height: result.height
6386
+ };
6387
+ case "jpeg":
6388
+ case "png":
6389
+ case "webp": {
6390
+ const blob = await getSvgAsImage(result.svg, {
6391
+ type: withDefaults.format,
6392
+ quality: withDefaults.quality,
6393
+ pixelRatio: withDefaults.pixelRatio,
6394
+ width: result.width,
6395
+ height: result.height
6396
+ });
6397
+ if (!blob) {
6398
+ throw new Error("Could not construct image.");
6399
+ }
6400
+ return {
6401
+ blob,
6402
+ width: result.width,
6403
+ height: result.height
6404
+ };
6405
+ }
6406
+ default: {
6407
+ exhaustiveSwitchError(withDefaults.format);
6408
+ }
6409
+ }
6410
+ }
6335
6411
  /**
6336
6412
  * Update the input points from a pointer, pinch, or wheel event.
6337
6413
  *
@@ -6825,6 +6901,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6825
6901
  }
6826
6902
  _flushEventForTick(info) {
6827
6903
  if (this.getCrashingError()) return this;
6904
+ this.emit("before-event", info);
6828
6905
  const { inputs } = this;
6829
6906
  const { type } = info;
6830
6907
  if (info.type === "misc") {