Merge branch 'v11' of github.com:wbkd/react-flow into v11
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
import React, { FC } from 'react';
|
||||||
|
|
||||||
|
import ReactFlow, {
|
||||||
|
Node,
|
||||||
|
ReactFlowProvider,
|
||||||
|
useNodesState,
|
||||||
|
} from '@react-flow/core';
|
||||||
|
|
||||||
|
import Background, {
|
||||||
|
BackgroundProps,
|
||||||
|
BackgroundVariant,
|
||||||
|
} from '@react-flow/background';
|
||||||
|
|
||||||
|
import styles from './style.module.css';
|
||||||
|
|
||||||
|
const initialNodes: Node[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
data: { label: 'Node 1' },
|
||||||
|
position: { x: 50, y: 50 },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Flow: FC<{ id: string; bgProps: BackgroundProps }> = ({
|
||||||
|
id,
|
||||||
|
bgProps,
|
||||||
|
}) => {
|
||||||
|
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactFlowProvider>
|
||||||
|
<ReactFlow nodes={nodes} onNodesChange={onNodesChange} id={id}>
|
||||||
|
<Background {...bgProps} />
|
||||||
|
</ReactFlow>
|
||||||
|
</ReactFlowProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Backgrounds: FC = () => (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
<Flow id="flow-a" bgProps={{ variant: BackgroundVariant.Dots }} />
|
||||||
|
<Flow
|
||||||
|
id="flow-b"
|
||||||
|
bgProps={{ variant: BackgroundVariant.Lines, gap: [50, 50] }}
|
||||||
|
/>
|
||||||
|
<Flow
|
||||||
|
id="flow-c"
|
||||||
|
bgProps={{ variant: BackgroundVariant.Cross, gap: [100, 50] }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Backgrounds;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper :global .react-flow {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper :global .react-flow {
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import '../styles/globals.css';
|
|||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
'/',
|
'/',
|
||||||
|
'/Backgrounds',
|
||||||
'/ControlledUncontrolled',
|
'/ControlledUncontrolled',
|
||||||
'/CustomConnectionLine',
|
'/CustomConnectionLine',
|
||||||
'/CustomNode',
|
'/CustomNode',
|
||||||
@@ -47,7 +48,7 @@ function MyApp({ Component, pageProps }) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<header>
|
<header>
|
||||||
<a className='logo' href='https://github.com/wbkd/react-flow'>
|
<a className="logo" href="https://github.com/wbkd/react-flow">
|
||||||
React Flow Dev
|
React Flow Dev
|
||||||
</a>
|
</a>
|
||||||
<select defaultValue={router.pathname} onChange={onRouteChange}>
|
<select defaultValue={router.pathname} onChange={onRouteChange}>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const BasicFlow = () => {
|
|||||||
onNodeClick={onNodeClick}
|
onNodeClick={onNodeClick}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
onNodeDrag={onNodeDrag}
|
onNodeDrag={onNodeDrag}
|
||||||
className='react-flow-basic-example'
|
className="react-flow-basic-example"
|
||||||
minZoom={0.2}
|
minZoom={0.2}
|
||||||
maxZoom={4}
|
maxZoom={4}
|
||||||
fitView
|
fitView
|
||||||
|
|||||||
@@ -3,19 +3,29 @@ import cc from 'classcat';
|
|||||||
import { useStore, ReactFlowState } from '@react-flow/core';
|
import { useStore, ReactFlowState } from '@react-flow/core';
|
||||||
|
|
||||||
import { BackgroundProps, BackgroundVariant } from './types';
|
import { BackgroundProps, BackgroundVariant } from './types';
|
||||||
import { createGridLinesPath, createGridDotsPath } from './utils';
|
import { DotPattern, LinePattern } from './utils';
|
||||||
|
|
||||||
const defaultColors = {
|
const defaultColors = {
|
||||||
[BackgroundVariant.Dots]: '#81818a',
|
[BackgroundVariant.Dots]: '#91919a',
|
||||||
[BackgroundVariant.Lines]: '#eee',
|
[BackgroundVariant.Lines]: '#eee',
|
||||||
|
[BackgroundVariant.Cross]: '#e2e2e2',
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultSize = {
|
||||||
|
[BackgroundVariant.Dots]: 1,
|
||||||
|
[BackgroundVariant.Lines]: 1,
|
||||||
|
[BackgroundVariant.Cross]: 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformSelector = (s: ReactFlowState) => s.transform;
|
const transformSelector = (s: ReactFlowState) => s.transform;
|
||||||
|
|
||||||
const Background: FC<BackgroundProps> = ({
|
const Background: FC<BackgroundProps> = ({
|
||||||
variant = BackgroundVariant.Dots,
|
variant = BackgroundVariant.Dots,
|
||||||
gap = 15,
|
gap = 25,
|
||||||
size = 0.4,
|
// only used for dots and cross
|
||||||
|
size,
|
||||||
|
// only used for lines and cross
|
||||||
|
lineWidth = 1,
|
||||||
color,
|
color,
|
||||||
style,
|
style,
|
||||||
className,
|
className,
|
||||||
@@ -31,15 +41,24 @@ const Background: FC<BackgroundProps> = ({
|
|||||||
setPatternId(`pattern-${index}`);
|
setPatternId(`pattern-${index}`);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const scaledGap = gap * tScale || 1;
|
const patternColor = color ? color : defaultColors[variant];
|
||||||
const xOffset = tX % scaledGap;
|
const patternSize = size ? size : defaultSize[variant];
|
||||||
const yOffset = tY % scaledGap;
|
const isDots = variant === BackgroundVariant.Dots;
|
||||||
|
const isCross = variant === BackgroundVariant.Cross;
|
||||||
|
const gapXY: [number, number] = Array.isArray(gap) ? gap : [gap, gap];
|
||||||
|
const scaledGap: [number, number] = [
|
||||||
|
gapXY[0] * tScale || 1,
|
||||||
|
gapXY[1] * tScale || 1,
|
||||||
|
];
|
||||||
|
const scaledSize = patternSize * tScale;
|
||||||
|
|
||||||
const isLines = variant === BackgroundVariant.Lines;
|
const patternDimensions: [number, number] = isCross
|
||||||
const bgColor = color ? color : defaultColors[variant];
|
? [scaledSize, scaledSize]
|
||||||
const path = isLines
|
: scaledGap;
|
||||||
? createGridLinesPath(scaledGap, size, bgColor)
|
|
||||||
: createGridDotsPath(size * tScale, bgColor);
|
const patternOffset = isDots
|
||||||
|
? [scaledSize / 2, scaledSize / 2]
|
||||||
|
: [patternDimensions[0] / 2, patternDimensions[1] / 2];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
@@ -59,19 +78,28 @@ const Background: FC<BackgroundProps> = ({
|
|||||||
<>
|
<>
|
||||||
<pattern
|
<pattern
|
||||||
id={patternId}
|
id={patternId}
|
||||||
x={xOffset}
|
x={tX % scaledGap[0]}
|
||||||
y={yOffset}
|
y={tY % scaledGap[1]}
|
||||||
width={scaledGap}
|
width={scaledGap[0]}
|
||||||
height={scaledGap}
|
height={scaledGap[1]}
|
||||||
patternUnits='userSpaceOnUse'
|
patternUnits="userSpaceOnUse"
|
||||||
|
patternTransform={`translate(-${patternOffset[0]},-${patternOffset[1]})`}
|
||||||
>
|
>
|
||||||
{path}
|
{isDots ? (
|
||||||
|
<DotPattern color={patternColor} radius={scaledSize / 2} />
|
||||||
|
) : (
|
||||||
|
<LinePattern
|
||||||
|
dimensions={patternDimensions}
|
||||||
|
color={patternColor}
|
||||||
|
lineWidth={lineWidth}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</pattern>
|
</pattern>
|
||||||
<rect
|
<rect
|
||||||
x='0'
|
x="0"
|
||||||
y='0'
|
y="0"
|
||||||
width='100%'
|
width="100%"
|
||||||
height='100%'
|
height="100%"
|
||||||
fill={`url(#${patternId})`}
|
fill={`url(#${patternId})`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import { HTMLAttributes } from 'react';
|
import { CSSProperties } from 'react';
|
||||||
|
|
||||||
export enum BackgroundVariant {
|
export enum BackgroundVariant {
|
||||||
Lines = 'lines',
|
Lines = 'lines',
|
||||||
Dots = 'dots',
|
Dots = 'dots',
|
||||||
|
Cross = 'cross',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BackgroundProps extends HTMLAttributes<SVGElement> {
|
export interface BackgroundProps {
|
||||||
variant?: BackgroundVariant;
|
|
||||||
gap?: number;
|
|
||||||
color?: string;
|
color?: string;
|
||||||
|
className?: string;
|
||||||
|
gap?: number | [number, number];
|
||||||
size?: number;
|
size?: number;
|
||||||
|
lineWidth?: number;
|
||||||
|
variant?: BackgroundVariant;
|
||||||
|
style?: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,32 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export const createGridLinesPath = (size: number, strokeWidth: number, stroke: string): React.ReactElement => {
|
type LinePatternProps = {
|
||||||
return <path stroke={stroke} strokeWidth={strokeWidth} d={`M${size / 2} 0 V${size} M0 ${size / 2} H${size}`} />;
|
dimensions: [number, number];
|
||||||
|
lineWidth?: number;
|
||||||
|
color: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createGridDotsPath = (size: number, fill: string): React.ReactElement => {
|
export function LinePattern({
|
||||||
return <circle cx={size} cy={size} r={size} fill={fill} />;
|
color,
|
||||||
|
dimensions,
|
||||||
|
lineWidth,
|
||||||
|
}: LinePatternProps) {
|
||||||
|
return (
|
||||||
|
<path
|
||||||
|
stroke={color}
|
||||||
|
strokeWidth={lineWidth}
|
||||||
|
d={`M${dimensions[0] / 2} 0 V${dimensions[1]} M0 ${dimensions[1] / 2} H${
|
||||||
|
dimensions[0]
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type DotPatternProps = {
|
||||||
|
radius: number;
|
||||||
|
color: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DotPattern = ({ color, radius }: DotPatternProps) => {
|
||||||
|
return <circle cx={radius} cy={radius} r={radius} fill={color} />;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user