@tldraw/editor 3.15.0-canary.e3f6387b7e04 → 3.15.0-canary.ef2f8fce47e3

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 (89) hide show
  1. package/dist-cjs/index.d.ts +94 -3
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/SVGContainer.js +1 -1
  5. package/dist-cjs/lib/components/SVGContainer.js.map +2 -2
  6. package/dist-cjs/lib/components/default-components/DefaultBrush.js +1 -1
  7. package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
  9. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
  11. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultCursor.js +1 -1
  13. package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultGrid.js +1 -1
  15. package/dist-cjs/lib/components/default-components/DefaultGrid.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultHandles.js +1 -1
  17. package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +2 -2
  18. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -1
  19. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  20. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +1 -1
  21. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +2 -2
  22. package/dist-cjs/lib/components/default-components/DefaultSpinner.js +27 -15
  23. package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +3 -3
  24. package/dist-cjs/lib/editor/Editor.js +67 -40
  25. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  26. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  27. package/dist-cjs/lib/editor/tools/StateNode.js +20 -1
  28. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  29. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  30. package/dist-cjs/lib/hooks/useEditorComponents.js.map +1 -1
  31. package/dist-cjs/lib/license/Watermark.js +2 -2
  32. package/dist-cjs/lib/license/Watermark.js.map +2 -2
  33. package/dist-cjs/version.js +3 -3
  34. package/dist-cjs/version.js.map +1 -1
  35. package/dist-esm/index.d.mts +94 -3
  36. package/dist-esm/index.mjs +1 -1
  37. package/dist-esm/index.mjs.map +2 -2
  38. package/dist-esm/lib/components/SVGContainer.mjs +1 -1
  39. package/dist-esm/lib/components/SVGContainer.mjs.map +2 -2
  40. package/dist-esm/lib/components/default-components/DefaultBrush.mjs +1 -1
  41. package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
  42. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
  43. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  44. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
  45. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
  46. package/dist-esm/lib/components/default-components/DefaultCursor.mjs +1 -1
  47. package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +2 -2
  48. package/dist-esm/lib/components/default-components/DefaultGrid.mjs +1 -1
  49. package/dist-esm/lib/components/default-components/DefaultGrid.mjs.map +2 -2
  50. package/dist-esm/lib/components/default-components/DefaultHandles.mjs +1 -1
  51. package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +2 -2
  52. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -1
  53. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  54. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +1 -1
  55. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +2 -2
  56. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +17 -15
  57. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
  58. package/dist-esm/lib/editor/Editor.mjs +67 -40
  59. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  60. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  61. package/dist-esm/lib/editor/tools/StateNode.mjs +20 -1
  62. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  63. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +1 -1
  64. package/dist-esm/lib/license/Watermark.mjs +2 -2
  65. package/dist-esm/lib/license/Watermark.mjs.map +2 -2
  66. package/dist-esm/version.mjs +3 -3
  67. package/dist-esm/version.mjs.map +1 -1
  68. package/editor.css +17 -4
  69. package/package.json +9 -8
  70. package/src/index.ts +1 -0
  71. package/src/lib/components/SVGContainer.tsx +1 -1
  72. package/src/lib/components/default-components/DefaultBrush.tsx +1 -1
  73. package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
  74. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
  75. package/src/lib/components/default-components/DefaultCursor.tsx +1 -1
  76. package/src/lib/components/default-components/DefaultGrid.tsx +1 -1
  77. package/src/lib/components/default-components/DefaultHandles.tsx +5 -1
  78. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +1 -1
  79. package/src/lib/components/default-components/DefaultSnapIndictor.tsx +1 -1
  80. package/src/lib/components/default-components/DefaultSpinner.tsx +12 -12
  81. package/src/lib/editor/Editor.ts +76 -39
  82. package/src/lib/editor/shapes/ShapeUtil.ts +57 -0
  83. package/src/lib/editor/tools/StateNode.test.ts +285 -0
  84. package/src/lib/editor/tools/StateNode.ts +27 -1
  85. package/src/lib/editor/types/misc-types.ts +19 -0
  86. package/src/lib/hooks/useEditorComponents.tsx +1 -1
  87. package/src/lib/license/Watermark.tsx +2 -2
  88. package/src/version.ts +3 -3
  89. package/src/lib/test/currentToolIdMask.test.ts +0 -49
