@tldraw/editor 3.8.0-canary.bc462846819a → 3.8.0-canary.be65d368fd8b

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