chore: add vueuse/core to deps

feat: Implement onKeystrok of vueuse
* Implement useEventlistener
fix: node selection not properly selecting underlying nodes
This commit is contained in:
Braks
2021-07-23 17:50:48 +02:00
parent 7eb7cb1dc3
commit ef9647ceb4
12 changed files with 213 additions and 281 deletions

View File

@@ -30,12 +30,12 @@
"dependencies": {
"@braks/revue-draggable": "^0.2.4",
"@types/d3": "^7.0.0",
"@vueuse/core": "^5.1.4",
"d3": "^7.0.0",
"d3-selection": "^3.0.0",
"d3-zoom": "^3.0.0",
"fast-deep-equal": "^3.1.3",
"pinia": "^2.0.0-beta.3",
"vue": "^3.0.5"
"pinia": "^2.0.0-beta.3"
},
"devDependencies": {
"@babel/core": "^7.14.6",
@@ -72,6 +72,7 @@
"typescript": "^4.3.5",
"vite": "^2.3.8",
"vite-svg-loader": "^2.1.0",
"vue": "^3.0.5",
"vue-router": "4",
"vue-tsc": "^0.0.24"
},

View File

@@ -66,7 +66,6 @@ const NodesSelection = defineComponent({
}));
const onStart: DraggableEventListener = ({ event }) => {
event.stopPropagation();
props.onSelectionDragStart?.(event, selectedNodes.value);
};

View File

