w-flow-vue 1.0.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.
Files changed (144) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.js +55 -0
  4. package/.jsdoc +25 -0
  5. package/AGENT.md +223 -0
  6. package/LICENSE +21 -0
  7. package/README.md +37 -0
  8. package/SECURITY.md +5 -0
  9. package/babel.config.js +16 -0
  10. package/dist/w-flow-vue.umd.js +15 -0
  11. package/dist/w-flow-vue.umd.js.map +1 -0
  12. package/docs/components_WFlowVue.vue.html +1214 -0
  13. package/docs/examples/app.html +62 -0
  14. package/docs/examples/app.umd.js +20 -0
  15. package/docs/examples/app.umd.js.map +1 -0
  16. package/docs/examples/ex-AppBasic.html +440 -0
  17. package/docs/examples/ex-AppConnectivity.html +131 -0
  18. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  19. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  20. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  21. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  22. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  23. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  24. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  25. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  28. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  29. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  30. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  31. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  32. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  33. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  34. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  35. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  36. package/docs/global.html +1919 -0
  37. package/docs/index.html +84 -0
  38. package/docs/js_defaults.mjs.html +105 -0
  39. package/docs/js_edge-path.mjs.html +237 -0
  40. package/docs/js_geometry.mjs.html +298 -0
  41. package/docs/js_graph.mjs.html +103 -0
  42. package/docs/js_step-routing.mjs.html +346 -0
  43. package/docs/module-WFlowVue.html +2790 -0
  44. package/docs/scripts/collapse.js +39 -0
  45. package/docs/scripts/commonNav.js +28 -0
  46. package/docs/scripts/linenumber.js +25 -0
  47. package/docs/scripts/nav.js +12 -0
  48. package/docs/scripts/polyfill.js +4 -0
  49. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  50. package/docs/scripts/prettify/lang-css.js +2 -0
  51. package/docs/scripts/prettify/prettify.js +28 -0
  52. package/docs/scripts/search.js +99 -0
  53. package/docs/styles/jsdoc.css +776 -0
  54. package/docs/styles/prettify.css +80 -0
  55. package/jest.config.js +20 -0
  56. package/package.json +80 -0
  57. package/public/index.html +38 -0
  58. package/script.txt +22 -0
  59. package/src/App.vue +326 -0
  60. package/src/AppBasic.vue +125 -0
  61. package/src/AppConnectivity.vue +186 -0
  62. package/src/components/WFlowVue.vue +1142 -0
  63. package/src/components/canvas/BackgroundLayer.vue +78 -0
  64. package/src/components/canvas/FlowCanvas.vue +64 -0
  65. package/src/components/canvas/SelectionBox.vue +36 -0
  66. package/src/components/canvas/ViewportTransform.vue +35 -0
  67. package/src/components/edges/ConnectionLine.vue +65 -0
  68. package/src/components/edges/EdgeMarkerDefs.vue +76 -0
  69. package/src/components/edges/EdgeRenderer.vue +120 -0
  70. package/src/components/edges/EdgeWrapper.vue +379 -0
  71. package/src/components/nodes/DefaultNode.vue +276 -0
  72. package/src/components/nodes/Handle.vue +101 -0
  73. package/src/components/nodes/InputNode.vue +47 -0
  74. package/src/components/nodes/NodeBody.vue +103 -0
  75. package/src/components/nodes/NodeFace.vue +128 -0
  76. package/src/components/nodes/NodeRenderer.vue +95 -0
  77. package/src/components/nodes/NodeWrapper.vue +475 -0
  78. package/src/components/nodes/OutputNode.vue +47 -0
  79. package/src/components/ui/ConnSettingsForm.vue +158 -0
  80. package/src/components/ui/Controls.vue +83 -0
  81. package/src/components/ui/NodeSettingsForm.vue +185 -0
  82. package/src/js/defaults.mjs +33 -0
  83. package/src/js/edge-path.mjs +165 -0
  84. package/src/js/geometry.mjs +226 -0
  85. package/src/js/graph.mjs +31 -0
  86. package/src/js/step-routing.mjs +274 -0
  87. package/src/main.js +22 -0
  88. package/test/WFlowVue-features.test.mjs +760 -0
  89. package/test/WFlowVue.test.mjs +421 -0
  90. package/test/components-canvas.test.mjs +102 -0
  91. package/test/components-edge.test.mjs +147 -0
  92. package/test/components-node.test.mjs +174 -0
  93. package/test/components-ui.test.mjs +69 -0
  94. package/test/defaults.test.mjs +86 -0
  95. package/test/edge-path.test.mjs +102 -0
  96. package/test/generate-routing-snapshots.mjs +77 -0
  97. package/test/generate-visual-baselines.mjs +206 -0
  98. package/test/geometry.test.mjs +236 -0
  99. package/test/graph.test.mjs +72 -0
  100. package/test/jsons/routing-snapshots.json +24994 -0
  101. package/test/pics/_check2.png +0 -0
  102. package/test/pics/_check3.png +0 -0
  103. package/test/pics/_check4.png +0 -0
  104. package/test/pics/_check5.png +0 -0
  105. package/test/pics/_v1.png +0 -0
  106. package/test/pics/_v2.png +0 -0
  107. package/test/pics/_v3.png +0 -0
  108. package/test/pics/_v4.png +0 -0
  109. package/test/pics/_v5.png +0 -0
  110. package/test/pics/_v6.png +0 -0
  111. package/test/pics/_v7.png +0 -0
  112. package/test/pics/vb-edge-hovered.png +0 -0
  113. package/test/pics/vb-edges-normal.png +0 -0
  114. package/test/pics/vb-locked-edge-hovered.png +0 -0
  115. package/test/pics/vb-locked-node-hovered.png +0 -0
  116. package/test/pics/vb-locked-node-selected.png +0 -0
  117. package/test/pics/vb-locked-overview.png +0 -0
  118. package/test/pics/vb-node-1.png +0 -0
  119. package/test/pics/vb-node-10.png +0 -0
  120. package/test/pics/vb-node-11.png +0 -0
  121. package/test/pics/vb-node-12.png +0 -0
  122. package/test/pics/vb-node-2.png +0 -0
  123. package/test/pics/vb-node-3.png +0 -0
  124. package/test/pics/vb-node-4.png +0 -0
  125. package/test/pics/vb-node-5.png +0 -0
  126. package/test/pics/vb-node-6.png +0 -0
  127. package/test/pics/vb-node-7.png +0 -0
  128. package/test/pics/vb-node-8.png +0 -0
  129. package/test/pics/vb-node-9.png +0 -0
  130. package/test/pics/vb-node-hovered.png +0 -0
  131. package/test/pics/vb-node-selected.png +0 -0
  132. package/test/pics/vb-overview.png +0 -0
  133. package/test/step-routing-connectivity.test.mjs +78 -0
  134. package/test/step-routing.test.mjs +88 -0
  135. package/test/visual-regression.test.mjs +274 -0
  136. package/toolg/addVersion.mjs +4 -0
  137. package/toolg/cleanFolder.mjs +4 -0
  138. package/toolg/gDistApp.mjs +34 -0
  139. package/toolg/gDistRollupComps.mjs +22 -0
  140. package/toolg/gDocExams.mjs +47 -0
  141. package/toolg/gExtractHtml.mjs +179 -0
  142. package/toolg/modifyReadme.mjs +4 -0
  143. package/vue.config.js +9 -0
  144. package/vue2/344/271/213foreignObject/345/205/247/346/270/262/346/237/223/345/225/217/351/241/214/350/210/207/344/277/256/346/255/243.md +151 -0
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <div
3
+ v-if="!locked"
4
+ :class="classes"
5
+ :style="offsetStyle"
6
+ :data-handle-id="id || type"
7
+ :data-handle-type="type"
8
+ :data-handle-position="position"
9
+ @mousedown.stop="onMouseDown"
10
+ />
11
+ </template>
12
+
13
+ <script>
14
+ export default {
15
+ name: 'FlowHandle',
16
+ props: {
17
+ type: { type: String, default: 'source' }, // 'source' | 'target'
18
+ position: { type: String, default: 'bottom' }, // 'top' | 'right' | 'bottom' | 'left'
19
+ id: { type: String, default: null },
20
+ connectable: { type: Boolean, default: true },
21
+ locked: { type: Boolean, default: false },
22
+ offset: { type: String, default: null },
23
+ customStyle: { type: Object, default: null },
24
+ },
25
+ computed: {
26
+ offsetStyle() {
27
+ if (this.customStyle) return this.customStyle
28
+ if (!this.offset) return null
29
+ const isHorizontal = this.position === 'top' || this.position === 'bottom'
30
+ if (isHorizontal) return { left: this.offset, transform: 'translateX(-50%)' }
31
+ return { top: this.offset, transform: 'translateY(-50%)' }
32
+ },
33
+ classes() {
34
+ return [
35
+ 'vue-flow__handle',
36
+ `vue-flow__handle--${this.position}`,
37
+ `vue-flow__handle--${this.type}`,
38
+ { 'vue-flow__handle--not-connectable': !this.connectable },
39
+ ]
40
+ },
41
+ },
42
+ methods: {
43
+ onMouseDown(event) {
44
+ if (!this.connectable) return
45
+ this.$emit('connect-start', {
46
+ event,
47
+ handleId: this.id || this.type,
48
+ handleType: this.type,
49
+ handlePosition: this.position,
50
+ })
51
+ },
52
+ },
53
+ }
54
+ </script>
55
+
56
+ <style scoped>
57
+ .vue-flow__handle {
58
+ position: absolute;
59
+ width: 8px;
60
+ height: 8px;
61
+ border-radius: 50%;
62
+ background: #555;
63
+ border: 1px solid #fff;
64
+ pointer-events: all;
65
+ cursor: crosshair;
66
+ z-index: 3;
67
+ }
68
+ .vue-flow__handle--top {
69
+ top: -4px;
70
+ left: 50%;
71
+ transform: translateX(-50%);
72
+ }
73
+ .vue-flow__handle--bottom {
74
+ bottom: -4px;
75
+ left: 50%;
76
+ transform: translateX(-50%);
77
+ }
78
+ .vue-flow__handle--left {
79
+ top: 50%;
80
+ left: -4px;
81
+ transform: translateY(-50%);
82
+ }
83
+ .vue-flow__handle--right {
84
+ top: 50%;
85
+ right: -4px;
86
+ transform: translateY(-50%);
87
+ }
88
+ .vue-flow__handle--not-connectable {
89
+ cursor: default;
90
+ pointer-events: none;
91
+ }
92
+ .vue-flow__handle:hover {
93
+ background: #0041d0;
94
+ width: 10px;
95
+ height: 10px;
96
+ }
97
+ .vue-flow__handle--top:hover { top: -5px; }
98
+ .vue-flow__handle--bottom:hover { bottom: -5px; }
99
+ .vue-flow__handle--left:hover { left: -5px; }
100
+ .vue-flow__handle--right:hover { right: -5px; }
101
+ </style>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <div class="vue-flow__node-input">
3
+ <div class="vue-flow__node-label">{{ node.name }}</div>
4
+ <Handle
5
+ type="source"
6
+ :position="node.toPosition || dn.toPosition || 'bottom'"
7
+ :connectable="connectable"
8
+ :locked="locked"
9
+ @connect-start="$emit('connect-start', $event)"
10
+ />
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ import Handle from './Handle.vue'
16
+
17
+ export default {
18
+ name: 'InputNode',
19
+ components: { Handle },
20
+ inject: { getDefNode: { default: () => () => ({}) } },
21
+ props: {
22
+ node: { type: Object, required: true },
23
+ connectable: { type: Boolean, default: true },
24
+ locked: { type: Boolean, default: false },
25
+ },
26
+ computed: {
27
+ dn() {
28
+ return this.getDefNode()
29
+ },
30
+ },
31
+ }
32
+ </script>
33
+
34
+ <style scoped>
35
+ .vue-flow__node-input {
36
+ position: absolute;
37
+ top: 0;
38
+ left: 0;
39
+ right: 0;
40
+ bottom: 0;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ box-sizing: border-box;
45
+ padding: 10px 20px;
46
+ }
47
+ </style>
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div class="vue-flow__node-body" :style="bodyStyle">
3
+ <NodeFace :node="node" :lastW="lastW" :lastH="lastH" />
4
+ <component
5
+ :is="nodeComponent"
6
+ :node="node"
7
+ :connectable="connectable"
8
+ :locked="locked"
9
+ @connect-start="$emit('connect-start', $event)"
10
+ />
11
+ <!-- Corner resize handles (4 corners only) -->
12
+ <transition name="vue-flow__fade">
13
+ <div v-if="resizable && !locked && (selected || hovered)" class="vue-flow__resize-group">
14
+ <div class="vue-flow__resize vue-flow__resize--top-left" @mousedown.stop="$emit('resize-start', { event: $event, edge: 'top-left' })"></div>
15
+ <div class="vue-flow__resize vue-flow__resize--top-right" @mousedown.stop="$emit('resize-start', { event: $event, edge: 'top-right' })"></div>
16
+ <div class="vue-flow__resize vue-flow__resize--bottom-left" @mousedown.stop="$emit('resize-start', { event: $event, edge: 'bottom-left' })"></div>
17
+ <div class="vue-flow__resize vue-flow__resize--bottom-right" @mousedown.stop="$emit('resize-start', { event: $event, edge: 'bottom-right' })"></div>
18
+ </div>
19
+ </transition>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ import NodeFace from './NodeFace.vue'
25
+ import DefaultNode from './DefaultNode.vue'
26
+ import InputNode from './InputNode.vue'
27
+ import OutputNode from './OutputNode.vue'
28
+
29
+ const builtInNodes = {
30
+ basic: DefaultNode,
31
+ input: InputNode,
32
+ output: OutputNode,
33
+ }
34
+
35
+ export default {
36
+ name: 'NodeBody',
37
+ components: { NodeFace, DefaultNode, InputNode, OutputNode },
38
+ props: {
39
+ node: { type: Object, required: true },
40
+ connectable: { type: Boolean, default: true },
41
+ selected: { type: Boolean, default: false },
42
+ resizable: { type: Boolean, default: true },
43
+ locked: { type: Boolean, default: false },
44
+ hovered: { type: Boolean, default: false },
45
+ lastW: { type: Number, default: 0 },
46
+ lastH: { type: Number, default: 0 },
47
+ },
48
+ computed: {
49
+ nodeComponent() {
50
+ return builtInNodes[this.node.type || 'basic'] || DefaultNode
51
+ },
52
+ bodyStyle() {
53
+ const w = this.lastW || this.node.width
54
+ const h = this.lastH || this.node.height
55
+ const s = {}
56
+ if (w) s.width = (typeof w === 'number' ? w + 'px' : w)
57
+ if (h) s.height = (typeof h === 'number' ? h + 'px' : h)
58
+ return s
59
+ },
60
+ },
61
+ }
62
+ </script>
63
+
64
+ <style scoped>
65
+ .vue-flow__node-body {
66
+ box-sizing: border-box;
67
+ }
68
+ .vue-flow__resize {
69
+ position: absolute;
70
+ pointer-events: all;
71
+ }
72
+ .vue-flow__resize--top-left,
73
+ .vue-flow__resize--top-right,
74
+ .vue-flow__resize--bottom-left,
75
+ .vue-flow__resize--bottom-right {
76
+ width: 10px;
77
+ height: 10px;
78
+ z-index: 1;
79
+ border-radius: 2px;
80
+ background: #fff;
81
+ border: 1.5px solid #bbb;
82
+ transition: border-color 0.15s ease;
83
+ }
84
+ .vue-flow__resize--top-left:hover,
85
+ .vue-flow__resize--top-right:hover,
86
+ .vue-flow__resize--bottom-left:hover,
87
+ .vue-flow__resize--bottom-right:hover {
88
+ border-color: #0041d0;
89
+ background: #e8f0fe;
90
+ }
91
+ .vue-flow__resize--top-left { top: -5px; left: -5px; cursor: nwse-resize; }
92
+ .vue-flow__resize--top-right { top: -5px; right: -5px; cursor: nesw-resize; }
93
+ .vue-flow__resize--bottom-left { bottom: -5px; left: -5px; cursor: nesw-resize; }
94
+ .vue-flow__resize--bottom-right { bottom: -5px; right: -5px; cursor: nwse-resize; }
95
+ .vue-flow__fade-enter-active,
96
+ .vue-flow__fade-leave-active {
97
+ transition: opacity 0.15s ease;
98
+ }
99
+ .vue-flow__fade-enter,
100
+ .vue-flow__fade-leave-to {
101
+ opacity: 0;
102
+ }
103
+ </style>
@@ -0,0 +1,128 @@
1
+ <template>
2
+ <div class="vue-flow__node-face">
3
+ <!-- Diamond shape SVG -->
4
+ <svg
5
+ v-if="isDiamond"
6
+ class="vue-flow__shape-svg"
7
+ :viewBox="diamondViewBox"
8
+ preserveAspectRatio="none"
9
+ >
10
+ <polygon
11
+ :points="diamondPoints"
12
+ :fill="node.faceColor || dn.faceColor || '#fff'"
13
+ :fill-opacity="1"
14
+ :stroke="node.edgeColor || dn.edgeColor || '#bbb'"
15
+ :stroke-opacity="1"
16
+ :stroke-width="node.edgeWidth !== undefined ? node.edgeWidth : (dn.edgeWidth !== undefined ? dn.edgeWidth : 1)"
17
+ />
18
+ </svg>
19
+ <!-- Ellipse shape SVG -->
20
+ <svg
21
+ v-if="isEllipse"
22
+ class="vue-flow__shape-svg"
23
+ :viewBox="svgViewBox"
24
+ preserveAspectRatio="none"
25
+ >
26
+ <ellipse
27
+ :cx="nodeW / 2"
28
+ :cy="nodeH / 2"
29
+ :rx="nodeW / 2"
30
+ :ry="nodeH / 2"
31
+ :fill="node.faceColor || dn.faceColor || '#fff'"
32
+ :fill-opacity="1"
33
+ :stroke="node.edgeColor || dn.edgeColor || '#bbb'"
34
+ :stroke-opacity="1"
35
+ :stroke-width="node.edgeWidth !== undefined ? node.edgeWidth : (dn.edgeWidth !== undefined ? dn.edgeWidth : 1)"
36
+ />
37
+ </svg>
38
+ <!-- Triangle shape SVG -->
39
+ <svg
40
+ v-if="isTriangle"
41
+ class="vue-flow__shape-svg"
42
+ :viewBox="svgViewBox"
43
+ preserveAspectRatio="none"
44
+ >
45
+ <polygon
46
+ :points="trianglePoints"
47
+ :fill="node.faceColor || dn.faceColor || '#fff'"
48
+ :fill-opacity="1"
49
+ :stroke="node.edgeColor || dn.edgeColor || '#bbb'"
50
+ :stroke-opacity="1"
51
+ :stroke-width="node.edgeWidth !== undefined ? node.edgeWidth : (dn.edgeWidth !== undefined ? dn.edgeWidth : 1)"
52
+ />
53
+ </svg>
54
+ </div>
55
+ </template>
56
+
57
+ <script>
58
+ export default {
59
+ name: 'NodeFace',
60
+ inject: { getDefNode: { default: () => () => ({}) } },
61
+ props: {
62
+ node: { type: Object, required: true },
63
+ lastW: { type: Number, default: 0 },
64
+ lastH: { type: Number, default: 0 },
65
+ },
66
+ computed: {
67
+ dn() {
68
+ return this.getDefNode()
69
+ },
70
+ nodeW() {
71
+ return this.node.width || this.lastW || 150
72
+ },
73
+ nodeH() {
74
+ return this.node.height || this.lastH || 40
75
+ },
76
+ isDiamond() {
77
+ return this.node.shape === 'diamond'
78
+ },
79
+ isEllipse() {
80
+ return this.node.shape === 'ellipse'
81
+ },
82
+ isTriangle() {
83
+ let s = this.node.shape
84
+ return s === 'triangle' || s === 'triangle-right' || s === 'triangle-down' || s === 'triangle-left'
85
+ },
86
+ diamondPoints() {
87
+ if (!this.isDiamond) return ''
88
+ return (this.nodeW / 2) + ',0 ' + this.nodeW + ',' + (this.nodeH / 2) + ' ' + (this.nodeW / 2) + ',' + this.nodeH + ' 0,' + (this.nodeH / 2)
89
+ },
90
+ trianglePoints() {
91
+ if (!this.isTriangle) return ''
92
+ let w = this.nodeW
93
+ let h = this.nodeH
94
+ let s = this.node.shape
95
+ if (s === 'triangle-right') return '0,0 ' + w + ',' + (h / 2) + ' 0,' + h
96
+ if (s === 'triangle-down') return '0,0 ' + w + ',0 ' + (w / 2) + ',' + h
97
+ if (s === 'triangle-left') return w + ',0 0,' + (h / 2) + ' ' + w + ',' + h
98
+ return (w / 2) + ',0 0,' + h + ' ' + w + ',' + h
99
+ },
100
+ svgViewBox() {
101
+ return '0 0 ' + this.nodeW + ' ' + this.nodeH
102
+ },
103
+ diamondViewBox() {
104
+ if (!this.isDiamond) return '0 0 150 40'
105
+ return this.svgViewBox
106
+ },
107
+ },
108
+ }
109
+ </script>
110
+
111
+ <style scoped>
112
+ .vue-flow__node-face {
113
+ pointer-events: none;
114
+ }
115
+ .vue-flow__shape-svg {
116
+ position: absolute;
117
+ top: 0;
118
+ left: 0;
119
+ width: 100%;
120
+ height: 100%;
121
+ pointer-events: none;
122
+ overflow: visible;
123
+ }
124
+ .vue-flow__shape-svg polygon,
125
+ .vue-flow__shape-svg ellipse {
126
+ transition: filter 0.3s ease;
127
+ }
128
+ </style>
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <div class="vue-flow__nodes">
3
+ <NodeWrapper
4
+ v-for="node in visibleNodes"
5
+ :key="node.id"
6
+ :node="node"
7
+ :selected="isSelected(node.id)"
8
+ :draggable="isDraggable(node)"
9
+ :connectable="isConnectable(node)"
10
+ :resizable="isResizable(node)"
11
+ :locked="locked"
12
+ :settings-popup-background-color="settingsPopupBackgroundColor"
13
+ :settings-popup-text-color="settingsPopupTextColor"
14
+ :settings-popup-text-font-size="settingsPopupTextFontSize"
15
+ :infor-popup-background-color="inforPopupBackgroundColor"
16
+ :infor-popup-title-text-color="inforPopupTitleTextColor"
17
+ :infor-popup-title-text-font-size="inforPopupTitleTextFontSize"
18
+ :infor-popup-description-text-color="inforPopupDescriptionTextColor"
19
+ :infor-popup-description-text-font-size="inforPopupDescriptionTextFontSize"
20
+ :snap-grid-size="snapGridSize"
21
+ @drag-start="$emit('drag-start', $event)"
22
+ @node-click="$emit('node-click', $event)"
23
+ @node-double-click="$emit('node-double-click', $event)"
24
+ @node-context-menu="$emit('node-context-menu', $event)"
25
+ @node-settings-click="$emit('node-settings-click', $event)"
26
+ @node-settings-update="$emit('node-settings-update', $event)"
27
+ @node-settings-delete="$emit('node-settings-delete', $event)"
28
+ @node-mouseenter="$emit('node-mouseenter', $event)"
29
+ @node-mouseleave="$emit('node-mouseleave', $event)"
30
+ @connect-start="$emit('connect-start', $event)"
31
+ @dimensions="$emit('dimensions', $event)"
32
+ @node-resize="$emit('node-resize', $event)"
33
+ @node-resize-end="$emit('node-resize-end', $event)"
34
+ >
35
+ <template v-if="$scopedSlots['node-popup']" v-slot:node-popup="scope">
36
+ <slot name="node-popup" v-bind="scope" />
37
+ </template>
38
+ </NodeWrapper>
39
+ </div>
40
+ </template>
41
+
42
+ <script>
43
+ import NodeWrapper from './NodeWrapper.vue'
44
+
45
+ export default {
46
+ name: 'NodeRenderer',
47
+ components: { NodeWrapper },
48
+ props: {
49
+ nodes: { type: Array, default: () => [] },
50
+ selectedNodeIds: { type: Array, default: () => [] },
51
+ nodesDraggable: { type: Boolean, default: true },
52
+ nodesConnectable: { type: Boolean, default: true },
53
+ nodesResizable: { type: Boolean, default: true },
54
+ locked: { type: Boolean, default: false },
55
+ settingsPopupBackgroundColor: { type: String, default: '#fff' },
56
+ settingsPopupTextColor: { type: String, default: '#333' },
57
+ settingsPopupTextFontSize: { type: String, default: '12px' },
58
+ inforPopupBackgroundColor: { type: String, default: '#fff' },
59
+ inforPopupTitleTextColor: { type: String, default: '#333' },
60
+ inforPopupTitleTextFontSize: { type: String, default: '12px' },
61
+ inforPopupDescriptionTextColor: { type: String, default: '#888' },
62
+ inforPopupDescriptionTextFontSize: { type: String, default: '10px' },
63
+ snapGridSize: { type: Number, default: null },
64
+ },
65
+ computed: {
66
+ visibleNodes() {
67
+ return this.nodes.filter(n => !n.hidden)
68
+ },
69
+ },
70
+ methods: {
71
+ isSelected(id) {
72
+ return this.selectedNodeIds.includes(id)
73
+ },
74
+ isDraggable(node) {
75
+ return node.draggable !== undefined ? node.draggable : this.nodesDraggable
76
+ },
77
+ isConnectable(node) {
78
+ return node.connectable !== undefined ? node.connectable : this.nodesConnectable
79
+ },
80
+ isResizable(node) {
81
+ return node.resizable !== undefined ? node.resizable : this.nodesResizable
82
+ },
83
+ },
84
+ }
85
+ </script>
86
+
87
+ <style scoped>
88
+ .vue-flow__nodes {
89
+ position: absolute;
90
+ top: 0;
91
+ left: 0;
92
+ width: 0;
93
+ height: 0;
94
+ }
95
+ </style>