diff --git a/src/components/Edges/EdgeWrapper.vue b/src/components/Edges/EdgeWrapper.vue index fbf4ab12..43e407e4 100644 --- a/src/components/Edges/EdgeWrapper.vue +++ b/src/components/Edges/EdgeWrapper.vue @@ -12,35 +12,35 @@ interface EdgeWrapper { const props = defineProps() const { store } = useVueFlow() -const edge = store.getEdge(props.id) -if (!edge) throw new Error(`Edge with ${props.id} not found!`) +const edge = computed(() => store.getEdge(props.id)!) +if (!edge.value) throw new Error(`Edge with ${props.id} not found!`) const updating = ref(false) -const { onMouseDown } = useHandle() +const { onMouseDown } = useHandle() const onEdgeClick = (event: MouseEvent) => { - const data = { event, edge } + const data = { event, edge: edge.value } if (props.selectable) { store.nodesSelectionActive = false - store.addSelectedEdges([edge]) + store.addSelectedEdges([edge.value]) } store.hooks.edgeClick.trigger(data) } -const onEdgeContextMenu = (event: MouseEvent) => store.hooks.edgeContextMenu.trigger({ event, edge }) -const onDoubleClick = (event: MouseEvent) => store.hooks.edgeDoubleClick.trigger({ event, edge }) -const onEdgeMouseEnter = (event: MouseEvent) => store.hooks.edgeMouseEnter.trigger({ event, edge }) -const onEdgeMouseMove = (event: MouseEvent) => store.hooks.edgeMouseMove.trigger({ event, edge }) -const onEdgeMouseLeave = (event: MouseEvent) => store.hooks.edgeMouseLeave.trigger({ event, edge }) +const onEdgeContextMenu = (event: MouseEvent) => store.hooks.edgeContextMenu.trigger({ event, edge: edge.value }) +const onDoubleClick = (event: MouseEvent) => store.hooks.edgeDoubleClick.trigger({ event, edge: edge.value }) +const onEdgeMouseEnter = (event: MouseEvent) => store.hooks.edgeMouseEnter.trigger({ event, edge: edge.value }) +const onEdgeMouseMove = (event: MouseEvent) => store.hooks.edgeMouseMove.trigger({ event, edge: edge.value }) +const onEdgeMouseLeave = (event: MouseEvent) => store.hooks.edgeMouseLeave.trigger({ event, edge: edge.value }) const onEdgeUpdaterMouseEnter = () => (updating.value = true) const onEdgeUpdaterMouseOut = () => (updating.value = false) const onEdgeUpdaterSourceMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, true) const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, false) const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => { - const nodeId = isSourceHandle ? edge.target : edge.source - const handleId = (isSourceHandle ? edge.targetHandle : edge.sourceHandle) ?? '' + const nodeId = isSourceHandle ? edge.value.target : edge.value.source + const handleId = (isSourceHandle ? edge.value.targetHandle : edge.value.sourceHandle) ?? '' - store.hooks.edgeUpdateStart.trigger({ event, edge }) + store.hooks.edgeUpdateStart.trigger({ event, edge: edge.value }) onMouseDown( event, handleId, @@ -48,22 +48,22 @@ const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => { isSourceHandle, undefined, isSourceHandle ? 'target' : 'source', - (connection) => store.hooks.edgeUpdate.trigger({ edge, connection }), - () => store.hooks.edgeUpdateEnd.trigger({ event, edge }), + (connection) => store.hooks.edgeUpdate.trigger({ edge: edge.value, connection }), + () => store.hooks.edgeUpdateEnd.trigger({ event, edge: edge.value }), ) } // when connection type is loose we can define all handles as sources const targetNodeHandles = computed(() => store.connectionMode === ConnectionMode.Strict - ? edge.targetNode.handleBounds.target - : edge.targetNode.handleBounds.target ?? edge.targetNode.handleBounds.source, + ? edge.value.targetNode.handleBounds.target + : edge.value.targetNode.handleBounds.target ?? edge.value.targetNode.handleBounds.source, ) const sourceHandle = controlledComputed( - () => edge.sourceNode.handleBounds, - () => getHandle(edge.sourceNode.handleBounds.source, edge.sourceHandle), + () => edge.value.sourceNode.handleBounds, + () => getHandle(edge.value.sourceNode.handleBounds.source, edge.value.sourceHandle), ) -const targetHandle = computed(() => getHandle(targetNodeHandles.value, edge.targetHandle)) +const targetHandle = computed(() => getHandle(targetNodeHandles.value, edge.value.targetHandle)) const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom)) const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top)) const edgeUpdaterRadius = computed(() => store.edgeUpdaterRadius) @@ -73,32 +73,32 @@ onMounted(() => { [ sourcePosition, targetPosition, - () => edge.sourceNode.position, - () => edge.targetNode.position, - () => edge.sourceNode.computedPosition, - () => edge.targetNode.computedPosition, - () => edge.sourceNode.dimensions, - () => edge.targetNode.dimensions, + () => edge.value.sourceNode.position, + () => edge.value.targetNode.position, + () => edge.value.sourceNode.computedPosition, + () => edge.value.targetNode.computedPosition, + () => edge.value.sourceNode.dimensions, + () => edge.value.targetNode.dimensions, ], () => { const { sourceX, sourceY, targetY, targetX } = getEdgePositions( - edge.sourceNode, + edge.value.sourceNode, sourceHandle.value, sourcePosition.value, - edge.targetNode, + edge.value.targetNode, targetHandle.value, targetPosition.value, ) - if (edge.sourceX !== sourceX) edge.sourceX = sourceX - if (edge.sourceY !== sourceY) edge.sourceY = sourceY - if (edge.targetX !== targetX) edge.targetX = targetX - if (edge.targetY !== targetY) edge.targetY = targetY + if (edge.value.sourceX !== sourceX) edge.value.sourceX = sourceX + if (edge.value.sourceY !== sourceY) edge.value.sourceY = sourceY + if (edge.value.targetX !== targetX) edge.value.targetX = targetX + if (edge.value.targetY !== targetY) edge.value.targetY = targetY }, { immediate: true, deep: true }, ) }) -const name = ref(edge.type ?? 'default') +const name = ref(edge.value.type ?? 'default') const type = computed(() => { let edgeType = store.getEdgeTypes[name.value] if (typeof edgeType === 'string') edgeType = resolveComponent(name.value, false) as EdgeComponent @@ -106,7 +106,7 @@ const type = computed(() => { const slot = useSlots()?.[name.value]?.({}) if (!slot || !slot[0].key?.toString().includes(name.value)) { - console.warn(`Node type "${edge.type}" not found and no slot detected. Using fallback type "default".`) + console.warn(`Node type "${edge.value.type}" not found and no slot detected. Using fallback type "default".`) name.value = 'default' return store.getEdgeTypes.default } diff --git a/src/components/Nodes/NodeWrapper.vue b/src/components/Nodes/NodeWrapper.vue index 765af292..b742c2e4 100644 --- a/src/components/Nodes/NodeWrapper.vue +++ b/src/components/Nodes/NodeWrapper.vue @@ -15,71 +15,74 @@ interface NodeWrapperProps { const props = defineProps() const { store } = useVueFlow() -const node = store.getNode(props.id) -if (!node) throw new Error(`Node with ${props.id} not found!`) +const node = computed(() => store.getNode(props.id)!) +if (!node.value) throw new Error(`Node with ${props.id} not found!`) provide(NodeId, props.id) const nodeElement = templateRef('node-element', null) -const onMouseEnterHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseEnter.trigger({ event, node })) -const onMouseMoveHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseMove.trigger({ event, node })) -const onMouseLeaveHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseLeave.trigger({ event, node })) +const onMouseEnterHandler = () => + node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseEnter.trigger({ event, node: node.value })) +const onMouseMoveHandler = () => + node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseMove.trigger({ event, node: node.value })) +const onMouseLeaveHandler = () => + node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseLeave.trigger({ event, node: node.value })) const onContextMenuHandler = () => (event: MouseEvent) => store.hooks.nodeContextMenu.trigger({ event, - node, + node: node.value, }) -const onDoubleClick = () => (event: MouseEvent) => store.hooks.nodeDoubleClick.trigger({ event, node }) +const onDoubleClick = () => (event: MouseEvent) => store.hooks.nodeDoubleClick.trigger({ event, node: node.value }) const onSelectNodeHandler = (event: MouseEvent) => { if (!props.draggable) { if (props.selectable) { store.nodesSelectionActive = false - if (!node.selected) store.addSelectedNodes([node]) + if (!node.value.selected) store.addSelectedNodes([node.value]) } - store.hooks.nodeClick.trigger({ event, node }) + store.hooks.nodeClick.trigger({ event, node: node.value }) } } const onDragStart: DraggableEventListener = ({ event }) => { store.addSelectedNodes([]) - store.hooks.nodeDragStart.trigger({ event, node }) + store.hooks.nodeDragStart.trigger({ event, node: node.value }) if (store.selectNodesOnDrag && props.selectable) { store.nodesSelectionActive = false - if (!node.selected) store.addSelectedNodes([node]) - } else if (!store.selectNodesOnDrag && !node.selected && props.selectable) { + if (!node.value.selected) store.addSelectedNodes([node.value]) + } else if (!store.selectNodesOnDrag && !node.value.selected && props.selectable) { store.nodesSelectionActive = false store.addSelectedNodes([]) } } const onDrag: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => { - nextTick(() => store.updateNodePosition({ id: node.id, diff: { x: deltaX, y: deltaY }, dragging: true })) - store.hooks.nodeDrag.trigger({ event, node }) + nextTick(() => store.updateNodePosition({ id: node.value.id, diff: { x: deltaX, y: deltaY }, dragging: true })) + store.hooks.nodeDrag.trigger({ event, node: node.value }) } const onDragStop: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => { // onDragStop also gets called when user just clicks on a node. // Because of that we set dragging to true inside the onDrag handler and handle the click here - if (!node.dragging) { - if (props.selectable && !store.selectNodesOnDrag && !node.selected) { - store.addSelectedNodes([node]) + if (!node.value.dragging) { + if (props.selectable && !store.selectNodesOnDrag && !node.value.selected) { + store.addSelectedNodes([node.value]) } - store.hooks.nodeClick.trigger({ event, node }) + store.hooks.nodeClick.trigger({ event, node: node.value }) return } - store.updateNodePosition({ id: node.id, diff: { x: deltaX, y: deltaY }, dragging: false }) - store.hooks.nodeDragStop.trigger({ event, node }) + store.updateNodePosition({ id: node.value.id, diff: { x: deltaX, y: deltaY }, dragging: false }) + store.hooks.nodeDragStop.trigger({ event, node: node.value }) } onMounted(() => { useResizeObserver(nodeElement, () => - store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value, forceUpdate: true }]), + store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value, forceUpdate: true }]), ) - watch([() => node.type, () => node.sourcePosition, () => node.targetPosition], () => - nextTick(() => store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value }])), + watch([() => node.value.type, () => node.value.sourcePosition, () => node.value.targetPosition], () => + nextTick(() => store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value }])), ) - store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value }]) + store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value }]) }) const scale = controlledComputed( @@ -88,24 +91,24 @@ const scale = controlledComputed( ) watch( - [() => node.position, () => store.getNode(node.parentNode!)], + [() => node.value.position, () => store.getNode(node.value.parentNode!)], ([pos, parent]) => { const xyzPos = { ...pos, - z: node.dragging || node.selected ? 1000 : node.computedPosition.z, + z: node.value.dragging || node.value.selected ? 1000 : node.value.computedPosition.z, } if (parent) { - node.computedPosition = getXYZPos(parent, xyzPos) + node.value.computedPosition = getXYZPos(parent, xyzPos) } else { - node.computedPosition = xyzPos + node.value.computedPosition = xyzPos } }, { deep: true }, ) -store.updateNodePosition({ id: node.id, diff: { x: 0, y: 0 } }) +store.updateNodePosition({ id: node.value.id, diff: { x: 0, y: 0 } }) -const name = ref(node.type ?? 'default') +const name = ref(node.value.type ?? 'default') const type = computed(() => { let nodeType = store.getNodeTypes[name.value] if (typeof nodeType === 'string') nodeType = resolveComponent(name.value, false) as NodeComponent @@ -113,7 +116,7 @@ const type = computed(() => { const slot = useSlots()?.[name.value]?.({}) if (!slot || !slot[0].key?.toString().includes(name.value)) { - console.warn(`Node type "${node.type}" not found and no slot detected. Using fallback type "default".`) + console.warn(`Node type "${node.value.type}" not found and no slot detected. Using fallback type "default".`) name.value = 'default' return store.getNodeTypes.default }