@inditextech/weave-sdk 0.10.3 → 0.12.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.
package/dist/sdk.cjs CHANGED
@@ -15571,6 +15571,15 @@ var WeaveStore = class {
15571
15571
  const newState = JSON.parse(JSON.stringify(this.getState()));
15572
15572
  config.callbacks?.onStateChange?.(newState);
15573
15573
  this.instance.emitEvent("onStateChange", newState);
15574
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
15575
+ if (this.isRoomLoaded && nodesSelectionPlugin && nodesSelectionPlugin.getSelectedNodes().length === 1) {
15576
+ const selectedNode = nodesSelectionPlugin.getSelectedNodes()[0];
15577
+ const nodeInfo = this.instance.getNode(selectedNode.getAttrs().id ?? "");
15578
+ if (nodeInfo && nodeInfo.node) this.instance.emitEvent("onNodeChange", {
15579
+ instance: selectedNode,
15580
+ node: JSON.parse(JSON.stringify(nodeInfo.node))
15581
+ });
15582
+ }
15574
15583
  if (!this.isRoomLoaded && !(0, import_lodash.isEmpty)(this.state.weave)) {
15575
15584
  this.instance.setupRenderer();
15576
15585
  this.isRoomLoaded = true;
@@ -15871,9 +15880,6 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15871
15880
  });
15872
15881
  this.initEvents();
15873
15882
  this.initialized = true;
