@metadev/daga 4.0.0 → 4.0.1

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/Changelog.md CHANGED
@@ -6,6 +6,16 @@ List of releases and changes.
6
6
 
7
7
  ## Next release Joyeuse
8
8
 
9
+ ## v. 4.0.1
10
+
11
+ - Ensure borders of nodes are fully contained within palette [#253](https://github.com/metadevpro/daga/pull/253)
12
+ - Adjust nodes in palette [#254](https://github.com/metadevpro/daga/pull/254)
13
+ - Fix bug where dragging a decorator creates a multiple selection instead of dragging the node [#257](https://github.com/metadevpro/daga/pull/257)
14
+ - Allow special characters in diagram element identifiers [#258](https://github.com/metadevpro/daga/pull/258)
15
+ - Add custom context menu buttons [#259](https://github.com/metadevpro/daga/pull/259)
16
+
17
+ ## v. 4.0.0 Hielo
18
+
9
19
  - Expose `viewInitialized$` observable in diagram component [#239](https://github.com/metadevpro/daga/pull/239)
10
20
  - Throw error when a diagram element is initialized with an empty or null id to prevent errors with selectors caused by empty ids [#240](https://github.com/metadevpro/daga/pull/240)
11
21
  - Change the structure of the configuration for the looks of nodes, sections, ports and connections [#244](https://github.com/metadevpro/daga/pull/244)
package/index.cjs.js CHANGED
@@ -1022,6 +1022,10 @@ class DiagramEntitySet {
1022
1022
  }
1023
1023
  }
1024
1024
 
1025
+ const escapeSelector = selector => {
1026
+ return selector.replace(/([!"#$%&'()*+,\-./:;<=>?@[\\\]^`{|}])/g, '\\$1');
1027
+ };
1028
+
1025
1029
  /**
1026
1030
  * Default priority value for diagram elements.
1027
1031
  * @private
@@ -1083,7 +1087,7 @@ class DiagramElement {
1083
1087
  */
1084
1088
  select() {
1085
1089
  var _a, _b;
1086
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`g#${this.id}`);
1090
+ return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`[id='${escapeSelector(this.id)}']`);
1087
1091
  }
1088
1092
  }
1089
1093
  class DiagramElementSet extends DiagramEntitySet {
@@ -2290,10 +2294,6 @@ class DiagramField extends DiagramElement {
2290
2294
  this.editable = editable;
2291
2295
  this.fit = fit;
2292
2296
  }
2293
- select() {
2294
- var _a, _b;
2295
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
2296
- }
2297
2297
  get removed() {
2298
2298
  return this.selfRemoved || this.rootElement !== undefined && this.rootElement.removed;
2299
2299
  }
@@ -5635,10 +5635,6 @@ class DiagramDecorator extends DiagramElement {
5635
5635
  this.priority = priority;
5636
5636
  this.html = html;
5637
5637
  }
5638
- select() {
5639
- var _a, _b;
5640
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
5641
- }
5642
5638
  get removed() {
5643
5639
  return this.selfRemoved || this.rootElement !== undefined && this.rootElement.removed;
5644
5640
  }
@@ -5728,10 +5724,6 @@ class DiagramObject extends DiagramElement {
5728
5724
  this.priority = priority;
5729
5725
  this.html = html;
5730
5726
  }
5731
- select() {
5732
- var _a, _b;
5733
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
5734
- }
5735
5727
  get removed() {
5736
5728
  return this.selfRemoved;
5737
5729
  }
@@ -5944,6 +5936,9 @@ const CONTEXT_MENU_BUTTON_RADIUS = 32;
5944
5936
  const CONTEXT_MENU_TOTAL_RADIUS = CONTEXT_MENU_MENU_RADIUS + CONTEXT_MENU_BUTTON_RADIUS;
5945
5937
  const CONTEXT_MENU_BUTTON_PADDING_RADIANS = Math.PI / 4;
5946
5938
  const CONTEXT_MENU_ANIMATION_DURATION_MS = 100;
5939
+ const CONTEXT_MENU_DEFAULTS = {
5940
+ customButtons: []
5941
+ };
5947
5942
  /**
5948
5943
  * Stores the functionality regarding the context menu of a diagram canvas.
5949
5944
  * @public
@@ -5955,8 +5950,9 @@ class DiagramContextMenu {
5955
5950
  * @public
5956
5951
  * @param canvas A canvas.
5957
5952
  */
5958
- constructor(canvas) {
5953
+ constructor(canvas, config) {
5959
5954
  this.canvas = canvas;
5955
+ this.config = config || CONTEXT_MENU_DEFAULTS;
5960
5956
  }
5961
5957
  /**
5962
5958
  * Opens the context menu at the location determined by the given mouse event.
@@ -5983,10 +5979,9 @@ class DiagramContextMenu {
5983
5979
  buttons.push({
5984
5980
  name: 'CUT',
5985
5981
  imageClass: 'daga-cut',
5986
- onPress: buttonPressEvent => {
5987
- buttonPressEvent.preventDefault();
5988
- this.canvas.userSelection.cutToClipboard();
5989
- this.canvas.cancelAllUserActions();
5982
+ onPress: canvas => {
5983
+ canvas.userSelection.cutToClipboard();
5984
+ canvas.cancelAllUserActions();
5990
5985
  }
5991
5986
  });
5992
5987
  }
@@ -5994,10 +5989,9 @@ class DiagramContextMenu {
5994
5989
  buttons.push({
5995
5990
  name: 'COPY',
5996
5991
  imageClass: 'daga-copy',
5997
- onPress: buttonPressEvent => {
5998
- buttonPressEvent.preventDefault();
5999
- this.canvas.userSelection.copyToClipboard();
6000
- this.canvas.cancelAllUserActions();
5992
+ onPress: canvas => {
5993
+ canvas.userSelection.copyToClipboard();
5994
+ canvas.cancelAllUserActions();
6001
5995
  }
6002
5996
  });
6003
5997
  }
@@ -6005,10 +5999,9 @@ class DiagramContextMenu {
6005
5999
  buttons.push({
6006
6000
  name: 'PASTE',
6007
6001
  imageClass: 'daga-paste',
6008
- onPress: buttonPressEvent => {
6009
- buttonPressEvent.preventDefault();
6010
- this.canvas.userSelection.pasteFromClipboard(this.canvas.getClosestGridPoint(coordsRelativeToCanvas));
6011
- this.canvas.cancelAllUserActions();
6002
+ onPress: canvas => {
6003
+ canvas.userSelection.pasteFromClipboard(canvas.getClosestGridPoint(coordsRelativeToCanvas));
6004
+ canvas.cancelAllUserActions();
6012
6005
  }
6013
6006
  });
6014
6007
  }
@@ -6016,13 +6009,17 @@ class DiagramContextMenu {
6016
6009
  buttons.push({
6017
6010
  name: 'DELETE',
6018
6011
  imageClass: 'daga-delete',
6019
- onPress: buttonPressEvent => {
6020
- buttonPressEvent.preventDefault();
6021
- this.canvas.userSelection.removeFromModel();
6022
- this.canvas.cancelAllUserActions();
6012
+ onPress: canvas => {
6013
+ canvas.userSelection.removeFromModel();
6014
+ canvas.cancelAllUserActions();
6023
6015
  }
6024
6016
  });
6025
6017
  }
6018
+ for (const customButton of this.config.customButtons || CONTEXT_MENU_DEFAULTS.customButtons) {
6019
+ if (customButton.condition !== undefined ? customButton.condition(this.canvas) : true) {
6020
+ buttons.push(customButton);
6021
+ }
6022
+ }
6026
6023
  // show something if there are no options available
6027
6024
  if (buttons.length === 0) {
6028
6025
  buttons.push({
@@ -6035,20 +6032,22 @@ class DiagramContextMenu {
6035
6032
  const button = buttons[i];
6036
6033
  const buttonOnPress = button.onPress;
6037
6034
  const angle = (i + 0.5 - buttons.length / 2) * CONTEXT_MENU_BUTTON_PADDING_RADIANS;
6038
- const buttonContainer = contextMenuContainer.append('xhtml:div').attr('class', `daga-context-menu-button ${button.imageClass}-button${button.onPress != undefined ? ' daga-clickable' : ''}`).attr('tabindex', 0).style('position', 'absolute').style('box-sizing', 'border-box').style('width', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('border-radius', `${CONTEXT_MENU_BUTTON_RADIUS}px`).style('pointer-events', 'auto')
6039
- // eslint-disable-next-line @typescript-eslint/no-empty-function
6040
- .on(exports.Events.Click, event => {
6035
+ const buttonContainer = contextMenuContainer.append('xhtml:div').attr('class', `daga-context-menu-button ${button.onPress !== undefined ? ' daga-clickable' : ''}`).attr('tabindex', 0).style('position', 'absolute').style('box-sizing', 'border-box').style('width', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('border-radius', `${CONTEXT_MENU_BUTTON_RADIUS}px`).style('pointer-events', 'auto').on(exports.Events.Click, event => {
6041
6036
  if (buttonOnPress) {
6042
- buttonOnPress(event);
6037
+ event.preventDefault();
6038
+ buttonOnPress(this.canvas);
6043
6039
  }
6044
- })
6045
- // eslint-disable-next-line @typescript-eslint/no-empty-function
6046
- .on(exports.Events.KeyDown, event => {
6040
+ }).on(exports.Events.KeyDown, event => {
6047
6041
  if (buttonOnPress && event.key === exports.Keys.Enter) {
6048
- buttonOnPress(event);
6042
+ event.preventDefault();
6043
+ buttonOnPress(this.canvas);
6049
6044
  }
6050
6045
  });
6051
- buttonContainer.append('xhtml:div').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('background-size', 'contain').style('background-repeat', 'no-repeat').attr('class', button.imageClass);
6046
+ if (button.imageClass !== undefined) {
6047
+ buttonContainer.append('xhtml:div').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('background-size', 'contain').style('background-repeat', 'no-repeat').attr('class', button.imageClass);
6048
+ } else if (button.image !== undefined) {
6049
+ buttonContainer.append('xhtml:img').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).attr('src', button.image);
6050
+ }
6052
6051
  buttonContainer.append('xhtml:span').style('position', 'absolute').style('left', `${0.2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${1.1 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('text-align', 'center').style('width', `${1.6 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.35 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('margin', '0').style('font-size', `${0.35 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('font-weight', '700').style('user-select', 'none').text(button.name);
6053
6052
  buttonContainer.transition().ease(d3__namespace.easeLinear).duration(CONTEXT_MENU_ANIMATION_DURATION_MS).tween('progress', () => {
6054
6053
  return value => {
@@ -6588,7 +6587,7 @@ class DiagramCanvas {
6588
6587
  * @param config The configuration object used to set the parameters of this canvas.
6589
6588
  */
6590
6589
  constructor(parentComponent, config) {
6591
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6590
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
6592
6591
  this.backgroundPatternId = `daga-background-pattern-id-${DiagramCanvas.canvasCount++}`;
6593
6592
  this.zoomTransform = d3__namespace.zoomIdentity;
6594
6593
  // used to distinguish drags from clicks when dragging elements and during multiple selection
@@ -6605,17 +6604,17 @@ class DiagramCanvas {
6605
6604
  this.model = new DiagramModel(this, undefined, config.name || 'unnamed', '', config.type || '', config.properties || []);
6606
6605
  this.userSelection = new DiagramUserSelection(this);
6607
6606
  this.userHighlight = new DiagramUserHighlight(this);
6608
- this.contextMenu = new DiagramContextMenu(this);
6609
- this.backgroundColor = ((_a = config.canvas) === null || _a === undefined ? undefined : _a.backgroundColor) || '#FFFFFF';
6610
- this.gridSize = ((_c = (_b = config.canvas) === null || _b === undefined ? undefined : _b.grid) === null || _c === undefined ? undefined : _c.enabled) === false || ((_d = config.canvas) === null || _d === undefined ? undefined : _d.grid) === undefined ? 0 : Math.abs(((_f = (_e = config.canvas) === null || _e === undefined ? undefined : _e.grid) === null || _f === undefined ? undefined : _f.spacing) || 10);
6611
- this.gridThickness = Math.abs(((_h = (_g = config.canvas) === null || _g === undefined ? undefined : _g.grid) === null || _h === undefined ? undefined : _h.thickness) || 0.05);
6612
- this.gridColor = ((_k = (_j = config.canvas) === null || _j === undefined ? undefined : _j.grid) === null || _k === undefined ? undefined : _k.color) || 'rgba(0, 0, 0, 0.1)';
6613
- this.snapToGrid = ((_m = (_l = config.canvas) === null || _l === undefined ? undefined : _l.grid) === null || _m === undefined ? undefined : _m.enabled) === false || ((_o = config.canvas) === null || _o === undefined ? undefined : _o.grid) === undefined ? false : ((_q = (_p = config.canvas) === null || _p === undefined ? undefined : _p.grid) === null || _q === undefined ? undefined : _q.snap) || false;
6614
- this.zoomFactor = ((_r = config.canvas) === null || _r === undefined ? undefined : _r.zoomFactor) || 2;
6615
- this.panRate = ((_s = config.canvas) === null || _s === undefined ? undefined : _s.panRate) || 100;
6607
+ this.contextMenu = new DiagramContextMenu(this, (_a = config.canvas) === null || _a === undefined ? undefined : _a.contextMenu);
6608
+ this.backgroundColor = ((_b = config.canvas) === null || _b === undefined ? undefined : _b.backgroundColor) || '#FFFFFF';
6609
+ this.gridSize = ((_d = (_c = config.canvas) === null || _c === undefined ? undefined : _c.grid) === null || _d === undefined ? undefined : _d.enabled) === false || ((_e = config.canvas) === null || _e === undefined ? undefined : _e.grid) === undefined ? 0 : Math.abs(((_g = (_f = config.canvas) === null || _f === undefined ? undefined : _f.grid) === null || _g === undefined ? undefined : _g.spacing) || 10);
6610
+ this.gridThickness = Math.abs(((_j = (_h = config.canvas) === null || _h === undefined ? undefined : _h.grid) === null || _j === undefined ? undefined : _j.thickness) || 0.05);
6611
+ this.gridColor = ((_l = (_k = config.canvas) === null || _k === undefined ? undefined : _k.grid) === null || _l === undefined ? undefined : _l.color) || 'rgba(0, 0, 0, 0.1)';
6612
+ this.snapToGrid = ((_o = (_m = config.canvas) === null || _m === undefined ? undefined : _m.grid) === null || _o === undefined ? undefined : _o.enabled) === false || ((_p = config.canvas) === null || _p === undefined ? undefined : _p.grid) === undefined ? false : ((_r = (_q = config.canvas) === null || _q === undefined ? undefined : _q.grid) === null || _r === undefined ? undefined : _r.snap) || false;
6613
+ this.zoomFactor = ((_s = config.canvas) === null || _s === undefined ? undefined : _s.zoomFactor) || 2;
6614
+ this.panRate = ((_t = config.canvas) === null || _t === undefined ? undefined : _t.panRate) || 100;
6616
6615
  this.inferConnectionType = config.inferConnectionType || false;
6617
6616
  this.multipleSelectionOn = false;
6618
- this.priorityThresholds = ((_t = config.canvas) === null || _t === undefined ? undefined : _t.priorityThresholds) || [];
6617
+ this.priorityThresholds = ((_u = config.canvas) === null || _u === undefined ? undefined : _u.priorityThresholds) || [];
6619
6618
  this.priorityThreshold = this.priorityThresholds ? this.priorityThresholds[0] : undefined;
6620
6619
  this.layoutFormat = config.layoutFormat;
6621
6620
  this.userActions = config.userActions || {};
@@ -7817,11 +7816,17 @@ class DiagramCanvas {
7817
7816
  this.secondaryButton = isSecondaryButton(event);
7818
7817
  return true;
7819
7818
  }).on(exports.DragEvents.Start, event => {
7820
- this.startMultipleSelection(event);
7819
+ if (this.multipleSelectionOn || this.secondaryButton) {
7820
+ this.startMultipleSelection(event);
7821
+ }
7821
7822
  }).on(exports.DragEvents.Drag, event => {
7822
- this.continueMultipleSelection(event);
7823
+ if (this.multipleSelectionOn || this.secondaryButton) {
7824
+ this.continueMultipleSelection(event);
7825
+ }
7823
7826
  }).on(exports.DragEvents.End, event => {
7824
- this.finishMultipleSelection(event);
7827
+ if (this.multipleSelectionOn || this.secondaryButton) {
7828
+ this.finishMultipleSelection(event);
7829
+ }
7825
7830
  }));
7826
7831
  }
7827
7832
  updateDecoratorsInView(...ids) {
@@ -7853,12 +7858,55 @@ class DiagramCanvas {
7853
7858
  }).call(d3__namespace.drag().filter(event => {
7854
7859
  this.secondaryButton = isSecondaryButton(event);
7855
7860
  return true;
7856
- }).on(exports.DragEvents.Start, event => {
7857
- this.startMultipleSelection(event);
7858
- }).on(exports.DragEvents.Drag, event => {
7859
- this.continueMultipleSelection(event);
7860
- }).on(exports.DragEvents.End, event => {
7861
- this.finishMultipleSelection(event);
7861
+ }).on(exports.DragEvents.Start, (event, d) => {
7862
+ if (this.multipleSelectionOn || this.secondaryButton) {
7863
+ this.startMultipleSelection(event);
7864
+ } else {
7865
+ let node;
7866
+ if (d.rootElement instanceof DiagramNode) {
7867
+ node = d.rootElement;
7868
+ } else if (d.rootElement instanceof DiagramSection) {
7869
+ node = d.rootElement.node;
7870
+ }
7871
+ if (node) {
7872
+ this.startMovingNode(event, node);
7873
+ } else {
7874
+ setCursorStyle(exports.CursorStyle.NotAllowed);
7875
+ }
7876
+ }
7877
+ }).on(exports.DragEvents.Drag, (event, d) => {
7878
+ if (this.multipleSelectionOn || this.secondaryButton) {
7879
+ this.continueMultipleSelection(event);
7880
+ } else {
7881
+ let node;
7882
+ if (d.rootElement instanceof DiagramNode) {
7883
+ node = d.rootElement;
7884
+ } else if (d.rootElement instanceof DiagramSection) {
7885
+ node = d.rootElement.node;
7886
+ }
7887
+ if (node) {
7888
+ this.continueMovingNode(event, node);
7889
+ } else {
7890
+ setCursorStyle(exports.CursorStyle.NotAllowed);
7891
+ }
7892
+ }
7893
+ }).on(exports.DragEvents.End, (event, d) => {
7894
+ if (this.multipleSelectionOn || this.secondaryButton) {
7895
+ this.finishMultipleSelection(event);
7896
+ } else {
7897
+ let node;
7898
+ if (d.rootElement instanceof DiagramNode) {
7899
+ node = d.rootElement;
7900
+ } else if (d.rootElement instanceof DiagramSection) {
7901
+ node = d.rootElement.node;
7902
+ }
7903
+ if (node) {
7904
+ this.finishMovingNode(event, node);
7905
+ } else {
7906
+ setCursorStyle();
7907
+ }
7908
+ }
7909
+ this.secondaryButton = false;
7862
7910
  }));
7863
7911
  }
7864
7912
  updateConnectionLabelsInView(connection) {
package/index.esm.js CHANGED
@@ -1001,6 +1001,10 @@ class DiagramEntitySet {
1001
1001
  }
1002
1002
  }
1003
1003
 
1004
+ const escapeSelector = selector => {
1005
+ return selector.replace(/([!"#$%&'()*+,\-./:;<=>?@[\\\]^`{|}])/g, '\\$1');
1006
+ };
1007
+
1004
1008
  /**
1005
1009
  * Default priority value for diagram elements.
1006
1010
  * @private
@@ -1062,7 +1066,7 @@ class DiagramElement {
1062
1066
  */
1063
1067
  select() {
1064
1068
  var _a, _b;
1065
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`g#${this.id}`);
1069
+ return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`[id='${escapeSelector(this.id)}']`);
1066
1070
  }
1067
1071
  }
1068
1072
  class DiagramElementSet extends DiagramEntitySet {
@@ -2269,10 +2273,6 @@ class DiagramField extends DiagramElement {
2269
2273
  this.editable = editable;
2270
2274
  this.fit = fit;
2271
2275
  }
2272
- select() {
2273
- var _a, _b;
2274
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
2275
- }
2276
2276
  get removed() {
2277
2277
  return this.selfRemoved || this.rootElement !== undefined && this.rootElement.removed;
2278
2278
  }
@@ -5614,10 +5614,6 @@ class DiagramDecorator extends DiagramElement {
5614
5614
  this.priority = priority;
5615
5615
  this.html = html;
5616
5616
  }
5617
- select() {
5618
- var _a, _b;
5619
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
5620
- }
5621
5617
  get removed() {
5622
5618
  return this.selfRemoved || this.rootElement !== undefined && this.rootElement.removed;
5623
5619
  }
@@ -5707,10 +5703,6 @@ class DiagramObject extends DiagramElement {
5707
5703
  this.priority = priority;
5708
5704
  this.html = html;
5709
5705
  }
5710
- select() {
5711
- var _a, _b;
5712
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
5713
- }
5714
5706
  get removed() {
5715
5707
  return this.selfRemoved;
5716
5708
  }
@@ -5923,6 +5915,9 @@ const CONTEXT_MENU_BUTTON_RADIUS = 32;
5923
5915
  const CONTEXT_MENU_TOTAL_RADIUS = CONTEXT_MENU_MENU_RADIUS + CONTEXT_MENU_BUTTON_RADIUS;
5924
5916
  const CONTEXT_MENU_BUTTON_PADDING_RADIANS = Math.PI / 4;
5925
5917
  const CONTEXT_MENU_ANIMATION_DURATION_MS = 100;
5918
+ const CONTEXT_MENU_DEFAULTS = {
5919
+ customButtons: []
5920
+ };
5926
5921
  /**
5927
5922
  * Stores the functionality regarding the context menu of a diagram canvas.
5928
5923
  * @public
@@ -5934,8 +5929,9 @@ class DiagramContextMenu {
5934
5929
  * @public
5935
5930
  * @param canvas A canvas.
5936
5931
  */
5937
- constructor(canvas) {
5932
+ constructor(canvas, config) {
5938
5933
  this.canvas = canvas;
5934
+ this.config = config || CONTEXT_MENU_DEFAULTS;
5939
5935
  }
5940
5936
  /**
5941
5937
  * Opens the context menu at the location determined by the given mouse event.
@@ -5962,10 +5958,9 @@ class DiagramContextMenu {
5962
5958
  buttons.push({
5963
5959
  name: 'CUT',
5964
5960
  imageClass: 'daga-cut',
5965
- onPress: buttonPressEvent => {
5966
- buttonPressEvent.preventDefault();
5967
- this.canvas.userSelection.cutToClipboard();
5968
- this.canvas.cancelAllUserActions();
5961
+ onPress: canvas => {
5962
+ canvas.userSelection.cutToClipboard();
5963
+ canvas.cancelAllUserActions();
5969
5964
  }
5970
5965
  });
5971
5966
  }
@@ -5973,10 +5968,9 @@ class DiagramContextMenu {
5973
5968
  buttons.push({
5974
5969
  name: 'COPY',
5975
5970
  imageClass: 'daga-copy',
5976
- onPress: buttonPressEvent => {
5977
- buttonPressEvent.preventDefault();
5978
- this.canvas.userSelection.copyToClipboard();
5979
- this.canvas.cancelAllUserActions();
5971
+ onPress: canvas => {
5972
+ canvas.userSelection.copyToClipboard();
5973
+ canvas.cancelAllUserActions();
5980
5974
  }
5981
5975
  });
5982
5976
  }
@@ -5984,10 +5978,9 @@ class DiagramContextMenu {
5984
5978
  buttons.push({
5985
5979
  name: 'PASTE',
5986
5980
  imageClass: 'daga-paste',
5987
- onPress: buttonPressEvent => {
5988
- buttonPressEvent.preventDefault();
5989
- this.canvas.userSelection.pasteFromClipboard(this.canvas.getClosestGridPoint(coordsRelativeToCanvas));
5990
- this.canvas.cancelAllUserActions();
5981
+ onPress: canvas => {
5982
+ canvas.userSelection.pasteFromClipboard(canvas.getClosestGridPoint(coordsRelativeToCanvas));
5983
+ canvas.cancelAllUserActions();
5991
5984
  }
5992
5985
  });
5993
5986
  }
@@ -5995,13 +5988,17 @@ class DiagramContextMenu {
5995
5988
  buttons.push({
5996
5989
  name: 'DELETE',
5997
5990
  imageClass: 'daga-delete',
5998
- onPress: buttonPressEvent => {
5999
- buttonPressEvent.preventDefault();
6000
- this.canvas.userSelection.removeFromModel();
6001
- this.canvas.cancelAllUserActions();
5991
+ onPress: canvas => {
5992
+ canvas.userSelection.removeFromModel();
5993
+ canvas.cancelAllUserActions();
6002
5994
  }
6003
5995
  });
6004
5996
  }
5997
+ for (const customButton of this.config.customButtons || CONTEXT_MENU_DEFAULTS.customButtons) {
5998
+ if (customButton.condition !== undefined ? customButton.condition(this.canvas) : true) {
5999
+ buttons.push(customButton);
6000
+ }
6001
+ }
6005
6002
  // show something if there are no options available
6006
6003
  if (buttons.length === 0) {
6007
6004
  buttons.push({
@@ -6014,20 +6011,22 @@ class DiagramContextMenu {
6014
6011
  const button = buttons[i];
6015
6012
  const buttonOnPress = button.onPress;
6016
6013
  const angle = (i + 0.5 - buttons.length / 2) * CONTEXT_MENU_BUTTON_PADDING_RADIANS;
6017
- const buttonContainer = contextMenuContainer.append('xhtml:div').attr('class', `daga-context-menu-button ${button.imageClass}-button${button.onPress != undefined ? ' daga-clickable' : ''}`).attr('tabindex', 0).style('position', 'absolute').style('box-sizing', 'border-box').style('width', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('border-radius', `${CONTEXT_MENU_BUTTON_RADIUS}px`).style('pointer-events', 'auto')
6018
- // eslint-disable-next-line @typescript-eslint/no-empty-function
6019
- .on(Events.Click, event => {
6014
+ const buttonContainer = contextMenuContainer.append('xhtml:div').attr('class', `daga-context-menu-button ${button.onPress !== undefined ? ' daga-clickable' : ''}`).attr('tabindex', 0).style('position', 'absolute').style('box-sizing', 'border-box').style('width', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('border-radius', `${CONTEXT_MENU_BUTTON_RADIUS}px`).style('pointer-events', 'auto').on(Events.Click, event => {
6020
6015
  if (buttonOnPress) {
6021
- buttonOnPress(event);
6016
+ event.preventDefault();
6017
+ buttonOnPress(this.canvas);
6022
6018
  }
6023
- })
6024
- // eslint-disable-next-line @typescript-eslint/no-empty-function
6025
- .on(Events.KeyDown, event => {
6019
+ }).on(Events.KeyDown, event => {
6026
6020
  if (buttonOnPress && event.key === Keys.Enter) {
6027
- buttonOnPress(event);
6021
+ event.preventDefault();
6022
+ buttonOnPress(this.canvas);
6028
6023
  }
6029
6024
  });
6030
- buttonContainer.append('xhtml:div').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('background-size', 'contain').style('background-repeat', 'no-repeat').attr('class', button.imageClass);
6025
+ if (button.imageClass !== undefined) {
6026
+ buttonContainer.append('xhtml:div').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('background-size', 'contain').style('background-repeat', 'no-repeat').attr('class', button.imageClass);
6027
+ } else if (button.image !== undefined) {
6028
+ buttonContainer.append('xhtml:img').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).attr('src', button.image);
6029
+ }
6031
6030
  buttonContainer.append('xhtml:span').style('position', 'absolute').style('left', `${0.2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${1.1 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('text-align', 'center').style('width', `${1.6 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.35 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('margin', '0').style('font-size', `${0.35 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('font-weight', '700').style('user-select', 'none').text(button.name);
6032
6031
  buttonContainer.transition().ease(d3.easeLinear).duration(CONTEXT_MENU_ANIMATION_DURATION_MS).tween('progress', () => {
6033
6032
  return value => {
@@ -6567,7 +6566,7 @@ class DiagramCanvas {
6567
6566
  * @param config The configuration object used to set the parameters of this canvas.
6568
6567
  */
6569
6568
  constructor(parentComponent, config) {
6570
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6569
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
6571
6570
  this.backgroundPatternId = `daga-background-pattern-id-${DiagramCanvas.canvasCount++}`;
6572
6571
  this.zoomTransform = d3.zoomIdentity;
6573
6572
  // used to distinguish drags from clicks when dragging elements and during multiple selection
@@ -6584,17 +6583,17 @@ class DiagramCanvas {
6584
6583
  this.model = new DiagramModel(this, undefined, config.name || 'unnamed', '', config.type || '', config.properties || []);
6585
6584
  this.userSelection = new DiagramUserSelection(this);
6586
6585
  this.userHighlight = new DiagramUserHighlight(this);
6587
- this.contextMenu = new DiagramContextMenu(this);
6588
- this.backgroundColor = ((_a = config.canvas) === null || _a === undefined ? undefined : _a.backgroundColor) || '#FFFFFF';
6589
- this.gridSize = ((_c = (_b = config.canvas) === null || _b === undefined ? undefined : _b.grid) === null || _c === undefined ? undefined : _c.enabled) === false || ((_d = config.canvas) === null || _d === undefined ? undefined : _d.grid) === undefined ? 0 : Math.abs(((_f = (_e = config.canvas) === null || _e === undefined ? undefined : _e.grid) === null || _f === undefined ? undefined : _f.spacing) || 10);
6590
- this.gridThickness = Math.abs(((_h = (_g = config.canvas) === null || _g === undefined ? undefined : _g.grid) === null || _h === undefined ? undefined : _h.thickness) || 0.05);
6591
- this.gridColor = ((_k = (_j = config.canvas) === null || _j === undefined ? undefined : _j.grid) === null || _k === undefined ? undefined : _k.color) || 'rgba(0, 0, 0, 0.1)';
6592
- this.snapToGrid = ((_m = (_l = config.canvas) === null || _l === undefined ? undefined : _l.grid) === null || _m === undefined ? undefined : _m.enabled) === false || ((_o = config.canvas) === null || _o === undefined ? undefined : _o.grid) === undefined ? false : ((_q = (_p = config.canvas) === null || _p === undefined ? undefined : _p.grid) === null || _q === undefined ? undefined : _q.snap) || false;
6593
- this.zoomFactor = ((_r = config.canvas) === null || _r === undefined ? undefined : _r.zoomFactor) || 2;
6594
- this.panRate = ((_s = config.canvas) === null || _s === undefined ? undefined : _s.panRate) || 100;
6586
+ this.contextMenu = new DiagramContextMenu(this, (_a = config.canvas) === null || _a === undefined ? undefined : _a.contextMenu);
6587
+ this.backgroundColor = ((_b = config.canvas) === null || _b === undefined ? undefined : _b.backgroundColor) || '#FFFFFF';
6588
+ this.gridSize = ((_d = (_c = config.canvas) === null || _c === undefined ? undefined : _c.grid) === null || _d === undefined ? undefined : _d.enabled) === false || ((_e = config.canvas) === null || _e === undefined ? undefined : _e.grid) === undefined ? 0 : Math.abs(((_g = (_f = config.canvas) === null || _f === undefined ? undefined : _f.grid) === null || _g === undefined ? undefined : _g.spacing) || 10);
6589
+ this.gridThickness = Math.abs(((_j = (_h = config.canvas) === null || _h === undefined ? undefined : _h.grid) === null || _j === undefined ? undefined : _j.thickness) || 0.05);
6590
+ this.gridColor = ((_l = (_k = config.canvas) === null || _k === undefined ? undefined : _k.grid) === null || _l === undefined ? undefined : _l.color) || 'rgba(0, 0, 0, 0.1)';
6591
+ this.snapToGrid = ((_o = (_m = config.canvas) === null || _m === undefined ? undefined : _m.grid) === null || _o === undefined ? undefined : _o.enabled) === false || ((_p = config.canvas) === null || _p === undefined ? undefined : _p.grid) === undefined ? false : ((_r = (_q = config.canvas) === null || _q === undefined ? undefined : _q.grid) === null || _r === undefined ? undefined : _r.snap) || false;
6592
+ this.zoomFactor = ((_s = config.canvas) === null || _s === undefined ? undefined : _s.zoomFactor) || 2;
6593
+ this.panRate = ((_t = config.canvas) === null || _t === undefined ? undefined : _t.panRate) || 100;
6595
6594
  this.inferConnectionType = config.inferConnectionType || false;
6596
6595
  this.multipleSelectionOn = false;
6597
- this.priorityThresholds = ((_t = config.canvas) === null || _t === undefined ? undefined : _t.priorityThresholds) || [];
6596
+ this.priorityThresholds = ((_u = config.canvas) === null || _u === undefined ? undefined : _u.priorityThresholds) || [];
6598
6597
  this.priorityThreshold = this.priorityThresholds ? this.priorityThresholds[0] : undefined;
6599
6598
  this.layoutFormat = config.layoutFormat;
6600
6599
  this.userActions = config.userActions || {};
@@ -7796,11 +7795,17 @@ class DiagramCanvas {
7796
7795
  this.secondaryButton = isSecondaryButton(event);
7797
7796
  return true;
7798
7797
  }).on(DragEvents.Start, event => {
7799
- this.startMultipleSelection(event);
7798
+ if (this.multipleSelectionOn || this.secondaryButton) {
7799
+ this.startMultipleSelection(event);
7800
+ }
7800
7801
  }).on(DragEvents.Drag, event => {
7801
- this.continueMultipleSelection(event);
7802
+ if (this.multipleSelectionOn || this.secondaryButton) {
7803
+ this.continueMultipleSelection(event);
7804
+ }
7802
7805
  }).on(DragEvents.End, event => {
7803
- this.finishMultipleSelection(event);
7806
+ if (this.multipleSelectionOn || this.secondaryButton) {
7807
+ this.finishMultipleSelection(event);
7808
+ }
7804
7809
  }));
7805
7810
  }
7806
7811
  updateDecoratorsInView(...ids) {
@@ -7832,12 +7837,55 @@ class DiagramCanvas {
7832
7837
  }).call(d3.drag().filter(event => {
7833
7838
  this.secondaryButton = isSecondaryButton(event);
7834
7839
  return true;
7835
- }).on(DragEvents.Start, event => {
7836
- this.startMultipleSelection(event);
7837
- }).on(DragEvents.Drag, event => {
7838
- this.continueMultipleSelection(event);
7839
- }).on(DragEvents.End, event => {
7840
- this.finishMultipleSelection(event);
7840
+ }).on(DragEvents.Start, (event, d) => {
7841
+ if (this.multipleSelectionOn || this.secondaryButton) {
7842
+ this.startMultipleSelection(event);
7843
+ } else {
7844
+ let node;
7845
+ if (d.rootElement instanceof DiagramNode) {
7846
+ node = d.rootElement;
7847
+ } else if (d.rootElement instanceof DiagramSection) {
7848
+ node = d.rootElement.node;
7849
+ }
7850
+ if (node) {
7851
+ this.startMovingNode(event, node);
7852
+ } else {
7853
+ setCursorStyle(CursorStyle.NotAllowed);
7854
+ }
7855
+ }
7856
+ }).on(DragEvents.Drag, (event, d) => {
7857
+ if (this.multipleSelectionOn || this.secondaryButton) {
7858
+ this.continueMultipleSelection(event);
7859
+ } else {
7860
+ let node;
7861
+ if (d.rootElement instanceof DiagramNode) {
7862
+ node = d.rootElement;
7863
+ } else if (d.rootElement instanceof DiagramSection) {
7864
+ node = d.rootElement.node;
7865
+ }
7866
+ if (node) {
7867
+ this.continueMovingNode(event, node);
7868
+ } else {
7869
+ setCursorStyle(CursorStyle.NotAllowed);
7870
+ }
7871
+ }
7872
+ }).on(DragEvents.End, (event, d) => {
7873
+ if (this.multipleSelectionOn || this.secondaryButton) {
7874
+ this.finishMultipleSelection(event);
7875
+ } else {
7876
+ let node;
7877
+ if (d.rootElement instanceof DiagramNode) {
7878
+ node = d.rootElement;
7879
+ } else if (d.rootElement instanceof DiagramSection) {
7880
+ node = d.rootElement.node;
7881
+ }
7882
+ if (node) {
7883
+ this.finishMovingNode(event, node);
7884
+ } else {
7885
+ setCursorStyle();
7886
+ }
7887
+ }
7888
+ this.secondaryButton = false;
7841
7889
  }));
7842
7890
  }
7843
7891
  updateConnectionLabelsInView(connection) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metadev/daga",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "dependencies": {},
5
5
  "peerDependencies": {
6
6
  "d3": "^7.9.0",
package/src/index.d.ts CHANGED
@@ -7,6 +7,9 @@ export { DiagramUserSelection } from './lib/diagram/canvas/diagram-user-selectio
7
7
  export type { CollabAction, CollabActionSerialized } from './lib/diagram/collab/collab-action';
8
8
  export { CollabClient } from './lib/diagram/collab/collab-client';
9
9
  export type { CollabTimestamp, CollabTimestampSet } from './lib/diagram/collab/primitives';
10
+ export type { CanvasConfig, GridConfig } from './lib/diagram/config/diagram-canvas-config';
11
+ export type { ButtonsComponentConfig, ComponentsConfig, ConnectionTemplateConfig, ConnectionTypeConfig, DiagramConfig, ErrorsComponentConfig, FieldConfig, NodeTemplateConfig, NodeTypeConfig, PaletteComponentConfig, PaletteSectionConfig, PortConfig, PortTypeConfig, PropertyEditorComponentConfig, SectionConfig, SectionGridConfig, UserActionConfig } from './lib/diagram/config/diagram-config';
12
+ export type { ImageLook, ImageLookConfig, Look, LookConfig, MarkerImageLook, MarkerImageLookConfig, ShapedLook, ShapedLookConfig, StretchableImageLook, StretchableImageLookConfig } from './lib/diagram/config/diagram-look-config';
10
13
  export { DagaExporter } from './lib/diagram/converters/daga-exporter';
11
14
  export { DagaImporter } from './lib/diagram/converters/daga-importer';
12
15
  export type { DagaConnection, DagaModel, DagaNode, DagaPort, DagaSection } from './lib/diagram/converters/daga-model';
@@ -14,8 +17,6 @@ export type { DiagramModelExporter } from './lib/diagram/converters/diagram-mode
14
17
  export type { DiagramModelImporter } from './lib/diagram/converters/diagram-model-importer';
15
18
  export { ActionStack, AddConnectionAction, AddNodeAction, ApplyLayoutAction, DiagramActionMethod, DiagramActions, EditFieldAction, MoveAction, PasteAction, RemoveAction, SetGeometryAction, SetParentAction, UpdateValuesAction } from './lib/diagram/diagram-action';
16
19
  export type { DiagramAction } from './lib/diagram/diagram-action';
17
- export type { ButtonsComponentConfig, CanvasConfig, ComponentsConfig, ConnectionTemplateConfig, ConnectionTypeConfig, DiagramConfig, ErrorsComponentConfig, FieldConfig, GridConfig, NodeTemplateConfig, NodeTypeConfig, PaletteComponentConfig, PaletteSectionConfig, PortConfig, PortTypeConfig, PropertyEditorComponentConfig, SectionConfig, SectionGridConfig, UserActionConfig } from './lib/diagram/config/diagram-config';
18
- export type { MarkerImageLook, StretchableImageLook, ImageLook, ShapedLook, Look, MarkerImageLookConfig, StretchableImageLookConfig, ImageLookConfig, ShapedLookConfig, LookConfig } from './lib/diagram/config/diagram-look';
19
20
  export { DiagramDoubleClickEvent, DiagramEvent, DiagramEvents, DiagramHighlightedEvent, DiagramSecondaryClickEvent, DiagramSelectionEvent } from './lib/diagram/diagram-event';
20
21
  export { AdjacencyLayout } from './lib/diagram/layout/adjacency-layout';
21
22
  export { BreadthAdjacencyLayout } from './lib/diagram/layout/breadth-adjacency-layout';
@@ -1,4 +1,8 @@
1
1
  import { Canvas } from '../../interfaces/canvas';
2
+ import { ContextMenuConfig } from '../config/diagram-canvas-config';
3
+ export declare const CONTEXT_MENU_DEFAULTS: {
4
+ customButtons: never[];
5
+ };
2
6
  /**
3
7
  * Stores the functionality regarding the context menu of a diagram canvas.
4
8
  * @public
@@ -6,13 +10,14 @@ import { Canvas } from '../../interfaces/canvas';
6
10
  */
7
11
  export declare class DiagramContextMenu {
8
12
  private readonly canvas;
13
+ private config;
9
14
  private contextMenuContainer?;
10
15
  /**
11
16
  * Constructs a context menu object.
12
17
  * @public
13
18
  * @param canvas A canvas.
14
19
  */
15
- constructor(canvas: Canvas);
20
+ constructor(canvas: Canvas, config?: ContextMenuConfig);
16
21
  /**
17
22
  * Opens the context menu at the location determined by the given mouse event.
18
23
  * @public
@@ -0,0 +1,97 @@
1
+ import { Canvas } from '../../interfaces/canvas';
2
+ /**
3
+ * The configuration for the visual behavior of a diagram in the user interface.
4
+ * @public
5
+ */
6
+ export interface CanvasConfig {
7
+ /**
8
+ * Configuration for the context menu in this diagram.
9
+ * If left undefined, the default context menu is used.
10
+ */
11
+ contextMenu?: ContextMenuConfig;
12
+ /**
13
+ * Configuration for the grid in the canvas.
14
+ * If left undefined, it is interpreted as disabling the grid,
15
+ * same as if the attribute `enabled` in its configuration was set to `false`.
16
+ */
17
+ grid?: GridConfig;
18
+ /**
19
+ * Background color of this diagram.
20
+ * @default "#FFFFFF"
21
+ */
22
+ backgroundColor?: string;
23
+ /**
24
+ * The factor by which the zoom level increases or decreases when the user users buttons or keys to zoom in or out. Should be above 1.
25
+ * @default 2
26
+ */
27
+ zoomFactor?: number;
28
+ /**
29
+ * The rate by which the view of the canvas moves when the user users buttons or keys to pan at a default zoom level in diagram units. Should be above 1.
30
+ * @default 100
31
+ */
32
+ panRate?: number;
33
+ /**
34
+ * Possible values of the priority threshold that the user can toggle between to hide nodes whose priority value is below it.
35
+ * If it is possible to toggle the priority threshold via the filter button, it should have at least two values.
36
+ * @default []
37
+ */
38
+ priorityThresholds?: number[];
39
+ }
40
+ /**
41
+ * Configuration of the guide grid in the background of the diagram.
42
+ */
43
+ export interface GridConfig {
44
+ /**
45
+ * Whether the grid is present in the diagram.
46
+ * @default true
47
+ */
48
+ enabled?: boolean;
49
+ /**
50
+ * Color of grid elements such as the points or axes.
51
+ * @default "rgba(0, 0, 0, 0.1)"
52
+ */
53
+ color?: string;
54
+ /**
55
+ * When true, the user moving or stretching nodes will cause their corners to automatically snap to the closest grid point.
56
+ * @default false
57
+ */
58
+ snap?: boolean;
59
+ /**
60
+ * Distance between each point of the grid of this diagram in diagram units.
61
+ * @default 10
62
+ */
63
+ spacing?: number;
64
+ /**
65
+ * In a range between 0 and 1, how thick the points of the grid are relative to the distance between them.
66
+ * @default 0.05
67
+ */
68
+ thickness?: number;
69
+ }
70
+ export interface ContextMenuConfig {
71
+ /**
72
+ * Custom buttons to be added to the context menu.
73
+ * @default []
74
+ */
75
+ customButtons?: ContextMenuButtonConfig[];
76
+ }
77
+ export interface ContextMenuButtonConfig {
78
+ /**
79
+ * Text on the button.
80
+ */
81
+ name: string;
82
+ /**
83
+ * File path to the image icon used by this button.
84
+ */
85
+ image?: string;
86
+ /**
87
+ * A function which is executed when the user clicks on this button.
88
+ * @param canvas The diagram's canvas.
89
+ */
90
+ onPress?: (canvas: Canvas) => void;
91
+ /**
92
+ * A function which given the canvas determines if the button should be present if the user opens a context menu on the canvas.
93
+ * @param canvas The diagram's canvas.
94
+ * @returns `true` if the button should be present on the menu, `false` otherwise.
95
+ */
96
+ condition?: (canvas: Canvas) => boolean;
97
+ }
@@ -2,7 +2,8 @@ import { Point } from '../../util/canvas-util';
2
2
  import { Corner, HorizontalAlign, Side, VerticalAlign } from '../../util/svg-util';
3
3
  import { DiagramActions } from '../diagram-action';
4
4
  import { Property } from '../model/diagram-property';
5
- import { ConnectionLookConfig, ImageLookConfig, MarkerImageLookConfig, ShapedLookConfig, StretchableImageLookConfig } from './diagram-look';
5
+ import { CanvasConfig } from './diagram-canvas-config';
6
+ import { ConnectionLookConfig, ImageLookConfig, MarkerImageLookConfig, ShapedLookConfig, StretchableImageLookConfig } from './diagram-look-config';
6
7
  /**
7
8
  * The configuration for a diagram.
8
9
  * @public
@@ -86,69 +87,6 @@ export interface DiagramConfig {
86
87
  */
87
88
  properties?: Property[];
88
89
  }
89
- /**
90
- * The configuration for the visual behavior of a diagram in the user interface.
91
- * @public
92
- */
93
- export interface CanvasConfig {
94
- /**
95
- * Configuration for the grid in the canvas.
96
- * If left undefined, it is interpreted as disabling the grid,
97
- * same as if the attribute `enabled` in its configuration was set to `false`.
98
- */
99
- grid?: GridConfig;
100
- /**
101
- * Background color of this diagram.
102
- * @default "#FFFFFF"
103
- */
104
- backgroundColor?: string;
105
- /**
106
- * The factor by which the zoom level increases or decreases when the user users buttons or keys to zoom in or out. Should be above 1.
107
- * @default 2
108
- */
109
- zoomFactor?: number;
110
- /**
111
- * The rate by which the view of the canvas moves when the user users buttons or keys to pan at a default zoom level in diagram units. Should be above 1.
112
- * @default 100
113
- */
114
- panRate?: number;
115
- /**
116
- * Possible values of the priority threshold that the user can toggle between to hide nodes whose priority value is below it.
117
- * If it is possible to toggle the priority threshold via the filter button, it should have at least two values.
118
- * @default []
119
- */
120
- priorityThresholds?: number[];
121
- }
122
- /**
123
- * Configuration of the guide grid in the background of the diagram.
124
- */
125
- export interface GridConfig {
126
- /**
127
- * Whether the grid is present in the diagram.
128
- * @default true
129
- */
130
- enabled?: boolean;
131
- /**
132
- * Color of grid elements such as the points or axes.
133
- * @default "rgba(0, 0, 0, 0.1)"
134
- */
135
- color?: string;
136
- /**
137
- * When true, the user moving or stretching nodes will cause their corners to automatically snap to the closest grid point.
138
- * @default false
139
- */
140
- snap?: boolean;
141
- /**
142
- * Distance between each point of the grid of this diagram in diagram units.
143
- * @default 10
144
- */
145
- spacing?: number;
146
- /**
147
- * In a range between 0 and 1, how thick the points of the grid are relative to the distance between them.
148
- * @default 0.05
149
- */
150
- thickness?: number;
151
- }
152
90
  /**
153
91
  * Configuration for which user actions are allowed in a diagram.
154
92
  * @public
@@ -2,7 +2,7 @@ import { Point } from '../../util/canvas-util';
2
2
  import { LineShape, LineStyle } from '../../util/line';
3
3
  import { Side } from '../../util/svg-util';
4
4
  import { ConnectionTypeConfig, FieldConfig } from '../config/diagram-config';
5
- import { ConnectionLook, ConnectionLookConfig, MarkerImageLook, MarkerImageLookConfig } from '../config/diagram-look';
5
+ import { ConnectionLook, ConnectionLookConfig, MarkerImageLook, MarkerImageLookConfig } from '../config/diagram-look-config';
6
6
  import { DiagramElement, DiagramElementSet } from './diagram-element';
7
7
  import { DiagramEntity, DiagramEntitySet } from './diagram-entity';
8
8
  import { DiagramModel } from './diagram-model';
@@ -36,7 +36,6 @@ export declare class DiagramDecorator extends DiagramElement {
36
36
  priority: number;
37
37
  html: string;
38
38
  constructor(model: DiagramModel, rootElement: DiagramNode | DiagramSection | undefined, coords: Point, width: number, height: number, priority: number, html: string, id: string);
39
- select(): d3.Selection<SVGGElement, unknown, null, unknown> | undefined;
40
39
  get removed(): boolean;
41
40
  updateInView(): void;
42
41
  raise(): void;
@@ -110,7 +110,6 @@ export declare class DiagramField extends DiagramElement {
110
110
  */
111
111
  fit: boolean;
112
112
  constructor(model: DiagramModel, rootElement: (LabeledElement & DiagramElement) | undefined, coords: Point, width: number, height: number, fontSize: number, fontFamily: string | null, color: string, selectedColor: string, horizontalAlign: HorizontalAlign, verticalAlign: VerticalAlign, text: string, editable: boolean, fit: boolean);
113
- select(): d3.Selection<SVGGElement, unknown, null, unknown> | undefined;
114
113
  get removed(): boolean;
115
114
  updateInView(): void;
116
115
  raise(): void;
@@ -2,7 +2,7 @@ import { Point } from '../../util/canvas-util';
2
2
  import { Side } from '../../util/svg-util';
3
3
  import { CollabTimestamp } from '../collab/primitives';
4
4
  import { FieldConfig, NodeTypeConfig, PortConfig } from '../config/diagram-config';
5
- import { ImageLook, ImageLookConfig, ShapedLook, ShapedLookConfig, StretchableImageLook, StretchableImageLookConfig } from '../config/diagram-look';
5
+ import { ImageLook, ImageLookConfig, ShapedLook, ShapedLookConfig, StretchableImageLook, StretchableImageLookConfig } from '../config/diagram-look-config';
6
6
  import { DiagramConnection } from './diagram-connection';
7
7
  import { DiagramDecorator } from './diagram-decorator';
8
8
  import { DiagramElement, DiagramElementSet } from './diagram-element';
@@ -25,7 +25,6 @@ export declare class DiagramObject extends DiagramElement {
25
25
  priority: number;
26
26
  html: string;
27
27
  constructor(model: DiagramModel, coords: Point, width: number, height: number, priority: number, html: string, id: string);
28
- select(): d3.Selection<SVGGElement, unknown, null, unknown> | undefined;
29
28
  get removed(): boolean;
30
29
  updateInView(): void;
31
30
  raise(): void;
@@ -1,7 +1,7 @@
1
1
  import { Point } from '../../util/canvas-util';
2
2
  import { Side } from '../../util/svg-util';
3
3
  import { FieldConfig, PortTypeConfig } from '../config/diagram-config';
4
- import { ImageLook, ImageLookConfig, ShapedLook, ShapedLookConfig } from '../config/diagram-look';
4
+ import { ImageLook, ImageLookConfig, ShapedLook, ShapedLookConfig } from '../config/diagram-look-config';
5
5
  import { DiagramConnection } from './diagram-connection';
6
6
  import { DiagramElement, DiagramElementSet } from './diagram-element';
7
7
  import { DiagramEntity, DiagramEntitySet } from './diagram-entity';
@@ -1,7 +1,7 @@
1
1
  import { Point } from '../../util/canvas-util';
2
2
  import { Side } from '../../util/svg-util';
3
3
  import { FieldConfig, PortConfig, SectionConfig, SectionGridConfig } from '../config/diagram-config';
4
- import { ImageLookConfig, ShapedLookConfig, StretchableImageLookConfig } from '../config/diagram-look';
4
+ import { ImageLookConfig, ShapedLookConfig, StretchableImageLookConfig } from '../config/diagram-look-config';
5
5
  import { DiagramConnection } from './diagram-connection';
6
6
  import { DiagramDecorator } from './diagram-decorator';
7
7
  import { DiagramElement, DiagramElementSet } from './diagram-element';
@@ -0,0 +1 @@
1
+ export declare const escapeSelector: (selector: string) => string;