docs(website): texts, docs, examples, favicon, cleanup

This commit is contained in:
moklick
2020-10-05 17:03:00 +02:00
parent 277e032770
commit aafae0ea70
41 changed files with 390 additions and 653 deletions
+2 -2
View File
@@ -31,12 +31,12 @@ module.exports = {
{
resolve: `gatsby-plugin-manifest`,
options: {
icon: `src/assets/icons/favicon.svg`,
icon: `src/assets/images/react-flow-logo.svg`,
name: `React Flow`,
short_name: `react-flow`,
start_url: `/`,
background_color: `#f7f0eb`,
theme_color: `#a2466c`,
theme_color: `#1A192B`,
display: `standalone`,
lang: 'en',
},
+3 -13
View File
@@ -1,17 +1,7 @@
[
{
"title": "Showcase 1",
"url": "https://github.com",
"image": "../images/showcases/showcase.jpg"
},
{
"title": "Showcase 2",
"url": "https://github.com",
"image": "../images/showcases/showcase.jpg"
},
{
"title": "Showcase 3",
"url": "https://github.com",
"image": "../images/showcases/showcase.jpg"
"title": "Circles - Visual degree planner",
"url": "https://circles360.github.io/",
"image": "../images/showcases/circles-showcase.png"
}
]
-4
View File
@@ -1,4 +0,0 @@
<svg width="342" height="342" viewBox="0 0 342 342" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M123.5 290L19 48L228 48L123.5 290Z" fill="#C5CBD2"/>
<path d="M218.5 290L114 48L323 48L218.5 290Z" fill="#1A192B"/>
</svg>

Before

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

+17 -12
View File
@@ -18,21 +18,26 @@ export default ({ children, className = 'javascript', language }) => {
style={{
...style,
overflowX: 'auto',
padding: '20px',
borderRadius: '6px',
margin: '40px 0 40px 0',
padding: 16,
borderRadius: 4,
margin: '20px 0 20px 0',
fontSize: 14,
}}
>
{tokens
.filter((line) => line.some((l) => l.content))
.map((line, i) => (
<div key={i} {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token, key })} />
))}
</div>
))}
{tokens.map(
(line, i, lines) =>
!(
line.length === 1 &&
line[0].empty &&
(i === 0 || i === lines.length - 1)
) && (
<div key={i} {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token, key })} />
))}
</div>
)
)}
</pre>
)}
</Highlight>
+2 -2
View File
@@ -3,11 +3,11 @@ import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { colors } from 'themes';
import CodeBlock from 'components/Mdx/CodeBlock';
import CodeBlock from './Mdx';
import { H4, AttributionText } from 'components/Typo';
const Wrapper = styled(Box)`
max-width: 800px;
max-width: 750px;
margin: 0 auto;
h4 {
@@ -1,30 +0,0 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex } from 'reflexbox';
import { Link } from 'gatsby';
import Button from 'components/Button';
import { H3 } from 'components/Typo';
import { getThemeSpacePx } from 'utils/css-utils';
const Wrapper = styled(Flex)`
text-align: center;
${H3} {
margin-bottom: ${getThemeSpacePx(3)};
}
`;
export default ({
caption = 'Are you interested in a collaboration?',
...props
}) => {
return (
<Wrapper alignItems="center" px={2} flexDirection="column" {...props}>
<H3 as="div">{caption}</H3>
<Button as={Link} to="/contact" icon="mail">
Contact us
</Button>
</Wrapper>
);
};
+2 -2
View File
@@ -209,10 +209,10 @@ const Header = () => {
<NavItem to="/" activeClassName="active" className="mobile">
Home
</NavItem>
<NavItem to="/docs" activeClassName="active">
<NavItem to="/docs/" activeClassName="active">
Docs
</NavItem>
<NavItem to="/examples" activeClassName="active">
<NavItem to="/examples/" activeClassName="active">
Examples
</NavItem>
@@ -1,33 +0,0 @@
import React from 'react';
import Highlight, { defaultProps } from 'prism-react-renderer';
import dracula from 'prism-react-renderer/themes/github';
export default ({ children, className = 'javascript', language }) => {
const lang = language ? language : className.replace(/language-/, '');
return (
<Highlight
{...defaultProps}
theme={dracula}
code={children}
language={lang}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre
className={className}
style={{ ...style, overflowX: 'auto', padding: '20px' }}
>
{tokens
.filter((line) => line.some((l) => l.content))
.map((line, i) => (
<div key={i} {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token, key })} />
))}
</div>
))}
</pre>
)}
</Highlight>
);
};
-58
View File
@@ -1,58 +0,0 @@
import React from 'react';
import styled from '@emotion/styled';
import { MDXProvider } from '@mdx-js/react';
import { MDXRenderer } from 'gatsby-plugin-mdx';
import { H1, H2, H3, H4, Text } from 'components/Typo';
import CodeBlock from 'components/Mdx/CodeBlock';
import CenterContent from 'components/CenterContent';
const doNotWrap = ['BlogpostAd'];
const MdxWrapper = ({ children }) => {
return children.map((child, i) =>
doNotWrap.includes(child.props?.mdxType) ? (
child
) : (
<CenterContent key={i} mb={2} maxWidth="680px">
{child}
</CenterContent>
)
);
};
const PostWrapper = styled.div`
img {
width: 100%;
}
.gatsby-resp-image-wrapper {
border: 1px solid ${(p) => p.theme.colors.silver};
border-radius: 2px;
overflow: hidden;
}
`;
const CustomComponents = {
h1: H1,
h2: H2,
h3: H3,
h4: H4,
p: Text,
pre: (props) => <div {...props} />,
code: CodeBlock,
wrapper: MdxWrapper,
};
const Mdx = ({ content = null }) => {
return (
<MDXProvider components={CustomComponents}>
<PostWrapper>
<MDXRenderer>{content}</MDXRenderer>
</PostWrapper>
</MDXProvider>
);
};
export default Mdx;
@@ -1,100 +0,0 @@
import React from 'react';
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { Link } from 'gatsby';
import Img from 'gatsby-image';
import { H2, H4, TextLight } from 'components/Typo';
import { getThemeColor, getThemeSpacePx, device } from 'utils/css-utils';
const Teaser = styled(Box)`
position: relative;
.gatsby-image-wrapper {
transition: transform 200ms ease, box-shadow 200ms ease;
}
&:hover {
.gatsby-image-wrapper {
transform-origin: center center;
transform: scale(1.025);
box-shadow: 0 2px 14px 2px rgba(0, 0, 0, 0.25);
}
}
`;
const StyledImg = styled(Img)`
border-radius: 4px;
margin-bottom: ${getThemeSpacePx(3)};
`;
const ReadMore = styled(Box)`
color: ${(p) => p.theme.colors.text};
&:hover {
opacity: 0.6;
}
`;
const TextWrapper = styled.div`
padding: 0;
position: relative;
top: 0;
left: 0;
width: 100%;
z-index: 10;
&& {
a,
a:visited,
a:hover,
a:focus,
a:active {
color: ${getThemeColor('silverLighten60')};
}
}
${TextLight} {
color: ${getThemeColor('silverDarken30')};
}
${H2} {
color: ${getThemeColor('silverLighten60')};
margin-top: 5px;
}
${H4} {
font-weight: 400;
color: ${getThemeColor('silverDarken30')};
}
@media ${device.tablet} {
width: 80%;
}
`;
const ProjectTeaser = ({
kicker = '',
title = '',
text = '',
fluid = null,
slug = '/',
}) => {
return (
<Link to={slug}>
<Teaser mb={[4, 5, 6]}>
<StyledImg fluid={fluid} />
<TextWrapper>
<TextLight>{kicker}</TextLight>
<H2 as="div">{title}</H2>
<H4 as="div">{text}</H4>
<ReadMore mt={3}>Read more</ReadMore>
</TextWrapper>
</Teaser>
</Link>
);
};
export default ProjectTeaser;
@@ -1,133 +0,0 @@
import React from 'react';
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { Link } from 'gatsby';
import { H3, H2, H4, TextLight, Text } from 'components/Typo';
import {
px,
getThemeColor,
getThemeSpacePx,
rgba,
device,
} from 'utils/css-utils';
const Wrapper = styled(Box)`
border-radius: 6px;
background: ${(props) =>
props.isDark
? props.theme.colors.dark.cardBackground
: props.theme.colors.light.background};
background-image: ${(props) =>
props.imgSrc ? `url(${props.imgSrc})` : 'none'};
background-repeat: no-repeat;
background-position: ${(props) => props.imgPosition};
color: ${(p) => p.theme.colors[p.isDark ? 'dark' : 'light'].text};
background-size: cover;
flex-grow: 1;
height: 270px;
display: flex;
align-items: center;
&.scale {
transition: transform 200ms ease, box-shadow 200ms ease;
transform-style: preserve-3d;
backface-visibility: hidden;
&:hover {
transform-origin: center center;
transform: scale(1.02);
box-shadow: 0 2px 12px 2px rgba(0, 0, 0, 0.45);
}
}
&& {
a,
a:visited,
a:hover,
a:focus,
a:active {
color: ${(p) => p.theme.colors[p.isDark ? 'dark' : 'light'].text};
}
}
`;
const getTextShadow = (props) => {
const color = props.theme.colors[props.isDark ? 'light' : 'dark'].text;
const rgbaColor = rgba(color, props.isDark ? 0.2 : 0.8);
return `-1px 0 14px ${rgbaColor}, 0 1px 14px ${rgbaColor}, 1px 0 14px ${rgbaColor}, 0 -1px 14px ${rgbaColor};`;
};
const TextWrapper = styled.div`
padding: ${getThemeSpacePx(3)};
position: relative;
top: 0;
left: 0;
width: 100%;
z-index: 10;
text-shadow: ${getTextShadow};
${H2} {
margin-top: 5px;
}
${H3} {
margin-top: 5px;
}
${TextLight} {
color: ${(p) =>
p.isDark
? getThemeColor('silverDarken30')
: getThemeColor('silverDarken60')};
}
${Text} {
color: ${(p) =>
p.isDark
? getThemeColor('silverDarken30')
: getThemeColor('silverDarken60')};
}
${H4} {
color: ${getThemeColor('silverDarken30')};
}
@media ${device.tablet} {
width: 50%;
}
`;
const ProjectTeaser = ({
kicker = '',
title = '',
text = '',
imgSrc = null,
isDark = false,
imgPosition = null,
imgSize = '100%',
slug = '/',
hoverEffect = null,
}) => {
const imagePosition = imgPosition ? imgPosition : 'center right';
return (
<Link to={slug}>
<Wrapper
imgSrc={imgSrc}
isDark={isDark}
imgPosition={imagePosition}
imgSize={imgSize}
className={hoverEffect}
>
<TextWrapper isDark={isDark}>
<TextLight>{kicker}</TextLight>
<H3 as="div">{title}</H3>
<Text as="div">{text}</Text>
</TextWrapper>
</Wrapper>
</Link>
);
};
export default ProjectTeaser;
+32 -3
View File
@@ -5,13 +5,25 @@ import Img from 'gatsby-image';
import CenterContent from 'components/CenterContent';
import useShowcaseImages from 'hooks/useShowcaseImages';
import { H4 } from 'components/Typo';
import { H4, Text } from 'components/Typo';
import { getThemeColor } from 'utils/css-utils';
import reactFlowIconSrc from 'assets/images/react-flow-logo.svg';
const gridPadding = 2;
const RoundImage = styled(Img)`
border-radius: 4px;
height: 250px;
transition: transform 200ms ease;
`;
const EmptyCase = styled(Box)`
border-radius: 4px;
height: 250px;
background: ${(p) => p.theme.colors.silverLighten60};
display: flex;
justify-content: center;
align-items: center;
`;
const Title = styled(H4)`
@@ -26,25 +38,42 @@ const Link = styled.a`
&:hover {
color: ${getThemeColor('silverLighten15')};
${RoundImage} {
transform: scale(1.025);
}
}
}
`;
const Showcases = () => {
const showcases = useShowcaseImages();
const emptyShowCases = [...Array(3 - showcases.length).keys()];
return (
<CenterContent>
<Flex marginX={-gridPadding}>
{showcases.map((showcase) => (
<Box key={showcase.title} width={1 / 3} px={gridPadding}>
<RoundImage fluid={showcase.image.childImageSharp.fluid} />
<Title>{showcase.title}</Title>
<Link href={showcase.url} target="_blank" rel="noopener noreferrer">
<RoundImage fluid={showcase.image.childImageSharp.fluid} />
<Title>{showcase.title}</Title>
{showcase.url}
</Link>
</Box>
))}
{emptyShowCases.map((index) => (
<Box key={index} width={1 / 3} px={gridPadding}>
<EmptyCase>
<img src={reactFlowIconSrc} alt="react flow logo" />
</EmptyCase>
<Title>Your Project here</Title>
<Text color="silverDarken15">
Let us know if you made something with React Flow.
</Text>
</Box>
))}
</Flex>
</CenterContent>
);
+1 -1
View File
@@ -80,7 +80,7 @@ const flowProps = {
export default () => (
<TeaserFlow
title="Feature-rich"
description="You only need a few lines to get started. You get seamless zooming & panning, different edge and node types, single and multi-selection, controls and more."
description="React Flow comes with seamless zooming & panning, different edge and node types, single and multi-selection, controls, several event handlers and more."
flowProps={flowProps}
withControls
fitView
+3 -3
View File
@@ -62,7 +62,7 @@ const nodeTypes = {
result: ResultNode,
};
const onLoad = (rf) => rf.fitView({ padding: 0.2 });
const onLoad = (rf) => setTimeout(() => rf.fitView({ padding: 0.1 }), 1);
const findNodeById = (id) => (n) => n.id === id;
@@ -96,7 +96,7 @@ export default () => {
resultNode.data = {
...resultNode.data,
value: result,
value: !forname && !lastname ? '*please enter a name*' : result,
};
return nextElements;
@@ -161,7 +161,7 @@ export default () => {
return (
<TeaserFlow
title="Customizable"
description="You can create your own node and edge types. Implement complex UIs inside your nodes or add functionality to your edges. React Flow comes with a lot of event handlers."
description="You can create your own node and edge types or just pass a custom style. You can implement custom UIs inside your nodes and add functionality to your edges."
textPosition="right"
fitView
isDark
@@ -8,15 +8,30 @@ export default memo(({ data }) => {
<Handle
type="target"
position="left"
style={{ background: '#fff' }}
style={{ background: '#555' }}
onConnect={(params) => console.log('handle onConnect', params)}
/>
<div>
Custom Color Picker Node: <strong>{data.color}</strong>
</div>
<input className="nodrag" type="color" onChange={data.onChange} defaultValue={data.color} />
<Handle type="source" position="right" id="a" style={{ top: 10, background: '#fff' }} />
<Handle type="source" position="right" id="b" style={{ bottom: 10, top: 'auto', background: '#fff' }} />
<input
className="nodrag"
type="color"
onChange={data.onChange}
defaultValue={data.color}
/>
<Handle
type="source"
position="right"
id="a"
style={{ top: 10, background: '#555' }}
/>
<Handle
type="source"
position="right"
id="b"
style={{ bottom: 10, top: 'auto', background: '#555' }}
/>
</>
);
});
+31 -23
View File
@@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react';
import ReactFlow, {
isEdge,
removeElements,
@@ -11,15 +12,17 @@ import ColorSelectorNode from './ColorSelectorNode';
import './index.css';
const onLoad = (reactFlowInstance) =>
const onLoad = (reactFlowInstance) => {
console.log('flow loaded:', reactFlowInstance);
setTimeout(() => reactFlowInstance.fitView(), 1);
};
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];
const snapGrid = [20, 20];
const nodeTypes = {
selectorNode: ColorSelectorNode,
};
@@ -32,7 +35,7 @@ const CustomNodeFlow = () => {
const onChange = (event) => {
setElements((els) =>
els.map((e) => {
if (isEdge(e) || e.id !== 'custom-2') {
if (isEdge(e) || e.id !== '2') {
return e;
}
@@ -53,52 +56,52 @@ const CustomNodeFlow = () => {
setElements([
{
id: 'custom-1',
id: '1',
type: 'input',
data: { label: 'An input node' },
position: { x: 0, y: 50 },
sourcePosition: 'right',
},
{
id: 'custom-2',
id: '2',
type: 'selectorNode',
data: { onChange: onChange, color: initBgColor },
style: { border: '1px solid #777', padding: 10 },
position: { x: 250, y: 50 },
position: { x: 300, y: 50 },
},
{
id: 'custom-3',
id: '3',
type: 'output',
data: { label: 'Output A' },
position: { x: 550, y: 25 },
position: { x: 650, y: 25 },
targetPosition: 'left',
},
{
id: 'custom-4',
id: '4',
type: 'output',
data: { label: 'Output B' },
position: { x: 550, y: 100 },
position: { x: 650, y: 100 },
targetPosition: 'left',
},
{
id: 'custom-e1-2',
source: 'custom-1',
target: 'custom-2',
id: 'e1-2',
source: '1',
target: '2',
animated: true,
style: { stroke: '#fff' },
},
{
id: 'custom-e2a-3',
source: 'custom-2__a',
target: 'custom-3',
id: 'e2a-3',
source: '2__a',
target: '3',
animated: true,
style: { stroke: '#fff' },
},
{
id: 'custom-e2b-4',
source: 'custom-2__b',
target: 'custom-4',
id: 'e2b-4',
source: '2__b',
target: '4',
animated: true,
style: { stroke: '#fff' },
},
@@ -125,12 +128,17 @@ const CustomNodeFlow = () => {
connectionLineStyle={connectionLineStyle}
snapToGrid={true}
snapGrid={snapGrid}
defaultZoom={1.5}
>
<MiniMap
nodeColor={(n) => {
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';
}}
/>
<Controls />
@@ -39,6 +39,8 @@ const onElementClick = (event, element) => console.log('click', element);
const onPaneClick = (event) => console.log('onPaneClick', event);
const onPaneScroll = (event) => console.log('onPaneScroll', event);
const onPaneContextMenu = (event) => console.log('onPaneContextMenu', event);
const onLoad = (reactFlowInstance) =>
reactFlowInstance.fitView({ padding: 0.2 });
const InteractionFlow = () => {
const [elements, setElements] = useState(initialElements);
@@ -70,6 +72,7 @@ const InteractionFlow = () => {
onPaneClick={captureZoomClick ? onPaneClick : undefined}
onPaneScroll={captureZoomScroll ? onPaneScroll : undefined}
onPaneContextMenu={captureZoomClick ? onPaneContextMenu : undefined}
onLoad={onLoad}
>
<MiniMap />
<Controls />
+33 -50
View File
@@ -33,7 +33,7 @@ const onMoveEnd = (transform) => console.log('zoom/move end', transform);
const initialElements = [
{
id: 'overview-1',
id: '1',
type: 'input',
data: {
label: (
@@ -45,7 +45,7 @@ const initialElements = [
position: { x: 250, y: 0 },
},
{
id: 'overview-2',
id: '2',
data: {
label: (
<>
@@ -56,7 +56,7 @@ const initialElements = [
position: { x: 100, y: 100 },
},
{
id: 'overview-3',
id: '3',
data: {
label: (
<>
@@ -73,36 +73,21 @@ const initialElements = [
},
},
{
id: 'overview-4',
id: '4',
position: { x: 250, y: 200 },
data: {
label: (
<>
You can find the docs on{' '}
<a
href="https://github.com/wbkd/react-flow"
target="_blank"
rel="noopener noreferrer"
>
Github
</a>
</>
),
label: 'Another default node',
},
},
{
id: 'overview-5',
id: '5',
data: {
label: (
<>
Or check out the other <strong>examples</strong>
</>
),
label: 'Node id: 5',
},
position: { x: 250, y: 325 },
},
{
id: 'overview-6',
id: '6',
type: 'output',
data: {
label: (
@@ -114,43 +99,38 @@ const initialElements = [
position: { x: 100, y: 480 },
},
{
id: 'overview-7',
id: '7',
type: 'output',
data: { label: 'Another output node' },
position: { x: 400, y: 450 },
},
{ id: 'e1-2', source: '1', target: '2', label: 'this is an edge label' },
{ id: 'e1-3', source: '1', target: '3' },
{
id: 'overview-e1-2',
source: 'overview-1',
target: 'overview-2',
label: 'this is an edge label',
},
{ id: 'overview-e1-3', source: 'overview-1', target: 'overview-3' },
{
id: 'overview-e3-4',
source: 'overview-3',
target: 'overview-4',
id: 'e3-4',
source: '3',
target: '4',
animated: true,
label: 'animated edge',
},
{
id: 'overview-e4-5',
source: 'overview-4',
target: 'overview-5',
id: 'e4-5',
source: '4',
target: '5',
arrowHeadType: 'arrowclosed',
label: 'edge with arrow head',
},
{
id: 'overview-e5-6',
source: 'overview-5',
target: 'overview-6',
id: 'e5-6',
source: '5',
target: '6',
type: 'smoothstep',
label: 'smooth step edge',
},
{
id: 'overview-e5-7',
source: 'overview-5',
target: 'overview-7',
id: 'e5-7',
source: '5',
target: '7',
type: 'step',
style: { stroke: '#f6ab6c' },
label: 'a step edge',
@@ -168,8 +148,6 @@ const OverviewFlow = () => {
setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params) => setElements((els) => addEdge(params, els));
console.log('render overview');
return (
<ReactFlow
elements={elements}
@@ -188,17 +166,22 @@ const OverviewFlow = () => {
connectionLineStyle={connectionLineStyle}
snapToGrid={true}
snapGrid={snapGrid}
key="overview"
>
<MiniMap
nodeColor={(n) => {
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}
/>
<Controls />
<Background color="#aaa" gap={16} />
@@ -2,8 +2,14 @@
title: Prop Types
---
This is the list of prop types you can pass to the main `ReactFlow` component.
```jsx
import ReactFlow from 'react-flow-renderer';
```
### Basic Props
- `elements`: array of [nodes](#nodes) and [edges](#edges) *(required)*
- `elements`: array of [nodes](/docs/api/nodes/) and [edges](/docs/api/edges/) *(required)*
- `style`: css properties
- `className`: additional class name
@@ -13,7 +19,7 @@ title: Prop Types
- `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)
@@ -55,7 +61,7 @@ title: Prop Types
### 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`
@@ -26,6 +26,6 @@ const FlowWithBackground = () => (
- `variant`: string - has to be 'dots' or 'lines' - default: `dots`
- `gap`: number - the gap between the dots or lines - default: `16`
- `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
@@ -18,4 +18,4 @@ const FlowWithOwnProvider = () => (
);
```
It is used in the [provider example](example/src/Provider/index.js).
It is used in the [provider example](https://github.com/wbkd/react-flow/blob/main/example/src/Provider/index.js).
@@ -0,0 +1,28 @@
---
title: Edge Types & Custom Edges
---
React Flow comes with four edge types (`default`, `straight`, `step`, `smoothstep`). As the names indicate, the edges differ in the representation. The default type is a bezier edge.
The basic edge types are `default` (bezier), `straight`, `step` and `smoothstep`. The default `edgeTypes` object looks like this:
```javascript
{
default: BezierEdge,
straight: StraightEdge,
step: StepEdge,
smoothstep: SmoothStepEdge
}
```
The keys represent the type names and the values are the edge components.
If you want to introduce a new edge type you can pass an `edgeTypes` object to the `ReactFlow` component:
```javascript
edgeTypes={{
special: MyCustomEdge
}}
```
Now you could use the new type `special` for an edge.
The `straight`, `default` and `step` types would still be available unless you overwrote one of them.
There is an implementation of a custom edge in the [edges example](/example/src/Edges/index.js).
@@ -0,0 +1,61 @@
---
title: Edge Utils
---
There are several utils that help you to create a custom edge. They are used in the [custom edge](/examples/custom-edge) example.
### `getBezierPath`
Returns the path of a bezier edge.
```
getBezierPath({
sourceX,
sourceY,
sourcePosition = Position.Bottom, // optional
targetX,
targetY,
targetPosition = Position.Top, // optional
centerX, // optional
centerY, // optional
}: GetBezierPathParams): string
```
### `getSmoothStepPath`
Returns the path of a smooth step edge. You can set `borderRadius` = `0` to get a step edge path.
```
getSmoothStepPath({
sourceX,
sourceY,
sourcePosition = Position.Bottom, // optional
targetX,
targetY,
targetPosition = Position.Top, // optional
borderRadius = 5, // optional
centerX, // optional
centerY, // optional
}: GetSmoothStepPathParams): string
```
### `getEdgeCenter`
Returns the center position and offset `[centerX, centerY, offsetX, offsetY]` of the edge.
```
getEdgeCenter({
sourceX,
sourceY,
targetX,
targetY
}: GetCenterParams): [number, number, number, number]
```
### `getMarkerEnd`
Returns the marker end url for displaying the arrow head.
```
getMarkerEnd(arrowHeadType?: ArrowHeadType, markerEndId?: string): string
```
+2 -73
View File
@@ -1,10 +1,8 @@
---
id: edges
title: Edges
title: Edge Options
---
React Flow comes with four [edge types](#edge-types--custom-edges) (`default`, `straight`, `step`, `smoothstep`). As the names indicate, the edges differ in the representation. The default type is a bezier edge. You create edges by adding them to your `elements` array of the `ReactFlow` component.
You create edges by adding them to your `elements` array of the `ReactFlow` component.
Edge example:
@@ -42,72 +40,3 @@ If you wanted to display this edge, you would need a node with id = 1 (source no
- `data`: {} you can use this to pass data to your custom edges.
You can find an example with different edges in the [edges example](https://reactflow.dev/edges).
## Edge Types & Custom Edges
The basic edge types are `default` (bezier), `straight`, `step` and `smoothstep`. The default `edgeTypes` object looks like this:
```javascript
{
default: BezierEdge,
straight: StraightEdge,
step: StepEdge,
smoothstep: SmoothStepEdge
}
```
The keys represent the type names and the values are the edge components.
If you want to introduce a new edge type you can pass an `edgeTypes` object to the `ReactFlow` component:
```javascript
edgeTypes={{
special: MyCustomEdge
}}
```
Now you could use the new type `special` for an edge.
The `straight`, `default` and `step` types would still be available unless you overwrote one of them.
There is an implementation of a custom edge in the [edges example](/example/src/Edges/index.js).
## Edge Utils
There are several utils that help you to create a custom edge. They are used in the [custom edge](/example/src/Edges/CustomEdge.js) example.
### `getBezierPath`
Returns the path of a bezier edge.
`getBezierPath({
sourceX,
sourceY,
sourcePosition = Position.Bottom,
targetX,
targetY,
targetPosition = Position.Top,
}: GetBezierPathParams): string`
### `getSmoothStepPath`
Returns the path of a smooth step edge. You can set `borderRadius` = `0` to get a step edge path.
`getSmoothStepPath({
sourceX,
sourceY,
sourcePosition = Position.Bottom,
targetX,
targetY,
targetPosition = Position.Top,
borderRadius = 5,
}: GetSmoothStepPathParams): string`
### `getEdgeCenter`
Returns the center poostion `[centerX, centerY]` of the edge.
`getEdgeCenter({ sourceX, sourceY, targetX, targetY }: GetCenterParams): [number, number, number, number]`
### `getMarkerEnd`
Returns the marker end url for displaying the arrow head.
`getMarkerEnd(arrowHeadType?: ArrowHeadType, markerEndId?: string): string`
+38
View File
@@ -0,0 +1,38 @@
---
title: Handle Component
---
We export a `Handle` component as a helper for your custom nodes:
```javascript
import { Handle } from 'react-flow-renderer';
const targetHandleWithValidation = (
<Handle
type="target"
position="left"
isValidConnection={(connection) => connection.source === 'some-id'}
onConnect={params => console.log('handle onConnect', params)}
style={{ background: '#fff' }}
/>
);
```
### Prop Types
- `type`: 'source' or 'target'
- `id`: string - you only need this when you have multiple source or target handles (otherwise the node id is used)
- `position`: 'left', 'right', 'top' or 'bottom' handle position - default: 'top' for type target, 'bottom' for type source
- `onConnect`: function that gets triggered on connect
- `isValidConnection`: function receives a connection `{ target: 'some-id', source: 'another-id' }` as param, returns a boolean - default: `true`
- `style`: css properties
- `className`: additional class name
### Validation
The handle receives the additional class names `connecting` when the connection line is above the handle and `valid` if the connection is valid. You can find an example which uses these classes [here](/examples/validation).
### Multiple Handles
If you need multiple source or target handles you can achieve this by creating a custom node. Normally you just use the id of a node for the `source` or `target` of an edge. If you have multiple source or target handles you need to pass an id to these handles. These ids get then added to the node id, so that you can connect a specific handle. If you have a node with an id = `1` and a handle with an id = `a` you can connect this handle by using the id = `1__a`.
You can find an example of how to implement a custom node with multiple handles in the [custom node example](https://github.com/wbkd/react-flow/blob/main/example/src/CustomNode/ColorSelectorNode.js#L18-L29).
@@ -50,4 +50,4 @@ Returns all edges that are connected to the passed nodes.
`getConnectedEdges = (nodes: Node[], edges: Edge[]): Edge[]`
You can use these function as seen in [this example](/example/src/Overview/index.js#L40-L41) or use your own ones.
You can use these function as seen in [this example](https://github.com/wbkd/react-flow/blob/main/example/src/Overview/index.js#L119-L120) or use your own ones.
@@ -27,7 +27,7 @@ const Flow = () => (
### Internal actions
You will not need this in most cases but you can also use the internal actions that are defined in the [store](/src/store/index.ts):
You will not need this in most cases but you can also use the internal actions that are defined in the [store](https://github.com/wbkd/react-flow/blob/main/src/store/index.ts):
```jsx
import React, { useEffect } from 'react';
@@ -0,0 +1,41 @@
---
title: Node Types & Custom Nodes
---
There are three different node types (`default`, `input`, `output`) you can use. The node types differ in the number and types of handles. An input node has only a source handle, a default node has a source and a target and an output node has only a target handle. The default node types object looks like this:
```js
{
input: InputNode,
default: DefaultNode,
output: OutputNode
}
```
The keys represent the type names and the values are the components that get rendered.
If you want to introduce a new type you can pass a `nodeTypes` object to the `ReactFlow` component:
```js
nodeTypes={{
special: MyCustomNode
}}
```
You can now use the type `special` for a node.
The `default`, `input` and `output` types would be still available except you overwrote one of them.
There is an example of a custom node implementation in the [custom node example](/examples/custom-node).
## Custom Node Props
Your custom nodes are wrapped so that the basic functions like dragging or selecting work. Custom nodes receive the following props:
- `id`: string
- `data`: object
- `type`: string
- `selected`: boolean
- `sourcePosition`: string
- `targetPosition`: string
### Prevent dragging
If you have controls or other elements inside your custom node that should not drag the node you can add the class name `nodrag`.
+2 -81
View File
@@ -1,9 +1,7 @@
---
id: nodes
title: Nodes
title: Node Options
---
There are three different [node types](#node-types--custom-nodes) (`default`, `input`, `output`) you can use. The node types differ in the number and types of handles. An input node has only a source handle, a default node has a source and a target and an output node has only a target handle. You create nodes by adding them to the `elements` array of the `ReactFlow` component.
You create nodes by adding them to the `elements` array of the `ReactFlow` component.
Node example:
@@ -30,80 +28,3 @@ Node example:
- `draggable`: boolean - if option is not set, the node is draggable (overwrites general `nodesDraggable` option)
- `connectable`: boolean - if option is not set, the node is connectable (overwrites general `nodesConnectable` option)
- `selectable`: boolean - if option is not set, the node is selectable (overwrites general `elementsSelectable` option)
## Node Types & Custom Nodes
The standard node types are `input`, `default` and `output`. The default node types object looks like this:
```js
{
input: InputNode,
default: DefaultNode,
output: OutputNode
}
```
The keys represent the type names and the values are the components that get rendered.
If you want to introduce a new type you can pass a `nodeTypes` object to the `ReactFlow` component:
```js
nodeTypes={{
special: MyCustomNode
}}
```
You can now use the type `special` for a node.
The `default`, `input` and `output` types would be still available except you overwrote one of them.
There is an example of a custom node implementation in the [custom node example](/example/src/CustomNode).
## Custom Node Props
Your custom nodes are wrapped so that the basic functions like dragging or selecting work. Custom nodes receive the following props:
- `id`: string
- `data`: object
- `type`: string
- `selected`: boolean
- `sourcePosition`: string
- `targetPosition`: string
### Prevent dragging
If you have controls or other elements inside your custom node that should not drag the node you can add the class name `nodrag`.
## Handle Component
We export a `Handle` component as a helper for your custom nodes:
```javascript
import { Handle } from 'react-flow-renderer';
const targetHandleWithValidation = (
<Handle
type="target"
position="left"
isValidConnection={(connection) => connection.source === 'some-id'}
onConnect={params => console.log('handle onConnect', params)}
style={{ background: '#fff' }}
/>
);
```
### Prop Types
- `type`: 'source' or 'target'
- `id`: string - you only need this when you have multiple source or target handles (otherwise the node id is used)
- `position`: 'left', 'right', 'top' or 'bottom' handle position - default: 'top' for type target, 'bottom' for type source
- `onConnect`: function that gets triggered on connect
- `isValidConnection`: function receives a connection `{ target: 'some-id', source: 'another-id' }` as param, returns a boolean - default: `true`
- `style`: css properties
- `className`: additional class name
### Validation
The handle receives the additional class names `connecting` when the connection line is above the handle and `valid` if the connection is valid. You can find an example which uses these classes [here](/example/src/Validation/index.js).
### Multiple Handles
If you need multiple source or target handles you can achieve this by creating a custom node. Normally you just use the id of a node for the `source` or `target` of an edge. If you have multiple source or target handles you need to pass an id to these handles. These ids get then added to the node id, so that you can connect a specific handle. If you have a node with an id = `1` and a handle with an id = `a` you can connect this handle by using the id = `1__a`.
You can find an example of how to implement a custom node with multiple handles in the [custom node example](/example/src/CustomNode/ColorSelectorNode.js#L18-L29).
@@ -15,31 +15,42 @@ const onLoad = (reactFlowInstance) => {
const BasicFlow = () => <ReactFlow onLoad={onLoad} elements={[]} />;
```
`reactFlowInstance` has the following functions:
The `reactFlowInstance` has the following functions:
### `project`
Transforms pixel coordinates to the internal ReactFlow coordinate system.
This can be used when you drag nodes (from a side bar for example) and need the position on the pane.
This can be used when you drag nodes (from a side bar for example) and need the internal position on the pane.
`project = (position: XYPosition): XYPosition`
**example:**
```
reactFlowInstance.project({ x: 100, y: 100 });
```
### `fitView`
Fits view port so that all nodes are inside the view port.
Fits the view port so that all nodes are visible
`fitView = ({ padding }): void`
### `zoomIn`
Zoom in
`zoomIn = (): void`
### `zoomOut`
Zoom out
`zoomOut = (): void`
### `zoomTo`
Zooms to the specified zoom level
`zoomTo = (zoomLevel: number): void`
### `getElements`
@@ -50,4 +61,9 @@ Fits view port so that all nodes are inside the view port.
Sets position and zoom of the pane.
`setTransform = (transform: FlowTransform): void`
`setTransform = (transform: FlowTransform): void`
**example:**
```
reactFlowInstance.setTransform({ x: 100, y: 100, zoom: 1.5 });
```
@@ -2,17 +2,23 @@
title: Getting Started
---
Before you can start to use React Flow you need to install `react-flow-renderer` from npm:
Before you can start to use React Flow you need to install `react-flow-renderer`:
## Installation
**npm:**
```bash
npm install react-flow-renderer
```
**yarn:**
```bash
yarn add react-flow-renderer
```
## Usage
This is a very basic example of how to use React Flow. We are rendering two nodes connected with an edge. There are more advanced examples in the [examples](/examples) section.
This is a very basic example of how to use React Flow. A flow consists of nodes and edges (or just nodes). Together we call them elements. You can pass a set of elements as a prop to the ReactFlow component. Hereby all elements need unique ids. A node needs a position and a label and an edge needs a source (node id) and a target (node id). This is the most basic for a flow. A simple flow could look like this:
```jsx
import React from 'react';
@@ -30,4 +36,6 @@ const BasicFlow = () => <ReactFlow elements={elements} />;
import Flow from './index';
<Flow />
<Flow />
You can find more advanced examples in the [examples](reactflow.dev/examples/) section.
+1 -1
View File
@@ -2,7 +2,7 @@
title: Introduction
---
React Flow is a library for building node-based graphs. You can easily implement custom node types and it comes with components like a mini-map and graph controls. Feel free to check out the [examples](https://reactflow.dev/) or read the [blog post](https://webkid.io/blog/react-flow-node-based-graph-library/) to get started.
React Flow is a library for building node-based applications. These can be simple static diagrams or complex node-based editors. You can implement custom node types and edge types and it comes with components like a mini-map and graph controls. Feel free to check out the [examples](https://reactflow.dev/examples/) or read the [blog post](https://webkid.io/blog/react-flow-node-based-graph-library/) to get started.
## Key Features
+1 -1
View File
@@ -7,7 +7,7 @@ import { ReactFlowProvider } from 'react-flow-renderer';
export const frontmatter = {
title: 'Edge Types',
slug: 'edge-types',
order: 4,
order: 11,
};
export default () => {
+1 -1
View File
@@ -7,7 +7,7 @@ import { ReactFlowProvider } from 'react-flow-renderer';
export const frontmatter = {
title: 'Hidden',
slug: 'hidden',
order: 4,
order: 12,
};
export default () => {
+6 -6
View File
@@ -92,7 +92,7 @@ const Home = () => {
<HeadlineAbsolute>
<CenterContent>
<HeadlineWrapper>
<H1>Wire your ideas together with React Flow</H1>
<H1>Wire your ideas with React Flow</H1>
<SectionSubtitle>
Highly customizable React.js library for building node-based
editors and diagrams.
@@ -128,7 +128,7 @@ const Home = () => {
<CenterContent>
<SectionIntro
title="Getting Started"
text="With React Flow you can build node-based applications. From complex interactive editors to simple static diagrams."
text="React Flow enables you to build node-based applications. From simple static diagrams to complex interactive editors."
color={baseColors.textLight}
/>
<Paragraph mb={3} color={baseColors.textLight}>
@@ -151,8 +151,8 @@ const Home = () => {
them elements. You can pass a set of elements as a prop to the
ReactFlow component. Hereby all elements need unique ids. A node
needs a position and a label and an edge needs a source (node id)
and a target (node id). This is the most basic set up you need to
get started. A simple flow could look like this:
and a target (node id). This is the most basic for a flow. A simple
flow could look like this:
</Paragraph>
<CodeBlock
code={`import React from 'react';
@@ -179,7 +179,7 @@ const BasicFlow = () => <ReactFlow elements={elements} />;`}
<ContentSection bg="violetLighten5">
<SectionIntro
title="Built with React Flow"
text="React Flow has a fast growing community. Since the first release new projects popup. Ranging from Music Synthesizers and Study catalogs over to presentational business logic."
text="You can do a wide range of applications with React Flow. Ranging from music synthesizers and study planners to visualizations of neural nets."
color={baseColors.textLight}
/>
<Showcases />
@@ -187,7 +187,7 @@ const BasicFlow = () => <ReactFlow elements={elements} />;`}
<ContentSection>
<SectionIntro
title="Do you want to realize a data driven experience?"
title="Do you want to build a data driven application?"
text="Reach out and contact us. Were happy to chat and always excited for a new data driven challenge."
/>
+17 -3
View File
@@ -12,10 +12,24 @@ const docsMenu = [
group: 'API Reference',
items: [
{ title: 'Prop Types' },
{ title: 'Instance' },
{ title: 'Nodes' },
{ title: 'Edges' },
{ title: 'Helper Functions' },
{
group: 'Nodes',
items: [
{ title: 'Node Options' },
{ title: 'Node Types & Custom Nodes' },
{ title: 'Handle Component' },
],
},
{
group: 'Edges',
items: [
{ title: 'Edge Options' },
{ title: 'Edge Types & Custom Edges' },
{ title: 'Edge Utils' },
],
},
{ title: 'Instance' },
{ title: 'Internal State and Actions' },
{
group: 'Components',
Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

After

Width:  |  Height:  |  Size: 1.1 KiB