@tldraw/editor 3.8.0-canary.80294e641ad6 → 3.8.0-canary.811fed79c8ad

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 (98) hide show
  1. package/dist-cjs/index.d.ts +257 -60
  2. package/dist-cjs/index.js +14 -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 +85 -21
  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.map +2 -2
  15. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js +66 -0
  16. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js.map +7 -0
  17. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  18. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  19. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  20. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  21. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  22. package/dist-cjs/lib/exports/exportToSvg.js.map +2 -2
  23. package/dist-cjs/lib/exports/getSvgAsImage.js +83 -0
  24. package/dist-cjs/lib/exports/getSvgAsImage.js.map +7 -0
  25. package/dist-cjs/lib/exports/getSvgJsx.js +16 -3
  26. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  27. package/dist-cjs/lib/hooks/useLocalStore.js +1 -1
  28. package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
  29. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -0
  30. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +3 -3
  31. package/dist-cjs/lib/options.js +3 -1
  32. package/dist-cjs/lib/options.js.map +2 -2
  33. package/dist-cjs/lib/utils/browserCanvasMaxSize.js +75 -0
  34. package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +7 -0
  35. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +3 -1
  36. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  37. package/dist-cjs/version.js +3 -3
  38. package/dist-cjs/version.js.map +1 -1
  39. package/dist-esm/index.d.mts +257 -60
  40. package/dist-esm/index.mjs +7 -1
  41. package/dist-esm/index.mjs.map +2 -2
  42. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +2 -5
  43. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  44. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  45. package/dist-esm/lib/config/createTLStore.mjs +4 -2
  46. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  47. package/dist-esm/lib/editor/Editor.mjs +85 -21
  48. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  49. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
  50. package/dist-esm/lib/editor/managers/TextManager.mjs +1 -0
  51. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  52. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  53. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs +46 -0
  54. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs.map +7 -0
  55. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  56. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  57. package/dist-esm/lib/exports/exportToSvg.mjs.map +2 -2
  58. package/dist-esm/lib/exports/getSvgAsImage.mjs +63 -0
  59. package/dist-esm/lib/exports/getSvgAsImage.mjs.map +7 -0
  60. package/dist-esm/lib/exports/getSvgJsx.mjs +16 -3
  61. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  62. package/dist-esm/lib/hooks/useLocalStore.mjs +1 -1
  63. package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
  64. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -0
  65. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +3 -3
  66. package/dist-esm/lib/options.mjs +3 -1
  67. package/dist-esm/lib/options.mjs.map +2 -2
  68. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +45 -0
  69. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +7 -0
  70. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +3 -1
  71. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  72. package/dist-esm/version.mjs +3 -3
  73. package/dist-esm/version.mjs.map +1 -1
  74. package/editor.css +2 -1
  75. package/package.json +22 -20
  76. package/src/index.ts +19 -1
  77. package/src/lib/components/default-components/DefaultCanvas.tsx +2 -5
  78. package/src/lib/config/TLSessionStateSnapshot.ts +3 -1
  79. package/src/lib/config/createTLStore.ts +4 -2
  80. package/src/lib/editor/Editor.ts +134 -44
  81. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +4 -4
  82. package/src/lib/editor/managers/TextManager.ts +1 -0
  83. package/src/lib/editor/shapes/ShapeUtil.ts +30 -1
  84. package/src/lib/editor/shapes/shared/resizeScaled.ts +61 -0
  85. package/src/lib/editor/types/SvgExportContext.tsx +21 -0
  86. package/src/lib/editor/types/emit-types.ts +1 -0
  87. package/src/lib/editor/types/external-content.ts +90 -50
  88. package/src/lib/editor/types/misc-types.ts +55 -2
  89. package/src/lib/exports/StyleEmbedder.ts +1 -1
  90. package/src/lib/exports/exportToSvg.tsx +2 -2
  91. package/src/lib/exports/getSvgAsImage.ts +92 -0
  92. package/src/lib/exports/getSvgJsx.tsx +17 -2
  93. package/src/lib/hooks/useLocalStore.ts +1 -1
  94. package/src/lib/hooks/usePassThroughWheelEvents.ts +7 -0
  95. package/src/lib/options.ts +11 -0
  96. package/src/lib/utils/browserCanvasMaxSize.ts +65 -0
  97. package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -1
  98. 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";