@@ -1,19 +1,21 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- function DefaultSpinner() {
3
- return /* @__PURE__ */ jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", "aria-hidden": "false", children: /* @__PURE__ */ jsxs("g", { strokeWidth: 2, fill: "none", fillRule: "evenodd", children: [
4
- /* @__PURE__ */ jsx("circle", { strokeOpacity: 0.25, cx: 8, cy: 8, r: 7, stroke: "currentColor" }),
5
- /* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M15 8c0-4.5-4.5-7-7-7", stroke: "currentColor", children: /* @__PURE__ */ jsx(
6
- "animateTransform",
7
- {
8
- attributeName: "transform",
9
- type: "rotate",
10
- from: "0 8 8",
11
- to: "360 8 8",
12
- dur: "1s",
13
- repeatCount: "indefinite"
14
- }
15
- ) })
16
- ] }) });
2
+ import classNames from "classnames";
3
+ function DefaultSpinner(props) {
4
+ return /* @__PURE__ */ jsx(
5
+ "svg",
6
+ {
7
+ width: 16,
8
+ height: 16,
9
+ viewBox: "0 0 16 16",
10
+ "aria-hidden": "false",
11
+ ...props,
12
+ className: classNames("tl-spinner", props.className),
13
+ children: /* @__PURE__ */ jsxs("g", { strokeWidth: 2, fill: "none", fillRule: "evenodd", children: [
14
+ /* @__PURE__ */ jsx("circle", { strokeOpacity: 0.25, cx: 8, cy: 8, r: 7, stroke: "currentColor" }),
15
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M15 8c0-4.5-4.5-7-7-7", stroke: "currentColor" })
16
+ ] })
17
+ }
18
+ );
17
19
  }
18
20
  export {
19
21
  DefaultSpinner
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultSpinner.tsx"],
4
- "sourcesContent": ["/** @public @react */\nexport function DefaultSpinner() {\n\treturn (\n\t\t<svg width={16} height={16} viewBox=\"0 0 16 16\" aria-hidden=\"false\">\n\t\t\t<g strokeWidth={2} fill=\"none\" fillRule=\"evenodd\">\n\t\t\t\t<circle strokeOpacity={0.25} cx={8} cy={8} r={7} stroke=\"currentColor\" />\n\t\t\t\t<path strokeLinecap=\"round\" d=\"M15 8c0-4.5-4.5-7-7-7\" stroke=\"currentColor\">\n\t\t\t\t\t<animateTransform\n\t\t\t\t\t\tattributeName=\"transform\"\n\t\t\t\t\t\ttype=\"rotate\"\n\t\t\t\t\t\tfrom=\"0 8 8\"\n\t\t\t\t\t\tto=\"360 8 8\"\n\t\t\t\t\t\tdur=\"1s\"\n\t\t\t\t\t\trepeatCount=\"indefinite\"\n\t\t\t\t\t/>\n\t\t\t\t</path>\n\t\t\t</g>\n\t\t</svg>\n\t)\n}\n"],
5
- "mappings": "AAIG,SACC,KADD;AAHI,SAAS,iBAAiB;AAChC,SACC,oBAAC,SAAI,OAAO,IAAI,QAAQ,IAAI,SAAQ,aAAY,eAAY,SAC3D,+BAAC,OAAE,aAAa,GAAG,MAAK,QAAO,UAAS,WACvC;AAAA,wBAAC,YAAO,eAAe,MAAM,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,QAAO,gBAAe;AAAA,IACvE,oBAAC,UAAK,eAAc,SAAQ,GAAE,yBAAwB,QAAO,gBAC5D;AAAA,MAAC;AAAA;AAAA,QACA,eAAc;AAAA,QACd,MAAK;AAAA,QACL,MAAK;AAAA,QACL,IAAG;AAAA,QACH,KAAI;AAAA,QACJ,aAAY;AAAA;AAAA,IACb,GACD;AAAA,KACD,GACD;AAEF;",
4
+ "sourcesContent": ["import classNames from 'classnames'\n\n/** @public @react */\nexport function DefaultSpinner(props: React.SVGProps<SVGSVGElement>) {\n\treturn (\n\t\t<svg\n\t\t\twidth={16}\n\t\t\theight={16}\n\t\t\tviewBox=\"0 0 16 16\"\n\t\t\taria-hidden=\"false\"\n\t\t\t{...props}\n\t\t\tclassName={classNames('tl-spinner', props.className)}\n\t\t>\n\t\t\t<g strokeWidth={2} fill=\"none\" fillRule=\"evenodd\">\n\t\t\t\t<circle strokeOpacity={0.25} cx={8} cy={8} r={7} stroke=\"currentColor\" />\n\t\t\t\t<path strokeLinecap=\"round\" d=\"M15 8c0-4.5-4.5-7-7-7\" stroke=\"currentColor\" />\n\t\t\t</g>\n\t\t</svg>\n\t)\n}\n"],
5
+ "mappings": "AAaG,SACC,KADD;AAbH,OAAO,gBAAgB;AAGhB,SAAS,eAAe,OAAsC;AACpE,SACC;AAAA,IAAC;AAAA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAQ;AAAA,MACR,eAAY;AAAA,MACX,GAAG;AAAA,MACJ,WAAW,WAAW,cAAc,MAAM,SAAS;AAAA,MAEnD,+BAAC,OAAE,aAAa,GAAG,MAAK,QAAO,UAAS,WACvC;AAAA,4BAAC,YAAO,eAAe,MAAM,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,QAAO,gBAAe;AAAA,QACvE,oBAAC,UAAK,eAAc,SAAQ,GAAE,yBAAwB,QAAO,gBAAe;AAAA,SAC7E;AAAA;AAAA,EACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1513,9 +1513,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1513
1513
  const selectedShapeIds = this.getSelectedShapeIds();
1514
1514
  const firstParentId = selectedShapeIds[0] ? this.getShape(selectedShapeIds[0])?.parentId : null;
1515
1515
  const isSelectedWithinContainer = firstParentId && selectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) && !isPageId(firstParentId);
