Add application file
Browse files- .eslintrc.cjs +18 -0
- .gitignore +24 -0
- LICENSE +21 -0
- index.html +13 -0
- package-lock.json +0 -0
- package.json +29 -0
- public/favicon.ico +0 -0
- src/App.tsx +43 -0
- src/edges/index.ts +11 -0
- src/index.css +12 -0
- src/main.tsx +12 -0
- src/nodes/PositionLoggerNode.tsx +28 -0
- src/nodes/index.ts +24 -0
- src/vite-env.d.ts +1 -0
- tsconfig.json +25 -0
- tsconfig.node.json +10 -0
- vite.config.ts +7 -0
- your-app-namenpx/.eslintrc.cjs +18 -0
- your-app-namenpx/.gitignore +24 -0
- your-app-namenpx/LICENSE +21 -0
- your-app-namenpx/README.md +54 -0
- your-app-namenpx/index.html +13 -0
- your-app-namenpx/package-lock.json +0 -0
- your-app-namenpx/package.json +29 -0
- your-app-namenpx/public/favicon.ico +0 -0
- your-app-namenpx/src/App.tsx +43 -0
- your-app-namenpx/src/edges/index.ts +11 -0
- your-app-namenpx/src/index.css +12 -0
- your-app-namenpx/src/main.tsx +12 -0
- your-app-namenpx/src/nodes/PositionLoggerNode.tsx +28 -0
- your-app-namenpx/src/nodes/index.ts +24 -0
- your-app-namenpx/src/vite-env.d.ts +1 -0
- your-app-namenpx/tsconfig.json +25 -0
- your-app-namenpx/tsconfig.node.json +10 -0
- your-app-namenpx/vite.config.ts +7 -0
.eslintrc.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
root: true,
|
| 3 |
+
env: { browser: true, es2020: true },
|
| 4 |
+
extends: [
|
| 5 |
+
'eslint:recommended',
|
| 6 |
+
'plugin:@typescript-eslint/recommended',
|
| 7 |
+
'plugin:react-hooks/recommended',
|
| 8 |
+
],
|
| 9 |
+
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
| 10 |
+
parser: '@typescript-eslint/parser',
|
| 11 |
+
plugins: ['react-refresh'],
|
| 12 |
+
rules: {
|
| 13 |
+
'react-refresh/only-export-components': [
|
| 14 |
+
'warn',
|
| 15 |
+
{ allowConstantExport: true },
|
| 16 |
+
],
|
| 17 |
+
},
|
| 18 |
+
}
|
.gitignore
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
npm-debug.log*
|
| 5 |
+
yarn-debug.log*
|
| 6 |
+
yarn-error.log*
|
| 7 |
+
pnpm-debug.log*
|
| 8 |
+
lerna-debug.log*
|
| 9 |
+
|
| 10 |
+
node_modules
|
| 11 |
+
dist
|
| 12 |
+
dist-ssr
|
| 13 |
+
*.local
|
| 14 |
+
|
| 15 |
+
# Editor directories and files
|
| 16 |
+
.vscode/*
|
| 17 |
+
!.vscode/extensions.json
|
| 18 |
+
.idea
|
| 19 |
+
.DS_Store
|
| 20 |
+
*.suo
|
| 21 |
+
*.ntvs*
|
| 22 |
+
*.njsproj
|
| 23 |
+
*.sln
|
| 24 |
+
*.sw?
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2023 webkid GmbH
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<link rel="icon" href="/favicon.ico" />
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
+
<title>React Flow starter (Vite + TS)</title>
|
| 8 |
+
</head>
|
| 9 |
+
<body>
|
| 10 |
+
<div id="root"></div>
|
| 11 |
+
<script type="module" src="/src/main.tsx"></script>
|
| 12 |
+
</body>
|
| 13 |
+
</html>
|
package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "vite-react-flow-template",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"type": "module",
|
| 5 |
+
"scripts": {
|
| 6 |
+
"dev": "vite",
|
| 7 |
+
"build": "tsc && vite build",
|
| 8 |
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
| 9 |
+
"preview": "vite preview"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"react": "^18.2.0",
|
| 13 |
+
"react-dom": "^18.2.0",
|
| 14 |
+
"reactflow": "^11.10.3"
|
| 15 |
+
},
|
| 16 |
+
"license": "MIT",
|
| 17 |
+
"devDependencies": {
|
| 18 |
+
"@types/react": "^18.2.53",
|
| 19 |
+
"@types/react-dom": "^18.2.18",
|
| 20 |
+
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
| 21 |
+
"@typescript-eslint/parser": "^6.20.0",
|
| 22 |
+
"@vitejs/plugin-react": "^4.2.1",
|
| 23 |
+
"eslint": "^8.56.0",
|
| 24 |
+
"eslint-plugin-react-hooks": "^4.6.0",
|
| 25 |
+
"eslint-plugin-react-refresh": "^0.4.5",
|
| 26 |
+
"typescript": "^5.3.3",
|
| 27 |
+
"vite": "^5.0.12"
|
| 28 |
+
}
|
| 29 |
+
}
|
public/favicon.ico
ADDED
|
|
src/App.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { OnConnect } from "reactflow";
|
| 2 |
+
|
| 3 |
+
import { useCallback } from "react";
|
| 4 |
+
import {
|
| 5 |
+
Background,
|
| 6 |
+
Controls,
|
| 7 |
+
MiniMap,
|
| 8 |
+
ReactFlow,
|
| 9 |
+
addEdge,
|
| 10 |
+
useNodesState,
|
| 11 |
+
useEdgesState,
|
| 12 |
+
} from "reactflow";
|
| 13 |
+
|
| 14 |
+
import "reactflow/dist/style.css";
|
| 15 |
+
|
| 16 |
+
import { initialNodes, nodeTypes } from "./nodes";
|
| 17 |
+
import { initialEdges, edgeTypes } from "./edges";
|
| 18 |
+
|
| 19 |
+
export default function App() {
|
| 20 |
+
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
| 21 |
+
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
| 22 |
+
const onConnect: OnConnect = useCallback(
|
| 23 |
+
(connection) => setEdges((edges) => addEdge(connection, edges)),
|
| 24 |
+
[setEdges]
|
| 25 |
+
);
|
| 26 |
+
|
| 27 |
+
return (
|
| 28 |
+
<ReactFlow
|
| 29 |
+
nodes={nodes}
|
| 30 |
+
nodeTypes={nodeTypes}
|
| 31 |
+
onNodesChange={onNodesChange}
|
| 32 |
+
edges={edges}
|
| 33 |
+
edgeTypes={edgeTypes}
|
| 34 |
+
onEdgesChange={onEdgesChange}
|
| 35 |
+
onConnect={onConnect}
|
| 36 |
+
fitView
|
| 37 |
+
>
|
| 38 |
+
<Background />
|
| 39 |
+
<MiniMap />
|
| 40 |
+
<Controls />
|
| 41 |
+
</ReactFlow>
|
| 42 |
+
);
|
| 43 |
+
}
|
src/edges/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Edge, EdgeTypes } from "reactflow";
|
| 2 |
+
|
| 3 |
+
export const initialEdges = [
|
| 4 |
+
{ id: "a->c", source: "a", target: "c", animated: true },
|
| 5 |
+
{ id: "b->d", source: "b", target: "d" },
|
| 6 |
+
{ id: "c->d", source: "c", target: "d", animated: true },
|
| 7 |
+
] satisfies Edge[];
|
| 8 |
+
|
| 9 |
+
export const edgeTypes = {
|
| 10 |
+
// Add your custom edge types here!
|
| 11 |
+
} satisfies EdgeTypes;
|
src/index.css
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
| 3 |
+
line-height: 1.5;
|
| 4 |
+
font-weight: 400;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
html,
|
| 8 |
+
body,
|
| 9 |
+
#root {
|
| 10 |
+
height: 100%;
|
| 11 |
+
margin: 0;
|
| 12 |
+
}
|
src/main.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
import ReactDOM from 'react-dom/client';
|
| 3 |
+
|
| 4 |
+
import App from './App';
|
| 5 |
+
|
| 6 |
+
import './index.css';
|
| 7 |
+
|
| 8 |
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
| 9 |
+
<React.StrictMode>
|
| 10 |
+
<App />
|
| 11 |
+
</React.StrictMode>
|
| 12 |
+
);
|
src/nodes/PositionLoggerNode.tsx
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { NodeProps } from "reactflow";
|
| 2 |
+
import { Handle, Position } from "reactflow";
|
| 3 |
+
|
| 4 |
+
export type PositionLoggerNodeData = {
|
| 5 |
+
label?: string;
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
export function PositionLoggerNode({
|
| 9 |
+
xPos,
|
| 10 |
+
yPos,
|
| 11 |
+
data,
|
| 12 |
+
}: NodeProps<PositionLoggerNodeData>) {
|
| 13 |
+
const x = `${Math.round(xPos)}px`;
|
| 14 |
+
const y = `${Math.round(yPos)}px`;
|
| 15 |
+
|
| 16 |
+
return (
|
| 17 |
+
// We add this class to use the same styles as React Flow's default nodes.
|
| 18 |
+
<div className="react-flow__node-default">
|
| 19 |
+
{data.label && <div>{data.label}</div>}
|
| 20 |
+
|
| 21 |
+
<div>
|
| 22 |
+
{x} {y}
|
| 23 |
+
</div>
|
| 24 |
+
|
| 25 |
+
<Handle type="source" position={Position.Bottom} />
|
| 26 |
+
</div>
|
| 27 |
+
);
|
| 28 |
+
}
|
src/nodes/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Node, NodeTypes } from "reactflow";
|
| 2 |
+
import { PositionLoggerNode } from "./PositionLoggerNode";
|
| 3 |
+
|
| 4 |
+
export const initialNodes = [
|
| 5 |
+
{ id: "a", type: "input", position: { x: 0, y: 0 }, data: { label: "wire" } },
|
| 6 |
+
{
|
| 7 |
+
id: "b",
|
| 8 |
+
type: "position-logger",
|
| 9 |
+
position: { x: -100, y: 100 },
|
| 10 |
+
data: { label: "drag me!" },
|
| 11 |
+
},
|
| 12 |
+
{ id: "c", position: { x: 100, y: 100 }, data: { label: "your ideas" } },
|
| 13 |
+
{
|
| 14 |
+
id: "d",
|
| 15 |
+
type: "output",
|
| 16 |
+
position: { x: 0, y: 200 },
|
| 17 |
+
data: { label: "with React Flow" },
|
| 18 |
+
},
|
| 19 |
+
] satisfies Node[];
|
| 20 |
+
|
| 21 |
+
export const nodeTypes = {
|
| 22 |
+
"position-logger": PositionLoggerNode,
|
| 23 |
+
// Add any of your custom nodes here!
|
| 24 |
+
} satisfies NodeTypes;
|
src/vite-env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
/// <reference types="vite/client" />
|
tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"target": "ES2020",
|
| 4 |
+
"useDefineForClassFields": true,
|
| 5 |
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
| 6 |
+
"module": "ESNext",
|
| 7 |
+
"skipLibCheck": true,
|
| 8 |
+
|
| 9 |
+
/* Bundler mode */
|
| 10 |
+
"moduleResolution": "bundler",
|
| 11 |
+
"allowImportingTsExtensions": true,
|
| 12 |
+
"resolveJsonModule": true,
|
| 13 |
+
"isolatedModules": true,
|
| 14 |
+
"noEmit": true,
|
| 15 |
+
"jsx": "react-jsx",
|
| 16 |
+
|
| 17 |
+
/* Linting */
|
| 18 |
+
"strict": true,
|
| 19 |
+
"noUnusedLocals": true,
|
| 20 |
+
"noUnusedParameters": true,
|
| 21 |
+
"noFallthroughCasesInSwitch": true
|
| 22 |
+
},
|
| 23 |
+
"include": ["src"],
|
| 24 |
+
"references": [{ "path": "./tsconfig.node.json" }]
|
| 25 |
+
}
|
tsconfig.node.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"composite": true,
|
| 4 |
+
"skipLibCheck": true,
|
| 5 |
+
"module": "ESNext",
|
| 6 |
+
"moduleResolution": "bundler",
|
| 7 |
+
"allowSyntheticDefaultImports": true
|
| 8 |
+
},
|
| 9 |
+
"include": ["vite.config.ts"]
|
| 10 |
+
}
|
vite.config.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig } from 'vite'
|
| 2 |
+
import react from '@vitejs/plugin-react'
|
| 3 |
+
|
| 4 |
+
// https://vitejs.dev/config/
|
| 5 |
+
export default defineConfig({
|
| 6 |
+
plugins: [react()],
|
| 7 |
+
})
|
your-app-namenpx/.eslintrc.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
root: true,
|
| 3 |
+
env: { browser: true, es2020: true },
|
| 4 |
+
extends: [
|
| 5 |
+
'eslint:recommended',
|
| 6 |
+
'plugin:@typescript-eslint/recommended',
|
| 7 |
+
'plugin:react-hooks/recommended',
|
| 8 |
+
],
|
| 9 |
+
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
| 10 |
+
parser: '@typescript-eslint/parser',
|
| 11 |
+
plugins: ['react-refresh'],
|
| 12 |
+
rules: {
|
| 13 |
+
'react-refresh/only-export-components': [
|
| 14 |
+
'warn',
|
| 15 |
+
{ allowConstantExport: true },
|
| 16 |
+
],
|
| 17 |
+
},
|
| 18 |
+
}
|
your-app-namenpx/.gitignore
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
npm-debug.log*
|
| 5 |
+
yarn-debug.log*
|
| 6 |
+
yarn-error.log*
|
| 7 |
+
pnpm-debug.log*
|
| 8 |
+
lerna-debug.log*
|
| 9 |
+
|
| 10 |
+
node_modules
|
| 11 |
+
dist
|
| 12 |
+
dist-ssr
|
| 13 |
+
*.local
|
| 14 |
+
|
| 15 |
+
# Editor directories and files
|
| 16 |
+
.vscode/*
|
| 17 |
+
!.vscode/extensions.json
|
| 18 |
+
.idea
|
| 19 |
+
.DS_Store
|
| 20 |
+
*.suo
|
| 21 |
+
*.ntvs*
|
| 22 |
+
*.njsproj
|
| 23 |
+
*.sln
|
| 24 |
+
*.sw?
|
your-app-namenpx/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2023 webkid GmbH
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
your-app-namenpx/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+

|
| 2 |
+
|
| 3 |
+
# React Flow starter (Vite + TS)
|
| 4 |
+
|
| 5 |
+
We've put together this template to serve as a starting point for folks
|
| 6 |
+
interested in React Flow. You can use this both as a base for your own React
|
| 7 |
+
Flow applications, or for small experiments or bug reports.
|
| 8 |
+
|
| 9 |
+
**TypeScript not your thing?** We also have a vanilla JavaScript starter template,
|
| 10 |
+
just for you!
|
| 11 |
+
|
| 12 |
+
## Getting up and running
|
| 13 |
+
|
| 14 |
+
You can get this template without forking/cloning the repo using `degit`:
|
| 15 |
+
|
| 16 |
+
```bash
|
| 17 |
+
npx degit xyflow/vite-react-flow-template your-app-name
|
| 18 |
+
```
|
| 19 |
+
|
| 20 |
+
The template contains mostly the minimum dependencies to get up and running, but
|
| 21 |
+
also includes eslint and some additional rules to help you write React code that
|
| 22 |
+
is less likely to run into issues:
|
| 23 |
+
|
| 24 |
+
```bash
|
| 25 |
+
npm install # or `pnpm install` or `yarn install`
|
| 26 |
+
```
|
| 27 |
+
|
| 28 |
+
Vite is a great development server and build tool that we recommend our users to
|
| 29 |
+
use. You can start a development server with:
|
| 30 |
+
|
| 31 |
+
```bash
|
| 32 |
+
npm run dev
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
While the development server is running, changes you make to the code will be
|
| 36 |
+
automatically reflected in the browser!
|
| 37 |
+
|
| 38 |
+
## Things to try:
|
| 39 |
+
|
| 40 |
+
- Create a new custom node inside `src/nodes/` (don't forget to export it from `src/nodes/index.ts`).
|
| 41 |
+
- Change how things look by [overriding some of the built-in classes](https://reactflow.dev/learn/customization/theming#overriding-built-in-classes).
|
| 42 |
+
- Add a layouting library to [position your nodes automatically](https://reactflow.dev/learn/layouting/layouting)
|
| 43 |
+
|
| 44 |
+
## Resources
|
| 45 |
+
|
| 46 |
+
Links:
|
| 47 |
+
|
| 48 |
+
- [React Flow - Docs](https://reactflow.dev)
|
| 49 |
+
- [React Flow - Discord](https://discord.com/invite/Bqt6xrs)
|
| 50 |
+
|
| 51 |
+
Learn:
|
| 52 |
+
|
| 53 |
+
- [React Flow – Custom Nodes](https://reactflow.dev/learn/customization/custom-nodes)
|
| 54 |
+
- [React Flow – Layouting](https://reactflow.dev/learn/layouting/layouting)
|
your-app-namenpx/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<link rel="icon" href="/favicon.ico" />
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
+
<title>React Flow starter (Vite + TS)</title>
|
| 8 |
+
</head>
|
| 9 |
+
<body>
|
| 10 |
+
<div id="root"></div>
|
| 11 |
+
<script type="module" src="/src/main.tsx"></script>
|
| 12 |
+
</body>
|
| 13 |
+
</html>
|
your-app-namenpx/package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
your-app-namenpx/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "vite-react-flow-template",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"type": "module",
|
| 5 |
+
"scripts": {
|
| 6 |
+
"dev": "vite",
|
| 7 |
+
"build": "tsc && vite build",
|
| 8 |
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
| 9 |
+
"preview": "vite preview"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"react": "^18.2.0",
|
| 13 |
+
"react-dom": "^18.2.0",
|
| 14 |
+
"reactflow": "^11.10.3"
|
| 15 |
+
},
|
| 16 |
+
"license": "MIT",
|
| 17 |
+
"devDependencies": {
|
| 18 |
+
"@types/react": "^18.2.53",
|
| 19 |
+
"@types/react-dom": "^18.2.18",
|
| 20 |
+
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
| 21 |
+
"@typescript-eslint/parser": "^6.20.0",
|
| 22 |
+
"@vitejs/plugin-react": "^4.2.1",
|
| 23 |
+
"eslint": "^8.56.0",
|
| 24 |
+
"eslint-plugin-react-hooks": "^4.6.0",
|
| 25 |
+
"eslint-plugin-react-refresh": "^0.4.5",
|
| 26 |
+
"typescript": "^5.3.3",
|
| 27 |
+
"vite": "^5.0.12"
|
| 28 |
+
}
|
| 29 |
+
}
|
your-app-namenpx/public/favicon.ico
ADDED
|
|
your-app-namenpx/src/App.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { OnConnect } from "reactflow";
|
| 2 |
+
|
| 3 |
+
import { useCallback } from "react";
|
| 4 |
+
import {
|
| 5 |
+
Background,
|
| 6 |
+
Controls,
|
| 7 |
+
MiniMap,
|
| 8 |
+
ReactFlow,
|
| 9 |
+
addEdge,
|
| 10 |
+
useNodesState,
|
| 11 |
+
useEdgesState,
|
| 12 |
+
} from "reactflow";
|
| 13 |
+
|
| 14 |
+
import "reactflow/dist/style.css";
|
| 15 |
+
|
| 16 |
+
import { initialNodes, nodeTypes } from "./nodes";
|
| 17 |
+
import { initialEdges, edgeTypes } from "./edges";
|
| 18 |
+
|
| 19 |
+
export default function App() {
|
| 20 |
+
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
| 21 |
+
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
| 22 |
+
const onConnect: OnConnect = useCallback(
|
| 23 |
+
(connection) => setEdges((edges) => addEdge(connection, edges)),
|
| 24 |
+
[setEdges]
|
| 25 |
+
);
|
| 26 |
+
|
| 27 |
+
return (
|
| 28 |
+
<ReactFlow
|
| 29 |
+
nodes={nodes}
|
| 30 |
+
nodeTypes={nodeTypes}
|
| 31 |
+
onNodesChange={onNodesChange}
|
| 32 |
+
edges={edges}
|
| 33 |
+
edgeTypes={edgeTypes}
|
| 34 |
+
onEdgesChange={onEdgesChange}
|
| 35 |
+
onConnect={onConnect}
|
| 36 |
+
fitView
|
| 37 |
+
>
|
| 38 |
+
<Background />
|
| 39 |
+
<MiniMap />
|
| 40 |
+
<Controls />
|
| 41 |
+
</ReactFlow>
|
| 42 |
+
);
|
| 43 |
+
}
|
your-app-namenpx/src/edges/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Edge, EdgeTypes } from "reactflow";
|
| 2 |
+
|
| 3 |
+
export const initialEdges = [
|
| 4 |
+
{ id: "a->c", source: "a", target: "c", animated: true },
|
| 5 |
+
{ id: "b->d", source: "b", target: "d" },
|
| 6 |
+
{ id: "c->d", source: "c", target: "d", animated: true },
|
| 7 |
+
] satisfies Edge[];
|
| 8 |
+
|
| 9 |
+
export const edgeTypes = {
|
| 10 |
+
// Add your custom edge types here!
|
| 11 |
+
} satisfies EdgeTypes;
|
your-app-namenpx/src/index.css
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
| 3 |
+
line-height: 1.5;
|
| 4 |
+
font-weight: 400;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
html,
|
| 8 |
+
body,
|
| 9 |
+
#root {
|
| 10 |
+
height: 100%;
|
| 11 |
+
margin: 0;
|
| 12 |
+
}
|
your-app-namenpx/src/main.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
import ReactDOM from 'react-dom/client';
|
| 3 |
+
|
| 4 |
+
import App from './App';
|
| 5 |
+
|
| 6 |
+
import './index.css';
|
| 7 |
+
|
| 8 |
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
| 9 |
+
<React.StrictMode>
|
| 10 |
+
<App />
|
| 11 |
+
</React.StrictMode>
|
| 12 |
+
);
|
your-app-namenpx/src/nodes/PositionLoggerNode.tsx
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { NodeProps } from "reactflow";
|
| 2 |
+
import { Handle, Position } from "reactflow";
|
| 3 |
+
|
| 4 |
+
export type PositionLoggerNodeData = {
|
| 5 |
+
label?: string;
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
export function PositionLoggerNode({
|
| 9 |
+
xPos,
|
| 10 |
+
yPos,
|
| 11 |
+
data,
|
| 12 |
+
}: NodeProps<PositionLoggerNodeData>) {
|
| 13 |
+
const x = `${Math.round(xPos)}px`;
|
| 14 |
+
const y = `${Math.round(yPos)}px`;
|
| 15 |
+
|
| 16 |
+
return (
|
| 17 |
+
// We add this class to use the same styles as React Flow's default nodes.
|
| 18 |
+
<div className="react-flow__node-default">
|
| 19 |
+
{data.label && <div>{data.label}</div>}
|
| 20 |
+
|
| 21 |
+
<div>
|
| 22 |
+
{x} {y}
|
| 23 |
+
</div>
|
| 24 |
+
|
| 25 |
+
<Handle type="source" position={Position.Bottom} />
|
| 26 |
+
</div>
|
| 27 |
+
);
|
| 28 |
+
}
|
your-app-namenpx/src/nodes/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Node, NodeTypes } from "reactflow";
|
| 2 |
+
import { PositionLoggerNode } from "./PositionLoggerNode";
|
| 3 |
+
|
| 4 |
+
export const initialNodes = [
|
| 5 |
+
{ id: "a", type: "input", position: { x: 0, y: 0 }, data: { label: "wire" } },
|
| 6 |
+
{
|
| 7 |
+
id: "b",
|
| 8 |
+
type: "position-logger",
|
| 9 |
+
position: { x: -100, y: 100 },
|
| 10 |
+
data: { label: "drag me!" },
|
| 11 |
+
},
|
| 12 |
+
{ id: "c", position: { x: 100, y: 100 }, data: { label: "your ideas" } },
|
| 13 |
+
{
|
| 14 |
+
id: "d",
|
| 15 |
+
type: "output",
|
| 16 |
+
position: { x: 0, y: 200 },
|
| 17 |
+
data: { label: "with React Flow" },
|
| 18 |
+
},
|
| 19 |
+
] satisfies Node[];
|
| 20 |
+
|
| 21 |
+
export const nodeTypes = {
|
| 22 |
+
"position-logger": PositionLoggerNode,
|
| 23 |
+
// Add any of your custom nodes here!
|
| 24 |
+
} satisfies NodeTypes;
|
your-app-namenpx/src/vite-env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
/// <reference types="vite/client" />
|
your-app-namenpx/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"target": "ES2020",
|
| 4 |
+
"useDefineForClassFields": true,
|
| 5 |
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
| 6 |
+
"module": "ESNext",
|
| 7 |
+
"skipLibCheck": true,
|
| 8 |
+
|
| 9 |
+
/* Bundler mode */
|
| 10 |
+
"moduleResolution": "bundler",
|
| 11 |
+
"allowImportingTsExtensions": true,
|
| 12 |
+
"resolveJsonModule": true,
|
| 13 |
+
"isolatedModules": true,
|
| 14 |
+
"noEmit": true,
|
| 15 |
+
"jsx": "react-jsx",
|
| 16 |
+
|
| 17 |
+
/* Linting */
|
| 18 |
+
"strict": true,
|
| 19 |
+
"noUnusedLocals": true,
|
| 20 |
+
"noUnusedParameters": true,
|
| 21 |
+
"noFallthroughCasesInSwitch": true
|
| 22 |
+
},
|
| 23 |
+
"include": ["src"],
|
| 24 |
+
"references": [{ "path": "./tsconfig.node.json" }]
|
| 25 |
+
}
|
your-app-namenpx/tsconfig.node.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"composite": true,
|
| 4 |
+
"skipLibCheck": true,
|
| 5 |
+
"module": "ESNext",
|
| 6 |
+
"moduleResolution": "bundler",
|
| 7 |
+
"allowSyntheticDefaultImports": true
|
| 8 |
+
},
|
| 9 |
+
"include": ["vite.config.ts"]
|
| 10 |
+
}
|
your-app-namenpx/vite.config.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig } from 'vite'
|
| 2 |
+
import react from '@vitejs/plugin-react'
|
| 3 |
+
|
| 4 |
+
// https://vitejs.dev/config/
|
| 5 |
+
export default defineConfig({
|
| 6 |
+
plugins: [react()],
|
| 7 |
+
})
|