15874
- this.instance.on("onRender", () => {
15875
- this.triggerSelectedNodesEvent();
15876
- });
15877
15883
  this.instance.on("onActiveActionChange", (activeAction) => {
15878
15884
  if (typeof activeAction !== "undefined" && activeAction !== "selectionTool") {
15879
15885
  this.active = false;
@@ -15923,7 +15929,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15923
15929
  this.selecting = false;
15924
15930
  const stage = this.instance.getStage();
15925
15931
  stage.container().addEventListener("keydown", (e) => {
15926
- if (e.key === "Backspace" || e.key === "Delete") {
15932
+ if ((e.key === "Backspace" || e.key === "Delete") && Object.keys(window.weaveTextEditing).length === 0) {
15927
15933
  this.removeSelectedNodes();
15928
15934
  return;
15929
15935
  }
@@ -15945,6 +15951,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15945
15951
  this.selectionRectangle.width(0);
15946
15952
  this.selectionRectangle.height(0);
15947
15953
  this.selecting = true;
15954
+ this.instance.emitEvent("onSelectionState", true);
15948
15955
  if (!(e.target instanceof konva.default.Stage)) this.cameFromSelectingMultiple = true;
15949
15956
  });
15950
15957
  stage.on("mousemove touchmove", (e) => {
@@ -15970,6 +15977,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15970
15977
  if (!this.initialized) return;
15971
15978
  if (!this.active) return;
15972
15979
  this.selecting = false;
15980
+ this.instance.emitEvent("onSelectionState", false);
15973
15981
  if (!this.selectionRectangle.visible()) {
15974
15982
  this.cameFromSelectingMultiple = false;
15975
15983
  return;
@@ -16143,9 +16151,9 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16143
16151
  weave: object.weave,
16144
16152
  weaveMinPoint: object.weaveMinPoint
16145
16153
  };
16146
- resolve();
16147
- } catch (ex) {
16148
- reject(ex);
16154
+ resolve(true);
16155
+ } catch (_) {
16156
+ resolve(false);
16149
16157
  }
16150
16158
  }).catch((error) => {
16151
16159
  reject(error);
@@ -16167,31 +16175,36 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16167
16175
  }
16168
16176
  initEvents() {
16169
16177
  const stage = this.instance.getStage();
16170
- document.oncopy = async () => {
16171
- this.performCopy();
16172
- return;
16173
- };
16174
- document.onpaste = async (event) => {
16175
- if (!this.enabled) return;
16176
- const items = event.clipboardData?.items;
16177
- if (!items) return;
16178
- try {
16179
- await this.readClipboardData();
16180
- this.performPaste();
16181
- } catch (ex) {
16182
- this.instance.emitEvent("onPaste", ex);
16178
+ window.addEventListener("keydown", async (e) => {
16179
+ if (e.key === "c" && (e.ctrlKey || e.metaKey)) {
16180
+ e.preventDefault();
16181
+ await this.performCopy();
16182
+ return;
16183
16183
  }
16184
- try {
16185
- const items$1 = await navigator.clipboard.read();
16186
- if (items$1 && items$1.length === 1) {
16187
- const item = items$1[0];
16188
- this.instance.emitEvent("onPasteExternal", item);
16184
+ if (e.key === "v" && (e.ctrlKey || e.metaKey)) {
16185
+ e.preventDefault();
16186
+ if (!this.enabled) return;
16187
+ try {
16188
+ const continueToPaste = await this.readClipboardData();
16189
+ if (!continueToPaste) {
16190
+ this.instance.emitEvent("onPaste", new Error("Invalid elements to paste"));
16191
+ return;
16192
+ }
16193
+ this.performPaste();
16194
+ } catch (ex) {
16195
+ this.instance.emitEvent("onPaste", ex);
16189
16196
  }
16190
- } catch (ex) {
16191
- this.instance.emitEvent("onPaste", ex);
16197
+ try {
16198
+ const items = await navigator.clipboard.read();
16199
+ if (items && items.length === 1) {
16200
+ const item = items[0];
16201
+ this.instance.emitEvent("onPasteExternal", item);
16202
+ }
16203
+ } catch (ex) {
16204
+ this.instance.emitEvent("onPaste", ex);
16205
+ }
16206
+ return;
16192
16207
  }
16193
- };
16194
- stage.container().addEventListener("keydown", (e) => {
16195
16208
  if (e.key === "Escape") {
16196
16209
  this.cancel();
16197
16210
  return;
@@ -16275,7 +16288,11 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16275
16288
  await this.performCopy();
16276
16289
  }
16277
16290
  async paste() {
16278
- await this.readClipboardData();
16291
+ const continueToPaste = await this.readClipboardData();
16292
+ if (!continueToPaste) {
16293
+ this.instance.emitEvent("onPaste", new Error("Invalid elements to paste"));
16294
+ return;
16295
+ }
16279
16296
  this.performPaste();
16280
16297
  }
16281
16298
  getSelectedNodes() {
@@ -17744,7 +17761,7 @@ var WeaveStateManager = class {
17744
17761
  getElementsTree() {
17745
17762
  const state = this.instance.getStore().getState().weave;
17746
17763
  const jsonState = JSON.parse(JSON.stringify(state, null, 2));
17747
- const mainLayer = jsonState.props.children.find((node) => node.key === "mainLayer");
17764
+ const mainLayer = jsonState.props?.children.find((node) => node.key === "mainLayer");
17748
17765
  if (!mainLayer) return [];
17749
17766
  return mainLayer.props.children;
17750
17767
  }
@@ -17838,7 +17855,7 @@ var WeaveRegisterManager = class {
17838
17855
 
17839
17856
  //#endregion
17840
17857
  //#region package.json
17841
- var version = "0.10.3";
17858
+ var version = "0.12.0";
17842
17859
 
17843
17860
  //#endregion
17844
17861
  //#region src/managers/setup.ts
@@ -18224,6 +18241,8 @@ var Weave = class extends Emittery {
18224
18241
  this.actionsManager = new WeaveActionsManager(this);
18225
18242
  this.pluginsManager = new WeavePluginsManager(this);
18226
18243
  if (!window.weave) window.weave = this;
18244
+ window.weaveTextEditing = {};
18245
+ window.weaveDragImageURL = void 0;
18227
18246
  this.setupManager.welcomeLog();
18228
18247
  }
18229
18248
  setupRenderer() {
@@ -18647,8 +18666,19 @@ var WeaveTextNode = class extends WeaveNode {
18647
18666
  name: "node"
18648
18667
  });
18649
18668
  this.setupDefaultNodeEvents(text);
18650
- text.on("dblclick dbltap", (evt) => {
18651
- evt.cancelBubble = true;
18669
+ window.addEventListener("keypress", (e) => {
18670
+ if (this.editing) return;
18671
+ if (e.key !== "Enter" && !e.shiftKey) return;
18672
+ if (this.isSelecting() && this.isNodeSelected(text)) {
18673
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
18674
+ if (nodesSelectionPlugin && nodesSelectionPlugin.getSelectedNodes().length === 1 && nodesSelectionPlugin.getSelectedNodes()[0].getAttrs().nodeType === WEAVE_TEXT_NODE_TYPE && !window.weaveTextEditing[nodesSelectionPlugin.getSelectedNodes()[0].id()]) {
18675
+ e.preventDefault();
18676
+ this.triggerEditMode(nodesSelectionPlugin.getSelectedNodes()[0]);
18677
+ }
18678
+ }
18679
+ });
18680
+ text.on("dblclick dbltap", (e) => {
18681
+ e.cancelBubble = true;
18652
18682
  if (this.editing) return;
18653
18683
  if (!(this.isSelecting() && this.isNodeSelected(text))) return;
18654
18684
  const stage = this.instance.getStage();
@@ -18693,24 +18723,50 @@ var WeaveTextNode = class extends WeaveNode {
18693
18723
  }
18694
18724
  };
18695
18725
  }
18726
+ resizeTextAreaDOM(textNode) {
18727
+ const textArea = document.getElementById(textNode.id());
18728
+ if (!textArea) return;
18729
+ const stage = this.instance.getStage();
18730
+ const textPosition = textNode.absolutePosition();
18731
+ const position = {
18732
+ x: stage.container().offsetLeft + textPosition.x,
18733
+ y: stage.container().offsetTop + textPosition.y
18734
+ };
18735
+ textArea.style.top = position.y + "px";
18736
+ textArea.style.left = position.x + "px";
18737
+ textArea.style.width = textNode.getWidth() * textNode.getAbsoluteScale().x + "px";
18738
+ textArea.style.height = textNode.getHeight() * textNode.getAbsoluteScale().x + "px";
18739
+ textArea.style.fontSize = textNode.fontSize() * textNode.getAbsoluteScale().x + "px";
18740
+ }
18741
+ onZoomChangeHandler = (textNode) => () => {
18742
+ if (!this.editing) return;
18743
+ this.resizeTextAreaDOM(textNode);
18744
+ };
18745
+ onStageMoveHandler = (textNode) => () => {
18746
+ if (!this.editing) return;
18747
+ this.resizeTextAreaDOM(textNode);
18748
+ };
18696
18749
  createTextAreaDOM(textNode, position) {
18697
18750
  const stage = this.instance.getStage();
18698
18751
  const textArea = document.createElement("textarea");
18752
+ textArea.id = textNode.id();
18699
18753
  stage.container().appendChild(textArea);
18700
- window.weaveTextEditing = true;
18754
+ this.instance.addEventListener("onZoomChange", this.onZoomChangeHandler(textNode).bind(this));
18755
+ this.instance.addEventListener("onStageMove", this.onStageMoveHandler(textNode).bind(this));
18756
+ window.weaveTextEditing[textNode.id()] = "editing";
18701
18757
  textArea.value = textNode.text();
18702
18758
  textArea.id = textNode.id();
18703
18759
  textArea.style.position = "fixed";
18704
18760
  textArea.style.top = position.y + "px";
18705
18761
  textArea.style.left = position.x + "px";
18706
18762
  textArea.style.width = (textNode.width() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
18707
- textArea.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
18763
+ textArea.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + 2 + "px";
18708
18764
  textArea.style.fontSize = textNode.fontSize() * textNode.getAbsoluteScale().x + "px";
18709
- textArea.style.border = "solid 1px rgba(0,0,255,0.5)";
18710
- textArea.style.padding = "0px";
18765
+ textArea.style.border = "solid 1px #1e40af";
18766
+ textArea.style.minHeight = "auto";
18711
18767
  textArea.style.margin = "0px";
18712
18768
  textArea.style.overflow = "hidden";
18713
- textArea.style.background = "rgba(255,255,255,0.5)";
18769
+ textArea.style.background = "transparent";
18714
18770
  textArea.style.outline = "none";
18715
18771
  textArea.style.resize = "none";
18716
18772
  textArea.style.lineHeight = `${textNode.lineHeight()}`;
@@ -18718,29 +18774,42 @@ var WeaveTextNode = class extends WeaveNode {
18718
18774
  textArea.style.transformOrigin = "left top";
18719
18775
  textArea.style.textAlign = textNode.align();
18720
18776
  textArea.style.color = `${textNode.fill()}`;
18777
+ textArea.onfocus = () => {
18778
+ textArea.style.height = "auto";
18779
+ textArea.style.height = textArea.scrollHeight + 1.6 * textNode.getAbsoluteScale().x + "px";
18780
+ textArea.setSelectionRange(textArea.value.length, textArea.value.length);
18781
+ };
18782
+ textArea.onkeydown = () => {
18783
+ textArea.style.height = "auto";
18784
+ textArea.style.height = textArea.scrollHeight + 1.6 * textNode.getAbsoluteScale().x + "px";
18785
+ };
18786
+ textArea.onkeyup = () => {
18787
+ textArea.style.height = "auto";
18788
+ textArea.style.height = textArea.scrollHeight + 1.6 * textNode.getAbsoluteScale().x + "px";
18789
+ };
18790
+ textArea.onwheel = (e) => {
18791
+ e.preventDefault();
18792
+ };
18793
+ textArea.oninput = () => {
18794
+ textArea.style.height = "auto";
18795
+ textArea.style.height = textArea.scrollHeight + 1.6 * textNode.getAbsoluteScale().x + "px";
18796
+ };
18721
18797
  const rotation = textNode.rotation();
18722
18798
  let transform = "";
18723
18799
  if (rotation) transform += "rotateZ(" + rotation + "deg)";
18724
- const px = 1;
18725
- const py = 2;
18726
- transform += "translateX(-" + px + "px)";
18727
- transform += "translateY(-" + py + "px)";
18800
+ const px = 0;
18801
+ const py = -3 * textNode.getAbsoluteScale().x;
18802
+ transform += "translateX(" + px + "px)";
18803
+ transform += "translateY(" + py + "px)";
18728
18804
  textArea.style.transform = transform;
18729
18805
  const handleKeyDown = (e) => {
18730
18806
  if (textArea && textNode) {
18731
- if (e.key === "Enter" && !e.shiftKey) {
18732
- textNode.text(textArea.value);
18733
- this.updateNode(textNode);
18734
- this.removeTextAreaDOM(textNode);
18735
- window.removeEventListener("click", handleOutsideClick);
18736
- return;
18737
- }
18738
- if (e.key === "Enter" && e.shiftKey) {
18807
+ if (e.key === "Enter") {
18739
18808
  if (textArea && textNode) try {
18740
18809
  textNode.text(textArea.value);
18741
18810
  textArea.style.width = textNode.width() * textNode.getAbsoluteScale().x + "px";
18742
18811
  textArea.style.height = "auto";
18743
- textArea.style.height = textArea.scrollHeight + textNode.fontSize() * textNode.getAbsoluteScale().x + "px";
18812
+ textArea.style.height = textArea.scrollHeight + 1.6 * textNode.getAbsoluteScale().x + "px";
18744
18813
  textArea.tabIndex = 1;
18745
18814
  textArea.focus();
18746
18815
  } catch (ex) {
@@ -18749,20 +18818,24 @@ var WeaveTextNode = class extends WeaveNode {
18749
18818
  return;
18750
18819
  }
18751
18820
  if (e.key === "Escape") {
18821
+ textNode.width(parseFloat(textArea.style.width) * (1 / textNode.getAbsoluteScale().x));
18822
+ textNode.height((textArea.scrollHeight + 1.6) * (1 / textNode.getAbsoluteScale().x));
18823
+ textNode.text(textArea.value);
18824
+ this.updateNode(textNode);
18752
18825
  this.removeTextAreaDOM(textNode);
18826
+ this.instance.removeEventListener("onZoomChange", this.onZoomChangeHandler(textNode).bind(this));
18827
+ this.instance.removeEventListener("onStageMove", this.onStageMoveHandler(textNode).bind(this));
18753
18828
  window.removeEventListener("click", handleOutsideClick);
18754
18829
  return;
18755
18830
  }
18756
18831
  }
18757
18832
  };
18758
- const handleKeyUp = (e) => {
18833
+ const handleKeyUp = () => {
18759
18834
  textNode.text(textArea.value);
18760
18835
  if (textArea && textNode) {
18761
18836
  textArea.style.width = textNode.width() * textNode.getAbsoluteScale().x + "px";
18762
- if (!(e.key === "Enter" && e.shiftKey)) {
18763
- textArea.style.height = "auto";
18764
- textArea.style.height = textArea.scrollHeight + "px";
18765
- }
18837
+ textArea.style.height = "auto";
18838
+ textArea.style.height = textArea.scrollHeight + 1.6 * textNode.getAbsoluteScale().x + "px";
18766
18839
  }
18767
18840
  };
18768
18841
  textArea.addEventListener("keydown", handleKeyDown);
@@ -18795,7 +18868,7 @@ var WeaveTextNode = class extends WeaveNode {
18795
18868
  }
18796
18869
  removeTextAreaDOM(textNode) {
18797
18870
  const stage = this.instance.getStage();
18798
- window.weaveTextEditing = false;
18871
+ delete window.weaveTextEditing[textNode.id()];
18799
18872
  const textArea = document.getElementById(textNode.id());
18800
18873
  if (textArea) textArea.remove();
18801
18874
  textNode.visible(true);
@@ -18848,6 +18921,7 @@ const IMAGE_TOOL_STATE = {
18848
18921
  var WeaveImageToolAction = class extends WeaveAction {
18849
18922
  initialized = false;
18850
18923
  initialCursor = null;
18924
+ onPropsChange = void 0;
18851
18925
  update = void 0;
18852
18926
  constructor() {
18853
18927
  super();
@@ -18903,13 +18977,8 @@ var WeaveImageToolAction = class extends WeaveAction {
18903
18977
  if (this.state === IMAGE_TOOL_STATE.ADDING && tempImage) {
18904
18978
  const mousePos = stage.getRelativePointerPosition();
18905
18979
  tempImage.setAttrs({
18906
- ...this.props,
18907
- name: void 0,
18908
18980
  x: (mousePos?.x ?? 0) + 2,
18909
- y: (mousePos?.y ?? 0) + 2,
18910
- fill: "#ccccccff",
18911
- stroke: "#000000ff",
18912
- strokeWidth: 1
18981
+ y: (mousePos?.y ?? 0) + 2
18913
18982
  });
18914
18983
  const nodeHandler = this.instance.getNodeHandler("rectangle");
18915
18984
  this.instance.updateNode(nodeHandler.serialize(tempImage));
@@ -18934,6 +19003,7 @@ var WeaveImageToolAction = class extends WeaveAction {
18934
19003
  this.instance.emitEvent("onImageLoadEnd", void 0);
18935
19004
  if (this.imageId) this.props = {
18936
19005
  ...this.props,
19006
+ imageURL: this.imageURL,
18937
19007
  width: this.preloadImgs[this.imageId].width,
18938
19008
  height: this.preloadImgs[this.imageId].height
18939
19009
  };
@@ -18952,17 +19022,20 @@ var WeaveImageToolAction = class extends WeaveAction {
18952
19022
  stage.container().focus();
18953
19023
  if (this.imageId) {
18954
19024
  const mousePos = stage.getRelativePointerPosition();
18955
- const nodeHandler = this.instance.getNodeHandler("rectangle");
19025
+ const nodeHandler = this.instance.getNodeHandler("image");
18956
19026
  this.tempImageId = v4_default();
19027
+ const aspectRatio = this.preloadImgs[this.imageId].width / this.preloadImgs[this.imageId].height;
18957
19028
  const node = nodeHandler.create(this.tempImageId, {
18958
- ...this.props,
18959
19029
  x: (mousePos?.x ?? 0) + 5,
18960
19030
  y: (mousePos?.y ?? 0) + 5,
18961
- width: this.preloadImgs[this.imageId].width,
18962
- height: this.preloadImgs[this.imageId].height,
18963
- fill: "#ccccccff",
19031
+ width: 100 * aspectRatio,
19032
+ height: 100,
19033
+ opacity: 1,
19034
+ imageURL: this.imageURL,
18964
19035
  stroke: "#000000ff",
18965
- strokeWidth: 1
19036
+ strokeWidth: 0,
19037
+ strokeScaleEnabled: false,
19038
+ listening: false
18966
19039
  });
18967
19040
  this.instance.addNode(node, this.container?.getAttrs().id);
18968
19041
  }
@@ -19004,6 +19077,8 @@ var WeaveImageToolAction = class extends WeaveAction {
19004
19077
  if (!this.instance) throw new Error("Instance not defined");
19005
19078
  if (!this.initialized) this.setupEvents();
19006
19079
  this.cancelAction = cancelAction;
19080
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
19081
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
19007
19082
  if (params?.imageURL) {
19008
19083
  this.loadImage(params.imageURL);
19009
19084
  return;
@@ -19012,23 +19087,6 @@ var WeaveImageToolAction = class extends WeaveAction {
19012
19087
  this.addImage();
19013
19088
  return { finishUploadCallback: this.loadImage.bind(this) };
19014
19089
  }
19015
- onPropsChange() {
19016
- const stage = this.instance?.getStage();
19017
- if (stage) {
19018
- const tempImage = this.instance.getStage().findOne(`#${this.tempImageId}`);
19019
- if (tempImage) {
19020
- tempImage.setAttrs({
19021
- ...this.props,
19022
- name: void 0,
19023
- fill: "#ccccccff",
19024
- stroke: "#000000ff",
19025
- strokeWidth: 1
19026
- });
19027
- const nodeHandler = this.instance.getNodeHandler("rectangle");
19028
- this.instance.updateNode(nodeHandler.serialize(tempImage));
19029
- }
19030
- }
19031
- }
19032
19090
  cleanup() {
19033
19091
  const stage = this.instance.getStage();
19034
19092
  if (this.imageId) delete this.preloadImgs[this.imageId];
@@ -19719,7 +19777,7 @@ const WEAVE_STAGE_ZOOM_KEY = "stageZoom";
19719
19777
  var WeaveStageZoomPlugin = class extends WeavePlugin {
19720
19778
  getLayerName = void 0;
19721
19779
  initLayer = void 0;
19722
- padding = 100;
19780
+ padding = 175;
19723
19781
  defaultStep = 3;
19724
19782
  constructor(params) {
19725
19783
  super();
@@ -19738,6 +19796,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
19738
19796
  ...config
19739
19797
  };
19740
19798
  if (!this.config.zoomSteps.includes(this.config.defaultZoom)) throw new Error(`Default zoom ${this.config.defaultZoom} is not in zoom steps`);
19799
+ this.isCtrlOrMetaPressed = false;
19741
19800
  this.actualStep = this.config.zoomSteps.findIndex((step) => step === this.config.defaultZoom);
19742
19801
  this.actualScale = this.config.zoomSteps[this.actualStep];
19743
19802
  this.defaultStep = this.actualStep;
@@ -19746,6 +19805,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
19746
19805
  return WEAVE_STAGE_ZOOM_KEY;
19747
19806
  }
19748
19807
  onInit() {
19808
+ this.initEvents();
19749
19809
  this.setZoom(this.config.zoomSteps[this.actualStep]);
19750
19810
  }
19751
19811
  setZoom(scale, centered = true) {
@@ -19894,6 +19954,19 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
19894
19954
  disable() {
19895
19955
  this.enabled = false;
19896
19956
  }
19957
+ initEvents() {
19958
+ window.addEventListener("keydown", (e) => {
19959
+ if (e.ctrlKey || e.metaKey) this.isCtrlOrMetaPressed = true;
19960
+ });
19961
+ window.addEventListener("keyup", (e) => {
19962
+ if (!(e.ctrlKey || e.metaKey)) this.isCtrlOrMetaPressed = false;
19963
+ });
19964
+ window.addEventListener("wheel", (e) => {
19965
+ if (!this.enabled || !this.isCtrlOrMetaPressed) return;
19966
+ if (e.deltaY > 0) this.zoomOut();
19967
+ if (e.deltaY < 0) this.zoomIn();
19968
+ });
19969
+ }
19897
19970
  };
19898
19971
 
19899
19972
  //#endregion
@@ -20275,6 +20348,8 @@ var WeaveRectangleToolAction = class extends WeaveAction {
20275
20348
  stage.container().tabIndex = 1;
20276
20349
  stage.container().focus();
20277
20350
  this.cancelAction = cancelAction;
20351
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
20352
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
20278
20353
  this.props = this.initProps();
20279
20354
  this.addRectangle();
20280
20355
  }
@@ -20487,6 +20562,8 @@ var WeavePenToolAction = class extends WeaveAction {
20487
20562
  stage.container().tabIndex = 1;
20488
20563
  stage.container().focus();
20489
20564
  this.cancelAction = cancelAction;
20565
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
20566
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
20490
20567
  this.props = this.initProps();
20491
20568
  this.addLine();
20492
20569
  }
@@ -20661,6 +20738,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
20661
20738
  stage.container().tabIndex = 1;
20662
20739
  stage.container().focus();
20663
20740
  this.cancelAction = cancel;
20741
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
20664
20742
  this.props = this.initProps();
20665
20743
  this.setState(BRUSH_TOOL_STATE.IDLE);
20666
20744
  stage.container().style.cursor = "crosshair";
@@ -20752,7 +20830,7 @@ var WeaveTextToolAction = class extends WeaveAction {
20752
20830
  text: "Your text here...",
20753
20831
  width: 300,
20754
20832
  fontSize: 20,
20755
- fontFamily: "NotoSansMono, monospace",
20833
+ fontFamily: "Arial, sans-serif",
20756
20834
  fill: "#000000ff",
20757
20835
  strokeEnabled: false,
20758
20836
  stroke: "#000000ff",
@@ -20771,11 +20849,19 @@ var WeaveTextToolAction = class extends WeaveAction {
20771
20849
  if (!this.instance) throw new Error("Instance not defined");
20772
20850
  if (!this.initialized) this.setupEvents();
20773
20851
  this.cancelAction = cancelAction;
20852
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
20853
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
20774
20854
  this.addText();
20775
20855
  }
20776
20856
  cleanup() {
20777
20857
  const stage = this.instance.getStage();
20778
20858
  stage.container().style.cursor = "default";
20859
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
20860
+ if (selectionPlugin) {
20861
+ const node$1 = stage.findOne(`#${this.textId}`);
20862
+ if (node$1) selectionPlugin.setSelectedNodes([node$1]);
20863
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
20864
+ }
20779
20865
  const node = stage.findOne(`#${this.textId}`);
20780
20866
  if (node) node.getAttr("triggerEditMode")(node);
20781
20867
  this.initialCursor = null;
@@ -20873,6 +20959,8 @@ var WeaveFrameToolAction = class extends WeaveAction {
20873
20959
  stage.container().tabIndex = 1;
20874
20960
  stage.container().focus();
20875
20961
  this.cancelAction = cancelAction;
20962
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
20963
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
20876
20964
  this.props = this.initProps(params);
20877
20965
  this.addFrame();
20878
20966
  }
@@ -20995,6 +21083,9 @@ const WEAVE_GRID_LAYER_ID = "gridLayer";
20995
21083
 
20996
21084
  //#endregion
20997
21085
  //#region src/plugins/stage-grid/stage-grid.ts
21086
+ function isZeroOrClose(value, tolerance = 1e-6) {
21087
+ return Math.abs(value) <= tolerance;
21088
+ }
20998
21089
  var WeaveStageGridPlugin = class extends WeavePlugin {
20999
21090
  constructor(params) {
21000
21091
  super();
@@ -21030,10 +21121,10 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
21030
21121
  }
21031
21122
  initEvents() {
21032
21123
  const stage = this.instance.getStage();
21033
- stage.container().addEventListener("keydown", (e) => {
21124
+ window.addEventListener("keydown", (e) => {
21034
21125
  if (e.code === "Space") this.isSpaceKeyPressed = true;
21035
21126
  });
21036
- stage.container().addEventListener("keyup", (e) => {
21127
+ window.addEventListener("keyup", (e) => {
21037
21128
  if (e.code === "Space") this.isSpaceKeyPressed = false;
21038
21129
  });
21039
21130
  stage.on("mousedown", (e) => {
@@ -21104,40 +21195,48 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
21104
21195
  if (!layer) return;
21105
21196
  const stage = this.instance.getStage();
21106
21197
  const stageXRound = this.round(stage.x(), this.config.gridSize) * -1;
21198
+ const overflowX = this.round(10 * this.config.gridSize, this.config.gridSize);
21199
+ const overflowY = this.round(10 * this.config.gridSize, this.config.gridSize);
21107
21200
  const pointsX = [];
21108
- for (let i = stageXRound; i < stageXRound + stage.width(); i += this.config.gridSize) pointsX.push(i / stage.scaleX());
21201
+ for (let i = stageXRound - overflowX; i < stageXRound + stage.width() + overflowX; i += this.config.gridSize) pointsX.push({
21202
+ real: i / stage.scaleX(),
21203
+ ref: i
21204
+ });
21109
21205
  const stageYRound = this.round(stage.y(), this.config.gridSize) * -1;
21110
21206
  const pointsY = [];
21111
- for (let i = stageYRound; i < stageYRound + stage.height(); i += this.config.gridSize) pointsY.push(i / stage.scaleY());
21207
+ for (let i = stageYRound - overflowY; i < stageYRound + stage.height() + overflowY; i += this.config.gridSize) pointsY.push({
21208
+ real: i / stage.scaleY(),
21209
+ ref: i
21210
+ });
21112
21211
  for (let index = 0; index < pointsX.length; index++) {
21113
- const point = pointsX[index];
21212
+ const { real: point, ref } = pointsX[index];
21114
21213
  let color = this.config.gridColor;
21115
21214
  if (point === 0) color = this.config.gridOriginColor;
21116
21215
  layer.add(new konva_lib_shapes_Line.Line({
21117
21216
  points: [
21118
21217
  point,
21119
- (-stage.y() - 2 * this.config.gridSize) / stage.scaleY(),
21218
+ (-stage.y() - overflowY) / stage.scaleY(),
21120
21219
  point,
21121
- (stage.height() - stage.y() + 2 * this.config.gridSize) / stage.scaleY()
21220
+ (-stage.y() + stage.height() + overflowY) / stage.scaleY()
21122
21221
  ],
21123
21222
  stroke: color,
21124
- strokeWidth: (point % (10 * (this.config.gridSize / stage.scaleX())) === 0 ? 2.5 : .5) / stage.scaleX(),
21223
+ strokeWidth: (isZeroOrClose(ref % (10 * this.config.gridSize)) ? 2.5 : .5) / stage.scaleX(),
21125
21224
  listening: false
21126
21225
  }));
21127
21226
  }
21128
21227
  for (let index = 0; index < pointsY.length; index++) {
21129
- const point = pointsY[index];
21228
+ const { real: point, ref } = pointsY[index];
21130
21229
  let color = this.config.gridColor;
21131
21230
  if (point === 0) color = this.config.gridOriginColor;
21132
21231
  layer.add(new konva_lib_shapes_Line.Line({
21133
21232
  points: [
21134
- (-stage.x() - 2 * this.config.gridSize) / stage.scaleX(),
21233
+ (-stage.x() - overflowX) / stage.scaleX(),
21135
21234
  point,
21136
- (stage.width() - stage.x() + 2 * this.config.gridSize) / stage.scaleX(),
21235
+ (-stage.x() + stage.width() + overflowX) / stage.scaleX(),
21137
21236
  point
21138
21237
  ],
21139
21238
  stroke: color,
21140
- strokeWidth: (point % (10 * (this.config.gridSize / stage.scaleY())) === 0 ? 2.5 : .5) / stage.scaleX(),
21239
+ strokeWidth: (isZeroOrClose(ref % (10 * this.config.gridSize)) ? 2.5 : .5) / stage.scaleX(),
21141
21240
  listening: false
21142
21241
  }));
21143
21242
  }
@@ -21146,18 +21245,26 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
21146
21245
  const layer = this.getLayer();
21147
21246
  if (!layer) return;
21148
21247
  const stage = this.instance.getStage();
21248
+ const overflowX = 10 * this.config.gridSize;
21249
+ const overflowY = 10 * this.config.gridSize;
21149
21250
  const stageXRound = this.round(stage.x(), this.config.gridSize) * -1;
21150
21251
  const pointsX = [];
21151
- for (let i = stageXRound; i < stageXRound + stage.width(); i += this.config.gridSize) pointsX.push(i / stage.scaleX());
21252
+ for (let i = stageXRound - overflowX; i < stageXRound + stage.width() + overflowX; i += this.config.gridSize) pointsX.push({
21253
+ real: i / stage.scaleX(),
21254
+ ref: i
21255
+ });
21152
21256
  const stageYRound = this.round(stage.y(), this.config.gridSize) * -1;
21153
21257
  const pointsY = [];
21154
- for (let i = stageYRound; i < stageYRound + stage.height(); i += this.config.gridSize) pointsY.push(i / stage.scaleY());
21258
+ for (let i = stageYRound - overflowY; i < stageYRound + stage.height() + overflowY; i += this.config.gridSize) pointsY.push({
21259
+ real: i / stage.scaleY(),
21260
+ ref: i
21261
+ });
21155
21262
  for (let indexX = 0; indexX < pointsX.length; indexX++) {
21156
- const pointX = pointsX[indexX];
21263
+ const { real: pointX, ref: refX } = pointsX[indexX];
21157
21264
  for (let indexY = 0; indexY < pointsY.length; indexY++) {
21158
- const pointY = pointsY[indexY];
21265
+ const { real: pointY, ref: refY } = pointsY[indexY];
21159
21266
  let color = this.config.gridColor;
21160
- if (pointX === 0 || pointY === 0) color = this.config.gridOriginColor;
21267
+ if (refX === 0 || refY === 0) color = this.config.gridOriginColor;
21161
21268
  layer.add(new konva_lib_shapes_Circle.Circle({
21162
21269
  x: pointX,
21163
21270
  y: pointY,
@@ -21206,6 +21313,7 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
21206
21313
  this.enabled = true;
21207
21314
  this.moveToolActive = false;
21208
21315
  this.isMouseMiddleButtonPressed = false;
21316
+ this.isCtrlOrMetaPressed = false;
21209
21317
  this.isSpaceKeyPressed = false;
21210
21318
  this.previousPointer = null;
21211
21319
  }
@@ -21233,13 +21341,15 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
21233
21341
  let previousMouseX = Infinity;
21234
21342
  let previousMouseY = Infinity;
21235
21343
  const stage = this.instance.getStage();
21236
- stage.container().addEventListener("keydown", (e) => {
21344
+ window.addEventListener("keydown", (e) => {
21345
+ if (e.ctrlKey || e.metaKey) this.isCtrlOrMetaPressed = true;
21237
21346
  if (e.code === "Space") {
21238
21347
  this.isSpaceKeyPressed = true;
21239
21348
  this.enableMove();
21240
21349
  }
21241
21350
  });
21242
- stage.container().addEventListener("keyup", (e) => {
21351
+ window.addEventListener("keyup", (e) => {
21352
+ if (e.ctrlKey || e.metaKey) this.isCtrlOrMetaPressed = false;
21243
21353
  if (e.code === "Space") {
21244
21354
  this.isSpaceKeyPressed = false;
21245
21355
  this.disableMove();
@@ -21289,6 +21399,7 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
21289
21399
  if (!this.enabled || !(this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed || this.moveToolActive)) return;
21290
21400
  stage.x(stage.x() - deltaX);
21291
21401
  stage.y(stage.y() - deltaY);
21402
+ this.instance.emit("onStageMove", void 0);
21292
21403
  });
21293
21404
  stage.on("touchstart", (e) => {
21294
21405
  e.evt.preventDefault();
@@ -21310,12 +21421,13 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
21310
21421
  if (!this.enabled) return;
21311
21422
  stage.x(stage.x() - deltaX);
21312
21423
  stage.y(stage.y() - deltaY);
21424
+ this.instance.emit("onStageMove", void 0);
21313
21425
  });
21314
- stage.on("wheel", (e) => {
21315
- e.evt.preventDefault();
21316
- if (!this.enabled || this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed) return;
21317
- stage.x(stage.x() - e.evt.deltaX);
21318
- stage.y(stage.y() - e.evt.deltaY);
21426
+ window.addEventListener("wheel", (e) => {
21427
+ if (!this.enabled || this.isCtrlOrMetaPressed || this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed) return;
21428
+ stage.x(stage.x() - e.deltaX);
21429
+ stage.y(stage.y() - e.deltaY);
21430
+ this.instance.emit("stageMove", void 0);
21319
21431
  });
21320
21432
  }
21321
21433
  enable() {
@@ -21442,9 +21554,7 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21442
21554
  constructor(params) {
21443
21555
  super();
21444
21556
  const { config } = params;
21445
- this.renderCursors = true;
21446
21557
  this.usersPointers = {};
21447
- this.usersPointersTimers = {};
21448
21558
  this.config = config;
21449
21559
  }
21450
21560
  getName() {
@@ -21455,9 +21565,15 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21455
21565
  }
21456
21566
  initLayer() {
21457
21567
  const stage = this.instance.getStage();
21458
- const layer = new konva.default.Layer({ id: this.getLayerName() });
21568
+ const layer = new konva.default.Layer({
21569
+ id: this.getLayerName(),
21570
+ listening: false
21571
+ });
21459
21572
  stage.add(layer);
21460
21573
  }
21574
+ onRender() {
21575
+ this.renderPointers();
21576
+ }
21461
21577
  getLayer() {
21462
21578
  const stage = this.instance.getStage();
21463
21579
  return stage.findOne(`#${WEAVE_USERS_POINTERS_LAYER_ID}`);
@@ -21467,10 +21583,12 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21467
21583
  const stage = this.instance.getStage();
21468
21584
  this.instance.addEventListener("onAwarenessChange", (changes) => {
21469
21585
  const selfUser = this.config.getUser();
21586
+ const allActiveUsers = [];
21470
21587
  for (const change of changes) {
21471
21588
  if (!change[WEAVE_USER_POINTER_KEY]) continue;
21472
21589
  if (change[WEAVE_USER_POINTER_KEY] && selfUser.name !== change[WEAVE_USER_POINTER_KEY].user) {
21473
21590
  const userPointer = change[WEAVE_USER_POINTER_KEY];
21591
+ allActiveUsers.push(userPointer.user);
21474
21592
  this.usersPointers[userPointer.user] = {
21475
21593
  oldPos: this.usersPointers[userPointer.user]?.actualPos ?? {
21476
21594
  user: userPointer.user,
@@ -21481,6 +21599,17 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21481
21599
  };
21482
21600
  }
21483
21601
  }
21602
+ const allActiveUsersPointers = Object.keys(this.usersPointers).map((userPointerKey) => {
21603
+ const pointerInfo = this.usersPointers[userPointerKey];
21604
+ return pointerInfo.actualPos.user;
21605
+ });
21606
+ const inactivePointers = import_lodash.default.differenceWith(allActiveUsersPointers, allActiveUsers, import_lodash.default.isEqual);
21607
+ const pointersLayer = this.getLayer();
21608
+ for (const inactivePointer of inactivePointers) {
21609
+ const userPointerNode = pointersLayer?.findOne(`#${inactivePointer}`);
21610
+ if (userPointerNode) userPointerNode.destroy();
21611
+ delete this.usersPointers[inactivePointer];
21612
+ }
21484
21613
  this.renderPointers();
21485
21614
  });
21486
21615
  stage.on("dragmove", (e) => {
@@ -21503,9 +21632,7 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21503
21632
  y: mousePos.y
21504
21633
  });
21505
21634
  });
21506
- this.instance.addEventListener("onZoomChange", () => {
21507
- this.renderPointers();
21508
- });
21635
+ this.renderPointers();
21509
21636
  }
21510
21637
  stringToColour(str) {
21511
21638
  let hash = 0;
@@ -21519,29 +21646,16 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21519
21646
  }
21520
21647
  return colour;
21521
21648
  }
21522
- setUserMovementTimer(userPointer) {
21523
- const pointersLayer = this.getLayer();
21524
- if (this.usersPointersTimers[`${userPointer.user}-opacity`]) clearTimeout(this.usersPointersTimers[`${userPointer.user}-opacity`]);
21525
- this.usersPointersTimers[`${userPointer.user}-opacity`] = setTimeout(() => {
21526
- const userPointerNode = pointersLayer?.findOne(`#${userPointer.user}`);
21527
- if (userPointerNode) userPointerNode.opacity(.5);
21528
- }, 5e3);
21529
- if (this.usersPointersTimers[`${userPointer.user}-destroy`]) clearTimeout(this.usersPointersTimers[`${userPointer.user}-destroy`]);
21530
- this.usersPointersTimers[`${userPointer.user}-destroy`] = setTimeout(() => {
21531
- const userPointerNode = pointersLayer?.findOne(`#${userPointer.user}`);
21532
- if (userPointerNode) userPointerNode.destroy();
21533
- }, 3e4);
21534
- }
21535
21649
  renderPointers() {
21536
21650
  const stage = this.instance.getStage();
21537
21651
  const pointersLayer = this.getLayer();
21538
- pointersLayer?.clear();
21539
21652
  if (!this.enabled) return;
21540
- if (this.renderCursors) for (const userPointerKey of Object.keys(this.usersPointers)) {
21653
+ for (const userPointerKey of Object.keys(this.usersPointers)) {
21541
21654
  const userPointer = this.usersPointers[userPointerKey];
21542
21655
  const userPointerNode = pointersLayer?.findOne(`#${userPointer.actualPos.user}`);
21543
21656
  if (!userPointerNode) {
21544
21657
  const userPointerNode$1 = new konva.default.Group({
21658
+ name: "pointer",
21545
21659
  id: userPointer.actualPos.user,
21546
21660
  x: userPointer.actualPos.x,
21547
21661
  y: userPointer.actualPos.y,
@@ -21587,7 +21701,6 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21587
21701
  userPointerNode$1.add(userNameBackground);
21588
21702
  userPointerNode$1.add(userNameNode);
21589
21703
  pointersLayer?.add(userPointerNode$1);
21590
- this.setUserMovementTimer(userPointer.actualPos);
21591
21704
  continue;
21592
21705
  }
21593
21706
  const oldPos = {
@@ -21620,22 +21733,13 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21620
21733
  height: userPointNodeText[0]?.height() + this.userPointerBackgroundPaddingY * 2
21621
21734
  });
21622
21735
  userPointNode[0]?.setAttrs({ y: userPointNodeBackground[0]?.y() + userPointNodeBackground[0]?.height() / 2 });
21623
- if (hasChanged) {
21624
- userPointerNode.setAttrs({
21625
- x: userPointer.actualPos.x,
21626
- y: userPointer.actualPos.y,
21627
- opacity: 1
21628
- });
21629
- if (hasChanged) this.setUserMovementTimer(userPointer.actualPos);
21630
- }
21736
+ if (hasChanged) userPointerNode.setAttrs({
21737
+ x: userPointer.actualPos.x,
21738
+ y: userPointer.actualPos.y,
21739
+ opacity: 1
21740
+ });
21631
21741
  }
21632
21742
  }
21633
- toggleRenderCursors() {
21634
- this.renderCursors = !this.renderCursors;
21635
- }
21636
- setRenderCursors(render) {
21637
- this.renderCursors = render;
21638
- }
21639
21743
  enable() {
21640
21744
  this.getLayer()?.show();
21641
21745
  this.enabled = true;