@inditextech/weave-sdk 0.19.0 → 0.20.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.js CHANGED
@@ -1,6 +1,7 @@
1
+ import "./node-extensions.d-Q3CaoYb8.d.ts";
1
2
  import Konva from "konva";
2
3
  import "konva/lib/types";
3
- import { WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FILE_FORMAT, WEAVE_EXPORT_FORMATS, WEAVE_INSTANCE_STATUS, WEAVE_NODE_CUSTOM_EVENTS, WEAVE_NODE_LAYER_ID, WEAVE_NODE_POSITION, WEAVE_UTILITY_LAYER_ID } from "@inditextech/weave-types";
4
+ import { WEAVE_AWARENESS_LAYER_ID, WEAVE_DEFAULT_TRANSFORM_PROPERTIES, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FILE_FORMAT, WEAVE_EXPORT_FORMATS, WEAVE_INSTANCE_STATUS, WEAVE_NODE_CUSTOM_EVENTS, WEAVE_NODE_LAYER_ID, WEAVE_NODE_POSITION, WEAVE_UTILITY_LAYER_ID } from "@inditextech/weave-types";
4
5
  import { getYjsDoc, getYjsValue, observeDeep, syncedStore } from "@syncedstore/core";
5
6
  import { Doc, UndoManager } from "yjs";
6
7
  import React from "react";
@@ -15802,43 +15803,70 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15802
15803
  constructor(params) {
15803
15804
  super();
15804
15805
  const { config } = params ?? {};
15805
- this.config = { transformer: {
15806
- rotationSnaps: [
15807
- 0,
15808
- 45,
15809
- 90,
15810
- 135,
15811
- 180,
15812
- 225,
15813
- 270,
15814
- 315,
15815
- 360
15816
- ],
15817
- rotationSnapTolerance: 3,
15818
- ignoreStroke: true,
15819
- flipEnabled: false,
15820
- keepRatio: false,
15821
- useSingleNodeRotation: true,
15822
- shouldOverdrawWholeArea: true,
15823
- anchorStyleFunc: (anchor) => {
15824
- anchor.stroke("#27272aff");
15825
- anchor.cornerRadius(12);
15826
- if (anchor.hasName("top-center") || anchor.hasName("bottom-center")) {
15827
- anchor.height(8);
15828
- anchor.offsetY(4);
15829
- anchor.width(32);
15830
- anchor.offsetX(16);
15831
- }
15832
- if (anchor.hasName("middle-left") || anchor.hasName("middle-right")) {
15833
- anchor.height(32);
15834
- anchor.offsetY(16);
15835
- anchor.width(8);
15836
- anchor.offsetX(4);
15837
- }
15806
+ this.config = {
15807
+ transformer: {
15808
+ rotationSnaps: [
15809
+ 0,
15810
+ 45,
15811
+ 90,
15812
+ 135,
15813
+ 180,
15814
+ 225,
15815
+ 270,
15816
+ 315,
15817
+ 360
15818
+ ],
15819
+ rotationSnapTolerance: 3,
15820
+ ignoreStroke: true,
15821
+ flipEnabled: false,
15822
+ keepRatio: false,
15823
+ useSingleNodeRotation: true,
15824
+ shouldOverdrawWholeArea: true,
15825
+ enabledAnchors: [
15826
+ "top-left",
15827
+ "top-center",
15828
+ "top-right",
15829
+ "middle-right",
15830
+ "middle-left",
15831
+ "bottom-left",
15832
+ "bottom-center",
15833
+ "bottom-right"
15834
+ ],
15835
+ anchorStyleFunc: (anchor) => {
15836
+ anchor.stroke("#27272aff");
15837
+ anchor.cornerRadius(12);
15838
+ if (anchor.hasName("top-center") || anchor.hasName("bottom-center")) {
15839
+ anchor.height(8);
15840
+ anchor.offsetY(4);
15841
+ anchor.width(32);
15842
+ anchor.offsetX(16);
15843
+ }
15844
+ if (anchor.hasName("middle-left") || anchor.hasName("middle-right")) {
15845
+ anchor.height(32);
15846
+ anchor.offsetY(16);
15847
+ anchor.width(8);
15848
+ anchor.offsetX(4);
15849
+ }
15850
+ },
15851
+ borderStroke: "#0074ffcc",
15852
+ ...config?.transformer
15838
15853
  },
15839
- borderStroke: "#1e40afff",
15840
- ...config?.transformer
15841
- } };
15854
+ transformations: {
15855
+ singleSelection: { enabled: true },
15856
+ multipleSelection: { enabled: false },
15857
+ ...config?.transformations
15858
+ }
15859
+ };
15860
+ this.defaultEnabledAnchors = this.config.transformer?.enabledAnchors ?? [
15861
+ "top-left",
15862
+ "top-center",
15863
+ "top-right",
15864
+ "middle-right",
15865
+ "middle-left",
15866
+ "bottom-left",
15867
+ "bottom-center",
15868
+ "bottom-right"
15869
+ ];
15842
15870
  this.active = false;
15843
15871
  this.cameFromSelectingMultiple = false;
15844
15872
  this.selecting = false;
@@ -15901,21 +15929,47 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15901
15929
  e.cancelBubble = true;
15902
15930
  }
15903
15931
  });