@@ -3,6 +3,7 @@
*/
import { RevueFlowStore, XYPosition } from '../../types';
import { computed, defineComponent, inject } from 'vue';
import { templateRef, useEventListener } from '@vueuse/core';
function getMousePosition(event: MouseEvent): XYPosition | void {
const revueFlowNode = (event.target as Element).closest('.revue-flow');
@@ -18,39 +19,30 @@ function getMousePosition(event: MouseEvent): XYPosition | void {
};
}
const SelectionRect = defineComponent({
setup() {
const store = inject<RevueFlowStore>('store');
return () => {
return store?.userSelectionRect.draw ? (
<div
class="revue-flow__selection"
style={{
width: `${store?.userSelectionRect.width}px`,
height: `${store?.userSelectionRect.height}px`,
transform: `translate(${store?.userSelectionRect.x}px, ${store?.userSelectionRect.y}px)`
}}
/>
) : (
''
);
};
}
});
const SelectionRect = (props: { width: number; height: number; x: number; y: number }) => {
return (
<div
class="revue-flow__selection"
style={{
width: `${props.width}px`,
height: `${props.height}px`,
transform: `translate(${props.x}px, ${props.y}px)`
}}
/>
);
};
export default defineComponent({
components: { SelectionRect },
setup() {
const store = inject<RevueFlowStore>('store')!;
const el = templateRef('user-selection', null);
const shouldRender = computed(() => store.selectionActive || store.elementsSelectable);
if (!shouldRender.value) {
return null;
}
const onMouseDown = (event: MouseEvent): void => {
const onMouseDown = (event: MouseEvent) => {
const mousePos = getMousePosition(event);
if (!mousePos) {
return;
@@ -59,7 +51,8 @@ export default defineComponent({
store.setUserSelection(mousePos);
};
const onMouseMove = (event: MouseEvent): void => {
const onMouseMove = (event: MouseEvent) => {
if (!store.selectionActive) {
return;
}
@@ -72,23 +65,33 @@ export default defineComponent({
store.updateUserSelection(mousePos);
};
const onMouseUp = () => store.unsetUserSelection();
const onMouseUp = () => {
store.unsetUserSelection();
};
const onMouseLeave = () => {
store.unsetUserSelection();
store.unsetNodesSelection();
};
useEventListener(el, 'mousedown', onMouseDown);
useEventListener(el, 'mousemove', onMouseMove);
useEventListener(el, 'click', onMouseUp);
useEventListener(el, 'mouseup', onMouseUp);
useEventListener(el, 'mouseleave', onMouseLeave);
return () => (
<div
class="revue-flow__selectionpane"
onMousedown={onMouseDown}
onMousemove={onMouseMove}
onClick={onMouseUp}
onMouseup={onMouseUp}
onMouseleave={onMouseLeave}
>
<SelectionRect />
<div class="revue-flow__selectionpane" ref="user-selection">
{store?.userSelectionRect.draw ? (
<SelectionRect
width={store.userSelectionRect.width}
height={store.userSelectionRect.height}
x={store.userSelectionRect.x}
y={store.userSelectionRect.y}
/>
) : (
''
)}
</div>
);
}

View File

@@ -1,9 +1,8 @@
import { GraphViewProps } from '../GraphView';
import { defineComponent, inject, PropType } from 'vue';
import ZoomPane from '../ZoomPane';
import UserSelection from '../../components/UserSelection';
import NodesSelection from '../../components/NodesSelection';
import { defineComponent, inject, PropType } from 'vue';
import { RevueFlowStore } from '../../types';
import { RevueFlowStore, GraphViewProps } from '../../types';
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
import useKeyPress from '../../hooks/useKeyPress';
@@ -199,7 +198,7 @@ const FlowRenderer = defineComponent({
zoomActivationKeyCode={props.zoomActivationKeyCode}
>
{slots.default ? slots.default() : ''}
{keyPressed.value ? <UserSelection track-by={'selection'} /> : ''}
{keyPressed.value ? <UserSelection /> : ''}
{store?.nodesSelectionActive && (
<NodesSelection
onSelectionDragStart={props.onSelectionDragStart}

View File

@@ -3,26 +3,9 @@ import FlowRenderer from '../FlowRenderer';
import NodeRenderer from '../NodeRenderer';
import EdgeRenderer from '../EdgeRenderer';
import { onLoadProject, onLoadGetElements, onLoadToObject } from '../../utils/graph';
import { RevueFlowProps } from '../RevueFlow';
import { NodeTypesType, EdgeTypesType, ConnectionLineType, KeyCode, RevueFlowStore } from '../../types';
import { GraphViewProps, RevueFlowStore } from '../../types';
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
export interface GraphViewProps extends Omit<RevueFlowProps, 'onSelectionChange' | 'elements'> {
nodeTypes: NodeTypesType;
edgeTypes: EdgeTypesType;
selectionKeyCode: KeyCode;
deleteKeyCode: KeyCode;
multiSelectionKeyCode: KeyCode;
connectionLineType: ConnectionLineType;
snapToGrid: boolean;
snapGrid: [number, number];
onlyRenderVisibleElements: boolean;
defaultZoom: number;
defaultPosition: [number, number];
arrowHeadColor: string;
selectNodesOnDrag: boolean;
}
const GraphView = defineComponent({
name: 'GraphView',
components: { NodeRenderer, EdgeRenderer },

View File

@@ -1,14 +1,6 @@
import {
computed,
CSSProperties,
defineComponent,
HTMLAttributes,
onBeforeUnmount,
onUpdated,
PropType,
provide,
watchEffect
} from 'vue';
import { computed, defineComponent, onBeforeUnmount, PropType, provide, watch } from 'vue';
import '../../style.css';
import '../../theme-default.css';
import GraphView from '../GraphView';
import DefaultNode from '../../components/Nodes/DefaultNode';
import InputNode from '../../components/Nodes/InputNode';
@@ -16,30 +8,7 @@ import OutputNode from '../../components/Nodes/OutputNode';
import { createNodeTypes } from '../NodeRenderer/utils';
import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges';
import { createEdgeTypes } from '../EdgeRenderer/utils';
import {
Elements,
NodeTypesType,
EdgeTypesType,
OnLoadFunc,
Node,
Edge,
Connection,
ConnectionMode,
ConnectionLineType,
ConnectionLineComponent,
FlowTransform,
OnConnectStartFunc,
OnConnectStopFunc,
OnConnectEndFunc,
TranslateExtent,
KeyCode,
PanOnScrollMode,
OnEdgeUpdateFunc,
NodeExtent,
RevueFlowStore
} from '../../types';
import '../../style.css';
import '../../theme-default.css';
import { ConnectionMode, ConnectionLineType, PanOnScrollMode, RevueFlowStore, RevueFlowProps } from '../../types';
import { initialState } from '../../store';
import configureStore from '../../store/configure-store';
@@ -56,79 +25,6 @@ const defaultEdgeTypes = {
smoothstep: SmoothStepEdge
};
export interface RevueFlowProps extends Omit<HTMLAttributes, 'onLoad'> {
elements: Elements;
onElementClick?: (event: MouseEvent, element: Node | Edge) => void;
onElementsRemove?: (elements: Elements) => void;
onNodeDoubleClick?: (event: MouseEvent, node: Node) => void;
onNodeMouseEnter?: (event: MouseEvent, node: Node) => void;
onNodeMouseMove?: (event: MouseEvent, node: Node) => void;
onNodeMouseLeave?: (event: MouseEvent, node: Node) => void;
onNodeContextMenu?: (event: MouseEvent, node: Node) => void;
onNodeDragStart?: (event: MouseEvent, node: Node) => void;
onNodeDrag?: (event: MouseEvent, node: Node) => void;
onNodeDragStop?: (event: MouseEvent, node: Node) => void;
onConnect?: (connection: Edge | Connection) => void;
onConnectStart?: OnConnectStartFunc;
onConnectStop?: OnConnectStopFunc;
onConnectEnd?: OnConnectEndFunc;
onLoad?: OnLoadFunc;
onMove?: (flowTransform?: FlowTransform) => void;
onMoveStart?: (flowTransform?: FlowTransform) => void;
onMoveEnd?: (flowTransform?: FlowTransform) => void;
onSelectionChange?: (elements: Elements | null) => void;
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
onSelectionDrag?: (event: MouseEvent, nodes: Node[]) => void;
onSelectionDragStop?: (event: MouseEvent, nodes: Node[]) => void;
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
onPaneScroll?: (event?: WheelEvent) => void;
onPaneClick?: (event: MouseEvent) => void;
onPaneContextMenu?: (event: MouseEvent) => void;
nodeTypes?: NodeTypesType;
edgeTypes?: EdgeTypesType;
connectionMode?: ConnectionMode;
connectionLineType?: ConnectionLineType;
connectionLineStyle?: CSSProperties;
connectionLineComponent?: ConnectionLineComponent;
deleteKeyCode?: KeyCode;
selectionKeyCode?: KeyCode;
multiSelectionKeyCode?: KeyCode;
zoomActivationKeyCode?: KeyCode;
snapToGrid?: boolean;
snapGrid?: [number, number];
onlyRenderVisibleElements?: boolean;
nodesDraggable?: boolean;
nodesConnectable?: boolean;
elementsSelectable?: boolean;
selectNodesOnDrag?: boolean;
paneMoveable?: boolean;
minZoom?: number;
maxZoom?: number;
defaultZoom?: number;
defaultPosition?: [number, number];
translateExtent?: TranslateExtent;
nodeExtent?: NodeExtent;
arrowHeadColor?: string;
markerEndId?: string;
zoomOnScroll?: boolean;
zoomOnPinch?: boolean;
panOnScroll?: boolean;
panOnScrollSpeed?: number;
panOnScrollMode?: PanOnScrollMode;
zoomOnDoubleClick?: 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;
onEdgeDoubleClick?: (event: MouseEvent, edge: Edge) => void;
onEdgeUpdateStart?: (event: MouseEvent, edge: Edge) => void;
onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge) => void;
edgeUpdaterRadius?: number;
nodeTypesId?: string;
edgeTypesId?: string;
}
const RevueFlow = defineComponent({
name: 'RevueFlow',
components: { GraphView },
@@ -552,14 +448,8 @@ const RevueFlow = defineComponent({
provide<RevueFlowStore>('store', store);
store.setElements(props.elements);
watchEffect(() => {
watch(props, () => {
store.setElements(props.elements);
props.onSelectionChange?.(store.selectedElements);
});
onUpdated(() => {
store.setElements(props.elements);
props.onSelectionChange?.(store.selectedElements);
});
onBeforeUnmount(() => {

View File

@@ -1,44 +1,37 @@
import { isInputDOMNode } from '../utils';
import { ref, Ref } from 'vue';
import { KeyCode } from '../types';
import { onBeforeUnmount, onMounted, ref, Ref } from 'vue';
import { onKeyStroke, useEventListener } from '@vueuse/core';
export default (keyCode?: KeyCode): Ref<boolean> => {
const keyPressed = ref<boolean>(false);
const downHandler = (event: KeyboardEvent) => {
if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) {
event.preventDefault();
onKeyStroke(
(event) => event.key === keyCode || event.keyCode === keyCode,
(e) => {
e.preventDefault();
keyPressed.value = true;
}
};
const upHandler = (event: KeyboardEvent) => {
if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) {
},
{ eventName: 'keypress' }
);
onKeyStroke(
(event) => event.key === keyCode || event.keyCode === keyCode,
(e) => {
e.preventDefault();
keyPressed.value = true;
},
{ eventName: 'keydown' }
);
onKeyStroke(
(event) => event.key === keyCode || event.keyCode === keyCode,
(e) => {
e.preventDefault();
keyPressed.value = false;
}
};
},
{ eventName: 'keyup' }
);
const resetHandler = () => (keyPressed.value = false);
const bindEvents = () => {
if (typeof keyCode !== 'undefined') {
window.addEventListener('keydown', downHandler);
window.addEventListener('keyup', upHandler);
window.addEventListener('blur', resetHandler);
}
};
const unbindEvents = () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
window.removeEventListener('blur', resetHandler);
};
onMounted(() => {
bindEvents();
});
onBeforeUnmount(() => {
unbindEvents();
useEventListener(window, 'blur', () => {
keyPressed.value = false;
});
return keyPressed;

View File

@@ -5,77 +5,61 @@ import { inject } from 'vue';
const DEFAULT_PADDING = 0.1;
const initialZoomPanHelper: ZoomPanHelperFunctions = {
zoomIn: () => {},
zoomOut: () => {},
zoomTo: (_: number) => {},
transform: (_: FlowTransform) => {},
fitView: (_: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {},
setCenter: (_: number, __: number) => {},
fitBounds: (_: Rect) => {},
project: (position: XYPosition) => position,
initialized: false
};
const useZoomPanHelper = (): ZoomPanHelperFunctions => {
const store = inject<RevueFlowStore>('store')!;
const zoomPanHelperFunctions = () => {
if (store.d3Selection && store.d3Zoom) {
return {
zoomIn: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1.2),
zoomOut: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1 / 1.2),
zoomTo: (zoomLevel: number) => store.d3Zoom?.scaleTo(store.d3Selection as any, zoomLevel),
transform: (transform: FlowTransform) => {
const nextTransform = zoomIdentity.translate(transform.x, transform.y).scale(transform.zoom);
return {
zoomIn: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1.2),
zoomOut: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1 / 1.2),
zoomTo: (zoomLevel: number) => store.d3Zoom?.scaleTo(store.d3Selection as any, zoomLevel),
transform: (transform: FlowTransform) => {
const nextTransform = zoomIdentity.translate(transform.x, transform.y).scale(transform.zoom);
store.d3Zoom?.transform(store.d3Selection as any, nextTransform);
},
fitView: (options: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {
const { nodes, width, height, minZoom, maxZoom } = store;
store.d3Zoom?.transform(store.d3Selection as any, nextTransform);
},
fitView: (options: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {
const { nodes, width, height, minZoom, maxZoom } = store;
if (!nodes.length) {
return;
}
if (!nodes.length) {
return;
}
const bounds = getRectOfNodes(options.includeHiddenNodes ? nodes : nodes.filter((node) => !node.isHidden));
const [x, y, zoom] = getTransformForBounds(
bounds,
width,
height,
options.minZoom || minZoom,
options.maxZoom || maxZoom,
options.padding || DEFAULT_PADDING
);
const transform = zoomIdentity.translate(x, y).scale(zoom);
const bounds = getRectOfNodes(options.includeHiddenNodes ? nodes : nodes.filter((node) => !node.isHidden));
const [x, y, zoom] = getTransformForBounds(
bounds,
width,
height,
options.minZoom || minZoom,
options.maxZoom || maxZoom,
options.padding || DEFAULT_PADDING
);
const transform = zoomIdentity.translate(x, y).scale(zoom);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
setCenter: (x: number, y: number, zoom?: number) => {
const { width, height, maxZoom } = store;
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
setCenter: (x: number, y: number, zoom?: number) => {
const { width, height, maxZoom } = store;
const nextZoom = typeof zoom !== 'undefined' ? zoom : maxZoom;
const centerX = width / 2 - x * nextZoom;
const centerY = height / 2 - y * nextZoom;
const transform = zoomIdentity.translate(centerX, centerY).scale(nextZoom);
const nextZoom = typeof zoom !== 'undefined' ? zoom : maxZoom;
const centerX = width / 2 - x * nextZoom;
const centerY = height / 2 - y * nextZoom;
const transform = zoomIdentity.translate(centerX, centerY).scale(nextZoom);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
fitBounds: (bounds: Rect, padding = DEFAULT_PADDING) => {
const { width, height, minZoom, maxZoom } = store;
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
const transform = zoomIdentity.translate(x, y).scale(zoom);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
fitBounds: (bounds: Rect, padding = DEFAULT_PADDING) => {
const { width, height, minZoom, maxZoom } = store;
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
const transform = zoomIdentity.translate(x, y).scale(zoom);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
project: (position: XYPosition) => {
const { transform, snapToGrid, snapGrid } = store;
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
},
initialized: true
};
}
return initialZoomPanHelper;
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
project: (position: XYPosition) => {
const { transform, snapToGrid, snapGrid } = store;
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
},
initialized: true
};
};
return zoomPanHelperFunctions();

View File

@@ -1,6 +1,4 @@
import RevueFlow from './container/RevueFlow';
export default RevueFlow;
export { default as default } from './container/RevueFlow';
export { default as Handle } from './components/Handle';
export { default as EdgeText } from './components/Edges/EdgeText';
export { getBezierPath } from './components/Edges/BezierEdge';

View File

@@ -189,15 +189,8 @@ export default function configureStore(
const selectedEdges = getConnectedEdges(selectedNodes, this.edges);
const nextSelectedElements = [...selectedNodes, ...selectedEdges];
const selectedElementsChanged = !isEqual(nextSelectedElements, this.selectedElements);
const selectedElementsUpdate = selectedElementsChanged
? nextSelectedElements.length > 0
? nextSelectedElements
: []
: [];
this.userSelectionRect = nextUserSelectRect;
this.selectedElements = selectedElementsUpdate;
this.selectedElements = nextSelectedElements;
},
unsetUserSelection() {
const selectedNodes = this.selectedElements?.filter((node) => isNode(node) && node.__rf) as Node[];

View File

@@ -1,5 +1,5 @@
import { Selection as D3Selection, ZoomBehavior } from 'd3';
import { DefineComponent, HTMLAttributes, PropType, VNode } from 'vue';
import { CSSProperties, DefineComponent, HTMLAttributes, PropType, VNode } from 'vue';
import { Store } from 'pinia';
export type ElementId = string;
@@ -906,3 +906,92 @@ export type RevueFlowActions = {
export type RevueFlowStore = Store<string, RevueFlowState, any, RevueFlowActions>;
export type UpdateNodeInternals = (nodeId: ElementId) => void;
export interface RevueFlowProps extends Omit<HTMLAttributes, 'onLoad'> {
elements: Elements;
onElementClick?: (event: MouseEvent, element: Node | Edge) => void;
onElementsRemove?: (elements: Elements) => void;
onNodeDoubleClick?: (event: MouseEvent, node: Node) => void;
onNodeMouseEnter?: (event: MouseEvent, node: Node) => void;
onNodeMouseMove?: (event: MouseEvent, node: Node) => void;
onNodeMouseLeave?: (event: MouseEvent, node: Node) => void;
onNodeContextMenu?: (event: MouseEvent, node: Node) => void;
onNodeDragStart?: (event: MouseEvent, node: Node) => void;
onNodeDrag?: (event: MouseEvent, node: Node) => void;
onNodeDragStop?: (event: MouseEvent, node: Node) => void;
onConnect?: (connection: Edge | Connection) => void;
onConnectStart?: OnConnectStartFunc;
onConnectStop?: OnConnectStopFunc;
onConnectEnd?: OnConnectEndFunc;
onLoad?: OnLoadFunc;
onMove?: (flowTransform?: FlowTransform) => void;
onMoveStart?: (flowTransform?: FlowTransform) => void;
onMoveEnd?: (flowTransform?: FlowTransform) => void;
onSelectionChange?: (elements: Elements | null) => void;
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
onSelectionDrag?: (event: MouseEvent, nodes: Node[]) => void;
onSelectionDragStop?: (event: MouseEvent, nodes: Node[]) => void;
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
onPaneScroll?: (event?: WheelEvent) => void;
onPaneClick?: (event: MouseEvent) => void;
onPaneContextMenu?: (event: MouseEvent) => void;
nodeTypes?: NodeTypesType;
edgeTypes?: EdgeTypesType;
connectionMode?: ConnectionMode;
connectionLineType?: ConnectionLineType;
connectionLineStyle?: CSSProperties;
connectionLineComponent?: ConnectionLineComponent;
deleteKeyCode?: KeyCode;
selectionKeyCode?: KeyCode;
multiSelectionKeyCode?: KeyCode;
zoomActivationKeyCode?: KeyCode;
snapToGrid?: boolean;
snapGrid?: [number, number];
onlyRenderVisibleElements?: boolean;
nodesDraggable?: boolean;
nodesConnectable?: boolean;
elementsSelectable?: boolean;
selectNodesOnDrag?: boolean;
paneMoveable?: boolean;
minZoom?: number;
maxZoom?: number;
defaultZoom?: number;
defaultPosition?: [number, number];
translateExtent?: TranslateExtent;
nodeExtent?: NodeExtent;
arrowHeadColor?: string;
markerEndId?: string;
zoomOnScroll?: boolean;
zoomOnPinch?: boolean;
panOnScroll?: boolean;
panOnScrollSpeed?: number;
panOnScrollMode?: PanOnScrollMode;
zoomOnDoubleClick?: 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;
onEdgeDoubleClick?: (event: MouseEvent, edge: Edge) => void;
onEdgeUpdateStart?: (event: MouseEvent, edge: Edge) => void;
onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge) => void;
edgeUpdaterRadius?: number;
nodeTypesId?: string;
edgeTypesId?: string;
}
export interface GraphViewProps extends Omit<RevueFlowProps, 'onSelectionChange' | 'elements'> {
nodeTypes: NodeTypesType;
edgeTypes: EdgeTypesType;
selectionKeyCode: KeyCode;
deleteKeyCode: KeyCode;
multiSelectionKeyCode: KeyCode;
connectionLineType: ConnectionLineType;
snapToGrid: boolean;
snapGrid: [number, number];
onlyRenderVisibleElements: boolean;
defaultZoom: number;
defaultPosition: [number, number];
arrowHeadColor: string;
selectNodesOnDrag: boolean;
}

View File

@@ -912,7 +912,7 @@
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.4.tgz#c14c461ec42ea2c1556e86f60b0354341d91adc3"
integrity sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==
"@vueuse/core@^5.1.3":
"@vueuse/core@^5.1.3", "@vueuse/core@^5.1.4":
version "5.1.4"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-5.1.4.tgz#c590bd1ff5cdd3d2caa033b65ed8cb42fc12a534"
integrity sha512-iuRhSaScI1GJS4N3CFPc1GajOr6F6J1Nng1I6ocNOjLx+evss6egImx9wnuX45fxqQstnh7Vfqe3FF7+0NgoWg==