feat(edge): add onEdgeContextMenu handler #943
This commit is contained in:
@@ -40,6 +40,7 @@ const onLoad = (reactFlowInstance: OnLoadParams) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onMoveEnd = (transform?: FlowTransform) => console.log('zoom/move end', transform);
|
const onMoveEnd = (transform?: FlowTransform) => console.log('zoom/move end', transform);
|
||||||
|
const onEdgeContextMenu = (_: MouseEvent, edge: Edge) => console.log('edge context menu', edge);
|
||||||
|
|
||||||
const initialElements: Elements = [
|
const initialElements: Elements = [
|
||||||
{
|
{
|
||||||
@@ -177,6 +178,7 @@ const OverviewFlow = () => {
|
|||||||
connectionLineStyle={connectionLineStyle}
|
connectionLineStyle={connectionLineStyle}
|
||||||
snapToGrid={true}
|
snapToGrid={true}
|
||||||
snapGrid={snapGrid}
|
snapGrid={snapGrid}
|
||||||
|
onEdgeContextMenu={onEdgeContextMenu}
|
||||||
>
|
>
|
||||||
<MiniMap nodeStrokeColor={nodeStrokeColor} nodeColor={nodeColor} nodeBorderRadius={2} />
|
<MiniMap nodeStrokeColor={nodeStrokeColor} nodeColor={nodeColor} nodeBorderRadius={2} />
|
||||||
<Controls />
|
<Controls />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { memo, ComponentType, useCallback, useState } from 'react';
|
import React, { memo, ComponentType, useCallback, useState, useMemo } from 'react';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStoreActions, useStoreState } from '../../store/hooks';
|
import { useStoreActions, useStoreState } from '../../store/hooks';
|
||||||
@@ -37,7 +37,8 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
targetHandleId,
|
targetHandleId,
|
||||||
handleEdgeUpdate,
|
handleEdgeUpdate,
|
||||||
onConnectEdge,
|
onConnectEdge,
|
||||||
}: WrapEdgeProps) => {
|
onContextMenu,
|
||||||
|
}: WrapEdgeProps): JSX.Element | null => {
|
||||||
const addSelectedElements = useStoreActions((actions) => actions.addSelectedElements);
|
const addSelectedElements = useStoreActions((actions) => actions.addSelectedElements);
|
||||||
const setConnectionNodeId = useStoreActions((actions) => actions.setConnectionNodeId);
|
const setConnectionNodeId = useStoreActions((actions) => actions.setConnectionNodeId);
|
||||||
const setPosition = useStoreActions((actions) => actions.setConnectionPosition);
|
const setPosition = useStoreActions((actions) => actions.setConnectionPosition);
|
||||||
@@ -53,34 +54,45 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
{ selected, animated, inactive, updating },
|
{ selected, animated, inactive, updating },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const edgeElement = useMemo<Edge>(() => {
|
||||||
|
const el: Edge = {
|
||||||
|
id,
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
type,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sourceHandleId) {
|
||||||
|
el.sourceHandle = sourceHandleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetHandleId) {
|
||||||
|
el.targetHandle = targetHandleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof data !== 'undefined') {
|
||||||
|
el.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}, [id, source, target, type, sourceHandleId, targetHandleId, data]);
|
||||||
|
|
||||||
const onEdgeClick = useCallback(
|
const onEdgeClick = useCallback(
|
||||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||||
const edgeElement: Edge = {
|
|
||||||
id,
|
|
||||||
source,
|
|
||||||
target,
|
|
||||||
type,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (sourceHandleId) {
|
|
||||||
edgeElement.sourceHandle = sourceHandleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetHandleId) {
|
|
||||||
edgeElement.targetHandle = targetHandleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data !== 'undefined') {
|
|
||||||
edgeElement.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elementsSelectable) {
|
if (elementsSelectable) {
|
||||||
addSelectedElements(edgeElement);
|
addSelectedElements(edgeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick?.(event, edgeElement);
|
onClick?.(event, edgeElement);
|
||||||
},
|
},
|
||||||
[elementsSelectable, id, source, target, type, data, sourceHandleId, targetHandleId, onClick]
|
[elementsSelectable, edgeElement, onClick]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onEdgeContextMenu = useCallback(
|
||||||
|
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||||
|
onContextMenu?.(event, edgeElement);
|
||||||
|
},
|
||||||
|
[edgeElement, onContextMenu]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleEdgeUpdater = useCallback(
|
const handleEdgeUpdater = useCallback(
|
||||||
@@ -127,7 +139,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g className={edgeClasses} onClick={onEdgeClick}>
|
<g className={edgeClasses} onClick={onEdgeClick} onContextMenu={onEdgeContextMenu}>
|
||||||
{handleEdgeUpdate && (
|
{handleEdgeUpdate && (
|
||||||
<g
|
<g
|
||||||
onMouseDown={onEdgeUpdaterSourceMouseDown}
|
onMouseDown={onEdgeUpdaterSourceMouseDown}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ interface EdgeRendererProps {
|
|||||||
markerEndId?: string;
|
markerEndId?: string;
|
||||||
onlyRenderVisibleElements: boolean;
|
onlyRenderVisibleElements: boolean;
|
||||||
onEdgeUpdate?: OnEdgeUpdateFunc;
|
onEdgeUpdate?: OnEdgeUpdateFunc;
|
||||||
|
onEdgeContextMenu?: (event: React.MouseEvent, element: Edge) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EdgeWrapperProps {
|
interface EdgeWrapperProps {
|
||||||
@@ -163,6 +164,7 @@ const Edge = ({
|
|||||||
isHidden={edge.isHidden}
|
isHidden={edge.isHidden}
|
||||||
onConnectEdge={onConnectEdge}
|
onConnectEdge={onConnectEdge}
|
||||||
handleEdgeUpdate={typeof props.onEdgeUpdate !== 'undefined'}
|
handleEdgeUpdate={typeof props.onEdgeUpdate !== 'undefined'}
|
||||||
|
onContextMenu={props.onEdgeContextMenu}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ const GraphView = ({
|
|||||||
onPaneScroll,
|
onPaneScroll,
|
||||||
onPaneContextMenu,
|
onPaneContextMenu,
|
||||||
onEdgeUpdate,
|
onEdgeUpdate,
|
||||||
|
onEdgeContextMenu,
|
||||||
}: GraphViewProps) => {
|
}: GraphViewProps) => {
|
||||||
const isInitialised = useRef<boolean>(false);
|
const isInitialised = useRef<boolean>(false);
|
||||||
const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
|
const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
|
||||||
@@ -262,6 +263,7 @@ const GraphView = ({
|
|||||||
markerEndId={markerEndId}
|
markerEndId={markerEndId}
|
||||||
onEdgeUpdate={onEdgeUpdate}
|
onEdgeUpdate={onEdgeUpdate}
|
||||||
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
||||||
|
onEdgeContextMenu={onEdgeContextMenu}
|
||||||
/>
|
/>
|
||||||
</FlowRenderer>
|
</FlowRenderer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
|||||||
panOnScrollMode?: PanOnScrollMode;
|
panOnScrollMode?: PanOnScrollMode;
|
||||||
zoomOnDoubleClick?: boolean;
|
zoomOnDoubleClick?: boolean;
|
||||||
onEdgeUpdate?: OnEdgeUpdateFunc;
|
onEdgeUpdate?: OnEdgeUpdateFunc;
|
||||||
|
onEdgeContextMenu?: (event: MouseEvent, nodes: Edge) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReactFlow = ({
|
const ReactFlow = ({
|
||||||
@@ -173,6 +174,7 @@ const ReactFlow = ({
|
|||||||
onPaneContextMenu,
|
onPaneContextMenu,
|
||||||
children,
|
children,
|
||||||
onEdgeUpdate,
|
onEdgeUpdate,
|
||||||
|
onEdgeContextMenu,
|
||||||
...rest
|
...rest
|
||||||
}: ReactFlowProps) => {
|
}: ReactFlowProps) => {
|
||||||
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []);
|
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []);
|
||||||
@@ -240,6 +242,7 @@ const ReactFlow = ({
|
|||||||
onSelectionDragStop={onSelectionDragStop}
|
onSelectionDragStop={onSelectionDragStop}
|
||||||
onSelectionContextMenu={onSelectionContextMenu}
|
onSelectionContextMenu={onSelectionContextMenu}
|
||||||
onEdgeUpdate={onEdgeUpdate}
|
onEdgeUpdate={onEdgeUpdate}
|
||||||
|
onEdgeContextMenu={onEdgeContextMenu}
|
||||||
/>
|
/>
|
||||||
<ElementUpdater elements={elements} />
|
<ElementUpdater elements={elements} />
|
||||||
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ export interface WrapEdgeProps<T = any> {
|
|||||||
isHidden?: boolean;
|
isHidden?: boolean;
|
||||||
handleEdgeUpdate: boolean;
|
handleEdgeUpdate: boolean;
|
||||||
onConnectEdge: OnConnectFunc;
|
onConnectEdge: OnConnectFunc;
|
||||||
|
onContextMenu: (event: React.MouseEvent, edge: Edge) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EdgeProps<T = any> {
|
export interface EdgeProps<T = any> {
|
||||||
|
|||||||
Reference in New Issue
Block a user