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
+2
View File
@@ -0,0 +1,2 @@
website/* linguist-documentation
example/* linguist-documentation
+19 -3
View File
@@ -1,4 +1,6 @@
![react-flow](https://user-images.githubusercontent.com/2857535/88070904-7e5e2c80-cb73-11ea-9f69-6b8647eef24a.png)
![react-flow](https://user-images.githubusercontent.com/2857535/95224198-b2540000-07fa-11eb-832d-361d72d60345.jpg)
## ✨ React Flow has a [new website](https://reactflow.dev) ✨
# React Flow
@@ -130,6 +132,12 @@ const BasicFlow = () => <ReactFlow elements={elements} />;
- `deleteKeyCode`: default: `8` (delete)
- `selectionKeyCode`: default: `16` (shift)
**Typescript:** The interface of the ReactFlow Prop Types are exported as `ReactFlowProps`. You can use it in your code as follows:
```javascript
import { ReactFlowProps } from 'react-flow-renderer';
```
## React Flow Instance
You can receive a `reactFlowInstance` by using the `onLoad` callback:
@@ -271,6 +279,8 @@ const targetHandleWithValidation = (
- `style`: css properties
- `className`: additional class name
**Typescript:** The interface of the Handle Prop Types are exported as `HandleProps`.
### 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).
@@ -412,6 +422,8 @@ const FlowWithBackground = () => (
- `style`: css properties
- `className`: additional class name
**Typescript:** The interface of the Background Prop Types are exported as `BackgroundProps`.
## MiniMap
You can use the mini map plugin by passing it as a children to the `ReactFlow` component:
@@ -445,6 +457,8 @@ const FlowWithMiniMap = () => (
- `style`: css properties
- `className`: additional class name
**Typescript:** The interface of the MiniMap Prop Types are exported as `MiniMapProps`.
## Controls
The control panel contains a zoom-in, zoom-out, fit-view and a lock/unlock button. You can use it by passing it as a children to the `ReactFlow` component:
@@ -471,6 +485,8 @@ const FlowWithControls = () => (
- `style`: css properties
- `className`: additional class name
**Typescript:** The interface of the Controls Prop Types are exported as `ControlProps`.
## ReactFlowProvider
If you need access to the internal state and action of React Flow outside of the `ReactFlow` component you can wrap it with the `ReactFlowProvider` component:
@@ -510,8 +526,8 @@ The React Flow wrapper has the className `react-flow`. If you want to change the
### Used Class Names
* `.react-flow` - Outer container
* `.react-flow__renderer` - Inner container
* `.react-flow__zoompane` - Zoom & pan pane
* `.react-flow__renderer` - Flow container, used for zooming and panning
* `.react-flow__pane` - Background Pane for click and wheel events, previously `.react-flow__zoompane`
* `.react-flow__selectionpane` - Selection pane
* `.react-flow__selection` - User selection
* `.react-flow__edges` - Edges wrapper
+2 -2
View File
@@ -119,7 +119,7 @@ describe('Basic Flow Rendering', () => {
// for d3 we have to pass the window to the event
// https://github.com/cypress-io/cypress/issues/3441
cy.window().then((win) => {
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('mousedown', 'topLeft', { which: 1, view: win })
.trigger('mousemove', 'bottomLeft')
.trigger('mouseup', { force: true, view: win })
@@ -133,7 +133,7 @@ describe('Basic Flow Rendering', () => {
it('zooms the pane', () => {
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('wheel', 'topLeft', { deltaY: -200 })
.then(() => {
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
+1 -1
View File
@@ -36,7 +36,7 @@ describe('Controls Testing', () => {
// for d3 we have to pass the window to the event
// https://github.com/cypress-io/cypress/issues/3441
cy.window().then((win) => {
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('mousedown', 'topLeft', { which: 1, view: win })
.trigger('mousemove', 'bottomLeft')
.trigger('mouseup', { force: true, view: win })
+2
View File
@@ -16,6 +16,8 @@ describe('Empty Flow Rendering', () => {
.trigger('mousedown', 'topLeft', { which: 1, force: true })
.trigger('mousemove', 'bottomLeft', { which: 1 })
.trigger('mouseup', 'bottomLeft', { force: true });
cy.get('body').type('{shift}', { release: true });
});
it('renders an empty mini map', () => {
+4 -4
View File
@@ -52,7 +52,7 @@ describe('Interaction Flow Rendering', () => {
it('tries to zoom by scroll', () => {
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.dblclick()
.then(() => {
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
@@ -63,7 +63,7 @@ describe('Interaction Flow Rendering', () => {
it('tries to zoom by double click', () => {
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('wheel', 'topLeft', { deltaY: -200 })
.then(() => {
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
@@ -122,7 +122,7 @@ describe('Interaction Flow Rendering', () => {
it('zooms by scroll', () => {
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('wheel', 'topLeft', { deltaY: 200 })
.then(() => {
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
@@ -137,7 +137,7 @@ describe('Interaction Flow Rendering', () => {
it('zooms by double click', () => {
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.dblclick()
.then(() => {
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
+2 -2
View File
@@ -19,7 +19,7 @@ describe('Minimap Testing', () => {
const viewBoxBeforeZoom = Cypress.$('.react-flow__minimap').attr('viewBox');
const maskPathBeforeZoom = Cypress.$('.react-flow__minimap-mask').attr('d');
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('wheel', 'topLeft', { deltaY: -200 })
.then(() => {
const viewBoxAfterZoom = Cypress.$('.react-flow__minimap').attr('viewBox');
@@ -53,7 +53,7 @@ describe('Minimap Testing', () => {
// for d3 we have to pass the window to the event
// https://github.com/cypress-io/cypress/issues/3441
cy.window().then((win) => {
cy.get('.react-flow__zoompane')
cy.get('.react-flow__renderer')
.trigger('mousedown', 'topLeft', { which: 1, view: win })
.trigger('mousemove', 'bottomLeft')
.trigger('mouseup', { force: true, view: win })
+2 -13
View File
@@ -1,5 +1,5 @@
{
"name": "react-flow-examples",
"name": "react-flow-tests",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,
@@ -3996,11 +3996,6 @@
"type": "^1.0.1"
}
},
"d3-selection": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
"integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
},
"damerau-levenshtein": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
@@ -10458,10 +10453,7 @@
"react-flow-renderer": {
"version": "file:..",
"requires": {
"@welldone-software/why-did-you-render": "^4.3.2",
"classcat": "^4.1.0",
"d3-selection": "^2.0.0",
"d3-zoom": "^2.0.0",
"easy-peasy": "^3.3.1",
"fast-deep-equal": "^3.1.3",
"react-draggable": "^4.4.3",
@@ -16087,8 +16079,7 @@
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.4.tgz",
"integrity": "sha512-ICPurDETFAelF1CTHdIyiUM4PsyZLaM+7oIBhmyP+cuVjze5vDZ8V//LdOFjg0jGnFIZD/Sfmk0r95PSiu78rw==",
"requires": {
"d3-dispatch": "1",
"d3-selection": "1"
"d3-dispatch": "1"
}
},
"d3-ease": {
@@ -16118,7 +16109,6 @@
"d3-dispatch": "1",
"d3-ease": "1",
"d3-interpolate": "1",
"d3-selection": "^1.1.0",
"d3-timer": "1"
}
},
@@ -16130,7 +16120,6 @@
"d3-dispatch": "1",
"d3-drag": "1",
"d3-interpolate": "1",
"d3-selection": "1",
"d3-transition": "1"
}
},
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "react-flow-examples",
"name": "react-flow-tests",
"version": "0.1.0",
"private": true,
"dependencies": {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+2 -4
View File
@@ -4,12 +4,10 @@
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="theme-color" content="#222222" />
<meta name="description" content="react flow examples" />
<title>React Flow Examples</title>
<meta name="description" content="React Flow test flows" />
<title>React Flow - Test Flows</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

-25
View File
@@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
-90
View File
@@ -1,90 +0,0 @@
import React, { useState } from 'react';
import ReactFlow, { removeElements, addEdge } from 'react-flow-renderer';
const onLoad = (reactFlowInstance) => reactFlowInstance.fitView();
const onNodeMouseEnter = (event, node) => console.log('mouse enter:', node);
const onNodeMouseMove = (event, node) => console.log('mouse move:', node);
const onNodeMouseLeave = (event, node) => console.log('mouse leave:', node);
const onNodeContextMenu = (event, node) => {
event.preventDefault();
console.log('context menu:', node);
};
const initialElements = [
{
id: '1',
sourcePosition: 'right',
type: 'input',
className: 'dark-node',
data: { label: 'Input' },
position: { x: 0, y: 80 },
},
{ id: '2', sourcePosition: 'right', targetPosition: 'left', data: { label: 'A Node' }, position: { x: 250, y: 0 } },
{ id: '3', sourcePosition: 'right', targetPosition: 'left', data: { label: 'Node 3' }, position: { x: 250, y: 160 } },
{ 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',
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 },
{ id: 'e1-4', source: '2', type: 'smoothstep', target: '4', label: 'edge label' },
{ id: 'e3-5', source: '3', type: 'smoothstep', target: '5', animated: true },
{ id: 'e3-6', source: '3', type: 'smoothstep', target: '6', animated: true },
{ id: 'e5-7', source: '5', type: 'smoothstep', target: '7', animated: true },
{ id: 'e6-8', source: '6', type: 'smoothstep', target: '8', animated: true },
];
const HorizontalFlow = () => {
const [elements, setElements] = useState(initialElements);
const onElementsRemove = (elementsToRemove) => setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params) => setElements((els) => addEdge(params, els));
const changeClassName = () => {
setElements((elms) =>
elms.map((el) => {
if (el.type === 'input') {
el.className = el.className ? '' : 'dark-node';
}
return { ...el };
})
);
};
return (
<ReactFlow
elements={elements}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
onLoad={onLoad}
selectNodesOnDrag={false}
onNodeMouseEnter={onNodeMouseEnter}
onNodeMouseMove={onNodeMouseMove}
onNodeMouseLeave={onNodeMouseLeave}
onNodeContextMenu={onNodeContextMenu}
>
<button onClick={changeClassName} style={{ position: 'absolute', right: 10, top: 30, zIndex: 4 }}>
change class name
</button>
</ReactFlow>
);
};
export default HorizontalFlow;
+6
View File
@@ -4,6 +4,9 @@ import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background, isNo
const onNodeDragStart = (event, node) => console.log('drag start', node);
const onNodeDragStop = (event, node) => console.log('drag stop', node);
const onPaneClick = (event) => console.log('pane click', event);
const onPaneScroll = (event) => console.log('pane scroll', event);
const onPaneContextMenu = (event) => console.log('pane context menu', event);
const onSelectionDrag = (event, nodes) => console.log('selection drag', nodes);
const onSelectionDragStart = (event, nodes) => console.log('selection drag start', nodes);
const onSelectionDragStop = (event, nodes) => console.log('selection drag stop', nodes);
@@ -125,6 +128,9 @@ const OverviewFlow = () => {
onElementClick={onElementClick}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
onPaneClick={onPaneClick}
onPaneScroll={onPaneScroll}
onPaneContextMenu={onPaneContextMenu}
onNodeDragStart={onNodeDragStart}
onNodeDragStop={onNodeDragStop}
onSelectionDragStart={onSelectionDragStart}
+1 -3
View File
@@ -1,7 +1,5 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
body {
font-family: 'Roboto', sans-serif;
font-family: sans-serif;
color: #111;
}
+2 -20
View File
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch, NavLink, withRouter } from 'react-router-dom';
import { BrowserRouter as Router, Route, Switch, NavLink } from 'react-router-dom';
import Overview from './Overview';
import Basic from './Basic';
@@ -10,7 +10,6 @@ import Interaction from './Interaction';
import Empty from './Empty';
import Edges from './Edges';
import Validation from './Validation';
import Horizontal from './Horizontal';
import Provider from './Provider';
import Hidden from './Hidden';
import EdgeTypes from './EdgeTypes';
@@ -36,11 +35,6 @@ const routes = [
component: CustomNode,
label: 'CustomNode',
},
{
path: '/horizontal',
component: Horizontal,
label: 'Horizontal',
},
{
path: '/validation',
component: Validation,
@@ -94,24 +88,13 @@ const routes = [
const navLinks = routes.filter((route) => route.label);
const SourceDisplay = withRouter(({ location }) => {
const route = routes.find((route) => route.path === location.pathname);
const sourceLink = `https://github.com/wbkd/react-flow/tree/main/example/src/${route.label}/index.js`;
return (
<a className="sourcedisplay" href={sourceLink}>
{'<Source />'}
</a>
);
});
const Header = () => {
const [menuOpen, setMenuOpen] = useState();
return (
<header>
<a className="logo" href="https://github.com/wbkd/react-flow">
React Flow
React Flow Dev
</a>
<nav className={menuOpen ? 'is-open' : ''}>
{navLinks.map((route) => (
@@ -130,7 +113,6 @@ const Header = () => {
ReactDOM.render(
<Router forceRefresh={true}>
<Header />
<SourceDisplay />
<Switch>
{routes.map((route) => (
<Route exact path={route.path} render={() => <route.component />} key={route.path} />
+121 -110
View File
@@ -1,6 +1,6 @@
{
"name": "react-flow-renderer",
"version": "6.0.3",
"version": "6.1.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -4119,9 +4119,9 @@
}
},
"@octokit/endpoint": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.6.tgz",
"integrity": "sha512-7Cc8olaCoL/mtquB7j/HTbPM+sY6Ebr4k2X2y4JoXpVKQ7r5xB4iGQE0IoO58wIPsUk4AzoT65AMEpymSbWTgQ==",
"version": "6.0.8",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.8.tgz",
"integrity": "sha512-MuRrgv+bM4Q+e9uEvxAB/Kf+Sj0O2JAOBA131uo1o6lgdq1iS8ejKwtqHgdfY91V3rN9R/hdGKFiQYMzVzVBEQ==",
"dev": true,
"requires": {
"@octokit/types": "^5.0.0",
@@ -4752,9 +4752,9 @@
"dev": true
},
"@types/d3": {
"version": "5.16.1",
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.16.1.tgz",
"integrity": "sha512-CTy9JlhLP2DL7DFGXUYk5rgcipS2/NcbXeKul6kwaJ1gDipDveAPveIRa/pCGjep6wgCqq567kPGygoFdNAAQg==",
"version": "5.16.3",
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.16.3.tgz",
"integrity": "sha512-s3wrhYhu25XZQ5p1hI9gEMSX5bx7lg9hAmi0+i5r3v75Gz1zRTgB2Q0psx+SO+4K0AO/PPJ1pnHCz64pANN/4w==",
"dev": true,
"requires": {
"@types/d3-array": "^1",
@@ -4768,26 +4768,26 @@
"@types/d3-drag": "^1",
"@types/d3-dsv": "^1",
"@types/d3-ease": "^1",
"@types/d3-fetch": "*",
"@types/d3-fetch": "^1",
"@types/d3-force": "^1",
"@types/d3-format": "^1",
"@types/d3-geo": "^1",
"@types/d3-hierarchy": "^1",
"@types/d3-interpolate": "*",
"@types/d3-interpolate": "^1",
"@types/d3-path": "^1",
"@types/d3-polygon": "^1",
"@types/d3-quadtree": "^1",
"@types/d3-random": "^1",
"@types/d3-scale": "*",
"@types/d3-scale": "^2",
"@types/d3-scale-chromatic": "^1",
"@types/d3-selection": "^1",
"@types/d3-shape": "^1",
"@types/d3-time": "^1",
"@types/d3-time-format": "*",
"@types/d3-time-format": "^2",
"@types/d3-timer": "^1",
"@types/d3-transition": "*",
"@types/d3-transition": "^1",
"@types/d3-voronoi": "*",
"@types/d3-zoom": "*"
"@types/d3-zoom": "^1"
}
},
"@types/d3-array": {
@@ -4870,9 +4870,9 @@
"dev": true
},
"@types/d3-fetch": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.2.1.tgz",
"integrity": "sha512-J03JOSbExh3wmUt61v/Hx6nf2znMAKlW5vwV+jRWQ9VFR7MS0QCnj6nYuhXfxO8xgttjVuBKndCzkTRlqhMZgg==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.2.2.tgz",
"integrity": "sha512-rtFs92GugtV/NpiJQd0WsmGLcg52tIL0uF0bKbbJg231pR9JEb6HT4AUwrtuLq3lOeKdLBhsjV14qb0pMmd0Aw==",
"dev": true,
"requires": {
"@types/d3-dsv": "^1"
@@ -4906,9 +4906,9 @@
"dev": true
},
"@types/d3-interpolate": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.1.tgz",
"integrity": "sha512-8sCNMnDoRJhGH/QnNiWLAGBsZOccnjAY7laVXe/hfdWcLvh6cDCTMJZ5XBqSQVtB+Jlcb0SI8d5yKM7QIBdGtg==",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz",
"integrity": "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==",
"dev": true,
"requires": {
"@types/d3-color": "^1"
@@ -4939,9 +4939,9 @@
"dev": true
},
"@types/d3-scale": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.2.3.tgz",
"integrity": "sha512-rgxHPfnF7g7uH33O2v1etDmeDaQHzXqRo98m56GuE2uPTLfnDulDDM/V8sOdGErRTvUm+QLMrJJKjBkFlOP1qA==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.2.4.tgz",
"integrity": "sha512-wkQXT+IfgfAnKB5rtS1qMJg3FS32r1rVFHvqtiqk8pX8o5aQR3VwX1P7ErHjzNIicTlkWsaMiUTrYB+E75HFeA==",
"dev": true,
"requires": {
"@types/d3-time": "^1"
@@ -4975,9 +4975,9 @@
"dev": true
},
"@types/d3-time-format": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.0.tgz",
"integrity": "sha512-AdRnb7cQz9QLYKJwaq5lzznB2vmPWI7vQeY+P6g9TR3IyVQ5mpnN90YHo2jG8dK9ZeU+/TkAIMZXb1Pg1IWmeQ==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.1.tgz",
"integrity": "sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA==",
"dev": true
},
"@types/d3-timer": {
@@ -4987,9 +4987,9 @@
"dev": true
},
"@types/d3-transition": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.0.tgz",
"integrity": "sha512-+xY813L5WWXx43Cg1C8NNPzk94jVk6275KfC/3KTNuaMm7VMl3tNaUyhEb2N9gFoVxJf+obM4qYl2p06OvwVTQ==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.3.1.tgz",
"integrity": "sha512-U9CpMlTL/NlqdGXBlHYxTZwbmy/vN1cFv8TuAIFPX+xOW/1iChbeJBY2xmINhDQfkGJbgkH4IovafCwI1ZDrgg==",
"dev": true,
"requires": {
"@types/d3-selection": "^1"
@@ -5002,12 +5002,12 @@
"dev": true
},
"@types/d3-zoom": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.0.tgz",
"integrity": "sha512-ZoGuokWrCQaBWpmdHigiL5W82L+viWg8MZRRIqniHK7LjZG0/6iC8lzoQF3B8llMvHugWEjKWLeXX2nBVuJInA==",
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.8.2.tgz",
"integrity": "sha512-rU0LirorUxkLxEHSzkFs7pPC0KWsxRGc0sHrxEDR0/iQq+7/xpNkKuuOOwthlgvOtpOvtTLJ2JFOD6Kr0Si4Uw==",
"dev": true,
"requires": {
"@types/d3-interpolate": "*",
"@types/d3-interpolate": "^1",
"@types/d3-selection": "^1"
}
},
@@ -5063,9 +5063,9 @@
"dev": true
},
"@types/react": {
"version": "16.9.49",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.49.tgz",
"integrity": "sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==",
"version": "16.9.52",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.52.tgz",
"integrity": "sha512-EHRjmnxiNivwhGdMh9sz1Yw9AUxTSZFxKqdBWAAzyZx3sufWwx6ogqHYh/WB1m/I4ZpjkoZLExF5QTy2ekVi/Q==",
"dev": true,
"requires": {
"@types/prop-types": "*",
@@ -5845,12 +5845,11 @@
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@@ -6321,23 +6320,6 @@
"unique-string": "^2.0.0",
"write-file-atomic": "^3.0.0",
"xdg-basedir": "^4.0.0"
},
"dependencies": {
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"convert-source-map": {
@@ -7664,9 +7646,9 @@
}
},
"git-url-parse": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.2.0.tgz",
"integrity": "sha512-KPoHZg8v+plarZvto4ruIzzJLFQoRx+sUs5DQSr07By9IBKguVd+e6jwrFR6/TP6xrCJlNV1tPqLO1aREc7O2g==",
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.3.0.tgz",
"integrity": "sha512-i3XNa8IKmqnUqWBcdWBjOcnyZYfN3C1WRvnKI6ouFWwsXCZEnlgbwbm55ZpJ3OJMhfEP/ryFhqW8bBhej3C5Ug==",
"dev": true,
"requires": {
"git-up": "^4.0.0"
@@ -7725,9 +7707,9 @@
}
},
"got": {
"version": "11.6.2",
"resolved": "https://registry.npmjs.org/got/-/got-11.6.2.tgz",
"integrity": "sha512-/21qgUePCeus29Jk7MEti8cgQUNXFSWfIevNIk4H7u1wmXNDrGPKPY6YsPY+o9CIT/a2DjCjRz0x1nM9FtS2/A==",
"version": "11.7.0",
"resolved": "https://registry.npmjs.org/got/-/got-11.7.0.tgz",
"integrity": "sha512-7en2XwH2MEqOsrK0xaKhbWibBoZqy+f1RSUoIeF1BLcnf+pyQdDsljWMfmOh+QKJwuvDIiKx38GtPh5wFdGGjg==",
"dev": true,
"requires": {
"@sindresorhus/is": "^3.1.1",
@@ -8020,12 +8002,11 @@
"dev": true
},
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@@ -8241,9 +8222,9 @@
"dev": true
},
"is-npm": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
"integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz",
"integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==",
"dev": true
},
"is-number": {
@@ -8874,6 +8855,23 @@
"integrity": "sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg==",
"dev": true
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"map-or-similar": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz",
@@ -9236,12 +9234,11 @@
"dev": true
},
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@@ -10727,9 +10724,9 @@
}
},
"release-it": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/release-it/-/release-it-14.0.3.tgz",
"integrity": "sha512-C/gJJqr4csU6OkhMJZlXnbPR+xgPlp2aO2BWJl5MIj8UPTavSYImwUkAXF2qZUknBE7ArfKVXkY8qUNZ31IyCA==",
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/release-it/-/release-it-14.1.0.tgz",
"integrity": "sha512-S3yFUl7dv4D5+/Gqe7Qi3zKKDlH5KtrrZfSiNX6QanQ1B21htfzGWfU+JmE89aKJgZPmNG7W0vuiSGXoRzbFZA==",
"dev": true,
"requires": {
"@iarna/toml": "2.2.5",
@@ -10737,14 +10734,14 @@
"async-retry": "1.3.1",
"chalk": "4.1.0",
"cosmiconfig": "7.0.0",
"debug": "4.1.1",
"debug": "4.2.0",
"deprecated-obj": "2.0.0",
"execa": "4.0.3",
"find-up": "5.0.0",
"form-data": "3.0.0",
"git-url-parse": "11.2.0",
"git-url-parse": "11.3.0",
"globby": "11.0.1",
"got": "11.6.2",
"got": "11.7.0",
"import-cwd": "3.0.0",
"inquirer": "7.3.3",
"is-ci": "2.0.0",
@@ -10755,20 +10752,19 @@
"parse-json": "5.1.0",
"semver": "7.3.2",
"shelljs": "0.8.4",
"update-notifier": "4.1.1",
"update-notifier": "5.0.0",
"url-join": "4.0.1",
"uuid": "8.3.0",
"uuid": "8.3.1",
"yaml": "1.10.0",
"yargs-parser": "20.0.0"
"yargs-parser": "20.2.1"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@@ -10797,6 +10793,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"debug": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"execa": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
@@ -10890,9 +10895,9 @@
}
},
"uuid": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==",
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz",
"integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==",
"dev": true
},
"yaml": {
@@ -10999,9 +11004,9 @@
}
},
"rollup": {
"version": "2.28.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.28.2.tgz",
"integrity": "sha512-8txbsFBFLmm9Xdt4ByTOGa9Muonmc8MfNjnGAR8U8scJlF1ZW7AgNZa7aqBXaKtlvnYP/ab++fQIq9dB9NWUbg==",
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.29.0.tgz",
"integrity": "sha512-gtU0sjxMpsVlpuAf4QXienPmUAhd6Kc7owQ4f5lypoxBW18fw2UNYZ4NssLGsri6WhUZkE/Ts3EMRebN+gNLiQ==",
"dev": true,
"requires": {
"fsevents": "~2.1.2"
@@ -11510,9 +11515,9 @@
"dev": true
},
"start-server-and-test": {
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.11.4.tgz",
"integrity": "sha512-db89HoSLpRAj+gfcI2i5g1CSLijzFNXplG7cFvZM0ulyXTR8MtH6KtuKecEcH8GnMDEdrqfDiCidbG/QsBPu6Q==",
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.11.5.tgz",
"integrity": "sha512-XUGifPzbJcgD6tqWMFvbxnra1KByRuiw6Oc9FHR3tPm7UxB70a4iFDIuXfOAFtMJLvOJuwB3gnMUZxko8gtLow==",
"dev": true,
"requires": {
"bluebird": "3.7.2",
@@ -11912,40 +11917,40 @@
"dev": true
},
"update-notifier": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz",
"integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.0.tgz",
"integrity": "sha512-8tqsiVrMv7aZsKNSjqA6DdBLKJpZG1hRpkj1RbOJu1PgyP69OX+EInAnP1EK/ShX5YdPFgwWdk19oquZ0HTM8g==",
"dev": true,
"requires": {
"boxen": "^4.2.0",
"chalk": "^3.0.0",
"chalk": "^4.1.0",
"configstore": "^5.0.1",
"has-yarn": "^2.1.0",
"import-lazy": "^2.1.0",
"is-ci": "^2.0.0",
"is-installed-globally": "^0.3.1",
"is-npm": "^4.0.0",
"is-npm": "^5.0.0",
"is-yarn-global": "^0.3.0",
"latest-version": "^5.0.0",
"pupa": "^2.0.1",
"semver": "^7.3.2",
"semver-diff": "^3.1.1",
"xdg-basedir": "^4.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -11973,6 +11978,12 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12231,9 +12242,9 @@
}
},
"yargs-parser": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.0.0.tgz",
"integrity": "sha512-8eblPHTL7ZWRkyjIZJjnGf+TijiKJSwA24svzLRVvtgoi/RZiKa9fFQTrlx0OKLnyHSdt/enrdadji6WFfESVA==",
"version": "20.2.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.1.tgz",
"integrity": "sha512-yYsjuSkjbLMBp16eaOt7/siKTjNVjMm3SoJnIg3sEh/JsvqVVDyjRKmaJV4cl+lNIgq6QEco2i3gDebJl7/vLA==",
"dev": true
},
"yauzl": {
+10 -9
View File
@@ -1,6 +1,6 @@
{
"name": "react-flow-renderer",
"version": "6.0.3",
"version": "6.1.3",
"main": "dist/ReactFlow.js",
"module": "dist/ReactFlow.esm.js",
"types": "dist/index.d.ts",
@@ -13,9 +13,10 @@
"build": "rollup -c --environment NODE_ENV:production",
"start": "rollup -w -c",
"dev": "npm run build && npm start & cd example && npm start",
"start:examples": "npm run build && cd example && npm start",
"dev:wait": "start-server-and-test start:examples http-get://localhost:3000",
"build:example": "npm install && npm run build && cd example && npm install && npm run build",
"start:dev": "npm run build && cd example && npm start",
"dev:wait": "start-server-and-test start:dev http-get://localhost:3000",
"build:dev": "npm install && npm run build && cd example && npm install && npm run build",
"build:website": "cd website && npm install && GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES=true npm run build",
"cy:open": "cypress open",
"cypress": "npm run dev:wait cy:open",
"test:chrome": "cypress run --browser chrome --headless",
@@ -40,8 +41,8 @@
"@babel/preset-react": "^7.10.4",
"@svgr/rollup": "^5.4.0",
"@types/classnames": "^2.2.10",
"@types/d3": "^5.16.1",
"@types/react": "^16.9.49",
"@types/d3": "^5.16.3",
"@types/react": "^16.9.52",
"@types/react-dom": "^16.9.8",
"autoprefixer": "^9.8.6",
"babel-preset-react-app": "^9.1.2",
@@ -50,8 +51,8 @@
"prettier": "2.1.2",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"release-it": "^14.0.3",
"rollup": "^2.28.2",
"release-it": "^14.1.0",
"rollup": "^2.29.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-bundle-size": "^1.0.3",
"rollup-plugin-commonjs": "^10.1.0",
@@ -59,7 +60,7 @@
"rollup-plugin-postcss": "^3.1.8",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-typescript2": "^0.27.3",
"start-server-and-test": "^1.11.4",
"start-server-and-test": "^1.11.5",
"typescript": "^4.0.3"
},
"peerDependencies": {
@@ -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) => ({
+18
View File
@@ -0,0 +1,18 @@
module.exports = {
env: {
browser: true,
es6: true,
},
plugins: ['react'],
globals: {
graphql: false,
},
parserOptions: {
sourceType: 'module',
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
},
extends: 'react-app',
}
+9
View File
@@ -0,0 +1,9 @@
node_modules/
public
.gatsby-context.js
.DS_Store
.intermediate-representation/
.cache/
yarn.lock
*.log
.vscode
+1
View File
@@ -0,0 +1 @@
v10
+1
View File
@@ -0,0 +1 @@
src/pages/blog/**/*.md
+5
View File
@@ -0,0 +1,5 @@
{
"trailingComma": "es5",
"semi": true,
"singleQuote": true
}
+6
View File
@@ -0,0 +1,6 @@
# React Flow Website
![react-flow](https://user-images.githubusercontent.com/2857535/95224198-b2540000-07fa-11eb-832d-361d72d60345.jpg)
The [react flow website](https://reactflow.dev) powered by Gatsby
+6
View File
@@ -0,0 +1,6 @@
import 'babel-polyfill';
import './src/styles/global.css';
export const onRouteUpdate = () => {
document.body.classList.remove('noscroll');
};
+101
View File
@@ -0,0 +1,101 @@
module.exports = {
siteMetadata: {
title: `React Flow`,
siteUrl: `https://reactflow.dev`,
description:
'React Flow is a highly customizable library for building interactive node-based editors, flow charts and diagrams.',
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: 'pages',
path: `${__dirname}/src/pages`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: 'exampleflows',
path: `${__dirname}/src/example-flows`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `markdown`,
path: `${__dirname}/src/markdown`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `assets`,
path: `${__dirname}/src/assets`,
ignore: [`**/.*`], // ignore files starting with a dot
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
icon: `src/assets/images/react-flow-logo.svg`,
name: `React Flow`,
short_name: `react-flow`,
start_url: `/`,
background_color: `#f7f0eb`,
theme_color: `#1A192B`,
display: `standalone`,
lang: 'en',
},
},
`gatsby-plugin-sharp`,
`gatsby-remark-images`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-images`,
options: {
linkImagesToOriginal: false,
},
},
],
},
},
{
resolve: `gatsby-plugin-mdx`,
options: {
gatsbyRemarkPlugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 1200,
showCaptions: true,
quality: 85,
backgroundColor: 'white',
linkImagesToOriginal: false,
},
},
'gatsby-remark-copy-linked-files',
],
remarkPlugins: [require('remark-unwrap-images')],
extensions: [`.md`, `.mdx`],
},
},
`gatsby-transformer-json`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-emotion`,
{
resolve: `gatsby-plugin-react-svg`,
options: {
rule: {
include: /icons/,
},
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-netlify`,
`gatsby-transformer-javascript-frontmatter`,
],
};
+42
View File
@@ -0,0 +1,42 @@
const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
const docsGenerator = require('./generators/docs');
const exampleGenerator = require('./generators/examples');
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions;
const generateDocs = docsGenerator(createPage, graphql);
const generateExamples = exampleGenerator(createPage, graphql);
return Promise.all([generateDocs, generateExamples]);
};
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === 'Mdx') {
const value = createFilePath({ node, getNode });
createNodeField({
name: 'slug',
node,
value,
});
}
};
exports.onCreateWebpackConfig = ({ stage, actions, loaders }) => {
actions.setWebpackConfig({
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
alias: {
'example-flows': path.resolve(__dirname, 'src', 'example-flows'),
},
},
devServer: {
host: '0.0.0.0',
},
});
};
+66
View File
@@ -0,0 +1,66 @@
const path = require('path');
const docsTemplate = path.resolve('./src/templates/doc-page.js');
const docPagesQuery = `
{
docs: allMdx(
filter: {
fields: {
slug: { regex: "/docs/" },
}
}
) {
edges {
node {
fields {
slug
}
frontmatter {
title
}
}
}
}
}
`;
const createDocPages = (createPage, docPages) => {
const menu = docPages.map((page) => ({
slug: page.node.fields.slug,
title: page.node.frontmatter.title,
}));
docPages.forEach((page) => {
createPage({
path: page.node.fields.slug,
component: docsTemplate,
context: {
slug: page.node.fields.slug,
menu,
},
});
});
};
const blogGenerator = (createPage, graphql) =>
new Promise((resolve, reject) => {
resolve(
graphql(docPagesQuery).then((result) => {
if (result.errors) {
console.log(result.errors);
reject(result.errors);
}
const docPages = result.data.docs.edges;
try {
createDocPages(createPage, docPages);
} catch (e) {
console.log(e);
}
})
);
});
module.exports = blogGenerator;
+55
View File
@@ -0,0 +1,55 @@
const path = require('path');
const exampleTemplate = path.resolve('./src/templates/example-page.js');
const examplePagesQuery = `{
allExamplesJson {
edges {
node {
slug
title
source
}
}
}
}
`;
const createExamplePage = (createPage, examplePages) => {
examplePages.forEach((page) => {
const { slug, title, source } = page.node;
createPage({
path: slug,
component: exampleTemplate,
context: {
slug: slug,
title: title,
source: source,
sourceSlug: `/example-flows/${source}/`,
},
});
});
};
const exampleGenerator = (createPage, graphql) =>
new Promise((resolve, reject) => {
resolve(
graphql(examplePagesQuery).then((result) => {
if (result.errors) {
console.log(result.errors);
reject(result.errors);
}
const pages = result.data.allExamplesJson.edges;
try {
createExamplePage(createPage, pages);
} catch (e) {
console.log(e);
}
})
);
});
module.exports = exampleGenerator;
+63
View File
@@ -0,0 +1,63 @@
const path = require('path');
const utils = require('./utils');
const defaultTemplate = path.resolve('./src/templates/default-page.js');
const mdQuery = `
{
pages: allMdx {
edges {
node {
fields {
slug
}
frontmatter {
published
}
}
}
}
}
`;
const filterSpecialPages = (mdPage) => {
const slug = mdPage.node.fields.slug;
return slug.indexOf('/blog') !== 0 && slug.indexOf('/projects') !== 0;
};
const createMdPages = (createPage, mdPages) => {
mdPages
.filter(filterSpecialPages)
.filter(utils.filterPublished)
.forEach((mdPage) => {
createPage({
path: mdPage.node.fields.slug,
component: defaultTemplate,
context: {
slug: mdPage.node.fields.slug,
fields: mdPage.node.fields,
},
});
});
};
const mdPagesGenerator = (createPage, graphql) =>
new Promise((resolve, reject) => {
resolve(
graphql(mdQuery).then((result) => {
if (result.errors) {
console.log(result.errors);
reject(result.errors);
}
const mdPages = result.data.pages.edges;
try {
createMdPages(createPage, mdPages);
} catch (e) {
console.log(e);
}
})
);
});
module.exports = mdPagesGenerator;
+8
View File
@@ -0,0 +1,8 @@
function filterPublished(post) {
const isPublished = post.node.frontmatter && post.node.frontmatter.published;
return process.env.NODE_ENV === 'development' || isPublished;
}
module.exports = {
filterPublished,
};
+2
View File
@@ -0,0 +1,2 @@
[[plugins]]
package = "netlify-plugin-gatsby-cache"
+30
View File
@@ -0,0 +1,30 @@
curl -o ../static/fonts/NTDapper-thin.woff2 https://nodotypefoundry.com/fonts/ZDJ0TVNqY3pRa3BxYjBoWWRHVlRja0oxY1ZwUmVEWjVlR1o1YzNGVGRqQmlSQzlYUVhGd05HeEtSSEJxYmpVNGNtMWxZMVpyVDBaVmNIUk5LelpOVW04eWVrWlNZamR3TldWNGJrUnpjMjVKUkRGV1NGRTlQVG82Z3FzV3lOQ2w5eTVYY2c3NDExV1RSVG82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-thin.woff https://nodotypefoundry.com/fonts/Vm10cVR6Z3hXbUZRYTNkTmQydHdiazhyYnpSTGNHcHlZbEZRV1ZveVFuQXdkRXhSYnpsTFRVeFJaVFYzVHpCVk9XOVpTbWN5TTBOUlN6Sm9ZbWR6V213NVp6Qm9TRGRPUnpGaU9YbE1ha1YyUzFkM00wRTlQVG82TmVMYXF3TGZBQnlVOHJ4QXY4cFdIem82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-thin.eot https://nodotypefoundry.com/fonts/UkdvMlNVbG5WQ3RHUVd0aVlWRjJNMmRtTm5ONFlWSklUR1ZYVUd3eFdtazJkRGRVVVZaR2IyTTVkbTVVYVZKeFVtd3lhbEJDTW1obFVWTk9kM1JQWTAxNGJVeGtUSFZ6TVZkM2FtWTFTa3AxVVZaelNFRTlQVG82a1o2V2pXL1hjdlhVRWFCN1lkbTUyam82TWpVME1RPT0=.eot
curl -o ../static/fonts/NTDapper-extralight.woff2 https://nodotypefoundry.com/fonts/TDNGeGFrSkRZbEp5ZDJnMVFscFNVM0pCTTFselZqTjNOVXRTV1hCMlJGVlpkVTl3UW1abGJVZFFiWFpWY1ZSblZFcEtkVWg1ZEc1bmRraEJhMnhvZEhGSmVUTnZOM1Z4TDJvclQycDZPVFJuZGpKbFFsRTlQVG82eFJlWVZWWUgrdC9uelFUSXJiaEhuVG82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-extralight.woff https://nodotypefoundry.com/fonts/TmxSS2EyWTRlV2xvTmxwbmVYVnlZVFE0WnpNeWJYTnNaalo1VnpCNWVHa3plbnBaVGtKbU5EQjBRMUp4TUVSeU1pdE5ZMmRuTkhRd2IzSlBlbkU0Y1VOWFkwVllVR2xNYUc5RlVtaEJZbFp1V0RkSlNXYzlQVG82REVDWWpKN3pEbEdvbzN6RnN4NFAyVG82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-extralight.eot https://nodotypefoundry.com/fonts/VW5FMU5uZHlZVzU2U0hWV1RqWm9NMjgyYjFWMlVqRkNURlF4YWxNd2IyVTRkRVEwZWs0MWQwYzNWMUJXTjFwU2RrMHhNRmx3TlZCYU9HMHZkbXR2UW5CWWEwMVRlbWhyUjBsSWRtVjJWSHBHSzBSNE5uYzlQVG82S2Z0SVRJQm5XMy9YOEt5VS94OEdnVG82TWpVME1RPT0=.eot
curl -o ../static/fonts/NTDapper-light.woff2 https://nodotypefoundry.com/fonts/VldoRlMwaFdWMnhMVlZJMU0wcHlZazFJTkZSdFZUbE1OSGwxT0VoTlJtazNXVkJxU2xwd1oxUnJibEJGVEd0T01FTnpRMEk1TjJsdVFqRllPR0o0VURCaWIyeG1WR3RoT1RKTVdrVnZiR0pDUVZBek1tYzlQVG82RWhKeFJXcVZLeTl1WUgva3pZZ2Yzam82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-light.woff https://nodotypefoundry.com/fonts/WmxkQ1ptMHdTakZ4U1RWWVIxVXdSVWxOUnpWSmJXaElSVUV4YWs4eVFsaFBkamM1THk5d1NYWXZabkZ0UTNGR1RXUjRXbnBxVVhZNVMwMUNNVW93Tnk5M2VXWlRPVTB4WnpsTWVTOTBRV3hwTm01NVdFRTlQVG82UkltekRSdUN4aVlzZXh3dlJ5MW1yem82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-light.eot https://nodotypefoundry.com/fonts/VGpsTWFVTnBjMFJVY0dSNFZtWlFNSGxOTWxOdFRURm1jSGxpU0hKbFJuUlhlVGwwWmtOMWNHaFdkMGRTZWxGSlNFNXZjWFpJTVVvcldtSkVOelJSYlhadmNFdFVMMGdyU1Raek9FYzBZVmh3ZVVkMmEyYzlQVG82TVR0OXZieThhYlk0Z2VJdm5xeUViem82TWpVME1RPT0=.eot
curl -o ../static/fonts/NTDapper-regular.woff2 https://nodotypefoundry.com/fonts/ZW1kYU1VSndOVE5EWVVKa2RWbHZNRzF0U0dNd2JHbzFWbEJTY1VSWmMxTndTVEJxUWpaSWR6ZGpkM1V5TkROTE0xTXdOMFZ5VEdsTmJqSnFRMlpDVXpkblVEbFFjWFJLV2tWcmN6SnFWRU0zWWk5SE9IYzlQVG82dk1pSVFnYXBVS2kvNkp1TUVsYi9vVG82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-regular.woff https://nodotypefoundry.com/fonts/Um1KM1VXaHZaMlZCWlhkbWFrRm9hMUY2VWtWVVIzQktaMG8yVUhnMVdESldOM1pMVURObk9VRnBjbEV5TVZwNFZ6UTRSMFUwU1VSTWFIQndTbGd6ZVRoamVIVlZWalZ4ZDB4bWREaHlUSGhCVUdob2RrRTlQVG82aEdJdWs3VFZtM0JSZWttbWFWQ28vVG82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-regular.eot https://nodotypefoundry.com/fonts/V1dZM01EUTBWWFJNWjJwaWVsTmhkazUxZUhnMVVGVjRPR2xFV1drMGQyaFVOazl0ZFVZNE9VMVNRVGczUjJaS01ISXhhbWxqY1hvMVFXWjJSa3htUTIxUVpWbEZOa1V5VlhZMU9GWnViRVJhTVZwTGVHYzlQVG82UXRFTlVkbmJaa0p0anZ6bFZyNUZaVG82TWpVME1RPT0=.eot
curl -o ../static/fonts/NTDapper-medium.woff2 https://nodotypefoundry.com/fonts/ZFdwd1NWbFdOVUZrWVRaSGVuWXZXVFJwU21KT1ZEVXJVRzB4T0ZvekswWk5VM2d6YTJZMWNHMW1jRTg0YzJrM2R6WnNWVTkxV21kaU1uQmpSQ3N6T1VzNVFsUktlbEJYWldrNWN6aFNhRFJIUVZSeFFrRTlQVG82V09yckl0STl1TDJIUmQxK0JtcGVzVG82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-medium.woff https://nodotypefoundry.com/fonts/UjAxUFVIaG5lWGxtT0hWTWVYUmhRVkJWYVRCcVRqTkZPRTByTlZkTlpVdG9kMk5pTjJKaFNqWXJSbkJLUWxabGFHZ3ljbXRDVVVWSGJGZHVVVFZRTW1aeVJGWnlaa0V4WlhCTVVqaHlXV05GYUhWNlluYzlQVG82QWlEendjMjZRNDQ2R1BtVmJKbVRUem82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-medium.eot https://nodotypefoundry.com/fonts/T1d3d2FYaHlNWGs0ZFZGeGNXbElkVzlyYkhGUlNVVlBjVkozUVhsWWR6SlFOR00zYkVGQlNIWTROelExVGxwNVdVVlZXbEp6YzNoTFpVVXJSMlZ4Y1ZKMlF6RXpaWHBZVmxSM2JHNVZRa0ZwYVRKM04wRTlQVG82MUh0TW5nMG9qZHdhUzNsSmQ4YmZzVG82TWpVME1RPT0=.eot
curl -o ../static/fonts/NTDapper-bold.woff2 https://nodotypefoundry.com/fonts/VHpsUVEyWlRlVmh5TWxsYU56aGxSMHNyVjFac1JYVlpValpvTlZOelFqbFVNRlpqUkhKUk0yaGhVRGRsYVd4VFJIRXlielk0UTNWemJWSmFiVzVEV2xoNGFrdHFXWE5JWmtkR2VVMXlNbkZNWTNSRFFYYzlQVG82ZzNjVW9hTDZpbE56ZGZIQ2l5cHdJem82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-bold.woff https://nodotypefoundry.com/fonts/V0c5elowNDJORWd4WjBkS2VXNVpUVk5HTXpCUUwwVjVWMVJtY1V4TWEwdHVURFZCUVdobVVuQlpPR3BRYzJKYWVVMWxOMlpwTDA4MFlVRkpPRFl4Ykc1UVVsQjJiek5ZV1RCalptbDZTRFZTVURrd1FrRTlQVG82VGNHNzViL1VEOHdYVUU2dG1FdC9SVG82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-bold.eot https://nodotypefoundry.com/fonts/U1VFMlRYSTRhR2xXTlU1SGVESmplSFF4U1cxNGVXbERUV3BQVTJrMU5FczVVa1JGT0ZSdVVFMVVjVXBtTkc1SlQxZ3hiWEpqU1c5cE5VSlFRMVpWWm10ME9FeGlUMmx6VW1WbWFUQnlWblFyV2pSWE1sRTlQVG82c2UvSkEvTmdnQ0lTU3RqZ0MxOE8wRG82TWpVME1RPT0=.eot
curl -o ../static/fonts/NTDapper-black.woff2 https://nodotypefoundry.com/fonts/VG1Vdk5rUnRNSEF2Y1VsTGFuQm9NQzluTTJsWWVVdHplaXRUUW1aYWRHVmpPRTQxU0hNemEzaGlTa05yYWtKaGJWVkdNVWxwUTFCYVJYRmFSMjA0YkZkTFRsQmFRWFI2YW5ad1ptdzVjQzlrZFhaQ1JsRTlQVG82UndqVFIxVmFLUEN0aGQvNDFLVnpqem82TWpVME1RPT0=.woff2
curl -o ../static/fonts/NTDapper-black.woff https://nodotypefoundry.com/fonts/U3pOMVZsSm9VRTk2U2xWelRVWXlWVXhZTkVVemNGSlJWRXhxYkhWNlpVVTNSMlZrY0U0MlluUlBialJaUlZGRFZETXpZWFpFVDFSUFFXSnJZbFF3TW5oemVYUlFOVzFzVXpCS1YzQkNjWGRhWVVSeWJXYzlQVG82czRtQ2pqdmt5VkxWc1U0NzdOeGlWRG82TWpVME1RPT0=.woff
curl -o ../static/fonts/NTDapper-black.eot https://nodotypefoundry.com/fonts/ZFU5NVdXWnVNMGRvYkhGTWFHOXNja2RVUzNoekwyVlFlSFpQUm5SUFIzVnhWMWhMYjBGT05IbDNLMXBsUlVsb09VOVVSMEpxTlRCSk5rcGFWMlZaT0dsTlFsTnRNREJGZHpCa1FtdFhPREZ3VUVkMU9GRTlQVG82eTROSXZ5ZDFXWGxiVkFUYkNmVE9TRG82TWpVME1RPT0=.eot
@@ -0,0 +1,71 @@
const fs = require('fs');
const path = require('path');
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
auth: 'f5e6f805ea497290e162230f0e319ed7fde11cab',
});
const outputPath = path.resolve(__dirname, '..', 'src/assets/data/github.json');
const getRepos = async () => {
const repos = await octokit.repos.listForOrg({
org: 'wbkd',
per_page: 100,
sort: 'created',
});
return repos.data;
};
const getData = async (repos) => {
return Promise.all(
repos.map(async (repo) => {
const stats = await octokit.repos.getCommitActivityStats({
owner: 'wbkd',
repo: repo.name,
});
return {
repo: repo.name,
stats: stats.data,
};
})
);
};
const formatYearlyStats = (stats) => {
return stats.reduce((year, current) => {
return year.concat(current.days);
}, []);
};
const formatData = (data) => {
return data
.reduce((result, repoData) => {
if (repoData.stats) {
result.push(formatYearlyStats(repoData.stats));
}
return result;
}, [])
.filter((values) => values.some((value) => value > 0))
.map((values) =>
values.reduce((result, value, i) => {
if (value > 0) {
result.push([i, value]);
}
return result;
}, [])
)
.map((values) => ({ v: values }));
};
(async () => {
const repos = await getRepos();
const data = await getData(repos);
const outputData = formatData(data);
console.log(outputData);
fs.writeFileSync(outputPath, JSON.stringify(outputData));
})();
+24674
View File
File diff suppressed because it is too large Load Diff
+84
View File
@@ -0,0 +1,84 @@
{
"name": "react-flow-website",
"description": "",
"version": "1.0.0",
"author": "webkid",
"bugs": {
"url": "https://github.com/wbkd/react-flow/issues"
},
"browserslist": [
">0.25%",
"ie 11"
],
"dependencies": {
"@emotion/core": "^10.0.35",
"@emotion/styled": "^10.0.27",
"@mdx-js/mdx": "^1.6.18",
"@mdx-js/react": "^1.6.18",
"@react-hook/size": "^2.1.1",
"@svgr/webpack": "^5.4.0",
"babel-polyfill": "^6.26.0",
"d3-array": "^2.8.0",
"d3-color": "^2.0.0",
"d3-scale": "^3.2.3",
"d3-shape": "^2.0.0",
"emotion-normalize": "^10.1.0",
"emotion-theming": "^10.0.27",
"gatsby": "^2.24.73",
"gatsby-image": "^2.4.21",
"gatsby-plugin-draft": "^0.1.0",
"gatsby-plugin-emotion": "^4.3.13",
"gatsby-plugin-manifest": "^2.4.34",
"gatsby-plugin-mdx": "^1.2.46",
"gatsby-plugin-netlify": "^2.3.17",
"gatsby-plugin-react-helmet": "^3.3.14",
"gatsby-plugin-react-svg": "^3.0.0",
"gatsby-plugin-svgr": "^2.0.2",
"gatsby-remark-copy-linked-files": "^2.3.19",
"gatsby-remark-images": "^3.3.33",
"gatsby-remark-unwrap-images": "^1.0.2",
"gatsby-source-filesystem": "^2.3.34",
"gatsby-transformer-javascript-frontmatter": "^2.3.14",
"gatsby-transformer-json": "^2.4.14",
"gatsby-transformer-remark": "^2.8.38",
"prism-react-renderer": "^1.1.1",
"rc-table": "^7.10.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-flow-renderer": "^6.1.3",
"react-helmet": "^6.1.0",
"reflexbox": "^4.0.6",
"remark-unwrap-images": "^2.0.0"
},
"devDependencies": {
"@octokit/rest": "^18.0.6",
"babel-preset-gatsby": "^0.5.13",
"eslint": "^7.11.0",
"eslint-plugin-react": "^7.21.4",
"gatsby-cli": "^2.12.107",
"gatsby-plugin-sharp": "^2.6.40",
"gatsby-transformer-sharp": "^2.5.17",
"gh-pages": "^3.1.0",
"prettier": "^2.1.2"
},
"homepage": "https://reactflow.dev",
"keywords": [
"gatsby"
],
"license": "MIT",
"main": "n/a",
"repository": {
"type": "git",
"url": "git+https://github.com/wbkd/react-flow.git"
},
"scripts": {
"start": "npm run dev",
"dev": "gatsby develop -H 0.0.0.0",
"lint": "eslint --ext .js,.jsx --ignore-pattern public .",
"test": "echo \"Error: no test specified\" && exit 1",
"format": "prettier --trailing-comma es5 --no-semi --single-quote --write 'src/**/*.js' 'src/**/*.md'",
"build": "GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES=true gatsby build --log-pages",
"deploy": "gatsby build --prefix-paths && gh-pages -d public",
"fix-semi": "eslint --quiet --ignore-pattern node_modules --ignore-pattern public --parser babel-eslint --no-eslintrc --rule '{\"semi\": [2, \"never\"], \"no-extra-semi\": [2]}' --fix gatsby-node.js"
}
}
+57
View File
@@ -0,0 +1,57 @@
[
{
"title": "Overview",
"slug": "examples/",
"source": "Overview"
},
{
"title": "Custom Node",
"slug": "examples/custom-node",
"source": "CustomNode"
},
{
"title": "Edges",
"slug": "examples/edges",
"source": "Edges"
},
{
"title": "Horizontal",
"slug": "examples/horizontal",
"source": "Horizontal"
},
{
"title": "Interaction",
"slug": "examples/interaction",
"source": "Interaction"
},
{
"title": "Provider",
"slug": "examples/provider",
"source": "Provider"
},
{
"title": "Stress",
"slug": "examples/stress",
"source": "Stress"
},
{
"title": "Validation",
"slug": "examples/validation",
"source": "Validation"
},
{
"title": "Custom Connectionline",
"slug": "examples/custom-connectionline",
"source": "CustomConnectionLine"
},
{
"title": "Edge Types",
"slug": "examples/edge-types",
"source": "EdgeTypes"
},
{
"title": "Hidden",
"slug": "examples/hidden",
"source": "Hidden"
}
]
+7
View File
@@ -0,0 +1,7 @@
[
{
"title": "Circles - Visual degree planner",
"url": "https://circles360.github.io/",
"image": "../images/showcases/circles-showcase.png"
}
]
+3
View File
@@ -0,0 +1,3 @@
<svg width="23" height="15" viewBox="0 0 23 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path className="nostroke" fill-rule="evenodd" clip-rule="evenodd" d="M18.4535 6.49989L13.3195 1.73268L14.6805 0.26709L21.6805 6.76709L22.4696 7.49988L21.6805 8.23268L14.6805 14.7327L13.3195 13.2671L18.4535 8.49989L0 8.49988V6.49988L18.4535 6.49989Z" fill="#1A192B"/>
</svg>

After

Width:  |  Height:  |  Size: 371 B

@@ -0,0 +1 @@
<svg height="28" viewBox="0 0 21 21" width="28" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round" transform="translate(3 2)"><circle cx="8.5" cy="8.5" r="8"/><path d="m11.621 6.379v4.242h-4.242" transform="matrix(.70710678 .70710678 .70710678 -.70710678 -3.227683 7.792317)"/><path d="m8.5 4.5v8" transform="matrix(0 1 -1 0 17 0)"/></g></svg>

After

Width:  |  Height:  |  Size: 426 B

+5
View File
@@ -0,0 +1,5 @@
<svg width="54" height="54" viewBox="0 0 54 54" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="21" y="21.4141" width="2" height="16.1754" transform="rotate(-45 21 21.4141)" class="nostroke" fill="white"/>
<rect x="22" y="33" width="2" height="16.1754" transform="rotate(-135 22 33)" class="nostroke" fill="white"/>
<circle cx="27" cy="27" r="26" stroke="white" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 397 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="19" viewBox="0 0 20 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.48265 8.328C4.42132 8.328 4.85865 7.89067 4.79465 7.016L4.63465 4.504C4.61332 4.06667 4.66665 3.67733 4.79465 3.336C4.92265 2.99467 5.11465 2.70667 5.37065 2.472C5.63732 2.22667 5.95199 2.04 6.31465 1.912C6.68799 1.784 7.10399 1.72 7.56265 1.72H8.65065V3.56H7.83465C7.45065 3.56 7.15199 3.65067 6.93865 3.832C6.72532 4.01333 6.62932 4.30133 6.65065 4.696L6.81065 7.208C6.84265 7.80533 6.66665 8.28 6.28265 8.632C5.90932 8.984 5.40799 9.17067 4.77865 9.192V9.272C5.41865 9.29333 5.92532 9.49067 6.29865 9.864C6.67199 10.2267 6.84265 10.7067 6.81065 11.304L6.65065 13.8C6.62932 14.152 6.72532 14.4293 6.93865 14.632C7.16265 14.824 7.46132 14.92 7.83465 14.92H8.65065V16.776H7.56265C7.11465 16.776 6.70399 16.7067 6.33065 16.568C5.95732 16.44 5.63732 16.2533 5.37065 16.008C5.11465 15.7627 4.91732 15.464 4.77865 15.112C4.65065 14.76 4.60265 14.3653 4.63465 13.928L4.79465 11.496C4.82665 11.0587 4.73599 10.728 4.52265 10.504C4.31999 10.28 3.97332 10.168 3.48265 10.168H1.57865V8.328H3.48265ZM11.4036 16.776V14.92H12.2196C12.6036 14.92 12.9023 14.8293 13.1156 14.648C13.3396 14.4667 13.4409 14.184 13.4196 13.8L13.2596 11.288C13.2169 10.6907 13.3823 10.216 13.7556 9.864C14.1396 9.512 14.6463 9.32533 15.2756 9.304V9.224C14.6356 9.20267 14.1289 9.01067 13.7556 8.648C13.3823 8.27467 13.2169 7.78933 13.2596 7.192L13.4196 4.696C13.4409 4.33333 13.3396 4.056 13.1156 3.864C12.8916 3.66133 12.5929 3.56 12.2196 3.56H11.4036V1.72H12.5076C12.9556 1.72 13.3609 1.78933 13.7236 1.928C14.0969 2.056 14.4116 2.24267 14.6676 2.488C14.9343 2.73333 15.1316 3.032 15.2596 3.384C15.3983 3.72533 15.4516 4.11467 15.4196 4.552L15.2596 7C15.2276 7.43733 15.3129 7.768 15.5156 7.992C15.7289 8.20533 16.0809 8.312 16.5716 8.312H18.4756V10.152H16.5716C15.6329 10.152 15.1956 10.5947 15.2596 11.48L15.4196 13.976C15.4409 14.4027 15.3876 14.7867 15.2596 15.128C15.1316 15.48 14.9396 15.7787 14.6836 16.024C14.4276 16.2693 14.1129 16.456 13.7396 16.584C13.3663 16.712 12.9556 16.776 12.5076 16.776H11.4036Z" fill="white" class="nostroke" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

+5
View File
@@ -0,0 +1,5 @@
<svg width="30" height="20" viewBox="0 0 30 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="14.5158" cy="10.0006" r="5.38829" stroke="white" stroke-width="1.48148"/>
<path d="M27.0214 8.5334C27.7216 9.40104 27.7216 10.599 27.0214 11.4666C25.8703 12.8929 24.0857 14.8567 21.8995 16.4583C19.7074 18.0644 17.1761 19.2593 14.5161 19.2593C11.8561 19.2593 9.32487 18.0644 7.13272 16.4583C4.9466 14.8567 3.16191 12.8929 2.01087 11.4666C1.31069 10.599 1.31069 9.40104 2.01087 8.5334C3.16191 7.10708 4.9466 5.1433 7.13272 3.54168C9.32487 1.93565 11.8561 0.740741 14.5161 0.740741C17.1761 0.740741 19.7074 1.93565 21.8995 3.54168C24.0857 5.1433 25.8703 7.10708 27.0214 8.5334Z" stroke="white" stroke-width="1.48148"/>
<circle cx="14.4447" cy="9.99999" r="3.33333" fill="white" class="nostroke" />
</svg>

After

Width:  |  Height:  |  Size: 810 B

@@ -0,0 +1,9 @@
<svg width="342" height="342" viewBox="0 0 342 342" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="path-1-outside-1" maskUnits="userSpaceOnUse" x="6" y="40" width="330" height="271" fill="black">
<rect fill="white" x="6" y="40" width="330" height="271"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 48L123.5 290L171 180L218.5 290L323 48H228L114 48H19Z"/>
</mask>
<path d="M123.5 290L116.155 293.171L123.5 310.18L130.844 293.171L123.5 290ZM19 48V40H6.83145L11.6555 51.1715L19 48ZM171 180L178.344 176.829L171 159.82L163.655 176.829L171 180ZM218.5 290L211.155 293.171L218.5 310.18L225.844 293.171L218.5 290ZM323 48L330.345 51.1715L335.169 40H323V48ZM228 48L228 56H228V48ZM114 48L114 40H114V48ZM130.844 286.828L26.3445 44.8285L11.6555 51.1715L116.155 293.171L130.844 286.828ZM163.655 176.829L116.155 286.828L130.844 293.171L178.344 183.171L163.655 176.829ZM225.844 286.828L178.344 176.829L163.655 183.171L211.155 293.171L225.844 286.828ZM315.656 44.8285L211.155 286.828L225.844 293.171L330.345 51.1715L315.656 44.8285ZM228 56H323V40H228V56ZM114 56L228 56L228 40L114 40L114 56ZM19 56H114V40H19V56Z" fill="white" mask="url(#path-1-outside-1)"/>
<path d="M123.5 290L19 48L228 48L123.5 290Z" fill="#C5CBD2"/>
<path d="M218.5 290L114 48L323 48L218.5 290Z" fill="#1A192B"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="nostroke" d="M18.6586 5.10534C17.7643 3.53477 16.5514 2.29135 15.0194 1.37479C13.4871 0.458185 11.8144 0 9.99991 0C8.18569 0 6.51238 0.458325 4.98046 1.37479C3.4483 2.2913 2.23539 3.53477 1.34116 5.10534C0.447068 6.67587 0 8.39089 0 10.2504C0 12.484 0.635737 14.4926 1.90753 16.2766C3.17919 18.0607 4.82198 19.2952 6.83577 19.9803C7.07018 20.0249 7.24371 19.9936 7.35654 19.887C7.46941 19.7804 7.52578 19.6467 7.52578 19.4868C7.52578 19.4601 7.52354 19.2199 7.51921 18.766C7.51474 18.3122 7.51264 17.9162 7.51264 17.5783L7.21315 17.6315C7.0222 17.6673 6.78132 17.6825 6.49049 17.6782C6.19981 17.674 5.89804 17.6428 5.58559 17.5847C5.27302 17.5272 4.98228 17.3937 4.71317 17.1846C4.44419 16.9755 4.25324 16.7018 4.14036 16.3639L4.01016 16.0568C3.92337 15.8523 3.78674 15.6251 3.60008 15.3761C3.41342 15.1269 3.22466 14.958 3.03371 14.869L2.94254 14.8021C2.8818 14.7577 2.82543 14.704 2.7733 14.6418C2.72122 14.5796 2.68223 14.5173 2.65619 14.455C2.6301 14.3926 2.65172 14.3414 2.72127 14.3012C2.79081 14.261 2.9165 14.2416 3.09888 14.2416L3.35919 14.2814C3.53281 14.3171 3.74757 14.4236 4.00373 14.6017C4.25976 14.7796 4.47023 15.0109 4.63518 15.2956C4.83493 15.6605 5.07559 15.9385 5.35784 16.1299C5.63986 16.3212 5.92421 16.4167 6.21061 16.4167C6.49702 16.4167 6.74438 16.3945 6.95279 16.3502C7.16098 16.3057 7.35631 16.2388 7.53868 16.1499C7.61681 15.5535 7.82951 15.0953 8.17661 14.775C7.68189 14.7217 7.2371 14.6414 6.84202 14.5347C6.44717 14.4278 6.03914 14.2544 5.6182 14.0139C5.19704 13.7738 4.84766 13.4756 4.56997 13.1198C4.29223 12.7639 4.06429 12.2966 3.88648 11.7183C3.70857 11.1399 3.6196 10.4726 3.6196 9.71627C3.6196 8.63941 3.96255 7.72304 4.64832 6.96665C4.32707 6.15705 4.3574 5.24947 4.73939 4.244C4.99113 4.16382 5.36445 4.22399 5.85918 4.42412C6.354 4.62434 6.71628 4.79587 6.94641 4.93808C7.17653 5.08024 7.36092 5.20071 7.49983 5.29842C8.30727 5.06715 9.14052 4.95149 9.99982 4.95149C10.8591 4.95149 11.6925 5.06715 12.5 5.29842L12.9948 4.97823C13.3332 4.76459 13.7327 4.56881 14.1925 4.39083C14.6526 4.21295 15.0044 4.16396 15.2475 4.24414C15.638 5.24966 15.6728 6.15719 15.3515 6.96679C16.0372 7.72318 16.3803 8.63978 16.3803 9.71641C16.3803 10.4727 16.291 11.1421 16.1133 11.725C15.9355 12.308 15.7056 12.7749 15.4236 13.1265C15.1412 13.4781 14.7896 13.774 14.3687 14.0141C13.9476 14.2544 13.5395 14.4278 13.1446 14.5347C12.7496 14.6415 12.3048 14.7219 11.8101 14.7752C12.2613 15.1755 12.4869 15.8073 12.4869 16.6704V19.4864C12.4869 19.6464 12.5412 19.7799 12.6498 19.8867C12.7583 19.9932 12.9297 20.0246 13.1641 19.9799C15.1782 19.2949 16.8209 18.0603 18.0926 16.2762C19.364 14.4922 20 12.4837 20 10.25C19.9995 8.39075 19.5522 6.67587 18.6586 5.10534Z" fill="#F8F9F9"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

+1
View File
@@ -0,0 +1 @@
<svg height="28" viewBox="0 0 21 21" width="28" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round" transform="translate(3 3)"><path d="m.5.5v12c0 1.1045695.8954305 2 2 2h11.5"/><path d="m3.5 8.5v3"/><path d="m7.5 5.5v6"/><path d="m11.5 2.5v9"/></g></svg>

After

Width:  |  Height:  |  Size: 337 B

+7
View File
@@ -0,0 +1,7 @@
<svg height="28" viewBox="0 0 21 21" width="28" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<circle cx="10.5" cy="10.5" r="8" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round"/>
<path d="m10.5 14.5v-4" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="10.5" cy="7.5" fill="#2a2e3b" r="1" class="nostroke" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 405 B

+1
View File
@@ -0,0 +1 @@
<svg height="28" viewBox="0 0 21 21" width="28" xmlns="http://www.w3.org/2000/svg"><path d="m6.5 7.5h4l-6 9v-6.997l-4-.003 6-9z" fill="none" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round" transform="translate(5 2)"/></svg>

After

Width:  |  Height:  |  Size: 239 B

+1
View File
@@ -0,0 +1 @@
<svg height="28" viewBox="0 0 21 21" width="28" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round" transform="translate(3 4)"><path d="m4.17157288 4.87867966v-1.41421357c0-1.56209716 1.26632995-2.82842712 2.82842712-2.82842712s2.82842712 1.26632996 2.82842712 2.82842712v1.41421357m0 2.82842712v2.82842712c0 1.5620972-1.26632995 2.8284271-2.82842712 2.8284271s-2.82842712-1.2663299-2.82842712-2.8284271v-2.82842712" transform="matrix(.70710678 .70710678 -.70710678 .70710678 7 -2.899495)"/><path d="m4.5 9.5 5-5"/></g></svg>

After

Width:  |  Height:  |  Size: 607 B

+1
View File
@@ -0,0 +1 @@
<svg height="28" viewBox="0 0 21 21" width="28" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#2a2e3b" stroke-linecap="round" stroke-linejoin="round" transform="matrix(0 -1 1 0 2.5 16.5)"><path d="m2 .5h8c1.1045695 0 2 .8954305 2 2v10c0 1.1045695-.8954305 2-2 2h-8c-1.1045695 0-2-.8954305-2-2v-10c0-1.1045695.8954305-2 2-2z"/><path d="m2 6 5 3 5-3" transform="matrix(0 1 -1 0 14.5 .5)"/></g></svg>

After

Width:  |  Height:  |  Size: 429 B

+12
View File
@@ -0,0 +1,12 @@
<svg width="32" height="20" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<rect y="2" width="2" height="32" transform="rotate(-90 0 2)" fill="white" class="nostroke"/>
<rect y="13" width="2" height="32" transform="rotate(-90 0 13)" fill="white" class="nostroke"/>
<rect y="24" width="2" height="32" transform="rotate(-90 0 24)" fill="white" class="nostroke"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="32" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 515 B

+1
View File
@@ -0,0 +1 @@
<svg fill="currentColor" height="40px" width="40px" preserveAspectRatio="xMidYMid meet" viewBox="0 0 40 40" style="margin-right: 0.3em; vertical-align: sub;"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>

After

Width:  |  Height:  |  Size: 329 B

+11
View File
@@ -0,0 +1,11 @@
<svg width="28" height="28" viewBox="0 0 22 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="6.21875" y="0.5" width="9.62081" height="15.3397" rx="1.13397" stroke="#F8F9F9"/>
<mask id="path-2-inside-1" fill="white">
<rect x="8.16992" width="5.7189" height="2.45096" rx="0.816985"/>
</mask>
<rect class="nostroke" x="8.16992" width="5.7189" height="2.45096" rx="0.816985" stroke="#F8F9F9" stroke-width="2" mask="url(#path-2-inside-1)"/>
<path d="M3.89531 10.0226C3.70565 9.83295 3.5552 9.60779 3.45256 9.35999C3.34991 9.11218 3.29708 8.84659 3.29708 8.57837C3.29708 8.31015 3.34991 8.04455 3.45256 7.79675C3.5552 7.54895 3.70565 7.32379 3.89531 7.13413L4.34941 7.58823C4.21938 7.71826 4.11624 7.87262 4.04587 8.04251C3.9755 8.2124 3.93928 8.39448 3.93928 8.57837C3.93928 8.76225 3.9755 8.94434 4.04587 9.11423C4.11624 9.28412 4.21938 9.43848 4.34941 9.56851L3.89531 10.0226Z" class="nostroke" fill="#F8F9F9"/>
<path d="M18.1047 7.13413C18.2944 7.32379 18.4448 7.54895 18.5474 7.79675C18.6501 8.04456 18.7029 8.31015 18.7029 8.57837C18.7029 8.84659 18.6501 9.11218 18.5474 9.35999C18.4448 9.60779 18.2944 9.83295 18.1047 10.0226L17.6506 9.56851C17.7806 9.43848 17.8838 9.28412 17.9541 9.11423C18.0245 8.94434 18.0607 8.76225 18.0607 8.57837C18.0607 8.39448 18.0245 8.2124 17.9541 8.04251C17.8838 7.87262 17.7806 7.71826 17.6506 7.58823L18.1047 7.13413Z" class="nostroke" fill="#F8F9F9"/>
<path d="M2.84487 11.4232C2.47128 11.0496 2.17493 10.6061 1.97274 10.118C1.77056 9.62987 1.66649 9.1067 1.66649 8.57837C1.66649 8.05003 1.77056 7.52687 1.97274 7.03875C2.17493 6.55063 2.47128 6.10712 2.84487 5.73353L3.30299 6.19165C2.98956 6.50508 2.74094 6.87717 2.57131 7.28669C2.40169 7.6962 2.31438 8.13511 2.31438 8.57837C2.31438 9.02162 2.40169 9.46054 2.57131 9.87005C2.74094 10.2796 2.98956 10.6517 3.30299 10.9651L2.84487 11.4232Z" class="nostroke" fill="#F8F9F9"/>
<path d="M19.1546 5.73353C19.5282 6.10712 19.8246 6.55063 20.0268 7.03875C20.229 7.52687 20.333 8.05003 20.333 8.57837C20.333 9.10671 20.229 9.62987 20.0268 10.118C19.8246 10.6061 19.5282 11.0496 19.1546 11.4232L18.6965 10.9651C19.0099 10.6517 19.2586 10.2796 19.4282 9.87005C19.5978 9.46054 19.6851 9.02162 19.6851 8.57837C19.6851 8.13511 19.5978 7.6962 19.4282 7.28669C19.2586 6.87717 19.0099 6.50508 18.6965 6.19165L19.1546 5.73353Z" class="nostroke" fill="#F8F9F9"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="nostroke" d="M10 20C15.5224 20 20 15.5224 20 10C20 4.47755 15.5224 0 10 0C4.47755 0 0 4.47755 0 10C0 15.5224 4.47755 20 10 20ZM7.06122 7.43878C8.98367 8.4102 10.6082 8.35306 10.6082 8.35306C10.6082 8.35306 9.99184 6.20612 11.8959 5.2551C13.8 4.30408 15.1102 5.90816 15.1102 5.90816C15.1102 5.90816 15.4429 5.81633 15.6898 5.72653C15.9367 5.63469 16.2959 5.47347 16.2959 5.47347L15.7102 6.52041L16.6143 6.42449C16.6143 6.42449 16.502 6.58775 16.1408 6.91837C15.7796 7.24898 15.6306 7.42041 15.6306 7.42041C15.6306 7.42041 15.7592 10.0041 14.398 11.9939C13.0367 13.9837 11.2776 15.1776 8.72245 15.4286C6.16735 15.6796 4.50408 14.6449 4.50408 14.6449C4.50408 14.6449 5.62041 14.5816 6.33265 14.3082C7.0449 14.0367 8.06939 13.3184 8.06939 13.3184C8.06939 13.3184 6.61429 12.8694 6.0898 12.3673C5.56735 11.8633 5.43673 11.5653 5.43673 11.5653L6.87347 11.5469C6.87347 11.5469 5.36122 10.7449 4.93265 10.1102C4.50408 9.47551 4.44694 8.85918 4.44694 8.85918L5.55102 9.30612C5.55102 9.30612 4.63265 8.05714 4.50204 7.08571C4.37143 6.11429 4.66939 5.59184 4.66939 5.59184C4.66939 5.59184 5.13878 6.46735 7.06122 7.43878Z" fill="#F8F9F9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 24 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 3.95833C21.4055 4.25085 21.4054 4.25096 21.4053 4.25107L21.4052 4.2513L21.4048 4.25178L21.4041 4.25279L21.4025 4.25504L21.3984 4.26043L21.3875 4.27484C21.3788 4.28605 21.3673 4.3005 21.3526 4.3182C21.3233 4.35358 21.2813 4.40201 21.2237 4.46358C21.1086 4.58667 20.9308 4.76278 20.6671 4.99275C20.4214 5.20711 20.2499 5.36805 20.1416 5.47352C20.1377 5.47735 20.1338 5.4811 20.1301 5.48478C20.1306 5.5866 20.1294 5.72037 20.1237 5.88107C20.1102 6.26173 20.0716 6.79576 19.9713 7.41567C19.7716 8.64957 19.322 10.2554 18.3096 11.6658C16.3297 14.424 13.7448 16.0968 10.0203 16.4455C8.16106 16.6196 6.62325 16.3481 5.54671 16.0309C5.00842 15.8723 4.58465 15.7021 4.29244 15.5697C4.14627 15.5035 4.03284 15.4467 3.95425 15.4055C3.91495 15.3848 3.88435 15.3681 3.8627 15.356L3.83697 15.3414L3.8292 15.3369L3.82659 15.3353L3.82561 15.3348L3.82521 15.3345C3.82502 15.3344 3.82485 15.3343 4.07984 14.9042L3.82485 15.3343L2.40719 14.4938L4.05275 14.405L4.05277 14.405L4.05279 14.405L4.05287 14.4049L4.05322 14.4049L4.0558 14.4048L4.0674 14.4041L4.11508 14.401C4.15723 14.3982 4.21932 14.3937 4.29724 14.3871C4.45332 14.374 4.67174 14.3528 4.9199 14.3207C5.42536 14.2553 6.01914 14.1487 6.46287 13.9863L6.464 13.9859C6.89448 13.8295 7.43562 13.5412 7.89953 13.2703C7.85761 13.2545 7.81506 13.2382 7.77205 13.2215C7.17842 12.9909 6.40256 12.6461 5.9584 12.2409L5.95694 12.2396C5.5711 11.8848 5.3218 11.5951 5.16494 11.3852C5.08652 11.2803 5.03129 11.1955 4.99372 11.1327C4.97494 11.1013 4.96059 11.0754 4.94997 11.0553C4.94466 11.0452 4.94029 11.0366 4.93677 11.0295L4.93212 11.0199L4.93025 11.0159L4.92942 11.0141L4.92904 11.0133L4.92885 11.0129C4.92876 11.0127 4.92867 11.0125 5.38293 10.8036L4.92867 11.0125L4.60692 10.313L5.37683 10.3036L5.58523 10.3011C5.40249 10.1789 5.21981 10.0495 5.04849 9.91658C4.75412 9.68824 4.46335 9.42707 4.27066 9.1551C3.9336 8.67939 3.74314 8.21163 3.63652 7.8621C3.58306 7.68685 3.55016 7.53962 3.53034 7.4335C3.52041 7.38038 3.51373 7.33737 3.50937 7.30608C3.50719 7.29042 3.5056 7.27768 3.50446 7.26805L3.5031 7.25595L3.50265 7.2517L3.50248 7.25002L3.50241 7.2493L3.50238 7.24897C3.50236 7.24881 3.50235 7.24866 4 7.20024L3.50235 7.24866L3.42388 6.44206L4.17997 6.73376L4.28567 6.77453C3.98088 6.22476 3.67168 5.54509 3.58189 4.90863C3.48133 4.19582 3.54424 3.63487 3.63951 3.24146C3.68699 3.04536 3.74219 2.89216 3.78819 2.78354C3.81118 2.72924 3.83188 2.68608 3.84816 2.65425C3.85631 2.63834 3.86335 2.62525 3.86904 2.61501L3.87651 2.60179L3.87943 2.59679L3.88067 2.59469L3.88123 2.59374L3.8815 2.59329C3.88163 2.59307 3.88176 2.59286 4.3108 2.84961L3.88176 2.59286L4.32416 1.85357L4.74423 2.60027C4.74429 2.60038 4.74436 2.60049 4.74443 2.6006C4.74637 2.60375 4.75108 2.61125 4.7589 2.62285C4.77452 2.64605 4.80263 2.68573 4.8459 2.7399C4.93239 2.84817 5.07993 3.01486 5.31034 3.2238C5.77094 3.64147 6.56536 4.23034 7.86957 4.85841C9.16 5.47985 10.3503 5.77208 11.2158 5.9088C11.524 5.95749 11.7905 5.98635 12.0047 6.00336C11.9711 5.6978 11.9568 5.30368 12.0148 4.87208C12.1495 3.8695 12.6784 2.67058 14.1927 1.94976C15.6848 1.23952 16.9676 1.48277 17.8654 1.90958C18.3085 2.12025 18.6564 2.37417 18.894 2.57523C18.9512 2.62369 19.0024 2.66935 19.0472 2.71094C19.201 2.66688 19.3873 2.61096 19.5429 2.55711C19.7035 2.50012 19.9055 2.41987 20.0718 2.35183C20.1544 2.31809 20.2264 2.28806 20.2777 2.2665L20.3376 2.24118L20.3535 2.23446L20.3574 2.23278L20.3583 2.23238L20.3585 2.2323L20.3585 2.23229L21 3.95833ZM21 3.95833L21.4055 4.25085L22.0561 3.34899L20.9497 3.46086L20.6668 3.48946M21 3.95833L20.6668 3.48946M20.6668 3.48946L20.9864 2.94512L21.7557 1.63462L20.3585 2.23228L20.6668 3.48946Z" stroke="#F8F9F9"/>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

+18
View File
@@ -0,0 +1,18 @@
<svg width="600" height="128" viewBox="0 0 600 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M55.1521 128L1.88195e-05 -9.6431e-06L110.304 0L55.1521 128Z" fill="#C5CBD2"/>
<path d="M105.152 128L50 -9.6431e-06L160.304 0L105.152 128Z" fill="#F8F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M321.911 0H448.853L321.911 106.517V0Z" fill="#C5CBD2"/>
<rect x="175" width="89.6584" height="128" fill="#F8F9F9"/>
<rect x="472.82" width="67.4658" height="128" fill="#F8F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M264.215 51.021C278.187 51.021 289.514 39.5995 289.514 25.5105C289.514 11.4214 278.187 0 264.215 0C250.242 0 238.915 11.4214 238.915 25.5105C238.915 39.5995 250.242 51.021 264.215 51.021Z" fill="#F8F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M263.771 127.999C284.852 127.999 301.942 110.767 301.942 89.5095C301.942 68.2524 284.852 51.02 263.771 51.02C242.689 51.02 225.599 68.2524 225.599 89.5095C225.599 110.767 242.689 127.999 263.771 127.999Z" fill="#F8F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M536.291 128C571.346 128 599.762 99.3462 599.762 64C599.762 28.6538 571.346 0 536.291 0C501.237 0 472.82 28.6538 472.82 64C472.82 99.3462 501.237 128 536.291 128Z" fill="#F8F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M321.911 0L448.853 128H321.911V0Z" fill="#F8F9F9"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="600" height="128" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+18
View File
@@ -0,0 +1,18 @@
<svg width="600" height="128" viewBox="0 0 600 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M55.1521 128L1.88195e-05 -9.6431e-06L110.304 0L55.1521 128Z" fill="#53606C"/>
<path d="M105.152 128L50 -9.6431e-06L160.304 0L105.152 128Z" fill="#1A192B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M321.911 0H448.853L321.911 106.517V0Z" fill="#53606C"/>
<rect x="175" width="89.6584" height="128" fill="#1A192B"/>
<rect x="472.82" width="67.4658" height="128" fill="#1A192B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M264.215 51.021C278.187 51.021 289.514 39.5995 289.514 25.5105C289.514 11.4214 278.187 0 264.215 0C250.242 0 238.915 11.4214 238.915 25.5105C238.915 39.5995 250.242 51.021 264.215 51.021Z" fill="#1A192B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M263.771 127.999C284.852 127.999 301.942 110.767 301.942 89.5095C301.942 68.2524 284.852 51.02 263.771 51.02C242.689 51.02 225.599 68.2524 225.599 89.5095C225.599 110.767 242.689 127.999 263.771 127.999Z" fill="#1A192B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M536.291 128C571.346 128 599.762 99.3462 599.762 64C599.762 28.6538 571.346 0 536.291 0C501.237 0 472.82 28.6538 472.82 64C472.82 99.3462 501.237 128 536.291 128Z" fill="#1A192B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M321.911 0L448.853 128H321.911V0Z" fill="#1A192B"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="600" height="128" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,22 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" fill="white"/>
<rect x="23" y="23" width="14" height="14" rx="2" fill="white" stroke="#1A192B" stroke-width="2"/>
<rect x="23" y="3" width="14" height="14" rx="2" fill="white" stroke="#FF0072" stroke-width="2"/>
<rect x="3" y="23" width="14" height="14" rx="2" fill="white" stroke="#1A192B" stroke-width="2"/>
<rect x="3" y="3" width="14" height="14" rx="2" fill="white" stroke="#1A192B" stroke-width="2"/>
<circle cx="17" cy="10" r="3" fill="white"/>
<circle cx="23" cy="10" r="3" fill="white"/>
<circle cx="30" cy="17" r="3" fill="white"/>
<circle cx="30" cy="23" r="3" fill="white"/>
<circle cx="17" cy="30" r="3" fill="white"/>
<circle cx="23" cy="30" r="3" fill="white"/>
<circle cx="30" cy="23" r="2" fill="#1A192B"/>
<circle cx="17" cy="30" r="2" fill="#1A192B"/>
<circle cx="23" cy="30" r="2" fill="#1A192B"/>
<rect opacity="0.35" x="18" y="9.5" width="4" height="1" fill="#1A192B"/>
<rect opacity="0.35" x="29.5" y="21.5" width="4" height="1" transform="rotate(-90 29.5 21.5)" fill="#1A192B"/>
<rect opacity="0.35" x="18" y="29.5" width="4" height="1" fill="#1A192B"/>
<circle cx="17" cy="10" r="2" fill="#1A192B"/>
<circle cx="23" cy="10" r="2" fill="#FF0072"/>
<circle cx="30" cy="17" r="2" fill="#FF0072"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

+88
View File
@@ -0,0 +1,88 @@
import React from 'react';
import styled from '@emotion/styled';
import { rgba } from 'utils/css-utils';
import { Flex } from 'reflexbox';
import Icon from 'components/Icon';
import { getThemeColor } from 'utils/css-utils';
const Button = styled.button`
color: ${(p) => p.theme.colors[p.color || 'button']};
border: ${(p) =>
p.type === 'ghost'
? '1px solid rgba(0,0,0,0)'
: `1px solid ${p.theme.colors[p.color || 'button']}`};
background: ${(p) =>
p.active
? rgba(p.color ? p.theme.colors[p.color] : p.theme.colors.button, 0.2)
: 'none'};
padding: ${(p) => (p.type === 'big' ? '12px 20px' : '8px 16px')};
border-radius: 25px;
outline: none;
cursor: pointer;
font-size: ${(p) => p.theme.fontSizesPx[1]};
letter-spacing: 0.5px;
line-height: 1;
transition: 0.075s all ease-in-out;
svg {
width: 100%;
}
&:visited,
&:focus,
&:active {
color: ${(p) => p.theme.colors[p.color || 'button']};
}
&:hover {
opacity: 1;
color: ${getThemeColor('background')};
background-color: ${getThemeColor('button')};
svg {
path,
circle,
rect,
line,
polyline {
stroke: ${getThemeColor('background')};
}
}
svg {
.nostroke {
stroke: none;
fill: ${getThemeColor('background')};
}
}
}
&:active {
transform: scale(0.95);
}
`;
export default ({
icon,
color = 'button',
children,
type = 'normal',
iconWidth = '20px',
...props
}) => (
<Button color={color} type={type} {...props}>
<Flex alignItems="center" justifyContent="center">
{icon && (
<Icon
strokeColor={color}
name={icon}
colorizeStroke
width={iconWidth}
mr={1}
/>
)}
{children}
</Flex>
</Button>
);
@@ -0,0 +1,13 @@
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { getThemeSpacePx } from 'utils/css-utils';
export default styled(Box)`
max-width: ${(p) =>
p.maxWidth || (p.big ? p.theme.maxWidthBig : p.theme.maxWidth)};
margin-left: auto;
margin-right: auto;
padding-left: ${getThemeSpacePx(3)};
padding-right: ${getThemeSpacePx(3)};
`;
+23
View File
@@ -0,0 +1,23 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex } from 'reflexbox';
import { getThemeSpacePx } from 'utils/css-utils';
import Icon from 'components/Icon';
const Close = styled(Flex)`
padding: ${getThemeSpacePx(1)};
line-height: 1;
width: 50px;
height: 50px;
`;
export default ({ onClick, ...props }) => {
return (
<Flex pb={4} alignItems="center" justifyContent="center" {...props}>
<Close alignItems="center" justifyContent="center" onClick={onClick}>
<Icon name="close" strokeColor="text" colorizeStroke />
</Close>
</Flex>
);
};
+45
View File
@@ -0,0 +1,45 @@
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: 16,
borderRadius: 4,
margin: '20px 0 20px 0',
fontSize: 14,
}}
>
{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>
);
};
+41
View File
@@ -0,0 +1,41 @@
import React from 'react';
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { colors } from 'themes';
import CodeBlock from './Mdx';
import { H4, AttributionText } from 'components/Typo';
const Wrapper = styled(Box)`
margin: 0 auto;
padding: 5px 0;
h4 {
margin-bottom: 10px;
}
pre {
margin: 0;
font-size: 14px;
}
code {
border: 1px solid ${colors.lightGrey};
border-radius: 3px;
}
`;
export default ({
language = 'javascript',
code,
title = '',
subtitle = '',
}) => {
return (
<Wrapper>
{title && <H4>{title}</H4>}
<CodeBlock language={language}>{code}</CodeBlock>
{subtitle && <AttributionText>{subtitle}</AttributionText>}
</Wrapper>
);
};
@@ -0,0 +1,22 @@
import React, { Fragment } from 'react';
import { Box } from 'reflexbox';
import CenterContent from 'components/CenterContent';
export default ({
children,
bg = 'transparent',
centered = false,
id = null,
big = false,
...rest
}) => {
const WrapperComponent = centered ? CenterContent : Fragment;
const wrapperProps = centered ? { big: big } : {};
return (
<Box id={id} bg={bg} py={[6, 7]} {...rest}>
<WrapperComponent {...wrapperProps}>{children}</WrapperComponent>
</Box>
);
};
+48
View File
@@ -0,0 +1,48 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex } from 'reflexbox';
import Icon from 'components/Icon';
import Logo from 'components/Logo';
const Wrapper = styled.footer`
flex-shrink: 0;
border-top: ${(p) =>
p.hasBorder ? `1px solid ${p.theme.colors.silverLighten30}` : 'nonde'};
`;
const Header = ({ hasBorder = false }) => {
return (
<Wrapper hasBorder={hasBorder}>
<Flex p={4}>
<Flex alignItems="center">
A project by
<a href="https://webkid.io" style={{ marginLeft: 8 }}>
<Logo />
</a>
</Flex>
<Flex ml="auto">
<Icon
as="a"
href="https://github.com/wbkd"
name="github_circle"
colorizeStroke
strokeColor="text"
style={{ marginRight: 8 }}
width="24px"
/>
<Icon
as="a"
href="https://twitter.com/webk1d"
name="twitter_circle"
colorizeStroke
strokeColor="text"
width="24px"
/>
</Flex>
</Flex>
</Wrapper>
);
};
export default Header;
+240
View File
@@ -0,0 +1,240 @@
import React, { useState } from 'react';
import { Link } from 'gatsby';
import styled from '@emotion/styled';
import { Flex, Box } from 'reflexbox';
import Icon from 'components/Icon';
import Button from 'components/Button';
import Close from 'components/Close';
import { getThemeColor, getThemeSpacePx, device, px } from 'utils/css-utils';
import useMenuHeight from 'hooks/useMenuHeight';
import ReactFlowLogo from 'assets/images/react-flow-logo.svg';
const Centered = styled(Flex)`
justify-content: space-between;
align-items: center;
padding: 24px 16px;
`;
const Wrapper = styled.nav`
flex-shrink: 0;
`;
const NavWrapper = styled(Box)`
position: absolute;
display: ${(p) => (p.menuOpen ? 'flex' : 'none')};
height: ${(p) => px(p.height)};
top: 0;
left: 0;
width: 100%;
padding: ${getThemeSpacePx(3)};
z-index: 500;
background: ${getThemeColor('background')};
align-items: center;
flex-direction: column;
.desktop {
display: none;
}
@media ${device.tablet} {
display: block;
height: auto;
position: relative;
padding: 0;
margin-left: auto;
width: auto;
background: transparent;
align-items: unset;
flex-direction: row;
.desktop {
display: inline-block;
}
.mobile {
display: none;
}
}
`;
const Nav = styled.div`
flex-grow: 1;
display: flex;
align-items: center;
`;
const NavInner = styled.div`
line-height: 1;
width: 100%;
@media ${device.tablet} {
display: flex;
align-items: center;
flex-direction: row;
width: auto;
}
`;
const NavItem = styled(Link)`
text-decoration: none;
font-size: 30px;
display: block;
padding: ${(p) => (p.isButton ? '8px 16px' : '16px 0')};
text-align: center;
color: ${getThemeColor('textLight')};
&:focus,
&:visited,
&:active {
color: ${getThemeColor('textLight')};
}
&.active {
color: ${getThemeColor('text')};
}
@media ${device.tablet} {
margin-left: 50px;
font-size: 16px;
display: inline-block;
padding: ${(p) => (p.isButton ? '8px 16px' : 0)};
color: ${getThemeColor('textLight')};
&:focus,
&:visited {
color: ${getThemeColor('textLight')};
}
&.active,
&:hover {
color: ${getThemeColor('text')};
}
}
`;
const GithubButton = styled.a`
font-size: 30px;
display: block;
padding: ${(p) => (p.isButton ? '12px 24px' : '16px 0')} !important;
text-align: center;
color: ${getThemeColor('textLight')};
&:focus,
&:visited,
&:active {
color: ${getThemeColor('textLight')};
}
@media ${device.tablet} {
margin-left: 50px;
font-size: 16px;
display: inline-block;
background: ${(p) => p.theme.colors.textDark};
&&& {
&:hover {
background: ${getThemeColor('red')};
}
}
}
`;
const NavButton = styled.div`
cursor: pointer;
@media ${device.tablet} {
display: none;
}
`;
const Image = styled.img`
display: block;
width: 40px;
margin-right: 12px;
`;
const LogoTitle = styled(Box)`
font-weight: 900;
font-size: 24px;
letter-spacing: 0.5px;
line-height: 1.2;
color: ${getThemeColor('violet')};
`;
const LogoSubtitle = styled(Box)`
font-size: 12px;
letter-spacing: 0.5px;
color: ${getThemeColor('silverDarken30')};
line-height: 1.2;
`;
const Header = () => {
const [menuOpen, setMenuOpen] = useState(false);
const menuHeight = useMenuHeight();
const toggleMenu = () => {
const nextMenuOpen = !menuOpen;
document.body.classList.toggle('noscroll', nextMenuOpen);
setMenuOpen(nextMenuOpen);
};
return (
<Wrapper>
<Centered>
<Flex as={Link} to="/">
<Image src={ReactFlowLogo} alt="React Flow Logo" />
<Box>
<LogoTitle>React Flow</LogoTitle>
<LogoSubtitle>an open source library by webkid.io</LogoSubtitle>
</Box>
</Flex>
<NavButton onClick={toggleMenu}>
<Icon name="menu" strokeColor="text" colorizeStroke />
</NavButton>
<NavWrapper menuOpen={menuOpen} height={menuHeight}>
<Nav>
<NavInner>
<NavItem to="/" activeClassName="active" className="mobile">
Home
</NavItem>
<NavItem to="/docs/" activeClassName="active" partiallyActive>
Docs
</NavItem>
<NavItem to="/examples/" activeClassName="active" partiallyActive>
Examples
</NavItem>
<Button
as={GithubButton}
href="https://github.com/wbkd/react-flow"
activeClassName="active"
icon="github_circle"
className="desktop"
isButton
color="textInverted"
>
Github
</Button>
<GithubButton
href="https://github.com/wbkd/react-flow"
activeClassName="active"
className="mobile"
isButton
>
Github
</GithubButton>
</NavInner>
</Nav>
<Close onClick={toggleMenu} className="mobile" />
</NavWrapper>
</Centered>
</Wrapper>
);
};
export default Header;
@@ -0,0 +1,72 @@
import React, { memo, useCallback } from 'react';
import styled from '@emotion/styled';
import { Handle } from 'react-flow-renderer';
import { getThemeColor } from 'utils/css-utils';
const ColorPickerNodeWrapper = styled.div`
padding: 10px;
background: white;
border: 1px solid ${getThemeColor('violet')};
border-radius: 4px;
box-shadow: ${(p) =>
p.selected ? `0 0 0 0.25px ${p.theme.colors.violet}` : 'none'};
.react-flow__handle {
background: ${(p) => p.color};
}
input {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 8px;
background: ${getThemeColor('silver')};
outline: none;
border-radius: 2px;
}
input::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 12px;
background: ${(p) => p.color};
cursor: pointer;
border-radius: 100%;
}
input::-moz-range-thumb {
width: 12px;
height: 12px;
background: ${(p) => p.color};
cursor: pointer;
border-radius: 100%;
}
`;
const ColorPickerNode = memo(({ data, id, selected }) => {
const onChange = useCallback((event) => data.onChange(event, id), [data, id]);
const colorName = `${data.color[0].toUpperCase()}${data.color.substr(1)}`;
return (
<ColorPickerNodeWrapper
color={data.color}
value={data.value}
selected={selected}
>
<div>{colorName} amount</div>
<input
type="range"
min="0"
max="255"
value={data.value}
onChange={onChange}
className="nodrag"
/>
<Handle type="source" position="right" />
</ColorPickerNodeWrapper>
);
});
export default ColorPickerNode;
+151
View File
@@ -0,0 +1,151 @@
import React, { useEffect, useState } from 'react';
import ReactFlow, {
ReactFlowProvider,
Background,
Controls,
addEdge,
} from 'react-flow-renderer';
import ColorPickerNode from './ColorPickerNode';
const windowWidth = typeof window !== 'undefined' ? window.innerWidth : 0;
const hasTouch = typeof window !== 'undefined' && 'ontouchstart' in window;
const isSmallScreen = windowWidth < 800;
const getOffset = () => {
if (isSmallScreen) {
return 0;
} else if (windowWidth < 1200) {
return 425;
} else {
return (windowWidth - 1200) / 2 + 500;
}
};
const getColorNodeX = () => {
if (windowWidth < 600) {
return offsetLeft + 250;
} else if (isSmallScreen) {
return offsetLeft + 400;
} else if (windowWidth < 1000) {
return offsetLeft + 300;
} else if (windowWidth < 1200) {
return offsetLeft + 400;
} else {
return offsetLeft + 550;
}
};
const offsetLeft = getOffset();
const nodeTypes = {
colorpicker: ColorPickerNode,
};
const findNodeByColor = (color) => (n) =>
n.type === 'colorpicker' && n.data.color === color;
export default () => {
const [elements, setElements] = useState([]);
const onConnect = (params) => setElements((els) => addEdge(params, els));
useEffect(() => {
const onChange = (event, id) => {
setElements((els) => {
const nextElements = els.map((e) => {
if (e.id !== id) {
return e;
}
const value = event.target.value;
return {
...e,
data: {
...e.data,
value,
},
};
});
const red = nextElements.find(findNodeByColor('red')).data.value;
const green = nextElements.find(findNodeByColor('green')).data.value;
const blue = nextElements.find(findNodeByColor('blue')).data.value;
const background = `rgb(${red}, ${green}, ${blue})`;
const colorNode = nextElements.find((n) => n.id === '4');
colorNode.style = {
background,
};
colorNode.data = {
...colorNode.data,
label: background,
};
return nextElements;
});
};
const initialElements = [
{
id: '1',
type: 'colorpicker',
data: { color: 'red', value: 105, onChange },
sourcePosition: 'right',
position: { x: offsetLeft + 50, y: isSmallScreen ? 250 : 5 },
},
{
id: '2',
type: 'colorpicker',
data: { color: 'green', value: 100, onChange },
sourcePosition: 'right',
position: { x: offsetLeft, y: isSmallScreen ? 325 : 150 },
},
{
id: '3',
data: { color: 'blue', value: 165, onChange },
type: 'colorpicker',
sourcePosition: 'right',
position: {
x: isSmallScreen ? offsetLeft + 50 : offsetLeft + 120,
y: isSmallScreen ? 400 : 300,
},
},
{
id: '4',
data: { label: 'rgb(105, 100, 165)' },
targetPosition: 'left',
sourcePosition: 'right',
position: { x: getColorNodeX(), y: isSmallScreen ? 350 : 180 },
style: {
width: 200,
background: 'rgb(105, 100, 165)',
color: 'white',
textShadow:
'rgba(0, 0, 0, 0.4) 1px 0px 0px, rgba(0, 0, 0, 0.4) -1px 0px 0px, rgba(0, 0, 0, 0.4) 0px 1px 0px, rgba(0, 0, 0, 0.4) 0px -1px 0px',
},
},
{ id: 'e1-4', source: '1', target: '4', animated: true },
{ id: 'e2-4', source: '2', target: '4', animated: true },
{ id: 'e3-4', source: '3', target: '4', animated: true },
];
setElements(initialElements);
}, []);
return (
<ReactFlowProvider>
<ReactFlow
elements={elements}
zoomOnScroll={false}
nodeTypes={nodeTypes}
onConnect={onConnect}
paneMoveable={!hasTouch}
>
<Background />
<Controls showInteractive={false} />
</ReactFlow>
</ReactFlowProvider>
);
};
+103
View File
@@ -0,0 +1,103 @@
import React, { useState, useEffect } from 'react';
import styled from '@emotion/styled';
import { Flex } from 'reflexbox';
import { isOldIE } from 'utils/browser-utils';
import Mail from 'assets/icons/mail.svg';
import Github from 'assets/icons/github_circle.svg';
import ArrowRight from 'assets/icons/arrow_right.svg';
import Menu from 'assets/icons/menu.svg';
import Code from 'assets/icons/code.svg';
const IconWrapper = styled(Flex)`
justify-content: center;
align-items: center;
svg {
max-width: 100%;
height: auto;
display: flex;
flex-direction: column;
justify-content: center;
path,
circle,
rect,
line,
polyline {
stroke: ${(p) =>
p.colorizeStroke
? p.theme.colors[p.strokeColor] || p.theme.colors.text
: 'none'};
}
path.nostroke,
circle.nostroke,
rect.nostroke,
line.nostroke,
polyline.nostroke {
stroke: none;
fill: ${(p) =>
p.colorizeStroke
? p.theme.colors[p.strokeColor] || p.theme.colors.text
: 'none'};
}
}
`;
const preLoaded = {
mail: Mail,
arrow_right: ArrowRight,
menu: Menu,
github_circle: Github,
code: Code,
};
const getPreLoadedIcon = (name) =>
preLoaded[name] ? () => preLoaded[name] : null;
export default ({
name = 'datavis',
colorizeStroke = false,
strokeColor = null,
...restProps
}) => {
const [SVGComponent, setSVGComponent] = useState(getPreLoadedIcon(name));
useEffect(() => {
if (!SVGComponent) {
(async () => {
try {
const svgComp = await import(`assets/icons/${name}.svg`);
setSVGComponent(svgComp);
} catch (err) {
console.warn(`error loading icon: ${name}`);
}
})();
}
}, [SVGComponent, name]);
if (!SVGComponent) {
return null;
}
const IconComponent = SVGComponent.default
? SVGComponent.default
: SVGComponent;
if (isOldIE()) {
return null;
}
return (
<IconWrapper
className="icon"
colorizeStroke={colorizeStroke}
strokeColor={strokeColor}
height={restProps.width || 'auto'}
{...restProps}
>
<IconComponent />
</IconWrapper>
);
};
+26
View File
@@ -0,0 +1,26 @@
import React from 'react';
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
const Wrapper = styled(Box)`
padding: 16px;
background: ${(p) => p.theme.colors.violetLighten45};
color: white;
border-radius: 5px;
margin: 20px 0;
`;
const Title = styled(Box)`
font-size: 20px;
margin-bottom: 4px;
font-weight: 900;
`;
export default ({ title = null, text, ...rest }) => {
return (
<Wrapper {...rest}>
<Title>{title}</Title>
<div>{text}</div>
</Wrapper>
);
};
+30
View File
@@ -0,0 +1,30 @@
import React from 'react';
import styled from '@emotion/styled';
import { useTheme } from 'emotion-theming';
import WbkdLogoWhite from 'assets/images/logo-white.svg';
import WbkdLogoBlack from 'assets/images/logo.svg';
const Image = styled.img`
display: block;
width: 75px;
`;
const getLogoSrc = (type, inverted, theme) => {
if (type) {
return type === 'white' ? WbkdLogoWhite : WbkdLogoBlack;
}
if (inverted) {
return theme.name === 'light' ? WbkdLogoWhite : WbkdLogoBlack;
}
return theme.name === 'light' ? WbkdLogoBlack : WbkdLogoWhite;
};
export default ({ type = null, inverted = false, style = {} }) => {
const theme = useTheme();
const logoSrc = getLogoSrc(type, inverted, theme);
return <Image src={logoSrc} alt="webkid logo" style={style} />;
};
+26
View File
@@ -0,0 +1,26 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex, Box } from 'reflexbox';
import Page from 'components/Page';
import Sidebar from 'components/Sidebar';
const Wrapper = styled(Flex)`
border-top: 1px solid ${(p) => p.theme.colors.silverLighten30};
`;
const DocWrapper = styled(Box)`
max-width: 620px;
margin: 0 auto;
position: relative;
padding: 0 16px;
`;
export default ({ children, menu = [], ...rest }) => (
<Page {...rest} footerBorder>
<Wrapper>
<Sidebar menu={menu} isDocs />
<DocWrapper>{children}</DocWrapper>
</Wrapper>
</Page>
);
+73
View File
@@ -0,0 +1,73 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex, Box } from 'reflexbox';
import Page from 'components/Page';
import Sidebar from 'components/Sidebar';
import useExamplePages from 'hooks/useExamplePages';
import CodeBlock from 'components/CodeBlock';
import { H4 } from 'components/Typo';
import 'example-flows/Overview';
const Wrapper = styled(Flex)`
border-top: 1px solid ${(p) => p.theme.colors.silverLighten30};
flex-grow: 1;
`;
const ReactFlowWrapper = styled(Box)`
flex-grow: 1;
.react-flow {
height: 65vh;
}
`;
const SourceWrapper = styled(Box)`
border-top: 1px solid #eee;
max-width: 1000px;
margin: 0 auto;
`;
const SourceCodeBlock = ({ absolutePath, internal }) => {
const splittedPath = absolutePath.split('/');
const fileName = splittedPath[splittedPath.length - 1];
return (
<Box>
<Box>{fileName}</Box>
<CodeBlock code={internal.content} />
</Box>
);
};
export default ({ children, title, slug, sourceCodeFiles = [] }) => {
const menu = useExamplePages();
const metaTags = {
title: `React Flow - ${title} Example`,
siteUrl: `https://reactflow.dev/examples/${slug}`,
robots: 'index, follow',
};
const hasSource = sourceCodeFiles.length > 0;
return (
<Page metaTags={metaTags} footerBorder>
<Wrapper>
<Sidebar menu={menu} />
<ReactFlowWrapper>
{children}
{hasSource && (
<SourceWrapper p={3}>
<H4 as="div">Source Code</H4>
{sourceCodeFiles.map((source) => (
<SourceCodeBlock key={source.absolutePath} {...source} />
))}
</SourceWrapper>
)}
</ReactFlowWrapper>
</Wrapper>
</Page>
);
};
+52
View File
@@ -0,0 +1,52 @@
import React from 'react';
import { Helmet } from 'react-helmet';
const MetaTags = ({
title,
description,
siteUrl,
robots,
image,
pathname,
article,
}) => {
if (pathname) {
siteUrl = `${siteUrl}${pathname}`;
}
if (image) {
image = `https://reactflow.dev${image}`;
} else {
image = 'https://reactflow.dev/images/react-flow-header.jpg';
}
return (
<Helmet defaultTitle="React Flow">
<html lang="en" />
<title>{title}</title>
{description && <meta name="description" content={description} />}
{description && <meta name="robots" content={robots} />}
{siteUrl && <meta property="og:url" content={siteUrl} />}
{(article ? true : null) && <meta property="og:type" content="article" />}
{title && <meta property="og:title" content={title} />}
{description && <meta property="og:description" content={description} />}
{image && <meta property="og:image" content={image} />}
<meta name="twitter:card" content="summary_large_image" />
{title && <meta name="twitter:title" content={title} />}
{description && <meta name="twitter:description" content={description} />}
{image && <meta name="twitter:image" content={image} />}
{process.env.NODE_ENV === 'production' && (
<script
src="https://cdn.usefathom.com/script.js"
site="LXMRMWLB"
defer
></script>
)}
</Helmet>
);
};
export default MetaTags;
+52
View File
@@ -0,0 +1,52 @@
import React from 'react';
import styled from '@emotion/styled';
import { ThemeProvider } from 'emotion-theming';
import { Flex, Box } from 'reflexbox';
import Header from 'components/Header';
import Footer from 'components/Footer';
import themes from 'themes';
import NormalizeStyle from 'themes/normalize';
import GlobalStyle from 'themes/global';
import MetaTags from './MetaTags';
import { getThemeColor } from 'utils/css-utils';
const PageWrapper = styled(Flex)`
color: ${getThemeColor('text')};
width: 100%;
position: relative;
flex-direction: column;
height: 100vh;
position: relative;
`;
const PageContent = styled(Box)`
flex: 1 0 auto;
position: relative;
`;
const Page = ({
children,
theme = 'light',
metaTags,
footerBorder = false,
...rest
}) => {
const pageTheme = themes[theme];
return (
<ThemeProvider theme={pageTheme}>
<MetaTags {...metaTags} />
<NormalizeStyle />
<GlobalStyle />
<PageWrapper>
<Header />
<PageContent {...rest}>{children}</PageContent>
<Footer hasBorder={footerBorder} />
</PageWrapper>
</ThemeProvider>
);
};
export default Page;
@@ -0,0 +1,37 @@
import React from 'react';
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { H1, H4 } from 'components/Typo';
import { getThemeSpacePx, getThemeColor } from 'utils/css-utils';
const SectionIntroWrapper = styled(Box)`
text-align: center;
/* padding-top: ${getThemeSpacePx(5)};
padding-bottom: ${getThemeSpacePx(
6
)}; */
max-width: 700px;
margin: 0 auto;
${H1} {
margin: 0 0 ${getThemeSpacePx(3)} 0;
}
`;
const SectionSubtitle = styled(H4)`
font-weight: 400;
line-height: 1.5;
color: ${getThemeColor('silverDarken30')};
`;
const SectionIntro = ({ title = '', text = '', ...props }) => {
return (
<SectionIntroWrapper pt={[3, 3, 5]} pb={[4, 4, 6]} {...props}>
<H1>{title}</H1>
{text && <SectionSubtitle>{text}</SectionSubtitle>}
</SectionIntroWrapper>
);
};
export default SectionIntro;
+92
View File
@@ -0,0 +1,92 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex, Box } from 'reflexbox';
import Img from 'gatsby-image';
import CenterContent from 'components/CenterContent';
import useShowcaseImages from 'hooks/useShowcaseImages';
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)`
color: ${getThemeColor('textInverted')};
margin: 16px 0 0 0;
font-weight: 400;
`;
const Link = styled.a`
&&& {
color: ${getThemeColor('silverDarken15')};
&: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={[0, 0, -gridPadding]} flexWrap="wrap">
{showcases.map((showcase) => (
<Box
key={showcase.title}
width={[1, 1, 1 / 3]}
px={[0, 0, gridPadding]}
mb={[3, 3, 0]}
>
<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, 1, 1 / 3]}
px={[0, 0, gridPadding]}
mb={[3, 3, 0]}
>
<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>
);
};
export default Showcases;
+131
View File
@@ -0,0 +1,131 @@
import React, { Fragment, useState } from 'react';
import Link from 'gatsby-link';
import styled from '@emotion/styled';
import { Flex } from 'reflexbox';
import Icon from 'components/Icon';
import Close from 'components/Close';
import useMenuHeight from 'hooks/useMenuHeight';
import { getThemeColor, getThemeSpacePx, device, px } from 'utils/css-utils';
const Aside = styled.aside`
display: ${(p) => (p.isOpen ? 'block' : 'none')};
position: absolute;
left: 0;
top: 0;
width: 100%;
height: ${(p) => px(p.height)};
overflow-y: auto;
background: white;
z-index: 400;
@media ${device.tablet} {
width: 30%;
max-width: 300px;
padding: 16px;
border-right: 1px solid ${getThemeColor('silverLighten30')};
display: block;
position: relative;
height: auto;
.mobile {
display: none;
}
}
`;
const AsideInner = styled.div``;
const MobileButton = styled(Flex)`
z-index: 10;
background: ${getThemeColor('violetLighten5')};
position: fixed;
right: 16px;
bottom: 16px;
color: white;
border-radius: 100%;
width: 36px;
height: 36px;
cursor: pointer;
justify-content: center;
align-items: center;
@media ${device.tablet} {
display: none;
}
`;
const MenuLink = styled(Link)`
display: block;
padding: ${getThemeSpacePx(1)} ${getThemeSpacePx(2)};
margin-left: ${(p) => (p.marginLeft ? `${p.marginLeft}px` : 0)};
&.active,
&:hover {
background: ${getThemeColor('silverLighten30')};
}
`;
const GroupLabel = styled.div`
padding: ${getThemeSpacePx(1)} ${getThemeSpacePx(2)};
color: ${getThemeColor('silverDarken60')};
margin-left: ${(p) => (p.marginLeft ? `${p.marginLeft}px` : 0)};
`;
const MenuItem = ({ title, slug, marginLeft }) => {
return (
<MenuLink to={slug} marginLeft={marginLeft} activeClassName="active">
{title}
</MenuLink>
);
};
const SideBarParts = ({ items, level }) =>
items.map((menuItem) => {
if (menuItem.title) {
return (
<MenuItem key={menuItem.slug} marginLeft={level * 16} {...menuItem} />
);
}
return (
<Fragment key={menuItem.group}>
<GroupLabel marginLeft={level * 16}>{menuItem.group}</GroupLabel>
<SideBarParts items={menuItem.items} level={level + 1} />
</Fragment>
);
});
const Sidebar = ({ menu }) => {
const [isOpen, setIsOpen] = useState(false);
const menuHeight = useMenuHeight();
const toggleSidebar = () => {
const nextMenuOpen = !isOpen;
document.body.classList.toggle('noscroll', nextMenuOpen);
setIsOpen(nextMenuOpen);
};
return (
<>
<MobileButton onClick={toggleSidebar}>
<Icon
name="menu"
width="24px"
colorizeStroke
strokeColor="silverLighten60"
/>
</MobileButton>
<Aside isOpen={isOpen} height={menuHeight}>
<AsideInner>
<SideBarParts items={menu} level={0} />
<Close className="mobile" onClick={toggleSidebar} />
</AsideInner>
</Aside>
</>
);
};
export default Sidebar;
+106
View File
@@ -0,0 +1,106 @@
import React, { useState } from 'react';
import ReactFlow, {
ReactFlowProvider,
Background,
Controls,
addEdge,
} from 'react-flow-renderer';
import TeaserFlow from 'components/TeaserFlow';
import { baseColors } from 'themes';
const initialElements = [
{
id: '1',
type: 'input',
position: {
x: 200,
y: 5,
},
data: {
label: 'Input',
},
},
{
id: '2',
position: {
x: 0,
y: 150,
},
data: {
label: 'Default',
},
},
{
id: '3',
position: {
x: 400,
y: 150,
},
data: {
label: 'Default',
},
},
{
id: '4',
type: 'output',
position: {
x: 200,
y: 300,
},
data: {
label: 'Output',
},
},
{
id: 'e1',
source: '1',
target: '2',
label: 'default edge',
},
{
id: 'e2',
source: '1',
target: '3',
animated: true,
label: 'animated edge',
},
{
id: 'e3',
source: '2',
target: '4',
type: 'smoothstep',
},
{
id: 'e4',
source: '3',
target: '4',
type: 'smoothstep',
},
];
const onLoad = (rf) => rf.fitView({ padding: 0.2 });
export default () => {
const [elements, setElements] = useState(initialElements);
const onConnect = (params) => setElements((els) => addEdge(params, els));
return (
<TeaserFlow
title="Feature-rich"
description="React Flow comes with seamless zooming & panning, different edge and node types, single and multi-selection, controls, several event handlers and more."
>
<ReactFlowProvider>
<ReactFlow
elements={elements}
onLoad={onLoad}
zoomOnScroll={false}
onConnect={onConnect}
>
<Background color={baseColors.silverDarken60} gap={15} />
<Controls showInteractive={false} />
</ReactFlow>
</ReactFlowProvider>
</TeaserFlow>
);
};
+194
View File
@@ -0,0 +1,194 @@
import React, { useState, useEffect } from 'react';
import styled from '@emotion/styled';
import ReactFlow, {
Handle,
ReactFlowProvider,
Background,
Controls,
} from 'react-flow-renderer';
import TeaserFlow from 'components/TeaserFlow';
import { baseColors } from 'themes';
const NodeWrapper = styled.div`
background: ${(p) => p.theme.colors.silverLighten30};
padding: 8px 10px;
font-size: 12px;
border-radius: 4px;
input {
font-size: 12px;
border: 1px solid ${(p) => p.theme.colors.violetLighten60};
width: 100%;
border-radius: 2px;
max-width: 100px;
}
.react-flow__handle {
background: ${(p) => p.theme.colors.violetLighten60};
}
`;
const InputLabel = styled.div`
color: ${(p) => p.theme.colors.violetLighten60};
`;
const InputNode = ({ id, data, isConnectable }) => {
return (
<NodeWrapper>
<InputLabel>{data.label}:</InputLabel>
<input
className="nodrag"
value={data.value}
onChange={(event) => data.onChange(event, id)}
/>
<Handle type="source" position="bottom" isConnectable={isConnectable} />
</NodeWrapper>
);
};
const ResultNode = ({ data, isConnectable }) => {
return (
<NodeWrapper>
<div>{data.value}</div>
<Handle
type="target"
position="top"
id="a"
style={{ left: '40%' }}
isConnectable={isConnectable}
/>
<Handle
type="target"
position="top"
id="b"
style={{ left: '60%' }}
isConnectable={isConnectable}
/>
</NodeWrapper>
);
};
const nodeTypes = {
nameinput: InputNode,
result: ResultNode,
};
const onLoad = (rf) => setTimeout(() => rf.fitView({ padding: 0.1 }), 1);
const findNodeById = (id) => (n) => n.id === id;
export default () => {
const [elements, setElements] = useState([]);
useEffect(() => {
const onChange = (event, id) => {
setElements((els) => {
const nextElements = els.map((e) => {
if (e.id !== id) {
return e;
}
const value = event.target.value;
return {
...e,
data: {
...e.data,
value,
},
};
});
const forname = nextElements.find(findNodeById('1')).data.value;
const lastname = nextElements.find(findNodeById('2')).data.value;
const result = `${forname} ${lastname}`;
const resultNode = nextElements.find((n) => n.type === 'result');
resultNode.data = {
...resultNode.data,
value: !forname && !lastname ? '*please enter a name*' : result,
};
return nextElements;
});
};
const initialElements = [
{
id: '1',
type: 'nameinput',
position: {
x: 0,
y: 200,
},
data: {
label: 'Forename',
value: 'React',
onChange,
},
},
{
id: '2',
type: 'nameinput',
position: {
x: 400,
y: 200,
},
data: {
label: 'Lastname',
value: 'Flow',
onChange,
},
},
{
id: '3',
type: 'result',
position: {
x: 200,
y: 400,
},
data: {
value: 'React Flow',
},
},
{
id: 'e1',
source: '1',
target: '3__a',
animated: true,
},
{
id: 'e2',
source: '2',
target: '3__b',
animated: true,
},
];
setElements(initialElements);
}, []);
return (
<TeaserFlow
title="Customizable"
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"
isDark
>
<ReactFlowProvider>
<ReactFlow
elements={elements}
nodeTypes={nodeTypes}
onLoad={onLoad}
zoomOnScroll={false}
nodesConnectable={false}
>
<Background color={baseColors.silverDarken60} gap={15} />
<Controls showInteractive={false} />
</ReactFlow>
</ReactFlowProvider>
</TeaserFlow>
);
};
+194
View File
@@ -0,0 +1,194 @@
import React, { useState } from 'react';
import ReactFlow, {
ReactFlowProvider,
Background,
Controls,
addEdge,
} from 'react-flow-renderer';
import TeaserFlow from 'components/TeaserFlow';
const defaultNodeOptions = {
targetPosition: 'left',
sourcePosition: 'right',
style: {
width: 50,
},
};
const initialElements = [
{
id: 'input',
type: 'input',
position: {
x: 0,
y: 100,
},
data: {
label: 'Input',
},
...defaultNodeOptions,
},
{
id: 'A',
position: {
x: 150,
y: 0,
},
data: {
label: 'A',
},
...defaultNodeOptions,
},
{
id: 'B',
position: {
x: 250,
y: 0,
},
data: {
label: 'B',
},
...defaultNodeOptions,
},
{
id: 'C',
position: {
x: 350,
y: 0,
},
data: {
label: 'C',
},
...defaultNodeOptions,
},
{
id: 'D',
position: {
x: 150,
y: 200,
},
data: {
label: 'D',
},
...defaultNodeOptions,
},
{
id: 'E',
position: {
x: 250,
y: 200,
},
data: {
label: 'E',
},
...defaultNodeOptions,
},
{
id: 'F',
position: {
x: 350,
y: 200,
},
data: {
label: 'F',
},
...defaultNodeOptions,
},
{
id: 'output',
type: 'output',
position: {
x: 500,
y: 100,
},
data: {
label: 'Output',
},
...defaultNodeOptions,
},
{
id: 'e1',
source: 'input',
target: 'A',
type: 'step',
},
{
id: 'e2',
source: 'A',
target: 'B',
type: 'step',
},
{
id: 'e3',
source: 'B',
target: 'C',
type: 'step',
},
{
id: 'e4',
source: 'C',
target: 'output',
type: 'step',
},
{
id: 'e5',
source: 'input',
target: 'D',
type: 'step',
animated: true,
},
{
id: 'e6',
source: 'D',
target: 'E',
type: 'step',
animated: true,
},
{
id: 'e7',
source: 'E',
target: 'F',
type: 'step',
animated: true,
},
{
id: 'e8',
source: 'F',
target: 'output',
type: 'step',
animated: true,
},
];
const onLoad = (rf) => rf.fitView({ padding: 0.2 });
export default () => {
const [elements, setElements] = useState(initialElements);
const onConnect = (params) =>
setElements((els) => {
params.type = 'step';
return addEdge(params, els);
});
return (
<TeaserFlow
title="Additional Components"
description="React Flow includes a MiniMap, Controls, Background and a FlowProvider you can use to access internal state outside the ReactFlow component."
linesBg
>
<ReactFlowProvider>
<ReactFlow
elements={elements}
onLoad={onLoad}
zoomOnScroll={false}
onConnect={onConnect}
connectionLineType="step"
>
<Background variant="lines" gap={20} />
<Controls showInteractive={false} />
</ReactFlow>
</ReactFlowProvider>
</TeaserFlow>
);
};
+141
View File
@@ -0,0 +1,141 @@
import React from 'react';
import styled from '@emotion/styled';
import { Flex, Box } from 'reflexbox';
import Link from 'gatsby-link';
import ReactFlow, {
ReactFlowProvider,
Background,
Controls,
MiniMap,
} from 'react-flow-renderer';
import { H2, Text } from 'components/Typo';
import Icon from 'components/Icon';
import { baseColors } from 'themes';
import { device, getThemeSpacePx } from 'utils/css-utils';
const Wrapper = styled(Flex)`
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
`;
const ReactFlowWrapper = styled(Box)`
height: 400px;
background: ${(p) => (p.isDark ? baseColors.violet : 'white')};
border-radius: 10px;
order: 2;
margin: ${getThemeSpacePx(4)} ${getThemeSpacePx(0)};
border: solid rgba(26, 25, 43, 0.054) 1.5px;
box-shadow: 0 2.8px 2.2px rgba(26, 25, 43, 0.014),
0 12.5px 10px rgba(26, 25, 43, 0.02),
0 22.3px 17.9px rgba(26, 25, 43, 0.022),
0 41.8px 33.4px rgba(26, 25, 43, 0.026), 0 100px 80px rgba(26, 25, 43, 0.02);
@media ${device.tablet} {
order: ${(p) => p.order};
}
@media ${device.mobile} {
margin-top: ${getThemeSpacePx(3)};
}
.react-flow__controls {
opacity: ${(p) => (p.isDark ? 0.5 : 1)};
}
`;
const DocsLink = styled(Link)`
display: flex;
font-weight: bold;
align-items: center;
margin-top: 16px;
@media ${device.mobile} {
margin-top: ${getThemeSpacePx(0)};
}
svg {
transform: translateX(0px);
transition: all 0.125s ease-in-out;
}
&:hover {
svg {
transform: translateX(5px);
transition: all 0.125s ease-in-out;
}
}
`;
const DescriptionWrapper = styled(Box)`
order: 1;
margin-bottom: ${getThemeSpacePx(3)};
@media ${device.tablet} {
order: ${(p) => p.order};
}
@media ${device.mobile} {
margin-bottom: ${getThemeSpacePx(0)};
}
`;
const Description = ({ title, description }) => (
<DescriptionWrapper width={[1, 1, 0.35]}>
<H2>{title}</H2>
<Text style={{ opacity: 0.7 }}>{description}</Text>
<DocsLink to="/docs">
Documentation{' '}
<Icon width={42} name="arrow_right" colorizeStroke strokeColor="red" />
</DocsLink>
</DescriptionWrapper>
);
export default ({
title,
description,
textPosition = 'left',
flowProps,
withControls = false,
withMinimap = false,
isDark = false,
linesBg = false,
children,
}) => {
const bgColor = isDark ? baseColors.violetLighten60 : baseColors.violet;
const reactFlowOrder = textPosition === 'left' ? 2 : 1;
return (
<Wrapper mb={[6, 6, 7]}>
{textPosition === 'left' && (
<Description order={1} title={title} description={description} />
)}
<ReactFlowWrapper
width={[1, 1, 0.6]}
isDark={isDark}
order={reactFlowOrder}
>
{children ? (
children
) : (
<ReactFlowProvider>
<ReactFlow {...flowProps} zoomOnScroll={false}>
<Background
color={linesBg ? '#eee' : bgColor}
gap={15}
variant={linesBg ? 'lines' : 'dots'}
/>
{withControls && <Controls />}
{withMinimap && <MiniMap />}
</ReactFlow>
</ReactFlowProvider>
)}
</ReactFlowWrapper>
{textPosition !== 'left' && (
<Description order={2} title={title} description={description} />
)}
</Wrapper>
);
};
+101
View File
@@ -0,0 +1,101 @@
import styled from '@emotion/styled';
import { Box } from 'reflexbox';
import { getThemeSpacePx, getThemeColor, device } from 'utils/css-utils';
export const H1 = styled.h1`
font-size: ${(p) => p.theme.fontSizesPx[4]};
line-height: 1.1;
letter-spacing: 1px;
font-weight: 900;
margin: ${getThemeSpacePx(3)} 0;
@media ${device.tablet} {
font-size: ${(p) => p.theme.fontSizesPx[5]};
}
`;
export const H2 = styled.h2`
font-size: ${(p) => p.theme.fontSizesPx[3]};
line-height: 1.1;
letter-spacing: 1px;
font-weight: 900;
margin: ${getThemeSpacePx(3)} 0;
@media ${device.tablet} {
font-size: ${(p) => p.theme.fontSizesPx[4]};
}
`;
export const H3 = styled.h3`
font-size: ${(p) => p.theme.fontSizesPx[2]};
line-height: 1.4;
letter-spacing: 1px;
font-weight: 900;
margin: ${getThemeSpacePx(3)} 0;
@media ${device.tablet} {
font-size: ${(p) => p.theme.fontSizesPx[3]};
}
`;
export const H4 = styled.h4`
font-size: ${(p) => p.theme.fontSizesPx[1]};
line-height: 1.3;
letter-spacing: 1px;
font-weight: 900;
margin: ${getThemeSpacePx(2)} 0;
@media ${device.tablet} {
font-size: ${(p) => p.theme.fontSizesPx[2]};
}
`;
export const H5 = H4;
export const UL = styled.ul`
padding: 0;
list-style: none;
`;
const BulletPointSvg = encodeURIComponent(
`<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" r="2" fill="#F7F8F8"/></svg>`
);
export const LI = styled.li`
color: ${getThemeColor('textLight')};
list-style-image: url('data:image/svg+xml;utf8,${BulletPointSvg}');
`;
export const Text = styled(Box)`
font-size: ${(p) => p.theme.fontSizesPx[p.fontSize || 1]};
line-height: 1.6;
`;
export const TextLight = styled(Text)`
color: ${getThemeColor('textLight')};
`;
export const Label = styled(Box)`
font-size: 12px;
line-height: 1.5;
letter-spacing: 1px;
`;
export const AttributionText = styled(TextLight)`
text-align: center;
margin-top: 12px;
font-size: ${(p) => p.theme.fontSizesPx[0]};
`;
export const Paragraph = styled(Box)`
max-width: 520px;
margin-left: auto;
margin-right: auto;
letter-spacing: 0.5px;
line-height: 1.5;
code {
color: ${(p) => p.theme.colors.violet};
}
`;

Some files were not shown because too many files have changed in this diff Show More