Skip to content

Commit

Permalink
Serve all react and svelte examples from a single app (#501)
Browse files Browse the repository at this point in the history
* 🚧 Experiment with a unified examples app for both react and svelte.

* 🔧 Wrap vite dev server so we can inject source.json files.

* 🚧 Try new iframe-based example viewer for dagre example.

* 📝 Replace svelte references with react.

* ♻️ Write a custom vite plugin to handle source.json generation.

* chore(pnpm): update lock file

* chore(example-apps): cleanup svelte example

* chore(tasks): start example apps dev server for react and svelte

* chore(example-apps): cleanup scaffolder

* 🔧 Add missing dagre dependency to dependencies.json.

* ✨ Create a <RemoteCodeViewer /> widget for example embeds.

* 🔧 No longer run svelte-examples app in dev.

* 🔧 Point env var to framework-specific example url.

* ♻️ Use remote code viewer for dagre examples.

* refactor(scaffold): make functions resuable

* feat(examples): add temp migration script

* feat(examples): use new example format

* chore(examples): update

* chore(examples): update

* chore(examples): cleanup

* chore(examples): cleanup

* chore(examples): cleanup

* chore(examples): remove example-flows yeahi

* chore(remote-code-viewer): cleanup

* ✨ Generate valid stackblitz projects.

* chore(examples): move learn examples to new format

* chore(learn): move to new remote code viewer

* chore(examples): migrate mindmap tutorial

* chore(tutorials): presentation examples

* chore(tutorials): migrate webaudio tutorial

* chore(react/examples): cleanup

* chore(svelte-examples): migrate

* chore(examples): cleanup

* chore(examples): use same env var for all sites

* chore(examples): cleanup

* chore(svelte-examples): cleanup

* chore(svelte-examples): adjust for vite template

* chore(code-viewer): hide bootstrap files

* feat(docs): add screenshot to examples, add overview page for svelte flow

* Update README.md

* fix(examples): copy preview images

* chore(screenshots): remove legacy app

* chore(svelte-examples): remove legacy app

* chore(example-apps): cleanup

* 🐛 Fixed a bug where d3-force example was not interactive in some browsers.

* chore(sites): remove unused code viewer components

* chore(examples): another cleanup

* chore(env): use new example apps url

* chore(sites): adjust remote image patterns

* chore(pnpm): update

* ♻️ Add tailwind play cdn to tailwind examples.

* 🐛 Fix incorrect url in base-style svelte example.

* 🐛 Fixed a bug where elk was not using nodes' measured dimensions.

* fix react computing flows example

* ✨ Generate an index page containing links to all the examples.

---------

Co-authored-by: moklick <info@moritzklack.com>
Co-authored-by: peterkogo <peter@xyflow.com>
  • Loading branch information
3 people authored Oct 8, 2024
1 parent 8e19dcc commit 63d216b
Show file tree
Hide file tree
Showing 1,764 changed files with 19,881 additions and 16,202 deletions.
1 change: 0 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ version: 2
updates:
- package-ecosystem: 'npm'
directories:
- '/apps/react-screenshots'
- '/packages/xy-shared'
- '/sites/reactflow.dev'
- '/sites/xyflow.com'
Expand Down
26 changes: 26 additions & 0 deletions apps/example-apps/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

public/
29 changes: 29 additions & 0 deletions apps/example-apps/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# xyflow example apps

## Scripts

### `pnpm dev`

Starts the vite dev server, with hot reloading. We have a custom plugin configured
to re-generate the `source.json` file whenever an example is updated, but this
will *not* hot-reload any external apps that are consuming it.

Also note that changing an example without triggering a hot-reload (eg you have
navigated to example `A` and then changed some files in example `B`) this wil
*not* trigger a re-generate of the `source.json` file.

### `pnpm scaffold`

You can run this script to generate a new React or Svelte example under a given
path. It will scaffold out all the files necessary for a new example, including
the entry `index.html` and a minimal React or Svelte component.

### `pnpm build`

Runs the `vite build` command. The same plugin that we use to generate the
`source.json` files during dev will be used here at the beginning of the build.

### `pnpm screenshots`

This command updates all preview screenshots for everything under /react and
/svelte.
72 changes: 72 additions & 0 deletions apps/example-apps/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>xyflow example apps</title>

<script src="https://cdn.tailwindcss.com"></script>
<script defer>
const addLink = (container, prefix, path) => {
const li = document.createElement('li');
const href = path + '/index.html';
const label = path.replace(prefix, '');

li.innerHTML = `<a href="${href}" class="hover:underline">${label}</a>`;
container.appendChild(li);
};

fetch('/all.json')
.then((res) => res.json())
.then(({ react, svelte }) => {
const reactList = document.getElementById('examples-react');
react.forEach((path) => {
addLink(reactList, 'react/', path);
});

const svelteList = document.getElementById('examples-svelte');
svelte.forEach((path) => {
addLink(svelteList, 'svelte/', path);
});
});
</script>
</head>
<body class="[&>*]:max-w-3xl [&>*]:mx-auto space-y-12 py-12">
<header class="space-y-8">
<h1 class="text-4xl font-bold mb-4">xyflow examples directory</h1>
<p>
Hello stranger! You've found your way over to the little app we have
hosting all of our examples here at xyflow. If you're not one of the
xyflow team, you're probably looking for one of our documentation sites:
</p>

<div
class="flex gap-4 [&>*]:flex-1 [&>*]:text-center [&>*]:rounded [&>*]:border [&>*]:p-4"
>
<a class="hover:bg-gray-50" href="https://www.reactflow.dev"
>reactflow.dev</a
>
<a class="hover:bg-gray-50" href="https://www.svelteflow.dev"
>svelteflow.dev</a
>
</div>

<p>
If you're still here, why not head over to our
<a class="underline" href="https://xyflow.com/careers">careers page</a>
and see if we're hiring, we'd love to chat ✌️
</p>
</header>

<main class="flex justify-between">
<section>
<h2 class="text-2xl font-bold mb-2">React examples</h2>
<ul id="examples-react"></ul>
</section>
<section>
<h2 class="text-2xl font-bold mb-2">Svelte examples</h2>
<ul id="examples-svelte"></ul>
</section>
</main>
</body>
</html>
56 changes: 56 additions & 0 deletions apps/example-apps/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "example-apps",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"scaffold": "node scripts/scaffold/index.js",
"screenshots": "concurrently \"vite dev\" \"node scripts/generate-screenshots.js\""
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@tsconfig/svelte": "^5.0.4",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.2.1",
"concurrently": "^9.0.1",
"cors": "^2.8.5",
"express": "^4.20.0",
"glob": "^11.0.0",
"picocolors": "^1.1.0",
"svelte-check": "^3.8.5",
"tslib": "^2.6.3",
"typescript": "^5.5.3",
"vite": "^5.4.1"
},
"dependencies": {
"@dagrejs/dagre": "^1.1.1",
"@threlte/core": "^6.1.0",
"@xyflow/react": "^12.1.1",
"@xyflow/svelte": "^0.1.16",
"d3-drag": "^3.0.0",
"d3-force": "^3.0.0",
"d3-hierarchy": "^3.1.2",
"d3-quadtree": "^3.0.1",
"d3-selection": "^3.0.0",
"elkjs": "^0.9.3",
"entitree-flex": "^0.4.1",
"html-to-image": "^1.11.11",
"nanoid": "^4.0.2",
"puppeteer": "^22.7.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.10.1",
"react-remark": "^2.1.0",
"styled-components": "^6.1.11",
"svelte": "^4.2.18",
"svelte-feather-icons": "^4.0.1",
"twind": "^0.16.19",
"webcola": "^3.4.0",
"zustand": "5.0.0-rc.2"
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useEffect, useMemo } from 'react';
import {
BaseEdge,
Edge,
EdgeProps,
getBezierPath,
useReactFlow,
type Edge,
type EdgeProps,
} from '@xyflow/react';