1516
- const readingOrderShapes = isSelectedWithinContainer ? this._getShapesInReadingOrder(
1517
- this.getCurrentPageShapes().filter((shape2) => shape2.parentId === firstParentId)
1518
- ) : this.getCurrentPageShapesInReadingOrder();
1516
+ const filteredShapes = isSelectedWithinContainer ? this.getCurrentPageShapes().filter((shape2) => shape2.parentId === firstParentId) : this.getCurrentPageShapes().filter((shape2) => isPageId(shape2.parentId));
1517
+ const readingOrderShapes = isSelectedWithinContainer ? this._getShapesInReadingOrder(filteredShapes) : this.getCurrentPageShapesInReadingOrder();
1519
1518
  const currentShapeId = selectedShapeIds.length === 1 ? selectedShapeIds[0] : readingOrderShapes.find((shape2) => selectedShapeIds.includes(shape2.id))?.id;
1520
1519
  let adjacentShapeId;
1521
1520
  if (direction === "next" || direction === "prev") {
@@ -1525,7 +1524,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1525
1524
  adjacentShapeId = shapeIds[adjacentIndex];
1526
1525
  } else {
1527
1526
  if (!currentShapeId) return;
1528
- adjacentShapeId = this.getNearestAdjacentShape(currentShapeId, direction);
1527
+ adjacentShapeId = this.getNearestAdjacentShape(filteredShapes, currentShapeId, direction);
1529
1528
  }
1530
1529
  const shape = this.getShape(adjacentShapeId);
1531
1530
  if (!shape) return;
@@ -1591,11 +1590,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1591
1590
  *
1592
1591
  * @public
1593
1592
  */
1594
- getNearestAdjacentShape(currentShapeId, direction) {
1593
+ getNearestAdjacentShape(shapes, currentShapeId, direction) {
1595
1594
  const directionToAngle = { right: 0, left: 180, down: 90, up: 270 };
1596
1595
  const currentShape = this.getShape(currentShapeId);
1597
1596
  if (!currentShape) return currentShapeId;
1598
- const shapes = this.getCurrentPageShapes();
1599
1597
  const tabbableShapes = shapes.filter(
1600
1598
  (shape) => this.getShapeUtil(shape).canTabTo(shape) && shape.id !== currentShapeId
1601
1599
  );
@@ -2359,28 +2357,11 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2359
2357
  { history: "ignore" }
2360
2358
  );
2361
2359
  const { currentScreenPoint, currentPagePoint } = this.inputs;
2362
- const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID);
2363
2360
  if (currentScreenPoint.x / z - x !== currentPagePoint.x || currentScreenPoint.y / z - y !== currentPagePoint.y) {
2364
- const event = {
2365
- type: "pointer",
2366
- target: "canvas",
2367
- name: "pointer_move",
2368
- // weird but true: we need to put the screen point back into client space
2369
- point: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),
2370
- pointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,
2371
- ctrlKey: this.inputs.ctrlKey,
2372
- altKey: this.inputs.altKey,
2373
- shiftKey: this.inputs.shiftKey,
2374
- metaKey: this.inputs.metaKey,
2375
- accelKey: isAccelKey(this.inputs),
2376
- button: 0,
2377
- isPen: this.getInstanceState().isPenMode ?? false
2378
- };
2379
- if (opts?.immediate) {
2380
- this._flushEventForTick(event);
2381
- } else {
2382
- this.dispatch(event);
2383
- }
2361
+ this.updatePointer({
2362
+ immediate: opts?.immediate,
2363
+ pointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE
2364
+ });
2384
2365
  }