@@ -838,6 +839,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
838
839
  assert(shapeUtil, `No shape util found for type "${type}"`);
839
840
  return shapeUtil;
840
841
  }
842
+ hasShapeUtil(arg) {
843
+ const type = typeof arg === "string" ? arg : arg.type;
844
+ return hasOwnProperty(this.shapeUtils, type);
845
+ }
841
846
  getBindingUtil(arg) {
842
847
  const type = typeof arg === "string" ? arg : arg.type;
843
848
  const bindingUtil = getOwnProperty(this.bindingUtils, type);
@@ -1185,8 +1190,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1185
1190
  *
1186
1191
  * @example
1187
1192
  * ```ts
1188
- * state.getStateDescendant('select')
1189
- * state.getStateDescendant('select.brushing')
1193
+ * editor.getStateDescendant('select')
1194
+ * editor.getStateDescendant('select.brushing')
1190
1195
  * ```
1191
1196
  *
1192
1197
  * @param path - The descendant's path of state ids, separated by periods.
@@ -1240,7 +1245,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1240
1245
  if (partial.isChangingStyle === true) {
1241
1246
  this._isChangingStyleTimeout = this.timers.setTimeout(() => {
1242
1247
  this._updateInstanceState({ isChangingStyle: false }, { history: "ignore" });
1243
- }, 2e3);
1248
+ }, 1e3);
1244
1249
  }
1245
1250
  }
1246
1251
  return this;
@@ -3191,11 +3196,14 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3191
3196
  if (!assetId) return null;
3192
3197
  const asset = this.getAsset(assetId);
3193
3198
  if (!asset) return null;
3194
- const { screenScale = 1, shouldResolveToOriginal = false } = context;
3199
+ const {
3200
+ screenScale = 1,
3201
+ shouldResolveToOriginal = false,
3202
+ dpr = this.getInstanceState().devicePixelRatio
3203
+ } = context;
3195
3204
  const zoomStepFunction = (zoom) => Math.pow(2, Math.ceil(Math.log2(zoom)));
3196
- const steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale));
3205
+ const steppedScreenScale = zoomStepFunction(screenScale);
3197
3206
  const networkEffectiveType = "connection" in navigator ? navigator.connection.effectiveType : null;
3198
- const dpr = this.getInstanceState().devicePixelRatio;
3199
3207
  return await this.store.props.assets.resolve(asset, {
3200
3208
  screenScale: screenScale || 1,
3201
3209
  steppedScreenScale,
@@ -5116,6 +5124,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5116
5124
  scale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
5117
5125
  }
5118
5126
  }
5127
+ let didResize = false;
5119
5128
  if (util.onResize && util.canResize(initialShape)) {
5120
5129
  const newPagePoint = this._scalePagePoint(
5121
5130
  Mat.applyToPoint(pageTransform, new Vec(0, 0)),
@@ -5140,24 +5149,28 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5140
5149
  util.onResizeStart?.(initialShape) ?? void 0
5141
5150
  );
5142
5151
  }