export type AnimatedNodeEdge = Edge<{ node: string }, 'animatedNode'>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import {
ReactFlow,
useNodesState,
useEdgesState,
Background,
} from '@xyflow/react';

import '@xyflow/react/dist/style.css';

import { AnimatedNodeEdge } from './AnimatedNodeEdge';

const initialNodes = [
{ id: '1', position: { x: -100, y: -200 }, data: { label: 'A' } },
{ id: '2', position: { x: 100, y: 200 }, data: { label: 'B' } },
{ id: '3', position: { x: 0, y: 0 }, data: { label: 'C' } },
];

const edgeTypes = {
animatedNode: AnimatedNodeEdge,
};

const initialEdges = [
{
id: '1->2',
type: 'animatedNode',
source: '1',
target: '2',
data: { node: '3' },
},
];

const EdgesFlow = () => {
const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, , onEdgesChange] = useEdgesState(initialEdges);

return (
<ReactFlow
nodes={nodes}
edges={edges}
edgeTypes={edgeTypes}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
fitView
>
<Background />
</ReactFlow>
);
};

export default EdgesFlow;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"@xyflow/react",
"react-dom",
"react"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
html,
body {
margin: 0;
font-family: sans-serif;
}

#app {
width: 100vw;
height: 100vh;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.tsx"></script>
</body>
</html>

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createRoot } from 'react-dom/client';
import App from './App';

import './index.css';

const container = document.querySelector('#app');
const root = createRoot(container);

root.render(<App />);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { BaseEdge, EdgeProps, getSmoothStepPath } from '@xyflow/react';
import { BaseEdge, getSmoothStepPath, type EdgeProps } from '@xyflow/react';

export function AnimatedSVGEdge({
id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"@xyflow/react",
"react-dom",
"react"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
html,
body {
margin: 0;
font-family: sans-serif;
}

#app {
width: 100vw;
height: 100vh;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.tsx"></script>
</body>
</html>

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createRoot } from 'react-dom/client';
import App from './App';

import './index.css';

const container = document.querySelector('#app');
const root = createRoot(container);

root.render(<App />);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"@xyflow/react",
"react-dom",
"react"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
html,
body {
margin: 0;
font-family: sans-serif;
box-sizing: border-box;
}

#app {
width: 100vw;
height: 100vh;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.jsx"></script>
</body>
</html>

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createRoot } from 'react-dom/client';
import App from './App';

import './index.css';

const container = document.querySelector('#app');
const root = createRoot(container);

root.render(<App />);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 63d216b

Please sign in to comment.