@stonecrop/node-editor 0.4.35 → 0.4.37
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/node-editor.css +1 -1
- package/dist/node-editor.js +2777 -2697
- package/dist/node-editor.js.map +1 -1
- package/dist/node-editor.umd.cjs +3 -3
- package/dist/node-editor.umd.cjs.map +1 -1
- package/dist/node_editor.tsbuildinfo +1 -1
- package/package.json +16 -15
- package/src/components/EditableEdge.vue +1 -1
- package/src/components/EditableNode.vue +1 -1
- package/src/components/NodeEditor.vue +31 -23
- package/src/components/StateEditor.vue +1 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"5.
|
|
1
|
+
{"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/node-editor",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.37",
|
|
4
4
|
"description": "Node editor UI for Stonecrop",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,29 +36,30 @@
|
|
|
36
36
|
"src/*"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@vue-flow/core": "^1.
|
|
40
|
-
"vue": "^3.5.
|
|
41
|
-
"vue-router": "^4.
|
|
39
|
+
"@vue-flow/core": "^1.47.0",
|
|
40
|
+
"vue": "^3.5.22",
|
|
41
|
+
"vue-router": "^4.6.3",
|
|
42
42
|
"xstate": "^5.20.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@typescript-eslint/parser": "^7.18.0",
|
|
45
|
+
"@eslint/js": "^9.38.0",
|
|
46
|
+
"@microsoft/api-documenter": "^7.27.3",
|
|
47
|
+
"@rushstack/heft": "^1.1.3",
|
|
49
48
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
50
|
-
"eslint": "^
|
|
51
|
-
"eslint-config-prettier": "^
|
|
52
|
-
"eslint-plugin-vue": "^
|
|
53
|
-
"
|
|
54
|
-
"
|
|
49
|
+
"eslint": "^9.38.0",
|
|
50
|
+
"eslint-config-prettier": "^10.1.8",
|
|
51
|
+
"eslint-plugin-vue": "^10.5.1",
|
|
52
|
+
"globals": "^16.4.0",
|
|
53
|
+
"typescript": "^5.9.3",
|
|
54
|
+
"typescript-eslint": "^8.46.2",
|
|
55
|
+
"vite": "^7.1.1",
|
|
55
56
|
"stonecrop-rig": "0.2.22"
|
|
56
57
|
},
|
|
57
58
|
"publishConfig": {
|
|
58
59
|
"access": "public"
|
|
59
60
|
},
|
|
60
61
|
"engines": {
|
|
61
|
-
"node": ">=
|
|
62
|
+
"node": ">=22.5.0"
|
|
62
63
|
},
|
|
63
64
|
"scripts": {
|
|
64
65
|
"_phase:build": "heft build && vite build && rushx docs",
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
"build": "heft build && vite build && rushx docs",
|
|
67
68
|
"dev": "vite",
|
|
68
69
|
"docs": "cd ../common/autoinstallers/doc-tools && node generate-docs.mjs node_editor",
|
|
69
|
-
"lint": "eslint .
|
|
70
|
+
"lint": "eslint .",
|
|
70
71
|
"preview": "vite preview"
|
|
71
72
|
}
|
|
72
73
|
}
|
|
@@ -22,11 +22,14 @@
|
|
|
22
22
|
|
|
23
23
|
<VueFlow
|
|
24
24
|
v-if="vueFlowElements && vueFlowElements.length"
|
|
25
|
+
v-model="vueFlowElements"
|
|
25
26
|
class="nowheel"
|
|
26
27
|
:prevent-scrolling="true"
|
|
27
28
|
:zoom-on-scroll="false"
|
|
28
29
|
:fit-view-on-init="true"
|
|
29
|
-
|
|
30
|
+
@connect="handleConnect"
|
|
31
|
+
@pane-ready="setInstance"
|
|
32
|
+
@edge-context-menu="handleEdgeContextMenu"
|
|
30
33
|
@wheel.prevent="onWheel">
|
|
31
34
|
<template #node-editable="props">
|
|
32
35
|
<EditableNode v-bind="props" @change="labelChanged($event, props.id)" />
|
|
@@ -39,14 +42,23 @@
|
|
|
39
42
|
</template>
|
|
40
43
|
|
|
41
44
|
<script setup lang="ts">
|
|
42
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
type VueFlowStore,
|
|
47
|
+
Position,
|
|
48
|
+
VueFlow,
|
|
49
|
+
useVueFlow,
|
|
50
|
+
Connection,
|
|
51
|
+
Node,
|
|
52
|
+
EdgeMouseEvent,
|
|
53
|
+
DefaultEdge,
|
|
54
|
+
} from '@vue-flow/core'
|
|
43
55
|
import { type HTMLAttributes, ref, computed, defineEmits, onBeforeUnmount, onMounted } from 'vue'
|
|
44
56
|
|
|
45
57
|
import EditableEdge from './EditableEdge.vue'
|
|
46
58
|
import EditableNode from './EditableNode.vue'
|
|
47
59
|
import type { FlowElements } from '../types'
|
|
48
60
|
|
|
49
|
-
const { modelValue, nodeContainerClass } = defineProps<{
|
|
61
|
+
const { modelValue, nodeContainerClass = '' } = defineProps<{
|
|
50
62
|
modelValue: FlowElements
|
|
51
63
|
nodeContainerClass?: HTMLAttributes['class']
|
|
52
64
|
}>()
|
|
@@ -103,7 +115,7 @@ const elements = computed({
|
|
|
103
115
|
emit('update:modelValue', JSON.parse(JSON.stringify(newValue)))
|
|
104
116
|
},
|
|
105
117
|
})
|
|
106
|
-
const {
|
|
118
|
+
const { addEdges, removeEdges } = useVueFlow()
|
|
107
119
|
|
|
108
120
|
onMounted(() => {
|
|
109
121
|
document.removeEventListener('keypress', handleKeypress)
|
|
@@ -114,9 +126,9 @@ onBeforeUnmount(() => {
|
|
|
114
126
|
document.removeEventListener('keypress', handleKeypress)
|
|
115
127
|
})
|
|
116
128
|
|
|
117
|
-
|
|
129
|
+
const setInstance = (instance: VueFlowStore) => {
|
|
118
130
|
vueFlowInstance.value = instance
|
|
119
|
-
}
|
|
131
|
+
}
|
|
120
132
|
|
|
121
133
|
vueFlowElements.value = elements.value
|
|
122
134
|
|
|
@@ -133,6 +145,7 @@ const shiftTerminal = (currentTerminal: Position) => {
|
|
|
133
145
|
const shiftOutput = () => {
|
|
134
146
|
if (activeElementIndex.value > -1) {
|
|
135
147
|
const activeNode = vueFlowElements.value[activeElementIndex.value] as Node
|
|
148
|
+
if (!activeNode.sourcePosition) return
|
|
136
149
|
activeNode.sourcePosition = shiftTerminal(activeNode.sourcePosition)
|
|
137
150
|
}
|
|
138
151
|
}
|
|
@@ -140,6 +153,7 @@ const shiftOutput = () => {
|
|
|
140
153
|
const shiftInput = () => {
|
|
141
154
|
if (activeElementIndex.value > -1) {
|
|
142
155
|
const activeNode = vueFlowElements.value[activeElementIndex.value] as Node
|
|
156
|
+
if (!activeNode.targetPosition) return
|
|
143
157
|
activeNode.targetPosition = shiftTerminal(activeNode.targetPosition)
|
|
144
158
|
}
|
|
145
159
|
}
|
|
@@ -151,16 +165,16 @@ const onWheel = (event: WheelEvent) => {
|
|
|
151
165
|
const handleKeypress = (event: KeyboardEvent) => {
|
|
152
166
|
if (hover.value && event.ctrlKey == true) {
|
|
153
167
|
if (event.key == '+' || event.key == '=') {
|
|
154
|
-
void vueFlowInstance.value
|
|
168
|
+
void vueFlowInstance.value?.zoomIn()
|
|
155
169
|
}
|
|
156
170
|
if (event.key == '-') {
|
|
157
|
-
void vueFlowInstance.value
|
|
171
|
+
void vueFlowInstance.value?.zoomOut()
|
|
158
172
|
}
|
|
159
173
|
}
|
|
160
174
|
}
|
|
161
175
|
|
|
162
176
|
const fitView = async () => {
|
|
163
|
-
await vueFlowInstance.value
|
|
177
|
+
await vueFlowInstance.value?.fitView()
|
|
164
178
|
}
|
|
165
179
|
|
|
166
180
|
const addNode = () => {
|
|
@@ -168,7 +182,7 @@ const addNode = () => {
|
|
|
168
182
|
let newNodePosition = { x: Math.random() * 200, y: Math.random() * 200 }
|
|
169
183
|
if (activeElementIndex.value > -1) {
|
|
170
184
|
const activeNode = vueFlowElements.value[activeElementIndex.value]
|
|
171
|
-
if (activeNode.data
|
|
185
|
+
if (activeNode.data?.hasOutput) {
|
|
172
186
|
newNodePosition = { x: (activeNode as Node).position.x + 200, y: (activeNode as Node).position.y + 50 }
|
|
173
187
|
makeEdge = true
|
|
174
188
|
}
|
|
@@ -214,21 +228,21 @@ const addNode = () => {
|
|
|
214
228
|
}
|
|
215
229
|
}
|
|
216
230
|
|
|
217
|
-
const labelChanged = (
|
|
231
|
+
const labelChanged = (event: DefaultEdge['label'], id: DefaultEdge['id']) => {
|
|
218
232
|
for (let j = 0; j < vueFlowElements.value.length; j++) {
|
|
219
233
|
if (vueFlowElements.value[j].id == id) {
|
|
220
|
-
vueFlowElements.value[j].label =
|
|
234
|
+
vueFlowElements.value[j].label = event
|
|
221
235
|
break
|
|
222
236
|
}
|
|
223
237
|
}
|
|
224
238
|
}
|
|
225
239
|
|
|
226
|
-
const handleConnect = (
|
|
240
|
+
const handleConnect = (event: Connection) => {
|
|
227
241
|
const id = vueFlowElements.value.length
|
|
228
242
|
const newEdge = {
|
|
229
243
|
id: `edge-${id}`,
|
|
230
|
-
source:
|
|
231
|
-
target:
|
|
244
|
+
source: event.source,
|
|
245
|
+
target: event.target,
|
|
232
246
|
type: 'editable',
|
|
233
247
|
label: `New Edge`,
|
|
234
248
|
interactionWidth: 400,
|
|
@@ -242,15 +256,9 @@ const handleConnect = (connection: Connection) => {
|
|
|
242
256
|
addEdges([newEdge])
|
|
243
257
|
}
|
|
244
258
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const handleEdgeRemove = edgeId => {
|
|
248
|
-
removeEdges(edgeId)
|
|
259
|
+
const handleEdgeContextMenu = (event: EdgeMouseEvent) => {
|
|
260
|
+
removeEdges(event.edge.id)
|
|
249
261
|
}
|
|
250
|
-
|
|
251
|
-
onEdgeContextMenu(({ event, edge }) => {
|
|
252
|
-
handleEdgeRemove(edge.id)
|
|
253
|
-
})
|
|
254
262
|
</script>
|
|
255
263
|
|
|
256
264
|
<style>
|
|
@@ -13,7 +13,7 @@ import type { EditorStates, FlowElement, FlowElements, Layout } from '../types'
|
|
|
13
13
|
|
|
14
14
|
const emit = defineEmits(['update:modelValue'])
|
|
15
15
|
const states = defineModel<EditorStates>()
|
|
16
|
-
const { layout, nodeContainerClass } = defineProps<{
|
|
16
|
+
const { layout, nodeContainerClass = '' } = defineProps<{
|
|
17
17
|
layout: Layout
|
|
18
18
|
nodeContainerClass?: HTMLAttributes['class']
|
|
19
19
|
}>()
|
|
@@ -53,7 +53,6 @@ const elements = computed<FlowElements>({
|
|
|
53
53
|
// where 'target' can be accessed. Otherwise, 'edgeValue' will be available directly.
|
|
54
54
|
|
|
55
55
|
// TODO: resolve type issues with xstate
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
57
56
|
const target = edgeValue.target || edgeValue
|
|
58
57
|
stateElements.push({
|
|
59
58
|
id: `${key}-${target}`,
|
|
@@ -63,7 +62,6 @@ const elements = computed<FlowElements>({
|
|
|
63
62
|
animated: true,
|
|
64
63
|
})
|
|
65
64
|
|
|
66
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
67
65
|
hasInputs[target] = true
|
|
68
66
|
}
|
|
69
67
|
}
|