5152
+ const resizedShape = util.onResize(
5153
+ { ...initialShape, x, y },
5154
+ {
5155
+ newPoint: newLocalPoint,
5156
+ handle: opts.dragHandle ?? "bottom_right",
5157
+ // don't set isSingle to true for children
5158
+ mode: opts.mode ?? "scale_shape",
5159
+ scaleX: myScale.x,
5160
+ scaleY: myScale.y,
5161
+ initialBounds,
5162
+ initialShape
5163
+ }
5164
+ );
5165
+ if (resizedShape) {
5166
+ didResize = true;
5167
+ }
5143
5168
  workingShape = applyPartialToRecordWithProps(workingShape, {
5144
5169
  id,
5145
5170
  type: initialShape.type,
5146
5171
  x: newLocalPoint.x,
5147
5172
  y: newLocalPoint.y,
5148
- ...util.onResize(
5149
- { ...initialShape, x, y },
5150
- {
5151
- newPoint: newLocalPoint,
5152
- handle: opts.dragHandle ?? "bottom_right",
5153
- // don't set isSingle to true for children
5154
- mode: opts.mode ?? "scale_shape",
5155
- scaleX: myScale.x,
5156
- scaleY: myScale.y,
5157
- initialBounds,
5158
- initialShape
5159
- }
5160
- )
5173
+ ...resizedShape
5161
5174
  });
5162
5175
  if (!opts.skipStartAndEndCallbacks) {
5163
5176
  workingShape = applyPartialToRecordWithProps(
@@ -5166,7 +5179,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5166
5179
  );
5167
5180
  }
5168
5181
  this.updateShapes([workingShape]);
5169
- } else {
5182
+ }
5183
+ if (!didResize) {
5170
5184
  const initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center);
5171
5185
  const newPageCenter = this._scalePagePoint(
5172
5186
  initialPageCenter,
@@ -6313,7 +6327,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6313
6327
  * @public
6314
6328
  */
6315
6329
  async getSvgElement(shapes, opts = {}) {
6316
- const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
6330
+ const ids = shapes.length === 0 ? this.getCurrentPageShapeIdsSorted() : typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
6317
6331
  if (ids.length === 0) return void 0;
6318
6332
  return exportToSvg(this, ids, opts);
6319
6333
  }
@@ -6343,6 +6357,55 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6343
6357
  if (!result) return void 0;
6344
6358
  return result.svg;
6345
6359
  }
6360
+ /**
6361
+ * Get an exported image of the given shapes.
6362
+ *
6363
+ * @param shapes - The shapes (or shape ids) to export.
6364
+ * @param opts - Options for the export.
6365
+ *
6366
+ * @returns A blob of the image.
6367
+ * @public
6368
+ */
6369
+ async toImage(shapes, opts = {}) {
6370
+ const withDefaults = {
6371
+ format: "png",
6372
+ scale: 1,
6373
+ pixelRatio: opts.format === "svg" ? void 0 : 2,
6374
+ ...opts
6375
+ };
6376
+ const result = await this.getSvgString(shapes, withDefaults);
6377
+ if (!result) throw new Error("Could not create SVG");
6378
+ switch (withDefaults.format) {
6379
+ case "svg":
6380
+ return {
6381
+ blob: new Blob([result.svg], { type: "text/plain" }),
6382
+ width: result.width,
6383
+ height: result.height
6384
+ };
6385
+ case "jpeg":
6386
+ case "png":
6387
+ case "webp": {
6388
+ const blob = await getSvgAsImage(result.svg, {
6389
+ type: withDefaults.format,
6390
+ quality: withDefaults.quality,
6391
+ pixelRatio: withDefaults.pixelRatio,
6392
+ width: result.width,
6393
+ height: result.height
6394
+ });
6395
+ if (!blob) {
6396
+ throw new Error("Could not construct image.");
6397
+ }
6398
+ return {
6399
+ blob,
6400
+ width: result.width,
6401
+ height: result.height
6402
+ };
6403
+ }
6404
+ default: {
6405
+ exhaustiveSwitchError(withDefaults.format);
6406
+ }
6407
+ }
6408
+ }
6346
6409
  /**
6347
6410
  * Update the input points from a pointer, pinch, or wheel event.
6348
6411
  *
@@ -6836,6 +6899,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
6836
6899
  }
6837
6900
  _flushEventForTick(info) {
6838
6901
  if (this.getCrashingError()) return this;
6902
+ this.emit("before-event", info);
6839
6903
  const { inputs } = this;
6840
6904
  const { type } = info;
6841
6905
  if (info.type === "misc") {