From e1b0d8f3972d1e536d4611abe303015a8a7ead7b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2020 05:07:32 +0000 Subject: [PATCH 1/4] chore(deps-dev): bump rollup from 2.27.1 to 2.28.2 Bumps [rollup](https://github.com/rollup/rollup) from 2.27.1 to 2.28.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v2.27.1...v2.28.2) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 68442ff1..1a407c51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11241,9 +11241,9 @@ } }, "rollup": { - "version": "2.27.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.27.1.tgz", - "integrity": "sha512-GiWHQvnmMgBktSpY/1+nrGpwPsTw4b9P28og2uedfeq4JZ16rzAmnQ5Pm/E0/BEmDNia1ZbY7+qu3nBgNa19Hg==", + "version": "2.28.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.28.2.tgz", + "integrity": "sha512-8txbsFBFLmm9Xdt4ByTOGa9Muonmc8MfNjnGAR8U8scJlF1ZW7AgNZa7aqBXaKtlvnYP/ab++fQIq9dB9NWUbg==", "dev": true, "requires": { "fsevents": "~2.1.2" diff --git a/package.json b/package.json index 04e974b4..633b1855 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "prop-types": "^15.7.2", "react": "^16.13.1", "release-it": "^14.0.3", - "rollup": "^2.27.1", + "rollup": "^2.28.2", "rollup-plugin-babel": "^4.4.0", "rollup-plugin-bundle-size": "^1.0.3", "rollup-plugin-commonjs": "^10.1.0", From ee35470dd7e0f3ca4351cd28e95444e211237b1d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2020 05:08:36 +0000 Subject: [PATCH 2/4] chore(deps-dev): bump rollup-plugin-typescript2 from 0.27.2 to 0.27.3 Bumps [rollup-plugin-typescript2](https://github.com/ezolenko/rollup-plugin-typescript2) from 0.27.2 to 0.27.3. - [Release notes](https://github.com/ezolenko/rollup-plugin-typescript2/releases) - [Commits](https://github.com/ezolenko/rollup-plugin-typescript2/compare/0.27.2...0.27.3) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 68442ff1..ec385052 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11570,9 +11570,9 @@ } }, "rollup-plugin-typescript2": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.2.tgz", - "integrity": "sha512-zarMH2F8oT/NO6p20gl/jkts+WxyzOlhOIUwUU/EDx5e6ewdDPS/flwLj5XFuijUCr64bZwqKuRVwCPdXXYefQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.3.tgz", + "integrity": "sha512-gmYPIFmALj9D3Ga1ZbTZAKTXq1JKlTQBtj299DXhqYz9cL3g/AQfUvbb2UhH+Nf++cCq941W2Mv7UcrcgLzJJg==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", diff --git a/package.json b/package.json index 04e974b4..aa10e631 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "rollup-plugin-replace": "^2.2.0", "rollup-plugin-serve": "^1.0.4", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.27.2", + "rollup-plugin-typescript2": "^0.27.3", "rollup-plugin-uglify": "^6.0.4", "start-server-and-test": "^1.11.4", "typescript": "^4.0.3" From 7ef6d0adb21c1785b148484062773088b0a3cda1 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 30 Sep 2020 16:44:50 +0200 Subject: [PATCH 3/4] fix(fitView): don't let defaultPosition overwrite fitView on load #533 --- src/container/GraphView/index.tsx | 13 +++---------- src/container/NodeRenderer/index.tsx | 1 + src/container/ReactFlow/index.tsx | 4 ++-- src/hooks/useD3Zoom.ts | 10 ++++++++-- src/store/index.ts | 24 ++++++++++++++++++++---- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx index 5f2010d3..88272045 100644 --- a/src/container/GraphView/index.tsx +++ b/src/container/GraphView/index.tsx @@ -188,6 +188,9 @@ const GraphView = ({ zoomOnScroll, zoomOnDoubleClick, paneMoveable, + defaultPosition, + defaultZoom, + translateExtent, }); useEffect(() => { @@ -205,16 +208,6 @@ const GraphView = ({ }); } - const initialTransform = { - x: defaultPosition[0], - y: defaultPosition[1], - k: defaultZoom, - }; - - if (initialTransform.x !== 0 || initialTransform.y !== 0 || initialTransform.k !== 1) { - setInitTransform(initialTransform); - } - isInitialised.current = true; } }, [d3Initialised, onLoad]); diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx index 18674df8..bf99ac32 100644 --- a/src/container/NodeRenderer/index.tsx +++ b/src/container/NodeRenderer/index.tsx @@ -83,6 +83,7 @@ const NodeRenderer = ({ onlyRenderVisibleNodes = true, ...props }: NodeRendererP const nodesDraggable = useStoreState((s) => s.nodesDraggable); const nodesConnectable = useStoreState((s) => s.nodesConnectable); const elementsSelectable = useStoreState((s) => s.elementsSelectable); + const transformStyle = { transform: `translate(${transform[0]}px,${transform[1]}px) scale(${transform[2]})`, }; diff --git a/src/container/ReactFlow/index.tsx b/src/container/ReactFlow/index.tsx index aee9fa52..63dba920 100644 --- a/src/container/ReactFlow/index.tsx +++ b/src/container/ReactFlow/index.tsx @@ -142,8 +142,8 @@ const ReactFlow = ({ onPaneScroll, onPaneContextMenu, }: ReactFlowProps) => { - const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []); - const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), []); + const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), [nodeTypes]); + const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), [edgeTypes]); const reactFlowClasses = cc(['react-flow', className]); return ( diff --git a/src/hooks/useD3Zoom.ts b/src/hooks/useD3Zoom.ts index 4fbbef6c..60d430c7 100644 --- a/src/hooks/useD3Zoom.ts +++ b/src/hooks/useD3Zoom.ts @@ -1,7 +1,7 @@ import { useEffect, useRef, MutableRefObject } from 'react'; import { useStoreState, useStoreActions } from '../store/hooks'; -import { FlowTransform } from '../types'; +import { FlowTransform, TranslateExtent } from '../types'; interface UseD3ZoomParams { zoomPane: MutableRefObject; @@ -9,6 +9,9 @@ interface UseD3ZoomParams { zoomOnScroll: boolean; zoomOnDoubleClick: boolean; paneMoveable: boolean; + defaultPosition: [number, number]; + defaultZoom: number; + translateExtent?: TranslateExtent; onMove?: (flowTransform?: FlowTransform) => void; onMoveStart?: (flowTransform?: FlowTransform) => void; onMoveEnd?: (flowTransform?: FlowTransform) => void; @@ -34,6 +37,9 @@ export default ({ zoomOnDoubleClick, selectionKeyPressed, paneMoveable, + defaultPosition, + defaultZoom, + translateExtent, }: UseD3ZoomParams): void => { const prevTransform = useRef({ x: 0, y: 0, zoom: 0 }); const d3Zoom = useStoreState((s) => s.d3Zoom); @@ -43,7 +49,7 @@ export default ({ useEffect(() => { if (zoomPane.current) { - initD3(zoomPane.current); + initD3({ zoomPane: zoomPane.current, defaultPosition, defaultZoom, translateExtent }); } }, []); diff --git a/src/store/index.ts b/src/store/index.ts index 85e08fba..1e3e743a 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -51,6 +51,12 @@ type SetSnapGrid = { snapGrid: [number, number]; }; +type InitD3 = { + zoomPane: Element; + defaultPosition: [number, number]; + defaultZoom: number; + translateExtent?: TranslateExtent; +}; export interface StoreModel { width: number; height: number; @@ -116,7 +122,7 @@ export interface StoreModel { updateSize: Action; - initD3: Action; + initD3: Action; setMinMaxZoom: Action; @@ -369,11 +375,21 @@ export const storeModel: StoreModel = { state.height = size.height || 500; }), - initD3: action((state, zoomPaneNode) => { - const d3ZoomInstance = zoom().scaleExtent([state.minZoom, state.maxZoom]).translateExtent(state.translateExtent); + initD3: action((state, { zoomPane, defaultPosition, defaultZoom, translateExtent }) => { + const currentTranslateExtent = typeof translateExtent !== 'undefined' ? translateExtent : state.translateExtent; + const d3ZoomInstance = zoom().scaleExtent([state.minZoom, state.maxZoom]).translateExtent(currentTranslateExtent); + const selection = select(zoomPane).call(d3ZoomInstance); - const selection = select(zoomPaneNode).call(d3ZoomInstance); + const clampedX = clamp(defaultPosition[0], currentTranslateExtent[0][0], currentTranslateExtent[1][0]); + const clampedY = clamp(defaultPosition[1], currentTranslateExtent[0][1], currentTranslateExtent[1][1]); + const clampedZoom = clamp(defaultZoom, state.minZoom, state.maxZoom); + const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom); + selection.property('__zoom', updatedTransform); + + state.transform[0] = clampedX; + state.transform[1] = clampedY; + state.transform[2] = clampedZoom; state.d3Zoom = d3ZoomInstance; state.d3Selection = selection; state.d3Initialised = true; From 284968ad54f6dad2bd097e3d0f63c52174996043 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 30 Sep 2020 18:07:40 +0200 Subject: [PATCH 4/4] style(flow): new default styles --- README.md | 11 +-- cypress/integration/flow/basic.spec.js | 4 +- cypress/integration/flow/interaction.spec.js | 2 +- example/src/CustomNode/ColorSelectorNode.js | 6 +- example/src/CustomNode/index.js | 13 +++- example/src/Horizontal/index.js | 18 ++++- example/src/Overview/index.js | 16 ++-- example/src/index.css | 12 ++- .../Background/index.tsx | 4 +- .../MiniMap/MiniMapNode.tsx | 9 ++- src/additional-components/MiniMap/index.tsx | 12 ++- src/container/ReactFlow/index.tsx | 4 +- src/style.css | 74 +++++++++++++------ 13 files changed, 126 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 8bd0e870..3b068061 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ const BasicFlow = () => ; - `defaultZoom`: default: `1` - `defaultPosition`: default: `[0, 0]` - `snapToGrid`: default: `false` -- `snapGrid`: [x, y] array - default: `[16, 16]` +- `snapGrid`: [x, y] array - default: `[15, 15]` - `onlyRenderVisibleNodes`: default: `true` - `translateExtent`: [default `[[-∞, -∞], [+∞, +∞]]`](https://github.com/d3/d3-zoom#zoom_translateExtent) @@ -118,7 +118,7 @@ const BasicFlow = () => ; #### Element Customization - `nodeTypes`: object with [node types](#node-types--custom-nodes) - `edgeTypes`: object with [edge types](#edge-types--custom-edges) -- `arrowHeadColor`: default: `#bbb` +- `arrowHeadColor`: default: `#b1b1b7` #### Connection Line Options - `connectionLineType`: connection line type = `default` (bezier), `straight`, `step`, `smoothstep` @@ -405,9 +405,9 @@ const FlowWithBackground = () => ( ### Prop Types - `variant`: string - has to be 'dots' or 'lines' - default: `dots` -- `gap`: number - the gap between the dots or lines - default: `16` +- `gap`: number - the gap between the dots or lines - default: `15` - `size`: number - the radius of the dots or the stroke width of the lines - default: `0.5` -- `color`: string - the color of the dots or lines - default: `#999` for dots, `#eee` for lines +- `color`: string - the color of the dots or lines - default: `#81818a` for dots, `#eee` for lines - `style`: css properties - `className`: additional class name @@ -437,6 +437,7 @@ const FlowWithMiniMap = () => ( ### Prop Types - `nodeColor`: string or function - If you pass a color as a string all nodes will get that color. If you pass a function you can return a color depending on the passed node. +- `nodeStrokeColor`: string or function - If you pass a color as a string all nodes will get that stroke color. If you pass a function you can return a color depending on the passed node. - `nodeBorderRadius`: number - `nodeClassName`: string or function for adding an additional class to the nodes inside the mini map - `maskColor`: string @@ -543,7 +544,7 @@ The React Flow wrapper has the className `react-flow`. If you want to change the You could achieve the same effect by passing a style prop to the `ReactFlow` component: ```javascript -const style = { background: 'red', width: '100%' height: '300px' }; +const style = { background: 'red', height: '300px' }; const FlowWithRedBg = ( { }); it('selects an edge by click', () => { - cy.get('.react-flow__edge:first').click().should('have.class', 'selected'); + cy.get('.react-flow__edge:first').click({ force: true }).should('have.class', 'selected'); }); it('deselects edge', () => { @@ -71,7 +71,7 @@ describe('Basic Flow Rendering', () => { }); it('selects an edge', () => { - cy.get('.react-flow__edge:first').click().should('have.class', 'selected'); + cy.get('.react-flow__edge:first').click({ force: true }).should('have.class', 'selected'); }); it('drags a node', () => { diff --git a/cypress/integration/flow/interaction.spec.js b/cypress/integration/flow/interaction.spec.js index 08236192..8846aade 100644 --- a/cypress/integration/flow/interaction.spec.js +++ b/cypress/integration/flow/interaction.spec.js @@ -93,7 +93,7 @@ describe('Interaction Flow Rendering', () => { }); it('selects an edge by click', () => { - cy.get('.react-flow__edge:first').click().should('have.class', 'selected'); + cy.get('.react-flow__edge:first').click({ force: true }).should('have.class', 'selected'); }); it('toggles connectable mode', () => { diff --git a/example/src/CustomNode/ColorSelectorNode.js b/example/src/CustomNode/ColorSelectorNode.js index 54ffdacf..1b6381f3 100644 --- a/example/src/CustomNode/ColorSelectorNode.js +++ b/example/src/CustomNode/ColorSelectorNode.js @@ -8,15 +8,15 @@ export default memo(({ data }) => { console.log('handle onConnect', params)} />
Custom Color Picker Node: {data.color}
- - + + ); }); diff --git a/example/src/CustomNode/index.js b/example/src/CustomNode/index.js index b633608d..6fa29443 100644 --- a/example/src/CustomNode/index.js +++ b/example/src/CustomNode/index.js @@ -8,7 +8,7 @@ const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInsta const onNodeDragStop = (event, node) => console.log('drag stop', node); const onElementClick = (event, element) => console.log('click', element); -const initBgColor = '#f0e742'; +const initBgColor = '#1A192B'; const connectionLineStyle = { stroke: '#fff' }; const snapGrid = [16, 16]; @@ -78,12 +78,17 @@ const CustomNodeFlow = () => { connectionLineStyle={connectionLineStyle} snapToGrid={true} snapGrid={snapGrid} + defaultZoom={1.5} > { - if (n.type === 'input') return 'blue'; + nodeStrokeColor={(n) => { + if (n.type === 'input') return '#0041d0'; if (n.type === 'selectorNode') return bgColor; - if (n.type === 'output') return 'green'; + if (n.type === 'output') return '#ff0072'; + }} + nodeColor={(n) => { + if (n.type === 'selectorNode') return bgColor; + return '#fff'; }} /> diff --git a/example/src/Horizontal/index.js b/example/src/Horizontal/index.js index e66e5c8a..3b9ce9fb 100644 --- a/example/src/Horizontal/index.js +++ b/example/src/Horizontal/index.js @@ -26,8 +26,22 @@ const initialElements = [ { id: '4', sourcePosition: 'right', targetPosition: 'left', data: { label: 'Node 4' }, position: { x: 500, y: 0 } }, { id: '5', sourcePosition: 'top', targetPosition: 'bottom', data: { label: 'Node 5' }, position: { x: 500, y: 100 } }, { id: '6', sourcePosition: 'bottom', targetPosition: 'top', data: { label: 'Node 6' }, position: { x: 500, y: 230 } }, - { id: '7', sourcePosition: 'right', targetPosition: 'left', data: { label: 'Node 7' }, position: { x: 750, y: 50 } }, - { id: '8', sourcePosition: 'right', targetPosition: 'left', data: { label: 'Node 8' }, position: { x: 750, y: 300 } }, + { + id: '7', + type: 'output', + sourcePosition: 'right', + targetPosition: 'left', + data: { label: 'Node 7' }, + position: { x: 750, y: 50 }, + }, + { + id: '8', + type: 'output', + sourcePosition: 'right', + targetPosition: 'left', + data: { label: 'Node 8' }, + position: { x: 750, y: 300 }, + }, { id: 'e1-2', source: '1', type: 'smoothstep', target: '2', animated: true }, { id: 'e1-3', source: '1', type: 'smoothstep', target: '3', animated: true }, diff --git a/example/src/Overview/index.js b/example/src/Overview/index.js index 20246191..d5703ead 100644 --- a/example/src/Overview/index.js +++ b/example/src/Overview/index.js @@ -54,7 +54,7 @@ const initialElements = [ ), }, position: { x: 400, y: 100 }, - style: { background: '#eee', color: '#222', border: '1px solid #bbb', width: 180 }, + style: { background: '#D6D5E6', color: '#333', border: '1px solid #222138', width: 180 }, }, { id: '4', @@ -139,14 +139,20 @@ const OverviewFlow = () => { snapGrid={snapGrid} > { + nodeStrokeColor={(n) => { if (n.style?.background) return n.style.background; - if (n.type === 'input') return '#9999ff'; - if (n.type === 'output') return '#79c9b7'; - if (n.type === 'default') return '#ff6060'; + if (n.type === 'input') return '#0041d0'; + if (n.type === 'output') return '#ff0072'; + if (n.type === 'default') return '#1a192b'; return '#eee'; }} + nodeColor={(n) => { + if (n.style?.background) return n.style.background; + + return '#fff'; + }} + borderRadius={2} /> diff --git a/example/src/index.css b/example/src/index.css index c9324205..8ad19a95 100644 --- a/example/src/index.css +++ b/example/src/index.css @@ -138,18 +138,22 @@ nav a.active:before { } .react-flow__node.dark-node { - background: #333; + background: #0041d0; color: #f8f8f8; } .react-flow__node-selectorNode { font-size: 12px; - background: #eee; - border: 1px solid #555; + background: #f0f2f3; + border: 1px solid 555; border-radius: 5px; text-align: center; } +.react-flow__node-selectorNode .react-flow__handle { + border-color: #f0f2f3; +} + @media screen and (min-width: 768px) { nav { position: relative; @@ -176,4 +180,4 @@ nav a.active:before { .overview-example__add { display: block; } -} \ No newline at end of file +} diff --git a/src/additional-components/Background/index.tsx b/src/additional-components/Background/index.tsx index 2007702a..4f1530a1 100644 --- a/src/additional-components/Background/index.tsx +++ b/src/additional-components/Background/index.tsx @@ -15,13 +15,13 @@ interface BackgroundProps extends HTMLAttributes { } const defaultColors = { - [BackgroundVariant.Dots]: '#999', + [BackgroundVariant.Dots]: '#81818a', [BackgroundVariant.Lines]: '#eee', }; const Background = ({ variant = BackgroundVariant.Dots, - gap = 24, + gap = 15, size = 0.5, color, style, diff --git a/src/additional-components/MiniMap/MiniMapNode.tsx b/src/additional-components/MiniMap/MiniMapNode.tsx index a3ab7a43..618c6135 100644 --- a/src/additional-components/MiniMap/MiniMapNode.tsx +++ b/src/additional-components/MiniMap/MiniMapNode.tsx @@ -6,13 +6,14 @@ interface MiniMapNodeProps { y: number; width: number; height: number; - color: string; - className: string; borderRadius: number; + className: string; + color: string; + strokeColor: string; style?: CSSProperties; } -const MiniMapNode = ({ x, y, width, height, style, color, className, borderRadius }: MiniMapNodeProps) => { +const MiniMapNode = ({ x, y, width, height, style, color, strokeColor, className, borderRadius }: MiniMapNodeProps) => { const { background, backgroundColor } = style || {}; const fill = (color || background || backgroundColor) as string; @@ -26,6 +27,8 @@ const MiniMapNode = ({ x, y, width, height, style, color, className, borderRadiu width={width} height={height} fill={fill} + stroke={strokeColor} + strokeWidth={2} /> ); }; diff --git a/src/additional-components/MiniMap/index.tsx b/src/additional-components/MiniMap/index.tsx index f01671c6..e1670738 100644 --- a/src/additional-components/MiniMap/index.tsx +++ b/src/additional-components/MiniMap/index.tsx @@ -12,6 +12,7 @@ type StringFunc = (node: Node) => string; interface MiniMapProps extends React.HTMLAttributes { nodeColor?: string | StringFunc; + nodeStrokeColor?: string | StringFunc; nodeClassName?: string | StringFunc; nodeBorderRadius?: number; maskColor?: string; @@ -21,12 +22,13 @@ const defaultWidth = 200; const defaultHeight = 150; const MiniMap = ({ - style = { backgroundColor: '#f8f8f8' }, + style = { backgroundColor: '#fff' }, className, - nodeColor = '#ddd', + nodeStrokeColor = '#555', + nodeColor = '#fff', nodeClassName = '', nodeBorderRadius = 5, - maskColor = 'rgba(10, 10, 10, .25)', + maskColor = '#F0F2F3', }: MiniMapProps) => { const containerWidth = useStoreState((s) => s.width); const containerHeight = useStoreState((s) => s.height); @@ -37,6 +39,9 @@ const MiniMap = ({ 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 + : () => nodeStrokeColor) as StringFunc; const nodeClassNameFunc = (nodeClassName instanceof Function ? nodeClassName : () => nodeClassName) as StringFunc; const hasNodes = nodes && nodes.length; const bb = getRectOfNodes(nodes); @@ -79,6 +84,7 @@ const MiniMap = ({ className={nodeClassNameFunc(node)} color={nodeColorFunc(node)} borderRadius={nodeBorderRadius} + strokeColor={nodeStrokeColorFunc(node)} /> ))}