15932
+ tr.on("transformstart", () => {
15933
+ this.triggerSelectedNodesEvent();
15934
+ });
15935
+ tr.on("transform", () => {
15936
+ this.triggerSelectedNodesEvent();
15937
+ });
15938
+ tr.on("transformend", () => {
15939
+ this.triggerSelectedNodesEvent();
15940
+ });
15941
+ tr.on("dragstart", (e) => {
15942
+ for (const node of tr.nodes()) node.updatePosition(e.target.getAbsolutePosition());
15943
+ tr.forceUpdate();
15944
+ e.cancelBubble = true;
15945
+ });
15904
15946
  tr.on("dragmove", (e) => {
15947
+ for (const node of tr.nodes()) node.updatePosition(e.target.getAbsolutePosition());
15948
+ e.cancelBubble = true;
15905
15949
  if (this.isSelecting() && tr.nodes().length > 1) {
15906
15950
  clearContainerTargets(this.instance);
15907
15951
  const layerToMove = checkIfOverContainer(this.instance, e.target);
15908
15952
  if (layerToMove) layerToMove.fire(WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
15953
+ for (const node of tr.nodes()) {
15954
+ const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
15955
+ this.instance.updateNode(nodeHandler.serialize(node));
15956
+ }
15909
15957
  }
15958
+ tr.forceUpdate();
15910
15959
  });
15911
- tr.on("dragend", () => {
15960
+ tr.on("dragend", (e) => {
15961
+ for (const node of tr.nodes()) node.updatePosition(e.target.getAbsolutePosition());
15962
+ e.cancelBubble = true;
15912
15963
  if (this.isSelecting() && tr.nodes().length > 1) {
15913
15964
  clearContainerTargets(this.instance);
15914
15965
  for (const node of tr.nodes()) {
15915
15966
  const layerToMove = moveNodeToContainer(this.instance, node);
15916
15967
  if (layerToMove) continue;
15968
+ const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
15969
+ this.instance.updateNode(nodeHandler.serialize(node));
15917
15970
  }
15918
15971
  }
15972
+ tr.forceUpdate();
15919
15973
  });
15920
15974
  this.tr = tr;
15921
15975
  this.selectionRectangle = selectionRectangle;
@@ -16040,7 +16094,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16040
16094
  });
16041
16095
  const box = this.selectionRectangle.getClientRect();
16042
16096
  const selected = shapes.filter((shape) => {
16043
- const parent = this.instance.getInstanceRecursive(shape.getParent());
16097
+ let parent = this.instance.getInstanceRecursive(shape.getParent());
16098
+ if (parent.getAttrs().nodeId) parent = this.instance.getStage().findOne(`#${parent.getAttrs().nodeId}`);
16044
16099
  if (shape.getAttrs().nodeType && shape.getAttrs().nodeType === "frame") {
16045
16100
  const frameBox = shape.getClientRect();
16046
16101
  const isContained = frameBox.x >= box.x && frameBox.y >= box.y && frameBox.x + frameBox.width <= box.x + box.width && frameBox.y + frameBox.height <= box.y + box.height;
@@ -16089,36 +16144,45 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16089
16144
  if (contextMenuPlugin && !contextMenuPlugin.isTapHold()) this.instance.emitEvent("onStageSelection");
16090
16145
  return;
16091
16146
  }
16092
- const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
16093
- const isSelected = this.tr.nodes().indexOf(e.target) >= 0;
16094
16147
  let areNodesSelected = false;
16095
- let nodeToAdd = selectedGroup && !(selectedGroup.getAttrs().active ?? false) ? selectedGroup : e.target;
16096
- if (nodeToAdd.getParent() instanceof Konva.Transformer) {
16148
+ let nodeTargeted = selectedGroup && !(selectedGroup.getAttrs().active ?? false) ? selectedGroup : e.target;
16149
+ if (nodeTargeted.getParent() instanceof Konva.Transformer) {
16097
16150
  const intersections = stage.getAllIntersections(mousePos);
16098
16151
  const nodesIntersected = intersections.filter((ele) => ele.getAttrs().nodeType);
16099
16152
  let targetNode = null;
16100
16153
  if (nodesIntersected.length > 0) targetNode = this.instance.getInstanceRecursive(nodesIntersected[nodesIntersected.length - 1]);
16101
- if (targetNode && targetNode.getAttrs().nodeType) {
16102
- this.tr.nodes([]);
16103
- this.triggerSelectedNodesEvent();
16104
- nodeToAdd = targetNode;
16105
- }
16154
+ if (targetNode && targetNode.getAttrs().nodeType) nodeTargeted = targetNode;
16106
16155
  }
16107
- if (!nodeToAdd.getAttrs().nodeType) return;
16108
- if (!metaPressed && !isSelected) {
16109
- this.tr.nodes([nodeToAdd]);
16156
+ if (!nodeTargeted.getAttrs().nodeType) return;
16157
+ let nodesSelected = 0;
16158
+ const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
16159
+ const nodeSelectedIndex = this.tr.nodes().findIndex((node) => {
16160
+ return node.getAttrs().id === nodeTargeted.getAttrs().id;
16161
+ });
16162
+ const isSelected = nodeSelectedIndex !== -1;
16163
+ if (!metaPressed) {
16164
+ this.tr.nodes([nodeTargeted]);
16165
+ nodesSelected = this.tr.nodes().length;
16110
16166
  this.tr.show();
16111
16167
  areNodesSelected = true;
16112
16168
  } else if (metaPressed && isSelected) {
16113
16169
  const nodes = this.tr.nodes().slice();
16114
- nodes.splice(nodes.indexOf(nodeToAdd), 1);
16170
+ nodes.splice(nodes.indexOf(nodeTargeted), 1);
16115
16171
  this.tr.nodes(nodes);
16172
+ nodesSelected = this.tr.nodes().length;
16116
16173
  areNodesSelected = true;
16117
16174
  } else if (metaPressed && !isSelected) {
16118
- const nodes = this.tr.nodes().concat([nodeToAdd]);
16175
+ const nodes = this.tr.nodes().concat([nodeTargeted]);
16119
16176
  this.tr.nodes(nodes);
16177
+ nodesSelected = this.tr.nodes().length;
16120
16178
  areNodesSelected = true;
16121
16179
  }
16180
+ if (nodesSelected > 1 && !this.config.transformations.multipleSelection.enabled || nodesSelected === 1 && !this.config.transformations.singleSelection.enabled) this.tr.enabledAnchors([]);
16181
+ if (nodesSelected > 1 && this.config.transformations.multipleSelection.enabled || nodesSelected === 1 && this.config.transformations.singleSelection.enabled) this.tr.enabledAnchors(this.defaultEnabledAnchors);
16182
+ if (nodesSelected === 1) {
16183
+ this.tr.setAttrs({ ...nodeTargeted.getTransformerProperties() });
16184
+ this.tr.forceUpdate();
16185
+ }
16122
16186
  if (areNodesSelected) {
16123
16187
  stage.container().tabIndex = 1;
16124
16188
  stage.container().focus();
@@ -16132,6 +16196,13 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16132
16196
  }
16133
16197
  setSelectedNodes(nodes) {
16134
16198
  this.tr.setNodes(nodes);
16199
+ const nodesSelected = nodes.length;
16200
+ if (nodesSelected > 1 && !this.config.transformations.multipleSelection.enabled || nodesSelected === 1 && !this.config.transformations.singleSelection.enabled) this.tr.enabledAnchors([]);
16201
+ if (nodesSelected > 1 && this.config.transformations.multipleSelection.enabled || nodesSelected === 1 && this.config.transformations.singleSelection.enabled) this.tr.enabledAnchors(this.defaultEnabledAnchors);
16202
+ if (nodesSelected === 1) {
16203
+ this.tr.setAttrs({ ...nodes[0].getTransformerProperties() });
16204
+ this.tr.forceUpdate();
16205
+ }
16135
16206
  this.triggerSelectedNodesEvent();
16136
16207
  }
16137
16208
  getSelectedNodes() {
@@ -16383,6 +16454,16 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16383
16454
 
16384
16455
  //#endregion
16385
16456
  //#region src/nodes/node.ts
16457
+ const setNodesDefaultConfiguration = (config) => {
16458
+ const { transform } = config ?? {};
16459
+ Konva.Node.prototype.getTransformerProperties = function() {
16460
+ return {
16461
+ WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
16462
+ ...transform
16463
+ };
16464
+ };
16465
+ Konva.Node.prototype.updatePosition = function() {};
16466
+ };
16386
16467
  var WeaveNode = class {
16387
16468
  register(instance) {
16388
16469
  this.instance = instance;
@@ -17002,11 +17083,11 @@ var WeaveGroupsManager = class {
17002
17083
  }, 0);
17003
17084
  }
17004
17085
  unGroup(group) {
17005
- this.logger.warn({ group }, "Un-grouping group");
17086
+ this.logger.debug({ group }, "Un-grouping group");
17006
17087
  const stage = this.instance.getStage();
17007
17088
  const konvaGroup = stage.findOne(`#${group.props.id}`);
17008
17089
  if (!konvaGroup) {
17009
- this.logger.warn({ group }, "Group instance doesn't exists, cannot un-group");
17090
+ this.logger.debug({ group }, "Group instance doesn't exists, cannot un-group");
17010
17091
  return;
17011
17092
  }
17012
17093
  let nodeId = void 0;
@@ -17018,7 +17099,7 @@ var WeaveGroupsManager = class {
17018
17099
  if (konvaGroup.getParent() && konvaGroup.getParent() instanceof Konva.Group && !konvaGroup.getParent()?.getAttrs().nodeId) newLayer = konvaGroup.getParent();
17019
17100
  if (konvaGroup.getParent() && konvaGroup.getParent() instanceof Konva.Layer) newLayer = konvaGroup.getParent();
17020
17101
  if (!newLayer) {
17021
- this.logger.warn({ group }, "Group target container doesn't exists, cannot un-group");
17102
+ this.logger.debug({ group }, "Group target container doesn't exists, cannot un-group");
17022
17103
  return;
17023
17104
  }
17024
17105
  const newLayerChildrenAmount = newLayer?.getChildren().length ?? 0;
@@ -17304,9 +17385,10 @@ var WeaveCloningManager = class {
17304
17385
  const serializedNodes = [];
17305
17386
  newGroup.getChildren().forEach((node) => {
17306
17387
  const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
17307
- if (node.x() < minPoint.x || node.y() < minPoint.y) {
17308
- minPoint.x = node.x();
17309
- minPoint.y = node.y();
17388
+ const nodePos = node.getClientRect();
17389
+ if (nodePos.x < minPoint.x || nodePos.y < minPoint.y) {
17390
+ minPoint.x = nodePos.x;
17391
+ minPoint.y = nodePos.y;
17310
17392
  }
17311
17393
  const serialized = nodeHandler.serialize(node);
17312
17394
  serializedNodes.push(serialized);
@@ -17943,7 +18025,7 @@ var WeaveRegisterManager = class {
17943
18025
 
17944
18026
  //#endregion
17945
18027
  //#region package.json
17946
- var version = "0.19.0";
18028
+ var version = "0.20.0";
17947
18029
 
17948
18030
  //#endregion
17949
18031
  //#region src/managers/setup.ts
@@ -18354,6 +18436,7 @@ var Weave = class extends Emittery {
18354
18436
  this.status = WEAVE_INSTANCE_STATUS.STARTING;
18355
18437
  this.emitEvent("onInstanceStatus", this.status);
18356
18438
  this.registerManager.registerNodesHandlers();
18439
+ this.setNodesDefaultConfiguration();
18357
18440
  this.registerManager.registerPlugins();
18358
18441
  this.registerManager.registerActionsHandlers();
18359
18442
  this.storeManager.registerStore(this.config.store);
@@ -18383,6 +18466,9 @@ var Weave = class extends Emittery {
18383
18466
  getConfiguration() {
18384
18467
  return this.config;
18385
18468
  }
18469
+ setNodesDefaultConfiguration(config) {
18470
+ setNodesDefaultConfiguration(config);
18471
+ }
18386
18472
  emitEvent(event, payload) {
18387
18473
  this.moduleLogger.debug({ payload }, `Emitted event [${event}]`);
18388
18474
  this.emit(event, payload);
@@ -18654,11 +18740,22 @@ const WEAVE_GROUP_NODE_TYPE = "group";
18654
18740
  //#region src/nodes/group/group.ts
18655
18741
  var WeaveGroupNode = class extends WeaveNode {
18656
18742
  nodeType = WEAVE_GROUP_NODE_TYPE;
18743
+ constructor(params) {
18744
+ super();
18745
+ const { config } = params ?? {};
18746
+ this.config = { transform: {
18747
+ ...WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
18748
+ ...config?.transform
18749
+ } };
18750
+ }
18657
18751
  onRender(props) {
18658
18752
  const group = new Konva.Group({
18659
18753
  ...props,
18660
18754
  name: "node"
18661
18755
  });
18756
+ group.getTransformerProperties = () => {
18757
+ return this.config.transform;
18758
+ };
18662
18759
  this.setupDefaultNodeEvents(group);
18663
18760
  return group;
18664
18761
  }
@@ -18694,11 +18791,22 @@ const WEAVE_RECTANGLE_NODE_TYPE = "rectangle";
18694
18791
  //#region src/nodes/rectangle/rectangle.ts
18695
18792
  var WeaveRectangleNode = class extends WeaveNode {
18696
18793
  nodeType = WEAVE_RECTANGLE_NODE_TYPE;
18794
+ constructor(params) {
18795
+ super();
18796
+ const { config } = params ?? {};
18797
+ this.config = { transform: {
18798
+ ...WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
18799
+ ...config?.transform
18800
+ } };
18801
+ }
18697
18802
  onRender(props) {
18698
18803
  const rectangle = new Konva.Rect({
18699
18804
  ...props,
18700
18805
  name: "node"
18701
18806
  });
18807
+ rectangle.getTransformerProperties = () => {
18808
+ return this.config.transform;
18809
+ };
18702
18810
  this.setupDefaultNodeEvents(rectangle);
18703
18811
  return rectangle;
18704
18812
  }
@@ -18715,11 +18823,22 @@ const WEAVE_LINE_NODE_TYPE = "line";
18715
18823
  //#region src/nodes/line/line.ts
18716
18824
  var WeaveLineNode = class extends WeaveNode {
18717
18825
  nodeType = WEAVE_LINE_NODE_TYPE;
18826
+ constructor(params) {
18827
+ super();
18828
+ const { config } = params ?? {};
18829
+ this.config = { transform: {
18830
+ ...WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
18831
+ ...config?.transform
18832
+ } };
18833
+ }
18718
18834
  onRender(props) {
18719
18835
  const line = new Konva.Line({
18720
18836
  ...props,
18721
18837
  name: "node"
18722
18838
  });
18839
+ line.getTransformerProperties = () => {
18840
+ return this.config.transform;
18841
+ };
18723
18842
  this.setupDefaultNodeEvents(line);
18724
18843
  return line;
18725
18844
  }
@@ -18759,8 +18878,13 @@ const TEXT_LAYOUT = {
18759
18878
  var WeaveTextNode = class extends WeaveNode {
18760
18879
  nodeType = WEAVE_TEXT_NODE_TYPE;
18761
18880
  editing = false;
18762
- constructor() {
18881
+ constructor(params) {
18763
18882
  super();
18883
+ const { config } = params ?? {};
18884
+ this.config = { transform: {
18885
+ ...WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
18886
+ ...config?.transform
18887
+ } };
18764
18888
  this.editing = false;
18765
18889
  }
18766
18890
  updateNode(nodeInstance) {
@@ -18774,6 +18898,9 @@ var WeaveTextNode = class extends WeaveNode {
18774
18898
  ...props,
18775
18899
  name: "node"
18776
18900
  });
18901
+ text.getTransformerProperties = () => {
18902
+ return this.config.transform;
18903
+ };
18777
18904
  text.setAttrs({ measureMultilineText: this.measureMultilineText(text) });
18778
18905
  this.setupDefaultNodeEvents(text);
18779
18906
  text.on("transform", (e) => {
@@ -18855,6 +18982,7 @@ var WeaveTextNode = class extends WeaveNode {
18855
18982
  const cleanedAttrs = { ...attrs };
18856
18983
  delete cleanedAttrs.draggable;
18857
18984
  delete cleanedAttrs.triggerEditMode;
18985
+ delete cleanedAttrs.measureMultilineText;
18858
18986
  return {
18859
18987
  key: attrs.id ?? "",
18860
18988
  type: attrs.nodeType,
@@ -19559,8 +19687,13 @@ const WEAVE_IMAGE_NODE_TYPE = "image";
19559
19687
  //#region src/nodes/image/image.ts
19560
19688
  var WeaveImageNode = class extends WeaveNode {
19561
19689
  nodeType = WEAVE_IMAGE_NODE_TYPE;
19562
- constructor() {
19690
+ constructor(params) {
19563
19691
  super();
19692
+ const { config } = params ?? {};
19693
+ this.config = { transform: {
19694
+ ...WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
19695
+ ...config?.transform
19696
+ } };
19564
19697
  this.imageLoaded = false;
19565
19698
  this.cropping = false;
19566
19699
  }
@@ -19581,6 +19714,9 @@ var WeaveImageNode = class extends WeaveNode {
19581
19714
  id,
19582
19715
  name: "node"
19583
19716
  });
19717
+ image.getTransformerProperties = () => {
19718
+ return this.config.transform;
19719
+ };
19584
19720
  const imagePlaceholder = new Konva.Rect({
19585
19721
  ...groupImageProps,
19586
19722
  id: `${id}-placeholder`,
@@ -19823,10 +19959,10 @@ const WEAVE_FRAME_NODE_SIZES = {
19823
19959
  };
19824
19960
  const WEAVE_FRAME_NODE_DEFAULT_CONFIG = {
19825
19961
  fontFamily: "Arial",
19826
- fontStyle: "normal",
19962
+ fontStyle: "bold",
19827
19963
  titleHeight: 30,
19828
19964
  borderColor: "#000000ff",
19829
- borderWidth: 2,
19965
+ borderWidth: 1,
19830
19966
  onTargetLeave: {
19831
19967
  borderColor: "#000000ff",
19832
19968
  fill: "#ffffffff"
@@ -19834,6 +19970,13 @@ const WEAVE_FRAME_NODE_DEFAULT_CONFIG = {
19834
19970
  onTargetEnter: {
19835
19971
  borderColor: "#ff6863ff",
19836
19972
  fill: "#ffffffff"
19973
+ },
19974
+ transform: {
19975
+ rotateEnabled: false,
19976
+ resizeEnabled: false,
19977
+ enabledAnchors: [],
19978
+ borderStrokeWidth: 3,
19979
+ padding: 0
19837
19980
  }
19838
19981
  };
19839
19982
  const WEAVE_FRAME_NODE_DEFAULT_PROPS = {
@@ -19886,34 +20029,42 @@ var WeaveFrameNode = class extends WeaveNode {
19886
20029
  containerOffsetX: 0,
19887
20030
  containerOffsetY: titleHeight,
19888
20031
  width: props.frameWidth,
19889
- height: props.frameHeight + titleHeight,
19890
- fill: "#ffffffff",
19891
- clipX: 0,
19892
- clipY: 0,
19893
- clipWidth: props.frameWidth,
19894
- clipHeight: props.frameHeight + titleHeight,
19895
- name: "node"
20032
+ height: props.frameHeight,
20033
+ fill: "transparent",
20034
+ draggable: false
20035
+ });
20036
+ const frameInternalGroup = new Konva.Group({
20037
+ id: `${id}-selector`,
20038
+ x: 0,
20039
+ y: 0,
20040
+ width: props.frameWidth,
20041
+ height: props.frameHeight,
20042
+ strokeScaleEnabled: false,
20043
+ draggable: false
19896
20044
  });
20045
+ frame.add(frameInternalGroup);
19897
20046
  const background = new Konva.Rect({
19898
20047
  id: `${id}-bg`,
19899
20048
  nodeId: id,
19900
20049
  x: 0,
19901
- y: titleHeight,
20050
+ y: 0,
19902
20051
  width: props.frameWidth,
19903
20052
  stroke: borderColor,
19904
20053
  strokeWidth: borderWidth,
19905
20054
  strokeScaleEnabled: false,
20055
+ shadowForStrokeEnabled: false,
19906
20056
  height: props.frameHeight,
19907
20057
  fill: "#ffffffff",
20058
+ listening: false,
19908
20059
  draggable: false
19909
20060
  });
19910
- frame.add(background);
20061
+ frameInternalGroup.add(background);
19911
20062
  const text = new Konva.Text({
19912
20063
  id: `${id}-title`,
19913
20064
  x: 0,
19914
- y: 0,
20065
+ y: -titleHeight,
19915
20066
  width: props.frameWidth,
19916
- height: titleHeight - 10,
20067
+ height: titleHeight,
19917
20068
  fontSize: 20,
19918
20069
  fontFamily,
19919
20070
  fontStyle,
@@ -19925,7 +20076,89 @@ var WeaveFrameNode = class extends WeaveNode {
19925
20076
  listening: false,
19926
20077
  draggable: false
19927
20078
  });
19928
- frame.add(text);
20079
+ frameInternalGroup.add(text);
20080
+ const selectorArea = new Konva.Rect({
20081
+ ...frameParams,
20082
+ id: `${id}-selector-area`,
20083
+ name: "node",
20084
+ nodeId: id,
20085
+ containerId: `${id}-group-internal`,
20086
+ x: 0,
20087
+ y: 0,
20088
+ strokeWidth: 0,
20089
+ strokeScaleEnabled: false,
20090
+ width: props.frameWidth,
20091
+ height: props.frameHeight,
20092
+ fill: "transparent",
20093
+ draggable: false
20094
+ });
20095
+ selectorArea.getTransformerProperties = () => {
20096
+ return this.config.transform;
20097
+ };
20098
+ selectorArea.updatePosition = (position) => {
20099
+ frame.setAbsolutePosition(position);
20100
+ selectorArea.setAttrs({
20101
+ x: 0,
20102
+ y: 0
20103
+ });
20104
+ this.instance.updateNode(this.serialize(selectorArea));
20105
+ };
20106
+ const updateFrame = (e) => {
20107
+ const selectorArea$1 = e.target;
20108
+ const stage = selectorArea$1.getStage();
20109
+ if (!stage) return;
20110
+ const absPos = selectorArea$1.getAbsolutePosition();
20111
+ const absRot = selectorArea$1.getAbsoluteRotation();
20112
+ const scaleX = selectorArea$1.scaleX();
20113
+ const scaleY = selectorArea$1.scaleY();
20114
+ selectorArea$1.x(0);
20115
+ selectorArea$1.y(0);
20116
+ frame.setAbsolutePosition(absPos);
20117
+ frame.rotation(absRot);
20118
+ frame.width(selectorArea$1.width());
20119
+ frame.height(selectorArea$1.height());
20120
+ frameInternalGroup.width(Math.max(5, selectorArea$1.width() * scaleX));
20121
+ frameInternalGroup.height(Math.max(5, selectorArea$1.height() * scaleY));
20122
+ background.width(Math.max(5, selectorArea$1.width() * scaleX));
20123
+ background.height(Math.max(5, selectorArea$1.height() * scaleY));
20124
+ text.width(Math.max(5, selectorArea$1.width() * scaleX));
20125
+ text.height(titleHeight * scaleY);
20126
+ frameInternal.width(Math.max(5, selectorArea$1.width() * scaleX));
20127
+ frameInternal.height(Math.max(5, selectorArea$1.height() * scaleY));
20128
+ };
20129
+ selectorArea.on("transform", (e) => {
20130
+ updateFrame(e);
20131
+ const node = e.target;
20132
+ const nodesSnappingPlugin = this.instance.getPlugin("nodesSnapping");
20133
+ if (nodesSnappingPlugin && this.isSelecting() && this.isNodeSelected(node)) nodesSnappingPlugin.evaluateGuidelines(e);
20134
+ const clonedSA = selectorArea.clone();
20135
+ const scaleX = clonedSA.scaleX();
20136
+ const scaleY = clonedSA.scaleY();
20137
+ clonedSA.x(0);
20138
+ clonedSA.y(0);
20139
+ clonedSA.width(Math.max(5, clonedSA.width() * scaleX));
20140
+ clonedSA.height(Math.max(5, clonedSA.height() * scaleY));
20141
+ clonedSA.scaleX(1);
20142
+ clonedSA.scaleY(1);
20143
+ this.instance.updateNode(this.serialize(clonedSA));
20144
+ e.cancelBubble = true;
20145
+ });
20146
+ selectorArea.on("transformend", (e) => {
20147
+ const node = e.target;
20148
+ const nodesSnappingPlugin = this.instance.getPlugin("nodesSnapping");
20149
+ if (nodesSnappingPlugin && this.isSelecting() && this.isNodeSelected(node)) nodesSnappingPlugin.cleanupEvaluateGuidelines();
20150
+ const scaleX = selectorArea.scaleX();
20151
+ const scaleY = selectorArea.scaleY();
20152
+ selectorArea.x(0);
20153
+ selectorArea.y(0);
20154
+ selectorArea.width(Math.max(5, selectorArea.width() * scaleX));
20155
+ selectorArea.height(Math.max(5, selectorArea.height() * scaleY));
20156
+ selectorArea.scaleX(1);
20157
+ selectorArea.scaleY(1);
20158
+ updateFrame(e);
20159
+ this.instance.updateNode(this.serialize(selectorArea));
20160
+ });
20161
+ frameInternalGroup.add(selectorArea);
19929
20162
  const frameInternal = new Konva.Group({
19930
20163
  id: `${id}-group-internal`,
19931
20164
  nodeId: id,
@@ -19933,17 +20166,18 @@ var WeaveFrameNode = class extends WeaveNode {
19933
20166
  y: titleHeight,
19934
20167
  width: props.frameWidth,
19935
20168
  height: props.frameHeight,
19936
- draggable: false,
19937
- stroke: "transparent",
19938
20169
  strokeScaleEnabled: false,
19939
- borderWidth: 0,
19940
- clipX: 0,
19941
- clipY: 0,
19942
- clipWidth: props.frameWidth,
19943
- clipHeight: props.frameHeight
20170
+ draggable: false
19944
20171
  });
19945
- frame.add(frameInternal);
20172
+ frameInternal.clipFunc((ctx) => {
20173
+ const width = frameInternal.width() * frameInternal.scaleX();
20174
+ const height = frameInternal.height() * frameInternal.scaleY();
20175
+ ctx.rect(0, -titleHeight, width, height);
20176
+ });
20177
+ frameInternalGroup.add(frameInternal);
19946
20178
  this.setupDefaultNodeEvents(frame);
20179
+ frame.on("dragmove", () => {});
20180
+ frame.on("dragend", () => {});
19947
20181
  frame.on(WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, () => {
19948
20182
  background.setAttrs({
19949
20183
  stroke: onTargetLeaveBorderColor,
@@ -19964,13 +20198,51 @@ var WeaveFrameNode = class extends WeaveNode {
19964
20198
  const { id } = nextProps;
19965
20199
  const frameNode = nodeInstance;
19966
20200
  const newProps = { ...nextProps };
20201
+ const { titleHeight } = this.config;
19967
20202
  nodeInstance.setAttrs({ ...newProps });
19968
- const frameTitle = frameNode.findOne(`#${id}-title`);
19969
- if (frameTitle) frameTitle.setAttrs({ text: nextProps.title });
20203
+ const selectorArea = frameNode.findOne(`#${id}-selector-area`);
20204
+ if (selectorArea) {
20205
+ selectorArea.setAttrs({
20206
+ x: 0,
20207
+ y: 0,
20208
+ width: nextProps.width,
20209
+ height: nextProps.height
20210
+ });
20211
+ const frameInternalGroup = frameNode.findOne(`#${id}-selector`);
20212
+ if (frameInternalGroup) frameInternalGroup.setAttrs({
20213
+ x: 0,
20214
+ y: 0,
20215
+ width: nextProps.width * selectorArea.scaleX(),
20216
+ height: nextProps.height * selectorArea.scaleY()
20217
+ });
20218
+ const background = frameNode.findOne(`#${id}-bg`);
20219
+ if (background) background.setAttrs({
20220
+ x: 0,
20221
+ y: 0,
20222
+ width: nextProps.width * selectorArea.scaleX(),
20223
+ height: nextProps.height * selectorArea.scaleY()
20224
+ });
20225
+ const text = frameNode.findOne(`#${id}-title`);
20226
+ if (text) text.setAttrs({
20227
+ x: 0,
20228
+ y: -titleHeight,
20229
+ text: nextProps.title,
20230
+ width: nextProps.width * selectorArea.scaleX()
20231
+ });
20232
+ const frameInternal = frameNode.findOne(`#${id}-group-internal`);
20233
+ if (frameInternal) frameInternal.setAttrs({
20234
+ x: 0,
20235
+ y: titleHeight,
20236
+ width: nextProps.width * selectorArea.scaleX(),
20237
+ height: nextProps.height * selectorArea.scaleY()
20238
+ });
20239
+ }
19970
20240
  }
19971
20241
  serialize(instance) {
20242
+ const stage = this.instance.getStage();
19972
20243
  const attrs = instance.getAttrs();
19973
- const frameInternal = instance.findOne(`#${attrs.containerId}`);
20244
+ const mainNode = stage?.findOne(`#${attrs.nodeId}`);
20245
+ const frameInternal = mainNode?.findOne(`#${attrs.containerId}`);
19974
20246
  const childrenMapped = [];
19975
20247
  if (frameInternal) {
19976
20248
  const children = [...frameInternal.getChildren()];
@@ -19979,15 +20251,16 @@ var WeaveFrameNode = class extends WeaveNode {
19979
20251
  childrenMapped.push(handler.serialize(node));
19980
20252
  }
19981
20253
  }
19982
- const cleanedAttrs = { ...attrs };
20254
+ const realAttrs = mainNode?.getAttrs();
20255
+ const cleanedAttrs = { ...realAttrs };
19983
20256
  delete cleanedAttrs.draggable;
19984
20257
  return {
19985
- key: attrs.id ?? "",
19986
- type: attrs.nodeType,
20258
+ key: realAttrs?.id ?? "",
20259
+ type: realAttrs?.nodeType,
19987
20260
  props: {
19988
20261
  ...cleanedAttrs,
19989
- id: attrs.id ?? "",
19990
- nodeType: attrs.nodeType,
20262
+ id: realAttrs?.id ?? "",
20263
+ nodeType: realAttrs?.nodeType,
19991
20264
  children: childrenMapped
19992
20265
  }
19993
20266
  };
@@ -19997,28 +20270,44 @@ var WeaveFrameNode = class extends WeaveNode {
19997
20270
  //#endregion
19998
20271
  //#region src/plugins/stage-zoom/constants.ts
19999
20272
  const WEAVE_STAGE_ZOOM_KEY = "stageZoom";
20273
+ const WEAVE_STAGE_ZOOM_DEFAULT_CONFIG = {
20274
+ zoomSteps: [
20275
+ .1,
20276
+ .2,
20277
+ .3,
20278
+ .4,
20279
+ .5,
20280
+ .6,
20281
+ .7,
20282
+ .8,
20283
+ .9,
20284
+ 1,
20285
+ 1.25,
20286
+ 1.5,
20287
+ 1.75,
20288
+ 2,
20289
+ 3,
20290
+ 4,
20291
+ 6,
20292
+ 8,
20293
+ 10
20294
+ ],
20295
+ defaultZoom: 1,
20296
+ fitToScreen: { padding: 40 },
20297
+ fitToSelection: { padding: 40 }
20298
+ };
20000
20299
 
20001
20300
  //#endregion
20002
20301
  //#region src/plugins/stage-zoom/stage-zoom.ts
20003
20302
  var WeaveStageZoomPlugin = class extends WeavePlugin {
20004
20303
  getLayerName = void 0;
20005
20304
  initLayer = void 0;
20006
- padding = 175;
20007
20305
  defaultStep = 3;
20008
20306
  constructor(params) {
20009
20307
  super();
20010
20308
  const { config } = params ?? {};
20011
20309
  this.config = {
20012
- zoomSteps: [
20013
- .1,
20014
- .25,
20015
- .5,
20016
- 1,
20017
- 2,
20018
- 4,
20019
- 8
20020
- ],
20021
- defaultZoom: 1,
20310
+ ...WEAVE_STAGE_ZOOM_DEFAULT_CONFIG,
20022
20311
  ...config
20023
20312
  };
20024
20313
  if (!this.config.zoomSteps.includes(this.config.defaultZoom)) throw new Error(`Default zoom ${this.config.defaultZoom} is not in zoom steps`);
@@ -20078,13 +20367,13 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
20078
20367
  canZoomOut() {
20079
20368
  if (!this.enabled) return false;
20080
20369
  const actualZoomIsStep = this.config.zoomSteps.findIndex((scale) => scale === this.actualScale);
20081
- if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex();
20370
+ if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex("zoomOut");
20082
20371
  return this.actualStep - 1 > 0;
20083
20372
  }
20084
20373
  canZoomIn() {
20085
20374
  if (!this.enabled) return false;
20086
20375
  const actualZoomIsStep = this.config.zoomSteps.findIndex((scale) => scale === this.actualScale);
20087
- if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex();
20376
+ if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex("zoomIn");
20088
20377
  return this.actualStep + 1 < this.config.zoomSteps.length;
20089
20378
  }
20090
20379
  zoomToStep(step) {
@@ -20093,20 +20382,15 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
20093
20382
  this.actualStep = step;
20094
20383
  this.setZoom(this.config.zoomSteps[step]);
20095
20384
  }
20096
- findClosestStepIndex() {
20097
- let closestStepIndex = 0;
20098
- let actualDiff = Infinity;
20099
- for (let i = 0; i < this.config.zoomSteps.length; i++) if (Math.abs(this.config.zoomSteps[i] - this.actualScale) < actualDiff) {
20100
- closestStepIndex = i;
20101
- actualDiff = Math.abs(this.config.zoomSteps[i] - this.actualScale);
20102
- }
20103
- return closestStepIndex;
20385
+ findClosestStepIndex(direction) {
20386
+ const nextValue = this.config.zoomSteps.filter((scale) => direction === "zoomIn" ? scale >= this.actualScale : scale <= this.actualScale).sort((a, b) => direction === "zoomIn" ? a - b : b - a)[0];
20387
+ return this.config.zoomSteps.findIndex((scale) => scale === nextValue);
20104
20388
  }
20105
20389
  zoomIn() {
20106
20390
  if (!this.enabled) return;
20107
20391
  if (!this.canZoomIn()) return;
20108
20392
  const actualZoomIsStep = this.config.zoomSteps.findIndex((scale) => scale === this.actualScale);
20109
- if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex();
20393
+ if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex("zoomIn");
20110
20394
  else this.actualStep += 1;
20111
20395
  this.setZoom(this.config.zoomSteps[this.actualStep]);
20112
20396
  }
@@ -20114,7 +20398,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
20114
20398
  if (!this.enabled) return;
20115
20399
  if (!this.canZoomOut()) return;
20116
20400
  const actualZoomIsStep = this.config.zoomSteps.findIndex((scale) => scale === this.actualScale);
20117
- if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex();
20401
+ if (actualZoomIsStep === -1) this.actualStep = this.findClosestStepIndex("zoomOut");
20118
20402
  else this.actualStep -= 1;
20119
20403
  this.setZoom(this.config.zoomSteps[this.actualStep]);
20120
20404
  }
@@ -20127,11 +20411,32 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
20127
20411
  }
20128
20412
  const stage = this.instance.getStage();
20129
20413
  if (mainLayer) {
20130
- const box = mainLayer.getClientRect({ relativeTo: stage });
20131
- const scale = Math.min(stage.width() / (box.width + this.padding * 2), stage.height() / (box.height + this.padding * 2));
20132
- stage.setAttrs({
20133
- x: -box.x * scale + (stage.width() - box.width * scale) / 2,
20134
- y: -box.y * scale + (stage.height() - box.height * scale) / 2
20414
+ const box = mainLayer.getClientRect({
20415
+ relativeTo: stage,
20416
+ skipStroke: true
20417
+ });
20418
+ const stageBox = {
20419
+ width: stage.width(),
20420
+ height: stage.height()
20421
+ };
20422
+ const availableScreenWidth = stageBox.width - 2 * this.config.fitToScreen.padding;
20423
+ const availableScreenHeight = stageBox.height - 2 * this.config.fitToScreen.padding;
20424
+ const scaleX = availableScreenWidth / box.width;
20425
+ const scaleY = availableScreenHeight / box.height;
20426
+ const scale = Math.min(scaleX, scaleY);
20427
+ stage.scale({
20428
+ x: scale,
20429
+ y: scale
20430
+ });
20431
+ const selectionCenterX = box.x + box.width / 2;
20432
+ const selectionCenterY = box.y + box.height / 2;
20433
+ const canvasCenterX = stage.width() / (2 * scale);
20434
+ const canvasCenterY = stage.height() / (2 * scale);
20435
+ const stageX = (canvasCenterX - selectionCenterX) * scale;
20436
+ const stageY = (canvasCenterY - selectionCenterY) * scale;
20437
+ stage.position({
20438
+ x: stageX,
20439
+ y: stageY
20135
20440
  });
20136
20441
  this.setZoom(scale, false);
20137
20442
  }
@@ -20166,10 +20471,28 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
20166
20471
  zoomTransformer.setNodes(selectionPlugin.getTransformer().getNodes());
20167
20472
  zoomTransformer.forceUpdate();
20168
20473
  const box = zoomTransformer.__getNodeRect();
20169
- const scale = Math.min(stage.width() / (zoomTransformer.width() + this.padding * 2), stage.height() / (zoomTransformer.height() + this.padding * 2));
20170
- stage.setAttrs({
20171
- x: -box.x * scale + (stage.width() - zoomTransformer.width() * scale) / 2,
20172
- y: -box.y * scale + (stage.height() - zoomTransformer.height() * scale) / 2
20474
+ const stageBox = {
20475
+ width: stage.width(),
20476
+ height: stage.height()
20477
+ };
20478
+ const availableScreenWidth = stageBox.width - 2 * this.config.fitToSelection.padding;
20479
+ const availableScreenHeight = stageBox.height - 2 * this.config.fitToSelection.padding;
20480
+ const scaleX = availableScreenWidth / box.width;
20481
+ const scaleY = availableScreenHeight / box.height;
20482
+ const scale = Math.min(scaleX, scaleY);
20483
+ stage.scale({
20484
+ x: scale,
20485
+ y: scale
20486
+ });
20487
+ const selectionCenterX = box.x + box.width / 2;
20488
+ const selectionCenterY = box.y + box.height / 2;
20489
+ const canvasCenterX = stage.width() / (2 * scale);
20490
+ const canvasCenterY = stage.height() / (2 * scale);
20491
+ const stageX = (canvasCenterX - selectionCenterX) * scale;
20492
+ const stageY = (canvasCenterY - selectionCenterY) * scale;
20493
+ stage.position({
20494
+ x: stageX,
20495
+ y: stageY
20173
20496
  });
20174
20497
  this.setZoom(scale, false);
20175
20498
  zoomTransformer.destroy();
@@ -21288,7 +21611,7 @@ var WeaveFrameToolAction = class extends WeaveAction {
21288
21611
  stage.container().style.cursor = "default";
21289
21612
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
21290
21613
  if (selectionPlugin) {
21291
- const node = stage.findOne(`#${this.frameId}`);
21614
+ const node = stage.findOne(`#${this.frameId}-selector-area`);
21292
21615
  if (node) selectionPlugin.setSelectedNodes([node]);
21293
21616
  this.instance.triggerAction("selectionTool");
21294
21617
  }
@@ -22330,6 +22653,10 @@ var WeaveNodesSnappingPlugin = class extends WeavePlugin {
22330
22653
  nodes
22331
22654
  };
22332
22655
  }
22656
+ deleteGuides() {
22657
+ const utilityLayer = this.instance.getUtilityLayer();
22658
+ if (utilityLayer) utilityLayer.find(`.${GUIDE_LINE_NAME}`).forEach((l) => l.destroy());
22659
+ }
22333
22660
  evaluateGuidelines(e) {
22334
22661
  const utilityLayer = this.instance.getUtilityLayer();
22335
22662
  if (!this.enabled) return;
@@ -22337,14 +22664,13 @@ var WeaveNodesSnappingPlugin = class extends WeavePlugin {
22337
22664
  const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
22338
22665
  let skipNodes = [];
22339
22666
  let node = void 0;
22340
- if (e.type === "dragmove" && nodesSelectionPlugin && e.target instanceof Konva.Transformer && e.target.getNodes().length === 1) {
22341
- const actualTarget = e.target;
22342
- node = actualTarget.getNodes()[0];
22667
+ if (e.type === "dragmove" && nodesSelectionPlugin && nodesSelectionPlugin.getTransformer().nodes().length === 1) {
22668
+ node = nodesSelectionPlugin.getTransformer().nodes()[0];
22343
22669
  skipNodes.push(node.getAttrs().id ?? "");
22344
22670
  }
22345
- if (e.type === "dragmove" && nodesSelectionPlugin && e.target instanceof Konva.Transformer && e.target.getNodes().length > 1) {
22346
- const { nodes } = this.getSelectedNodesMetadata(e.target);
22347
- node = e.target;
22671
+ if (e.type === "dragmove" && nodesSelectionPlugin && nodesSelectionPlugin.getTransformer().nodes().length > 1) {
22672
+ const { nodes } = this.getSelectedNodesMetadata(nodesSelectionPlugin.getTransformer());
22673
+ node = nodesSelectionPlugin.getTransformer();
22348
22674
  skipNodes = [...nodes];
22349
22675
  }
22350
22676
  if (e.type === "transform") node = e.target;