From 25c92ecd8437cf0272ab6fb970bdc5825d4bb5d5 Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sat, 24 Jul 2021 16:32:08 +0200 Subject: [PATCH] update: Remove wrapEdge and wrapNode files * implement Edge.tsx and Node.vue to wrap the components accordingly refactor!: Removing callbacks from props in favor of events chore: upgrade vue and vite vue plugin --- examples/Basic/Basic.vue | 16 +- package.json | 6 +- src/additional-components/MiniMap/index.tsx | 4 +- .../ConnectionLine/ConnectionLine.vue | 133 +++++ src/components/ConnectionLine/index.tsx | 181 ------ src/components/Edges/BezierEdge.tsx | 29 +- src/components/Edges/Edge.vue | 278 +++++++++ src/components/Edges/SmoothStepEdge.tsx | 1 + src/components/Edges/StepEdge.tsx | 1 + src/components/Edges/StraightEdge.tsx | 1 + src/components/Edges/wrapEdge.tsx | 355 ------------ src/components/Handle/Handle.ts | 70 +++ src/components/Handle/handler.ts | 24 +- src/components/Handle/index.tsx | 22 +- src/components/Nodes/DefaultNode.tsx | 5 +- src/components/Nodes/InputNode.tsx | 5 +- src/components/Nodes/Node.vue | 258 +++++++++ src/components/Nodes/OutputNode.tsx | 5 +- src/components/Nodes/wrapNode.tsx | 204 ------- src/container/EdgeRenderer/EdgeRenderer.vue | 118 ++++ src/container/EdgeRenderer/Marker.vue | 30 + .../EdgeRenderer/MarkerDefinitions.tsx | 72 --- .../EdgeRenderer/MarkerDefinitions.vue | 45 ++ src/container/EdgeRenderer/index.tsx | 363 ------------ src/container/EdgeRenderer/utils.ts | 14 +- src/container/FlowRenderer/FlowRenderer.vue | 72 +-- src/container/FlowRenderer/index.tsx | 217 ------- src/container/GraphView/GraphView.vue | 198 +------ src/container/GraphView/index.tsx | 477 ---------------- src/container/NodeRenderer/NodeRenderer.vue | 90 +++ src/container/NodeRenderer/index.tsx | 189 ------ src/container/NodeRenderer/utils.ts | 13 +- src/container/RevueFlow/RevueFlow.vue | 224 +------- src/container/RevueFlow/index.tsx | 538 ------------------ src/hooks/RevueFlowHooks.ts | 30 +- src/types/index.ts | 161 +----- src/utils/graph.ts | 6 +- tsconfig.json | 1 + vite.config.ts | 4 +- yarn.lock | 113 +++- 40 files changed, 1224 insertions(+), 3349 deletions(-) create mode 100644 src/components/ConnectionLine/ConnectionLine.vue delete mode 100644 src/components/ConnectionLine/index.tsx create mode 100644 src/components/Edges/Edge.vue delete mode 100644 src/components/Edges/wrapEdge.tsx create mode 100644 src/components/Handle/Handle.ts create mode 100644 src/components/Nodes/Node.vue delete mode 100644 src/components/Nodes/wrapNode.tsx create mode 100644 src/container/EdgeRenderer/EdgeRenderer.vue create mode 100644 src/container/EdgeRenderer/Marker.vue delete mode 100644 src/container/EdgeRenderer/MarkerDefinitions.tsx create mode 100644 src/container/EdgeRenderer/MarkerDefinitions.vue delete mode 100644 src/container/EdgeRenderer/index.tsx delete mode 100644 src/container/FlowRenderer/index.tsx delete mode 100644 src/container/GraphView/index.tsx create mode 100644 src/container/NodeRenderer/NodeRenderer.vue delete mode 100644 src/container/NodeRenderer/index.tsx delete mode 100644 src/container/RevueFlow/index.tsx diff --git a/examples/Basic/Basic.vue b/examples/Basic/Basic.vue index 32498af0..03668b50 100644 --- a/examples/Basic/Basic.vue +++ b/examples/Basic/Basic.vue @@ -5,6 +5,7 @@ :onElementsRemove="onElementsRemove" :onConnect="onConnect" :onNodeDragStop="onNodeDragStop" + :onNodeClick="onElementClick" :defaultZoom="1.5" :minZoom="0.2" :maxZoom="4" @@ -15,10 +16,10 @@
- - - - + + + +
@@ -31,7 +32,6 @@ import RevueFlow, { Edge, Elements, FlowElement, - Node, OnLoadParams, addEdge, isNode, @@ -42,8 +42,8 @@ import { defineComponent, ref } from 'vue'; const BasicFlow = defineComponent({ components: { RevueFlow, MiniMap, Controls, Background }, setup() { - const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); - const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element); + const onNodeDragStop = ({ node }) => console.log('drag stop', node); + const onElementClick = ({ node }) => console.log('click', node); const elements = ref([ { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }, { id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } }, @@ -51,7 +51,7 @@ const BasicFlow = defineComponent({ { id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } }, { id: 'e1-2', source: '1', target: '2', animated: true }, { id: 'e1-3', source: '1', target: '3' } - ]); + ] as Elements); const rfInstance = ref(null); const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value as Elements)); diff --git a/package.json b/package.json index 762735e5..e4cd4aa0 100644 --- a/package.json +++ b/package.json @@ -45,10 +45,10 @@ "@rollup/plugin-replace": "^2.4.2", "@typescript-eslint/eslint-plugin": "^4.28.1", "@typescript-eslint/parser": "^4.28.1", - "@vitejs/plugin-vue": "^1.2.3", + "@vitejs/plugin-vue": "^1.2.5", "@vitejs/plugin-vue-jsx": "^1.1.6", "@vue/babel-plugin-jsx": "^1.0.6", - "@vue/compiler-sfc": "^3.0.5", + "@vue/compiler-sfc": "^3.2.0-beta.5", "@vue/eslint-config-typescript": "^7.0.0", "autoprefixer": "^10.2.6", "babel-eslint": "latest", @@ -72,7 +72,7 @@ "typescript": "^4.3.5", "vite": "^2.3.8", "vite-svg-loader": "^2.1.0", - "vue": "^3.0.5", + "vue": "^3.2.0-beta.5", "vue-router": "4", "vue-tsc": "^0.0.24" }, diff --git a/src/additional-components/MiniMap/index.tsx b/src/additional-components/MiniMap/index.tsx index d57b77a0..4e7c9556 100644 --- a/src/additional-components/MiniMap/index.tsx +++ b/src/additional-components/MiniMap/index.tsx @@ -100,8 +100,8 @@ const MiniMap = defineComponent({ key={node.id} x={node.__rf.position.x} y={node.__rf.position.y} - width={node.__rf.width} - height={node.__rf.height} + width={node.__rf.width || 0} + height={node.__rf.height || 0} style={node.style} class={nodeClassNameFunc.value(node)} color={nodeColorFunc.value(node)} diff --git a/src/components/ConnectionLine/ConnectionLine.vue b/src/components/ConnectionLine/ConnectionLine.vue new file mode 100644 index 00000000..95afd72f --- /dev/null +++ b/src/components/ConnectionLine/ConnectionLine.vue @@ -0,0 +1,133 @@ + + diff --git a/src/components/ConnectionLine/index.tsx b/src/components/ConnectionLine/index.tsx deleted file mode 100644 index 5f136583..00000000 --- a/src/components/ConnectionLine/index.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { ref, defineComponent, CSSProperties, PropType, computed } from 'vue'; - -import { getBezierPath } from '../Edges/BezierEdge'; -import { getSmoothStepPath } from '../Edges/SmoothStepEdge'; -import { - ElementId, - Node, - Transform, - HandleElement, - Position, - ConnectionLineType, - ConnectionLineComponent, - HandleType -} from '../../types'; - -interface ConnectionLineProps { - connectionNodeId: ElementId; - connectionHandleId: ElementId | null; - connectionHandleType: HandleType; - connectionPositionX: number; - connectionPositionY: number; - connectionLineType: ConnectionLineType; - nodes: Node[]; - transform: Transform; - isConnectable: boolean; - connectionLineStyle?: CSSProperties; - CustomConnectionLineComponent?: ConnectionLineComponent; -} - -const ConnectionLine = defineComponent({ - props: { - connectionNodeId: { - type: String as PropType, - required: true - }, - connectionHandleId: { - type: String as PropType, - required: true - }, - connectionHandleType: { - type: String as PropType, - required: true - }, - connectionLineStyle: { - type: Object as PropType, - required: false, - default: () => ({}) - }, - connectionPositionX: { - type: Number as PropType, - required: false, - default: 0 - }, - connectionPositionY: { - type: Number as PropType, - required: false, - default: 0 - }, - connectionLineType: { - type: String as PropType, - required: false, - default: ConnectionLineType.Bezier - }, - nodes: { - type: Array as PropType, - required: true, - default: () => [] - }, - transform: { - type: Object as PropType, - required: false, - default: () => ({}) - }, - isConnectable: { - type: Boolean as PropType, - required: false, - default: false - }, - CustomConnectionLineComponent: { - type: Object as PropType, - required: false, - default: undefined - } - }, - setup(props) { - const sourceNode = ref(props.nodes.find((n) => n.id === props.connectionNodeId) || null); - - if (!sourceNode.value || !props.isConnectable) { - return null; - } - - const sourceHandle = computed(() => - props.connectionHandleId - ? sourceNode.value?.__rf.handleBounds[props.connectionHandleType].find( - (d: HandleElement) => d.id === props.connectionHandleId - ) - : sourceNode.value?.__rf.handleBounds[props.connectionHandleType][0] - ); - const sourceHandleX = computed(() => - sourceHandle.value ? sourceHandle.value.x + sourceHandle.value.width / 2 : sourceNode.value?.__rf.width / 2 - ); - const sourceHandleY = computed(() => - sourceHandle.value ? sourceHandle.value.y + sourceHandle.value.height / 2 : sourceNode.value?.__rf.height - ); - const sourceX = computed(() => sourceNode.value?.__rf.position.x + sourceHandleX.value); - const sourceY = computed(() => sourceNode.value?.__rf.position.y + sourceHandleY.value); - - const targetX = computed(() => (props.connectionPositionX - props.transform[0]) / props.transform[2]); - const targetY = computed(() => (props.connectionPositionY - props.transform[1]) / props.transform[2]); - - const isRightOrLeft = computed( - () => sourceHandle.value?.position === Position.Left || sourceHandle.value?.position === Position.Right - ); - const targetPosition = computed(() => (isRightOrLeft.value ? Position.Left : Position.Top)); - - if (props.CustomConnectionLineComponent) { - // eslint-disable-next-line vue/no-setup-props-destructure - const ConnectionLineComponent: any = props.CustomConnectionLineComponent; - return () => ( - - - - ); - } - - let dAttr = computed(() => `M${sourceX.value},${sourceY.value} ${targetX.value},${targetY.value}`); - - if (props.connectionLineType === ConnectionLineType.Bezier) { - dAttr = computed(() => - getBezierPath({ - sourceX: sourceX.value, - sourceY: sourceY.value, - sourcePosition: sourceHandle.value?.position, - targetX: targetX.value, - targetY: targetY.value, - targetPosition: targetPosition.value - }) - ); - } else if (props.connectionLineType === ConnectionLineType.Step) { - dAttr = computed(() => - getSmoothStepPath({ - sourceX: sourceX.value, - sourceY: sourceY.value, - sourcePosition: sourceHandle.value?.position, - targetX: targetX.value, - targetY: targetY.value, - targetPosition: targetPosition.value, - borderRadius: 0 - }) - ); - } else if (props.connectionLineType === ConnectionLineType.SmoothStep) { - dAttr = computed(() => - getSmoothStepPath({ - sourceX: sourceX.value, - sourceY: sourceY.value, - sourcePosition: sourceHandle.value?.position, - targetX: targetX.value, - targetY: targetY.value, - targetPosition: targetPosition.value - }) - ); - } - - return () => ( - - - - ); - } -}); - -export default ConnectionLine; diff --git a/src/components/Edges/BezierEdge.tsx b/src/components/Edges/BezierEdge.tsx index 925a7f32..b2bbfb02 100644 --- a/src/components/Edges/BezierEdge.tsx +++ b/src/components/Edges/BezierEdge.tsx @@ -46,44 +46,46 @@ export function getBezierPath({ } const BezierEdge = defineComponent({ + inheritAttrs: false, props: { sourceX: { type: Number, - required: true, + required: false, default: 0 }, sourceY: { type: Number, - required: true, + required: false, default: 0 }, targetX: { type: Number, - required: true, + required: false, default: 0 }, targetY: { type: Number, - required: true, + required: false, default: 0 }, sourcePosition: { type: String as PropType, - required: true, + required: false, default: Position.Bottom }, targetPosition: { type: String as PropType, - required: true, + required: false, default: Position.Top }, label: { type: String, - required: true + required: false, + default: undefined }, labelStyle: { type: Object, - required: true, + required: false, default: undefined }, labelShowBg: { @@ -93,7 +95,8 @@ const BezierEdge = defineComponent({ }, labelBgStyle: { type: String, - required: true + required: false, + default: undefined }, labelBgPadding: { type: Array as unknown as PropType<[number, number]>, @@ -106,12 +109,14 @@ const BezierEdge = defineComponent({ default: 0 }, arrowHeadType: { - type: Object as PropType, - required: true + type: String as PropType, + required: false, + default: undefined }, markerEndId: { type: String, - required: true + required: false, + default: undefined }, style: { type: Object as PropType, diff --git a/src/components/Edges/Edge.vue b/src/components/Edges/Edge.vue new file mode 100644 index 00000000..12fcb24c --- /dev/null +++ b/src/components/Edges/Edge.vue @@ -0,0 +1,278 @@ + + diff --git a/src/components/Edges/SmoothStepEdge.tsx b/src/components/Edges/SmoothStepEdge.tsx index bb1f932d..6b51cf0d 100644 --- a/src/components/Edges/SmoothStepEdge.tsx +++ b/src/components/Edges/SmoothStepEdge.tsx @@ -93,6 +93,7 @@ export function getSmoothStepPath({ } const SmoothStepEdge = defineComponent({ + inheritAttrs: false, props: EdgeSmoothStepProps, setup(props) { const [centerX, centerY] = getCenter({ diff --git a/src/components/Edges/StepEdge.tsx b/src/components/Edges/StepEdge.tsx index 19466a41..0736d131 100644 --- a/src/components/Edges/StepEdge.tsx +++ b/src/components/Edges/StepEdge.tsx @@ -4,6 +4,7 @@ import { EdgeSmoothStepProps } from '../../types'; import SmoothStepEdge from './SmoothStepEdge'; const StepEdge = defineComponent({ + inheritAttrs: false, components: { SmoothStepEdge }, props: EdgeSmoothStepProps, setup(props) { diff --git a/src/components/Edges/StraightEdge.tsx b/src/components/Edges/StraightEdge.tsx index 6243c3be..bae3772d 100644 --- a/src/components/Edges/StraightEdge.tsx +++ b/src/components/Edges/StraightEdge.tsx @@ -5,6 +5,7 @@ import { getMarkerEnd } from './utils'; import { EdgeProps } from '../../types'; const StraightEdge = defineComponent({ + inheritAttrs: false, props: EdgeProps, setup(props) { const yOffset = Math.abs(props.targetY - props.sourceY) / 2; diff --git a/src/components/Edges/wrapEdge.tsx b/src/components/Edges/wrapEdge.tsx deleted file mode 100644 index ef85a6a7..00000000 --- a/src/components/Edges/wrapEdge.tsx +++ /dev/null @@ -1,355 +0,0 @@ -import { computed, DefineComponent, defineComponent, inject, PropType, ref } from 'vue'; -import { Edge, Position, RevueFlowStore, WrapEdgeProps } from '../../types'; -import { onMouseDown } from '../Handle/handler'; -import { EdgeAnchor } from './EdgeAnchor'; - -export default (EdgeComponent: DefineComponent) => { - return defineComponent({ - components: { EdgeComponent }, - props: { - id: { - type: String as PropType, - required: false, - default: undefined - }, - type: { - type: String as PropType, - required: true - }, - data: { - type: String as PropType, - required: false, - default: undefined - }, - onClick: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeDoubleClick: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - selected: { - type: Boolean as PropType, - required: true, - default: false - }, - animated: { - type: Boolean as PropType, - required: false, - default: false - }, - label: { - type: Object as PropType, - required: false, - default: undefined - }, - labelStyle: { - type: Object as PropType, - required: false, - default: undefined - }, - labelShowBg: { - type: Boolean as PropType, - required: false, - default: false - }, - labelBgStyle: { - type: Object as PropType, - required: false, - default: undefined - }, - labelBgPadding: { - type: Array as unknown as PropType, - required: false, - default: undefined - }, - labelBgBorderRadius: { - type: Number as PropType, - required: false, - default: undefined - }, - style: { - type: Object as PropType, - required: false, - default: undefined - }, - arrowHeadType: { - type: String as PropType, - required: false, - default: undefined - }, - source: { - type: String as PropType, - required: true - }, - target: { - type: String as PropType, - required: true - }, - sourceHandleId: { - type: String as PropType, - required: true, - default: null - }, - targetHandleId: { - type: String as PropType, - required: true, - default: null - }, - sourceX: { - type: Number as PropType, - required: true - }, - sourceY: { - type: Number as PropType, - required: true - }, - targetX: { - type: Number as PropType, - required: true - }, - targetY: { - type: Number as PropType, - required: true - }, - sourcePosition: { - type: String as PropType, - required: true - }, - targetPosition: { - type: String as PropType, - required: true - }, - elementsSelectable: { - type: Boolean as PropType, - required: false, - default: false - }, - markerEndId: { - type: String as PropType, - required: false, - default: undefined - }, - isHidden: { - type: Boolean as PropType, - required: false, - default: false - }, - handleEdgeUpdate: { - type: Boolean as PropType, - required: false, - default: false - }, - onConnectEdge: { - type: Function as PropType, - required: false, - default: undefined - }, - onContextMenu: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMouseEnter: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMouseMove: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMouseLeave: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - edgeUpdaterRadius: { - type: Number as PropType, - required: false, - default: undefined - }, - onEdgeUpdateStart: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeUpdateEnd: { - type: Function as unknown as PropType, - required: false, - default: undefined - } - }, - setup(props) { - const store = inject('store')!; - const updating = ref(false); - const inactive = computed(() => !props.elementsSelectable && !props.onClick); - const edgeClasses = computed(() => [ - 'revue-flow__edge', - `revue-flow__edge-${props.type}`, - { selected: props.selected, animated: props.animated, inactive, updating: updating.value } - ]); - - const edgeElement = computed(() => { - const el: Edge = { - id: props.id as string, - source: props.source, - target: props.target, - type: props.type - }; - - if (props.sourceHandleId) { - el.sourceHandle = props.sourceHandleId; - } - - if (props.targetHandleId) { - el.targetHandle = props.targetHandleId; - } - - if (typeof props.data !== 'undefined') { - el.data = props.data; - } - - return el; - }); - - const onEdgeClick = (event: MouseEvent) => { - if (props.elementsSelectable) { - store.unsetNodesSelection(); - store.addSelectedElements(edgeElement.value as any); - } - - if (typeof props.onClick === 'function') props.onClick(event, edgeElement.value); - }; - - const onEdgeContextMenu = (event: MouseEvent) => { - if (typeof props.onContextMenu === 'function') props.onContextMenu(event, edgeElement.value); - }; - - const onEdgeMouseEnter = (event: MouseEvent) => { - if (typeof props.onMouseEnter === 'function') props.onMouseEnter(event, edgeElement.value); - }; - - const onEdgeMouseMove = (event: MouseEvent) => { - if (typeof props.onMouseMove === 'function') props.onMouseMove(event, edgeElement.value); - }; - - const onEdgeMouseLeave = (event: MouseEvent) => { - if (typeof props.onMouseLeave === 'function') props.onMouseLeave(event, edgeElement.value); - }; - - const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => { - const nodeId = isSourceHandle ? props.target : props.source; - const handleId = isSourceHandle ? props.targetHandleId : props.sourceHandleId; - const isValidConnection = () => true; - const isTarget = isSourceHandle; - - props.onEdgeUpdateStart?.(event, edgeElement.value); - - const _onEdgeUpdate = props.onEdgeUpdateEnd - ? (evt: MouseEvent) => { - if (props.onEdgeUpdateEnd) props.onEdgeUpdateEnd(evt, edgeElement.value); - } - : undefined; - - onMouseDown( - event, - handleId, - nodeId, - store.setConnectionNodeId, - store.setConnectionPosition, - props.onConnectEdge as any, - isTarget, - isValidConnection, - store.connectionMode, - isSourceHandle ? 'target' : 'source', - _onEdgeUpdate - ); - }; - - const onEdgeUpdaterSourceMouseDown = (event: MouseEvent) => { - handleEdgeUpdater(event, true); - }; - - const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => { - handleEdgeUpdater(event, false); - }; - - const onEdgeUpdaterMouseEnter = () => (updating.value = true); - const onEdgeUpdaterMouseOut = () => (updating.value = false); - - if (props.isHidden) { - return null; - } - - return () => ( - - - {props.handleEdgeUpdate && ( - - - - )} - {props.handleEdgeUpdate && ( - - - - )} - - ); - } - }); -}; diff --git a/src/components/Handle/Handle.ts b/src/components/Handle/Handle.ts new file mode 100644 index 00000000..c1418980 --- /dev/null +++ b/src/components/Handle/Handle.ts @@ -0,0 +1,70 @@ +import { ElementId, Position, RevueFlowStore } from '../../types'; +import { onMouseDown, ValidConnectionFunc } from './handler'; +import { computed, defineComponent, h, inject, PropType } from 'vue'; +import { RevueFlowHooks } from '../../hooks/RevueFlowHooks'; + +const alwaysValid = () => true; + +export default defineComponent({ + props: { + type: { + type: String, + required: false, + default: 'source' + }, + position: { + type: String as PropType, + required: false, + default: Position.Top + }, + isValidConnection: { + type: Function as PropType, + required: false, + default: alwaysValid + }, + isConnectable: { + type: Boolean, + required: false, + default: true + }, + id: { + type: String, + required: false, + default: undefined + } + }, + setup(props, { slots }) { + const store = inject('store')!; + const hooks = inject('hooks')!; + const nodeId = inject('NodeIdContext') as ElementId; + const isTarget = computed(() => props.type === 'target'); + + const onMouseDownHandler = (event: MouseEvent) => { + onMouseDown(event, store, hooks, props.id || '', nodeId, isTarget.value, props.isValidConnection); + }; + + const handleClasses = computed(() => [ + 'revue-flow__handle', + `revue-flow__handle-${props.position}`, + 'nodrag', + { + source: !isTarget.value, + target: isTarget.value, + connectable: props.isConnectable + } + ]); + + return () => + h( + 'div', + { + dataHandleid: props.id, + dataNodeid: nodeId, + dataHandlepos: props.position, + class: handleClasses.value, + onMouseDown: onMouseDownHandler + }, + slots.default?.() + ); + } +}); diff --git a/src/components/Handle/handler.ts b/src/components/Handle/handler.ts index b792b25a..2c840bc8 100644 --- a/src/components/Handle/handler.ts +++ b/src/components/Handle/handler.ts @@ -1,15 +1,5 @@ import { getHostForElement } from '../../utils'; - -import { - ElementId, - XYPosition, - OnConnectFunc, - ConnectionMode, - SetConnectionId, - Connection, - HandleType, - RevueFlowStore -} from '../../types'; +import { ElementId, XYPosition, ConnectionMode, SetConnectionId, Connection, HandleType, RevueFlowStore } from '../../types'; import { RevueFlowHooks } from '../../hooks/RevueFlowHooks'; export type ValidConnectionFunc = (connection: Connection) => boolean; @@ -89,14 +79,14 @@ export function onMouseDown( connectStart: RevueFlowHooks['connectStart']; connectStop: RevueFlowHooks['connectStop']; connectEnd: RevueFlowHooks['connectEnd']; + connect: RevueFlowHooks['connect']; + edgeUpdateEnd: RevueFlowHooks['edgeUpdateEnd']; }, handleId: ElementId | null, nodeId: ElementId, - onConnect: OnConnectFunc, isTarget: boolean, isValidConnection: ValidConnectionFunc, - elementEdgeUpdaterType?: HandleType, - onEdgeUpdateEnd?: (evt: MouseEvent) => void + elementEdgeUpdaterType?: HandleType ): void { const revueFlowNode = (event.target as Element).closest('.revue-flow'); // when revue-flow is used inside a shadow root we can't use document @@ -169,13 +159,13 @@ export function onMouseDown( hooks.connectStop.trigger(event); if (isValid) { - onConnect?.(connection); + hooks.connect.trigger(connection); } hooks.connectEnd.trigger(event); - if (elementEdgeUpdaterType && onEdgeUpdateEnd) { - onEdgeUpdateEnd(event); + if (elementEdgeUpdaterType) { + hooks.edgeUpdateEnd.trigger({ event } as any); } resetRecentHandle(recentHoveredHandle); diff --git a/src/components/Handle/index.tsx b/src/components/Handle/index.tsx index 3c149ae7..6fa3fb15 100644 --- a/src/components/Handle/index.tsx +++ b/src/components/Handle/index.tsx @@ -1,4 +1,4 @@ -import { Connection, ElementId, Position, RevueFlowStore } from '../../types'; +import { ElementId, Position, RevueFlowStore } from '../../types'; import { onMouseDown, ValidConnectionFunc } from './handler'; import { computed, defineComponent, inject, PropType } from 'vue'; import { RevueFlowHooks } from '../../hooks/RevueFlowHooks'; @@ -43,26 +43,10 @@ const Handle = defineComponent({ const hooks = inject('hooks')!; const nodeId = inject('NodeIdContext') as ElementId; const isTarget = computed(() => props.type === 'target'); - const onConnect = computed(() => store.onConnect); - - const onConnectExtended = (params: Connection) => { - onConnect.value?.(params); - props.onConnect?.(params); - }; const onMouseDownHandler = (event: MouseEvent) => { - onMouseDown( - event, - store, - hooks, - props.id as string, - nodeId, - onConnectExtended, - isTarget.value, - props.isValidConnection, - undefined, - undefined - ); + console.log('mousedown'); + onMouseDown(event, store, hooks, props.id as string, nodeId, isTarget.value, props.isValidConnection); }; const handleClasses = computed(() => [ diff --git a/src/components/Nodes/DefaultNode.tsx b/src/components/Nodes/DefaultNode.tsx index 26d9fb06..073c64b0 100644 --- a/src/components/Nodes/DefaultNode.tsx +++ b/src/components/Nodes/DefaultNode.tsx @@ -5,6 +5,7 @@ import { defineComponent, PropType } from 'vue'; const DefaultNode = defineComponent({ name: 'DefaultNode', components: { Handle }, + inheritAttrs: false, props: { data: { type: Object as PropType, @@ -29,11 +30,11 @@ const DefaultNode = defineComponent({ }, setup(props) { return () => ( -
+ <> {props.data?.label} -
+ ); } }); diff --git a/src/components/Nodes/InputNode.tsx b/src/components/Nodes/InputNode.tsx index 62e4cab8..69231e57 100644 --- a/src/components/Nodes/InputNode.tsx +++ b/src/components/Nodes/InputNode.tsx @@ -5,6 +5,7 @@ import { defineComponent, PropType } from 'vue'; const InputNode = defineComponent({ name: 'InputNode', components: { Handle }, + inheritAttrs: false, props: { data: { type: Object as PropType, @@ -24,10 +25,10 @@ const InputNode = defineComponent({ }, setup(props) { return () => ( -
+ <> {props.data?.label} -
+ ); } }); diff --git a/src/components/Nodes/Node.vue b/src/components/Nodes/Node.vue new file mode 100644 index 00000000..9b5bb1e2 --- /dev/null +++ b/src/components/Nodes/Node.vue @@ -0,0 +1,258 @@ + + diff --git a/src/components/Nodes/OutputNode.tsx b/src/components/Nodes/OutputNode.tsx index d47cae9d..160816fb 100644 --- a/src/components/Nodes/OutputNode.tsx +++ b/src/components/Nodes/OutputNode.tsx @@ -5,6 +5,7 @@ import { defineComponent, PropType } from 'vue'; const OutputNode = defineComponent({ name: 'OutputNode', components: { Handle }, + inheritAttrs: false, props: { data: { type: Object as PropType, @@ -24,10 +25,10 @@ const OutputNode = defineComponent({ }, setup(props) { return () => ( -
+ <> {props.data?.label} -
+ ); } }); diff --git a/src/components/Nodes/wrapNode.tsx b/src/components/Nodes/wrapNode.tsx deleted file mode 100644 index 9695592a..00000000 --- a/src/components/Nodes/wrapNode.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { Node, RevueFlowStore, WrapNodeProps } from '../../types'; -import { computed, CSSProperties, DefineComponent, defineComponent, inject, onMounted, onUpdated, provide, ref } from 'vue'; -import { DraggableEventHandler, DraggableCore } from '@braks/revue-draggable'; - -export default (NodeComponent: DefineComponent) => { - return defineComponent({ - props: WrapNodeProps, - setup(props) { - const store = inject('store')!; - provide('NodeIdContext', props.id); - - const nodeElement = ref(); - - const node = computed(() => ({ - id: props.id, - type: props.type, - position: { x: props.xPos, y: props.yPos }, - data: props.data - })); - const grid = computed(() => (props.snapToGrid ? props.snapGrid : [1, 1])! as [number, number]); - - const nodeStyle = computed(() => ({ - zIndex: props.selected ? 10 : 3, - transform: `translate(${props.xPos}px,${props.yPos}px)`, - pointerEvents: - props.isSelectable || - props.isDraggable || - props.onClick || - props.onMouseEnter || - props.onMouseMove || - props.onMouseLeave - ? 'all' - : 'none', - // prevents jumping of nodes on start - opacity: props.isInitialized ? 1 : 0, - ...props.style - })); - const onMouseEnterHandler = () => { - if (!props.onMouseEnter || props.isDragging) { - return; - } - - return (event: MouseEvent) => props.onMouseEnter && props.onMouseEnter(event, node.value as Node); - }; - - const onMouseMoveHandler = () => { - if (!props.onMouseMove || props.isDragging) { - return; - } - - return (event: MouseEvent) => props.onMouseMove && props.onMouseMove(event, node.value as Node); - }; - - const onMouseLeaveHandler = () => { - if (!props.onMouseLeave || props.isDragging) { - return; - } - - return (event: MouseEvent) => props.onMouseLeave && props.onMouseLeave(event, node.value as Node); - }; - - const onContextMenuHandler = () => { - if (!props.onContextMenu) { - return; - } - - return (event: MouseEvent) => props.onContextMenu && props.onContextMenu(event, node.value as Node); - }; - - const onSelectNodeHandler = (event: MouseEvent) => { - if (!props.isDraggable) { - if (props.isSelectable) { - store?.unsetNodesSelection(); - - if (!props.selected) { - store?.addSelectedElements([node.value as Node]); - } - } - - props.onClick?.(event, node.value as Node); - } - }; - - const onDragStart: DraggableEventHandler = (event) => { - props.onNodeDragStart?.(event as MouseEvent, node.value as Node); - - if (props.selectNodesOnDrag && props.isSelectable) { - store?.unsetNodesSelection(); - - if (!props.selected) { - store?.addSelectedElements([node.value as Node]); - } - } else if (!props.selectNodesOnDrag && !props.selected && props.isSelectable) { - store?.unsetNodesSelection(); - store?.addSelectedElements([]); - } - }; - - const onDrag: DraggableEventHandler = (event, draggableData) => { - if (props.onNodeDrag) { - node.value.position.x += draggableData.deltaX; - node.value.position.y += draggableData.deltaY; - props.onNodeDrag(event as MouseEvent, node.value as Node); - } - - store?.updateNodePosDiff({ - id: props.id as string, - diff: { - x: draggableData.deltaX, - y: draggableData.deltaY - }, - isDragging: true - }); - }; - - const onDragStop: DraggableEventHandler = (event) => { - // 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 (!props.isDragging) { - if (props.isSelectable && !props.selectNodesOnDrag && !props.selected) { - store?.addSelectedElements([node.value as Node]); - } - - props.onClick?.(event, node.value as Node); - - return; - } - - store?.updateNodePosDiff({ - id: node.value.id as string, - isDragging: false - }); - - props.onNodeDragStop?.(event as MouseEvent, node.value as Node); - }; - - onUpdated(() => { - if (nodeElement.value && !props.isHidden) { - store?.updateNodeDimensions([{ id: props.id || '', nodeElement: nodeElement.value, forceUpdate: true }]); - } - }); - - onMounted(() => { - if (nodeElement.value && typeof props.resizeObserver?.observe === 'function') { - const currNode = nodeElement.value; - props.resizeObserver?.observe(currNode); - - return () => props.resizeObserver?.unobserve(currNode); - } - }); - - if (props.isHidden) { - return null; - } - - const nodeClasses = computed(() => [ - 'revue-flow__node', - `revue-flow__node-${props.type}`, - { - selected: props.selected, - selectable: props.isSelectable - } - ]); - - return () => ( - -
- -
-
- ); - } - }); -}; diff --git a/src/container/EdgeRenderer/EdgeRenderer.vue b/src/container/EdgeRenderer/EdgeRenderer.vue new file mode 100644 index 00000000..cfd43318 --- /dev/null +++ b/src/container/EdgeRenderer/EdgeRenderer.vue @@ -0,0 +1,118 @@ + + diff --git a/src/container/EdgeRenderer/Marker.vue b/src/container/EdgeRenderer/Marker.vue new file mode 100644 index 00000000..a84c1fc9 --- /dev/null +++ b/src/container/EdgeRenderer/Marker.vue @@ -0,0 +1,30 @@ + + diff --git a/src/container/EdgeRenderer/MarkerDefinitions.tsx b/src/container/EdgeRenderer/MarkerDefinitions.tsx deleted file mode 100644 index a582a857..00000000 --- a/src/container/EdgeRenderer/MarkerDefinitions.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { defineComponent, PropType } from 'vue'; - -interface MarkerProps { - id: string; -} - -const Marker = defineComponent({ - props: { - id: { - type: String as PropType, - required: true - } - }, - setup(props, { slots }) { - return () => ( - - {slots.default ? slots.default() : ''} - - ); - } -}); - -interface MarkerDefinitionsProps { - color: string; -} - -const MarkerDefinitions = defineComponent({ - name: 'MarkerDefinitions', - props: { - color: { - type: String as PropType, - required: true - } - }, - setup(props) { - return () => ( - - - - - - - - - ); - } -}); - -export default MarkerDefinitions; diff --git a/src/container/EdgeRenderer/MarkerDefinitions.vue b/src/container/EdgeRenderer/MarkerDefinitions.vue new file mode 100644 index 00000000..a25eba25 --- /dev/null +++ b/src/container/EdgeRenderer/MarkerDefinitions.vue @@ -0,0 +1,45 @@ + + diff --git a/src/container/EdgeRenderer/index.tsx b/src/container/EdgeRenderer/index.tsx deleted file mode 100644 index 77a5ea18..00000000 --- a/src/container/EdgeRenderer/index.tsx +++ /dev/null @@ -1,363 +0,0 @@ -import ConnectionLine from '../../components/ConnectionLine/index'; -import { isEdge } from '../../utils/graph'; -import { getEdgePositions, getHandle, isEdgeVisible, getSourceTargetNodes } from './utils'; -import { - Position, - Edge, - Node, - Elements, - Connection, - ConnectionLineType, - ConnectionLineComponent, - ConnectionMode, - Transform, - OnEdgeUpdateFunc, - RevueFlowStore, - HandleType -} from '../../types'; -import { computed, CSSProperties, defineComponent, inject, PropType } from 'vue'; -import MarkerDefinitions from './MarkerDefinitions'; - -interface EdgeRendererProps { - edgeTypes: any; - connectionLineType: ConnectionLineType; - connectionLineStyle?: CSSProperties; - connectionLineComponent?: ConnectionLineComponent; - connectionMode?: ConnectionMode; - onElementClick?: (event: MouseEvent, element: Node | Edge) => void; - onEdgeDoubleClick?: (event: MouseEvent, edge: Edge) => void; - arrowHeadColor: string; - markerEndId?: string; - onlyRenderVisibleElements: boolean; - onEdgeUpdate?: OnEdgeUpdateFunc; - onEdgeContextMenu?: (event: MouseEvent, edge: Edge) => void; - onEdgeMouseEnter?: (event: MouseEvent, edge: Edge) => void; - onEdgeMouseMove?: (event: MouseEvent, edge: Edge) => void; - onEdgeMouseLeave?: (event: MouseEvent, edge: Edge) => void; - onEdgeUpdateStart?: (event: MouseEvent, edge: Edge) => void; - onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge) => void; - edgeUpdaterRadius?: number; -} - -interface EdgeWrapperProps { - edge: Edge; - props: EdgeRendererProps; - nodes: Node[]; - selectedElements: Elements | null; - elementsSelectable: boolean; - transform: Transform; - width: number; - height: number; - onlyRenderVisibleElements: boolean; - connectionMode?: ConnectionMode; -} - -const EdgeCmp = defineComponent({ - props: { - edge: { - type: Object as PropType, - required: true - }, - props: { - type: Object as PropType, - required: true - }, - nodes: { - type: Array as unknown as PropType, - required: true - }, - selectedElements: { - type: Array as unknown as PropType, - required: false, - default: undefined - }, - elementsSelectable: { - type: Boolean as PropType, - required: false, - default: false - }, - transform: { - type: Array as unknown as PropType, - required: false, - default: () => [] - }, - width: { - type: Number as PropType, - required: false, - default: undefined - }, - height: { - type: Number as PropType, - required: false, - default: undefined - }, - onlyRenderVisibleElements: { - type: Boolean as PropType, - required: false, - default: false - }, - connectionMode: { - type: String as PropType, - required: false, - default: undefined - } - }, - setup(props) { - const nodes = computed(() => getSourceTargetNodes(props.edge, props.nodes)); - - const onConnectEdge = (connection: Connection) => { - props.props.onEdgeUpdate?.(props.edge, connection); - }; - - if (!nodes.value.sourceNode) { - console.log(`couldn't create edge for source id: ${props.edge.source}; edge id: ${props.edge.id}`); - return () => null; - } - - if (!nodes.value.targetNode) { - console.log(`couldn't create edge for target id: ${props.edge.target}; edge id: ${props.edge.id}`); - return () => null; - } - - const EdgeComponent: any = props.props.edgeTypes[props.edge.type as string] || props.props.edgeTypes.default; - const targetNodeBounds = computed(() => nodes.value.targetNode?.__rf.handleBounds); - // when connection type is loose we can define all handles as sources - const targetNodeHandles = computed(() => - props.connectionMode === ConnectionMode.Strict - ? targetNodeBounds.value?.target - : targetNodeBounds.value?.target || targetNodeBounds.value?.source - ); - const sourceHandle = computed( - () => nodes.value.sourceNode && getHandle(nodes.value.sourceNode.__rf.handleBounds.source, props.edge.sourceHandle || null) - ); - const targetHandle = computed(() => getHandle(targetNodeHandles.value, props.edge.targetHandle || null)); - const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom)); - const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top)); - - const edgePositions = computed(() => { - return ( - nodes.value.sourceNode && - nodes.value.targetNode && - getEdgePositions( - nodes.value.sourceNode, - sourceHandle.value, - sourcePosition.value, - nodes.value.targetNode, - targetHandle.value, - targetPosition.value - ) - ); - }); - - const isVisible = computed(() => { - return props.onlyRenderVisibleElements - ? edgePositions.value && - isEdgeVisible({ - sourcePos: { x: edgePositions.value?.sourceX, y: edgePositions.value?.sourceY }, - targetPos: { x: edgePositions.value?.targetX, y: edgePositions.value?.targetY }, - width: props.width || 0, - height: props.height || 0, - transform: props.transform - }) - : true; - }); - - if (!isVisible.value) { - return null; - } - - const isSelected = computed(() => props.selectedElements?.some((elm) => isEdge(elm) && elm.id === props.edge.id) || false); - - return () => ( - - ); - } -}); - -const EdgeRenderer = defineComponent({ - name: 'EdgeRenderer', - components: { - EdgeCmp, - ConnectionLine, - MarkerDefinitions - }, - props: { - edgeTypes: { - type: Object, - required: false, - default: undefined - }, - connectionLineType: { - type: String as PropType, - required: false, - default: undefined - }, - connectionLineStyle: { - type: Object as PropType, - required: false, - default: undefined - }, - connectionLineComponent: { - type: Object as PropType, - required: false, - default: undefined - }, - connectionMode: { - type: String as PropType, - required: false, - default: undefined - }, - onElementClick: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeDoubleClick: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - arrowHeadColor: { - type: String as PropType, - required: false, - default: undefined - }, - markerEndId: { - type: String as PropType, - required: false, - default: undefined - }, - onlyRenderVisibleElements: { - type: Boolean as PropType, - required: false, - default: undefined - }, - onEdgeUpdate: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeContextMenu: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeMouseEnter: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeMouseMove: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeMouseLeave: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeUpdateStart: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onEdgeUpdateEnd: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - edgeUpdaterRadius: { - type: Number as PropType, - required: false, - default: undefined - } - }, - setup(props) { - const store = inject('store'); - const transform = computed(() => store?.transform); - const transformStyle = computed(() => { - return `translate(${transform.value?.[0]},${transform.value?.[1]}) scale(${transform.value?.[2]})`; - }); - const renderConnectionLine = computed(() => store?.connectionNodeId && store?.connectionHandleType); - - return () => ( - - - - {store?.edges.map((edge: Edge) => ( - - ))} - {renderConnectionLine.value && ( - - )} - - - ); - } -}); - -export default EdgeRenderer; diff --git a/src/container/EdgeRenderer/utils.ts b/src/container/EdgeRenderer/utils.ts index 50e23c68..9153081f 100644 --- a/src/container/EdgeRenderer/utils.ts +++ b/src/container/EdgeRenderer/utils.ts @@ -1,22 +1,20 @@ -import { DefineComponent } from 'vue'; import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges'; -import wrapEdge from '../../components/Edges/wrapEdge'; import { rectToBox } from '../../utils/graph'; -import { EdgeTypesType, Position, Node, XYPosition, ElementId, HandleElement, Transform, Edge, WrapEdgeProps } from '../../types'; +import { EdgeTypesType, Position, Node, XYPosition, ElementId, HandleElement, Transform, Edge } from '../../types'; export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType { const standardTypes: EdgeTypesType = { - default: wrapEdge(edgeTypes.default || BezierEdge) as DefineComponent, - straight: wrapEdge(edgeTypes.bezier || StraightEdge) as DefineComponent, - step: wrapEdge(edgeTypes.step || StepEdge) as DefineComponent, - smoothstep: wrapEdge(edgeTypes.step || SmoothStepEdge) as DefineComponent + default: edgeTypes.default || BezierEdge, + straight: edgeTypes.bezier || StraightEdge, + step: edgeTypes.step || StepEdge, + smoothstep: edgeTypes.step || SmoothStepEdge }; const wrappedTypes = {} as EdgeTypesType; const specialTypes: EdgeTypesType = Object.keys(edgeTypes) .filter((k) => !['default', 'bezier'].includes(k)) .reduce((res, key) => { - res[key] = wrapEdge(edgeTypes[key] || BezierEdge) as DefineComponent; + res[key] = edgeTypes[key] || BezierEdge; return res; }, wrappedTypes); diff --git a/src/container/FlowRenderer/FlowRenderer.vue b/src/container/FlowRenderer/FlowRenderer.vue index 13566cfd..f1e1aab8 100644 --- a/src/container/FlowRenderer/FlowRenderer.vue +++ b/src/container/FlowRenderer/FlowRenderer.vue @@ -1,8 +1,5 @@ @@ -56,61 +47,6 @@ const FlowRenderer = defineComponent({ name: 'FlowRenderer', components: { UserSelection, ZoomPane, NodesSelection }, props: { - onPaneClick: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onPaneContextMenu: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onPaneScroll: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onElementsRemove: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMove: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMoveStart: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMoveEnd: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionDragStart: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionDrag: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionDragStop: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionContextMenu: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, deleteKeyCode: { type: [Number, String] as PropType, required: false, @@ -194,9 +130,9 @@ const FlowRenderer = defineComponent({ useGlobalKeyHandler({ store, - onElementsRemove: props.onElementsRemove, - deleteKeyCode: props.deleteKeyCode, - multiSelectionKeyCode: props.multiSelectionKeyCode + onElementsRemove: hooks.elementsRemove.trigger, + deleteKeyCode: props.deleteKeyCode || '', + multiSelectionKeyCode: props.multiSelectionKeyCode || '' }); const onClick = (event: MouseEvent) => { diff --git a/src/container/FlowRenderer/index.tsx b/src/container/FlowRenderer/index.tsx deleted file mode 100644 index 27d17607..00000000 --- a/src/container/FlowRenderer/index.tsx +++ /dev/null @@ -1,217 +0,0 @@ -import { defineComponent, inject, PropType } from 'vue'; -import ZoomPane from '../ZoomPane'; -import UserSelection from '../../components/UserSelection'; -import NodesSelection from '../../components/NodesSelection'; -import { RevueFlowStore, GraphViewProps } from '../../types'; -import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler'; -import useKeyPress from '../../hooks/useKeyPress'; - -type FlowRendererProps = Omit< - GraphViewProps, - | 'elements' - | 'snapToGrid' - | 'nodeTypes' - | 'edgeTypes' - | 'snapGrid' - | 'connectionLineType' - | 'arrowHeadColor' - | 'onlyRenderVisibleElements' - | 'selectNodesOnDrag' ->; - -const FlowRenderer = defineComponent({ - name: 'FlowRenderer', - components: { UserSelection, ZoomPane, NodesSelection }, - props: { - onPaneClick: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onPaneContextMenu: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onPaneScroll: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onElementsRemove: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMove: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMoveStart: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onMoveEnd: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionDragStart: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionDrag: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionDragStop: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - onSelectionContextMenu: { - type: Function as unknown as PropType, - required: false, - default: undefined - }, - deleteKeyCode: { - type: [Number, String] as PropType, - required: false, - default: undefined - }, - selectionKeyCode: { - type: [Number, String] as PropType, - required: false, - default: undefined - }, - multiSelectionKeyCode: { - type: [Number, String] as PropType, - required: false, - default: undefined - }, - zoomActivationKeyCode: { - type: [Number, String] as PropType, - required: false, - default: undefined - }, - elementsSelectable: { - type: Boolean as PropType, - required: false, - default: false - }, - zoomOnScroll: { - type: Boolean as PropType, - required: false, - default: false - }, - zoomOnPinch: { - type: Boolean as PropType, - required: false, - default: false - }, - panOnScroll: { - type: Boolean as PropType, - required: false, - default: false - }, - panOnScrollSpeed: { - type: Number as PropType, - required: false, - default: undefined - }, - panOnScrollMode: { - type: String as PropType, - required: false, - default: undefined - }, - zoomOnDoubleClick: { - type: Boolean as PropType, - required: false, - default: false - }, - paneMoveable: { - type: Boolean as PropType, - required: false, - default: false - }, - defaultPosition: { - type: Array as unknown as PropType, - required: false, - default: undefined - }, - defaultZoom: { - type: Number as PropType, - required: false, - default: undefined - }, - translateExtent: { - type: Array as unknown as PropType, - required: false, - default: undefined - } - }, - setup(props, { slots }) { - const store = inject('store')!; - const keyPressed = useKeyPress(props.selectionKeyCode); - - useGlobalKeyHandler({ - store, - onElementsRemove: props.onElementsRemove, - deleteKeyCode: props.deleteKeyCode as string, - multiSelectionKeyCode: props.multiSelectionKeyCode as string - }); - - const onClick = (event: MouseEvent) => { - props.onPaneClick?.(event); - store?.unsetNodesSelection(); - store?.resetSelectedElements(); - }; - - const onContextMenu = (event: MouseEvent) => { - props.onPaneContextMenu?.(event); - }; - - const onWheel = (event: WheelEvent) => { - props.onPaneScroll?.(event); - }; - - return () => ( - - {slots.default ? slots.default() : ''} - {keyPressed.value ? : ''} - {store?.nodesSelectionActive && ( - - )} -
- - ); - } -}); - -export default FlowRenderer; diff --git a/src/container/GraphView/GraphView.vue b/src/container/GraphView/GraphView.vue index 8b4d0d10..7258cceb 100644 --- a/src/container/GraphView/GraphView.vue +++ b/src/container/GraphView/GraphView.vue @@ -1,17 +1,10 @@