Fix confict after merge branch master

This commit is contained in:
Long Nguyen
2020-10-13 11:58:28 +09:00
166 changed files with 31383 additions and 382 deletions
@@ -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;
+1 -1
View File
@@ -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;
+4 -4
View File
@@ -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
+2 -1
View File
@@ -3,4 +3,5 @@
z-index: 5;
bottom: 10px;
right: 10px;
}
background-color: #fff;
}
+9 -10
View File
@@ -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"
+8 -1
View File
@@ -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>
+113
View File
@@ -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);
+24 -69
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) => ({