2385
2366
  this._tickCameraState();
2386
2367
  });
@@ -3349,19 +3330,24 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3349
3330
  */
3350
3331
  deletePage(page) {
3351
3332
  const id = typeof page === "string" ? page : page.id;
3352
- this.run(() => {
3353
- if (this.getIsReadonly()) return;
3354
- const pages = this.getPages();
3355
- if (pages.length === 1) return;
3356
- const deletedPage = this.getPage(id);
3357
- if (!deletedPage) return;
3358
- if (id === this.getCurrentPageId()) {
3359
- const index = pages.findIndex((page2) => page2.id === id);
3360
- const next = pages[index - 1] ?? pages[index + 1];
3361
- this.setCurrentPage(next.id);
3362
- }
3363
- this.store.remove([deletedPage.id]);
3364
- });
3333
+ this.run(
3334
+ () => {
3335
+ if (this.getIsReadonly()) return;
3336
+ const pages = this.getPages();
3337
+ if (pages.length === 1) return;
3338
+ const deletedPage = this.getPage(id);
3339
+ if (!deletedPage) return;
3340
+ if (id === this.getCurrentPageId()) {
3341
+ const index = pages.findIndex((page2) => page2.id === id);
3342
+ const next = pages[index - 1] ?? pages[index + 1];
3343
+ this.setCurrentPage(next.id);
3344
+ }
3345
+ const shapes = this.getSortedChildIdsForParent(deletedPage.id);
3346
+ this.deleteShapes(shapes);
3347
+ this.store.remove([deletedPage.id]);
3348
+ },
3349
+ { ignoreShapeLock: true }
3350
+ );
3365
3351
  return this;
3366
3352
  }
3367
3353
  /**
@@ -7064,6 +7050,47 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7064
7050
  this.dispatch({ type: "misc", name: "complete" });
7065
7051
  return this;
7066
7052
  }
7053
+ /**
7054
+ * Dispatch a pointer move event in the current position of the pointer. This is useful when
7055
+ * external circumstances have changed (e.g. the camera moved or a shape was moved) and you want
7056
+ * the current interaction to respond to that change.
7057
+ *
7058
+ * @example
7059
+ * ```ts
7060
+ * editor.updatePointer()
7061
+ * ```
7062
+ *
7063
+ * @param options - The options for updating the pointer.
7064
+ * @returns The editor instance.
7065
+ * @public
7066
+ */
7067
+ updatePointer(options) {
7068
+ const event = {
7069
+ type: "pointer",
7070
+ target: "canvas",
7071
+ name: "pointer_move",
7072
+ point: options?.point ?? // weird but true: what `inputs` calls screen-space is actually viewport space. so
7073
+ // we need to convert back into true screen space first. we should fix this...
7074
+ Vec.Add(
7075
+ this.inputs.currentScreenPoint,
7076
+ this.store.unsafeGetWithoutCapture(TLINSTANCE_ID).screenBounds
7077
+ ),
7078
+ pointerId: options?.pointerId ?? 0,
7079
+ button: options?.button ?? 0,
7080
+ isPen: options?.isPen ?? this.inputs.isPen,
7081
+ shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
7082
+ altKey: options?.altKey ?? this.inputs.altKey,
7083
+ ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
7084
+ metaKey: options?.metaKey ?? this.inputs.metaKey,
7085
+ accelKey: options?.accelKey ?? isAccelKey(this.inputs)
7086
+ };
7087
+ if (options?.immediate) {
7088
+ this._flushEventForTick(event);
7089
+ } else {
7090
+ this.dispatch(event);
7091
+ }
7092
+ return this;
7093
+ }
7067
7094
  /**
7068
7095
  * Puts the editor into focused mode.
7069
7096
  *