Fix confict after merge branch master
This commit is contained in:
@@ -7,7 +7,7 @@ import { createGridLinesPath, createGridDotsPath } from './utils';
|
||||
|
||||
import './style.css';
|
||||
|
||||
interface BackgroundProps extends HTMLAttributes<SVGElement> {
|
||||
export interface BackgroundProps extends HTMLAttributes<SVGElement> {
|
||||
variant?: BackgroundVariant;
|
||||
gap?: number;
|
||||
color?: string;
|
||||
|
||||
@@ -11,7 +11,7 @@ import UnlockIcon from '../../../assets/icons/unlock.svg';
|
||||
|
||||
import './style.css';
|
||||
|
||||
interface ControlProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
export interface ControlProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
showZoom?: boolean;
|
||||
showFitView?: boolean;
|
||||
showInteractive?: boolean;
|
||||
|
||||
@@ -10,7 +10,7 @@ import './style.css';
|
||||
|
||||
type StringFunc = (node: Node) => string;
|
||||
|
||||
interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> {
|
||||
export interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> {
|
||||
nodeColor?: string | StringFunc;
|
||||
nodeStrokeColor?: string | StringFunc;
|
||||
nodeClassName?: string | StringFunc;
|
||||
@@ -22,7 +22,7 @@ const defaultWidth = 200;
|
||||
const defaultHeight = 150;
|
||||
|
||||
const MiniMap = ({
|
||||
style = { backgroundColor: '#fff' },
|
||||
style,
|
||||
className,
|
||||
nodeStrokeColor = '#555',
|
||||
nodeColor = '#fff',
|
||||
@@ -36,8 +36,8 @@ const MiniMap = ({
|
||||
const nodes = useStoreState((s) => s.nodes);
|
||||
|
||||
const mapClasses = cc(['react-flow__minimap', className]);
|
||||
const elementWidth = (style.width || defaultWidth)! as number;
|
||||
const elementHeight = (style.height || defaultHeight)! as number;
|
||||
const elementWidth = (style?.width || defaultWidth)! as number;
|
||||
const elementHeight = (style?.height || defaultHeight)! as number;
|
||||
const nodeColorFunc = (nodeColor instanceof Function ? nodeColor : () => nodeColor) as StringFunc;
|
||||
const nodeStrokeColorFunc = (nodeStrokeColor instanceof Function
|
||||
? nodeStrokeColor
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
z-index: 5;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { memo, useMemo, ComponentType, CSSProperties, useCallback } from 'react';
|
||||
import React, { memo, ComponentType, useCallback } from 'react';
|
||||
import cc from 'classcat';
|
||||
|
||||
import { useStoreActions } from '../../store/hooks';
|
||||
@@ -36,14 +36,13 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
}: WrapEdgeProps) => {
|
||||
const setSelectedElements = useStoreActions((actions) => actions.setSelectedElements);
|
||||
|
||||
const edgeClasses = cc(['react-flow__edge', `react-flow__edge-${type}`, className, { selected, animated }]);
|
||||
|
||||
const edgeGroupStyle: CSSProperties = useMemo(
|
||||
() => ({
|
||||
pointerEvents: elementsSelectable || onClick ? 'all' : 'none',
|
||||
}),
|
||||
[elementsSelectable, onClick]
|
||||
);
|
||||
const inactive = !elementsSelectable && !onClick;
|
||||
const edgeClasses = cc([
|
||||
'react-flow__edge',
|
||||
`react-flow__edge-${type}`,
|
||||
className,
|
||||
{ selected, animated, inactive },
|
||||
]);
|
||||
|
||||
const onEdgeClick = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
@@ -100,7 +99,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<g className={edgeClasses} onClick={onEdgeClick} style={edgeGroupStyle}>
|
||||
<g className={edgeClasses} onClick={onEdgeClick}>
|
||||
<g onMouseDown={handleEdgeFooterPress}>
|
||||
<circle
|
||||
className="move-handler"
|
||||
|
||||
@@ -12,7 +12,7 @@ type UserSelectionProps = {
|
||||
};
|
||||
|
||||
function getMousePosition(event: React.MouseEvent): XYPosition | void {
|
||||
const reactFlowNode = document.querySelector('.react-flow');
|
||||
const reactFlowNode = (event.target as Element).closest('.react-flow');
|
||||
if (!reactFlowNode) {
|
||||
return;
|
||||
}
|
||||
@@ -51,6 +51,7 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
||||
const setUserSelection = useStoreActions((actions) => actions.setUserSelection);
|
||||
const updateUserSelection = useStoreActions((actions) => actions.updateUserSelection);
|
||||
const unsetUserSelection = useStoreActions((actions) => actions.unsetUserSelection);
|
||||
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
|
||||
const renderUserSelectionPane = selectionActive || selectionKeyPressed;
|
||||
|
||||
if (!elementsSelectable || !renderUserSelectionPane) {
|
||||
@@ -81,12 +82,18 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
||||
|
||||
const onMouseUp = () => unsetUserSelection();
|
||||
|
||||
const onMouseLeave = () => {
|
||||
unsetUserSelection();
|
||||
unsetNodesSelection();
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="react-flow__selectionpane"
|
||||
onMouseDown={onMouseDown}
|
||||
onMouseMove={onMouseMove}
|
||||
onMouseUp={onMouseUp}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
<SelectionRect />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import React, { useCallback, useRef, memo, ReactNode, WheelEvent, MouseEvent } from 'react';
|
||||
import { useStoreActions, useStoreState } from '../../store/hooks';
|
||||
|
||||
import useResizeHandler from '../../hooks/useResizeHandler';
|
||||
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
|
||||
import useD3Zoom from '../../hooks/useD3Zoom';
|
||||
import useKeyPress from '../../hooks/useKeyPress';
|
||||
|
||||
import { GraphViewProps } from '../GraphView';
|
||||
import UserSelection from '../../components/UserSelection';
|
||||
import NodesSelection from '../../components/NodesSelection';
|
||||
|
||||
interface FlowRendererProps
|
||||
extends Omit<
|
||||
GraphViewProps,
|
||||
| 'elements'
|
||||
| 'snapToGrid'
|
||||
| 'nodeTypes'
|
||||
| 'edgeTypes'
|
||||
| 'snapGrid'
|
||||
| 'connectionLineType'
|
||||
| 'arrowHeadColor'
|
||||
| 'onlyRenderVisibleNodes'
|
||||
> {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const FlowRenderer = ({
|
||||
children,
|
||||
onPaneClick,
|
||||
onPaneContextMenu,
|
||||
onPaneScroll,
|
||||
onElementsRemove,
|
||||
deleteKeyCode,
|
||||
onMove,
|
||||
onMoveStart,
|
||||
onMoveEnd,
|
||||
selectionKeyCode,
|
||||
zoomOnScroll,
|
||||
zoomOnDoubleClick,
|
||||
paneMoveable,
|
||||
defaultPosition,
|
||||
defaultZoom,
|
||||
translateExtent,
|
||||
onSelectionDragStart,
|
||||
onSelectionDrag,
|
||||
onSelectionDragStop,
|
||||
onSelectionContextMenu,
|
||||
}: FlowRendererProps) => {
|
||||
const zoomPane = useRef<HTMLDivElement>(null);
|
||||
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
|
||||
const nodesSelectionActive = useStoreState((state) => state.nodesSelectionActive);
|
||||
const selectionKeyPressed = useKeyPress(selectionKeyCode);
|
||||
|
||||
useResizeHandler(zoomPane);
|
||||
useGlobalKeyHandler({ onElementsRemove, deleteKeyCode });
|
||||
|
||||
useD3Zoom({
|
||||
zoomPane,
|
||||
onMove,
|
||||
onMoveStart,
|
||||
onMoveEnd,
|
||||
selectionKeyPressed,
|
||||
zoomOnScroll,
|
||||
zoomOnDoubleClick,
|
||||
paneMoveable,
|
||||
defaultPosition,
|
||||
defaultZoom,
|
||||
translateExtent,
|
||||
});
|
||||
|
||||
const onClick = useCallback(
|
||||
(event: MouseEvent) => {
|
||||
onPaneClick?.(event);
|
||||
unsetNodesSelection();
|
||||
},
|
||||
[onPaneClick]
|
||||
);
|
||||
|
||||
const onContextMenu = useCallback(
|
||||
(event: MouseEvent) => {
|
||||
onPaneContextMenu?.(event);
|
||||
},
|
||||
[onPaneContextMenu]
|
||||
);
|
||||
|
||||
const onWheel = useCallback(
|
||||
(event: WheelEvent) => {
|
||||
onPaneScroll?.(event);
|
||||
},
|
||||
[onPaneScroll]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="react-flow__renderer" ref={zoomPane}>
|
||||
{children}
|
||||
<UserSelection selectionKeyPressed={selectionKeyPressed} />
|
||||
{nodesSelectionActive && (
|
||||
<NodesSelection
|
||||
onSelectionDragStart={onSelectionDragStart}
|
||||
onSelectionDrag={onSelectionDrag}
|
||||
onSelectionDragStop={onSelectionDragStop}
|
||||
onSelectionContextMenu={onSelectionContextMenu}
|
||||
/>
|
||||
)}
|
||||
<div className="react-flow__pane" onClick={onClick} onContextMenu={onContextMenu} onWheel={onWheel} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FlowRenderer.displayName = 'FlowRenderer';
|
||||
|
||||
export default memo(FlowRenderer);
|
||||
@@ -1,15 +1,10 @@
|
||||
import React, { useEffect, useRef, useCallback, memo, CSSProperties, MouseEvent, WheelEvent } from 'react';
|
||||
import React, { useEffect, useRef, memo, CSSProperties, MouseEvent, WheelEvent } from 'react';
|
||||
|
||||
import { useStoreState, useStoreActions, useStore } from '../../store/hooks';
|
||||
import FlowRenderer from '../FlowRenderer';
|
||||
import NodeRenderer from '../NodeRenderer';
|
||||
import EdgeRenderer from '../EdgeRenderer';
|
||||
import UserSelection from '../../components/UserSelection';
|
||||
import NodesSelection from '../../components/NodesSelection';
|
||||
import useKeyPress from '../../hooks/useKeyPress';
|
||||
import useD3Zoom from '../../hooks/useD3Zoom';
|
||||
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
|
||||
import useElementUpdater from '../../hooks/useElementUpdater';
|
||||
import useResizeHandler from '../../hooks/useResizeHandler';
|
||||
import { onLoadProject, onLoadGetElements } from '../../utils/graph';
|
||||
import {
|
||||
Elements,
|
||||
@@ -133,11 +128,7 @@ const GraphView = ({
|
||||
onEdgeUpdate,
|
||||
}: GraphViewProps) => {
|
||||
const isInitialised = useRef<boolean>(false);
|
||||
const zoomPane = useRef<HTMLDivElement>(null);
|
||||
const rendererNode = useRef<HTMLDivElement>(null);
|
||||
const d3Initialised = useStoreState((state) => state.d3Initialised);
|
||||
const nodesSelectionActive = useStoreState((state) => state.nodesSelectionActive);
|
||||
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
|
||||
const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
|
||||
const setOnConnectStart = useStoreActions((actions) => actions.setOnConnectStart);
|
||||
const setOnConnectStop = useStoreActions((actions) => actions.setOnConnectStop);
|
||||
@@ -156,26 +147,8 @@ const GraphView = ({
|
||||
const zoomTo = useStoreActions((actions) => actions.zoomTo);
|
||||
const currentStore = useStore();
|
||||
|
||||
useResizeHandler(rendererNode);
|
||||
useGlobalKeyHandler({ onElementsRemove, deleteKeyCode });
|
||||
useElementUpdater(elements);
|
||||
|
||||
const selectionKeyPressed = useKeyPress(selectionKeyCode);
|
||||
|
||||
useD3Zoom({
|
||||
zoomPane,
|
||||
onMove,
|
||||
onMoveStart,
|
||||
onMoveEnd,
|
||||
selectionKeyPressed,
|
||||
zoomOnScroll,
|
||||
zoomOnDoubleClick,
|
||||
paneMoveable,
|
||||
defaultPosition,
|
||||
defaultZoom,
|
||||
translateExtent,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInitialised.current && d3Initialised) {
|
||||
if (onLoad) {
|
||||
@@ -195,28 +168,6 @@ const GraphView = ({
|
||||
}
|
||||
}, [d3Initialised, onLoad]);
|
||||
|
||||
const onZoomPaneClick = useCallback(
|
||||
(event: React.MouseEvent) => {
|
||||
onPaneClick?.(event);
|
||||
unsetNodesSelection();
|
||||
},
|
||||
[onPaneClick]
|
||||
);
|
||||
|
||||
const onZoomPaneContextMenu = useCallback(
|
||||
(event: React.MouseEvent) => {
|
||||
onPaneContextMenu?.(event);
|
||||
},
|
||||
[onPaneContextMenu]
|
||||
);
|
||||
|
||||
const onZoomPaneScroll = useCallback(
|
||||
(event: WheelEvent) => {
|
||||
onPaneScroll?.(event);
|
||||
},
|
||||
[onPaneScroll]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (onConnect) {
|
||||
setOnConnect(onConnect);
|
||||
@@ -290,7 +241,27 @@ const GraphView = ({
|
||||
}, [translateExtent]);
|
||||
|
||||
return (
|
||||
<div className="react-flow__renderer" ref={rendererNode}>
|
||||
<FlowRenderer
|
||||
onPaneClick={onPaneClick}
|
||||
onPaneContextMenu={onPaneContextMenu}
|
||||
onPaneScroll={onPaneScroll}
|
||||
onElementsRemove={onElementsRemove}
|
||||
deleteKeyCode={deleteKeyCode}
|
||||
selectionKeyCode={selectionKeyCode}
|
||||
onMove={onMove}
|
||||
onMoveStart={onMoveStart}
|
||||
onMoveEnd={onMoveEnd}
|
||||
zoomOnScroll={zoomOnScroll}
|
||||
zoomOnDoubleClick={zoomOnDoubleClick}
|
||||
paneMoveable={paneMoveable}
|
||||
defaultPosition={defaultPosition}
|
||||
defaultZoom={defaultZoom}
|
||||
translateExtent={translateExtent}
|
||||
onSelectionDragStart={onSelectionDragStart}
|
||||
onSelectionDrag={onSelectionDrag}
|
||||
onSelectionDragStop={onSelectionDragStop}
|
||||
onSelectionContextMenu={onSelectionContextMenu}
|
||||
>
|
||||
<NodeRenderer
|
||||
nodeTypes={nodeTypes}
|
||||
onElementClick={onElementClick}
|
||||
@@ -315,23 +286,7 @@ const GraphView = ({
|
||||
connectionLineComponent={connectionLineComponent}
|
||||
onEdgeUpdate={onEdgeUpdate}
|
||||
/>
|
||||
<UserSelection selectionKeyPressed={selectionKeyPressed} />
|
||||
{nodesSelectionActive && (
|
||||
<NodesSelection
|
||||
onSelectionDragStart={onSelectionDragStart}
|
||||
onSelectionDrag={onSelectionDrag}
|
||||
onSelectionDragStop={onSelectionDragStop}
|
||||
onSelectionContextMenu={onSelectionContextMenu}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className="react-flow__zoompane"
|
||||
onClick={onZoomPaneClick}
|
||||
onContextMenu={onZoomPaneContextMenu}
|
||||
onWheel={onZoomPaneScroll}
|
||||
ref={zoomPane}
|
||||
/>
|
||||
</div>
|
||||
</FlowRenderer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+15
-1
@@ -107,6 +107,20 @@ export default ({
|
||||
useEffect(() => {
|
||||
if (d3Zoom) {
|
||||
d3Zoom.filter((event: any) => {
|
||||
if (selectionKeyPressed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// only allow zoom on nodes
|
||||
if (event.target.closest('.react-flow__node') && event.type !== 'wheel') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// only allow zoom on user selection
|
||||
if (event.target.closest('.react-flow__nodesselection') && event.type !== 'wheel') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!paneMoveable) {
|
||||
return false;
|
||||
}
|
||||
@@ -122,5 +136,5 @@ export default ({
|
||||
return !event.ctrlKey && !event.button;
|
||||
});
|
||||
}
|
||||
}, [d3Zoom, zoomOnScroll, zoomOnDoubleClick, paneMoveable]);
|
||||
}, [d3Zoom, zoomOnScroll, zoomOnDoubleClick, paneMoveable, selectionKeyPressed]);
|
||||
};
|
||||
|
||||
+6
-1
@@ -11,5 +11,10 @@ export { getMarkerEnd, getCenter as getEdgeCenter } from './components/Edges/uti
|
||||
export { isNode, isEdge, removeElements, addEdge, getOutgoers, getIncomers, getConnectedEdges, updateEdge } from './utils/graph';
|
||||
|
||||
export * from './additional-components';
|
||||
export * from './types';
|
||||
export * from './store/hooks';
|
||||
export * from './types';
|
||||
|
||||
export { ReactFlowProps } from './container/ReactFlow';
|
||||
export { MiniMapProps } from './additional-components/MiniMap';
|
||||
export { ControlProps } from './additional-components/Controls';
|
||||
export { BackgroundProps } from './additional-components/Background';
|
||||
|
||||
+1
-1
@@ -397,7 +397,7 @@ export const storeModel: StoreModel = {
|
||||
}),
|
||||
|
||||
setMaxZoom: action((state, maxZoom) => {
|
||||
state.minZoom = maxZoom;
|
||||
state.maxZoom = maxZoom;
|
||||
|
||||
if (state.d3Zoom) {
|
||||
state.d3Zoom.scaleExtent([state.minZoom, maxZoom]);
|
||||
|
||||
+11
-3
@@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
.react-flow__renderer,
|
||||
.react-flow__zoompane,
|
||||
.react-flow__pane,
|
||||
.react-flow__selectionpane {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -15,12 +15,16 @@
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.react-flow__zoompane {
|
||||
.react-flow__pane {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.react-flow__renderer {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.react-flow__selectionpane {
|
||||
z-index: 2;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.react-flow__selection {
|
||||
@@ -42,6 +46,10 @@
|
||||
.react-flow__edge {
|
||||
pointer-events: all;
|
||||
|
||||
&.inactive {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
.react-flow__edge-path {
|
||||
stroke: #555;
|
||||
|
||||
+5
-2
@@ -2,8 +2,11 @@ import { DraggableEvent } from 'react-draggable';
|
||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||
|
||||
export const isInputDOMNode = (e: ReactMouseEvent | DraggableEvent | KeyboardEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
return e && target && ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(target.nodeName);
|
||||
const target = e?.target as HTMLElement;
|
||||
|
||||
return (
|
||||
['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(target?.nodeName) || target?.hasAttribute('contenteditable')
|
||||
);
|
||||
};
|
||||
|
||||
export const getDimensions = (node: HTMLDivElement) => ({
|
||||
|
||||
Reference in New Issue
Block a user