Merge branch 'xyflow' into feat/ssr

This commit is contained in:
moklick
2023-10-05 20:31:55 +02:00
21 changed files with 602 additions and 43 deletions
@@ -49,9 +49,9 @@ const DnDFlow = () => {
if (reactFlowInstance) {
const type = event.dataTransfer.getData('application/reactflow');
const position = reactFlowInstance.project({
const position = reactFlowInstance.screenToFlowCoordinate({
x: event.clientX,
y: event.clientY - 40,
y: event.clientY,
});
const newNode: Node = {
id: getId(),
@@ -15,7 +15,9 @@
'two-way-viewport',
'usesvelteflow',
'useupdatenodeinternals',
'validation'
'validation',
'intersections',
'add-node-on-drop'
];
const onChange = (event: Event) => {
@@ -0,0 +1,9 @@
<script lang="ts">
import { SvelteFlowProvider } from '@xyflow/svelte';
import Flow from './Flow.svelte';
</script>
<!-- You need the SvelteFlowProvider so you can useSvelteFlow -->
<SvelteFlowProvider>
<Flow />
</SvelteFlowProvider>
@@ -0,0 +1,115 @@
<script lang="ts">
import { SvelteFlow, useSvelteFlow } from '@xyflow/svelte';
import type { Edge, Node } from '@xyflow/svelte';
import { writable } from 'svelte/store';
import '@xyflow/svelte/dist/style.css';
const initialNodes: Node[] = [
{
id: '0',
type: 'input',
data: { label: 'Node' },
position: { x: 0, y: 50 }
}
];
const nodes = writable<Node[]>(initialNodes);
const edges = writable<Edge[]>([]);
let connectingNodeId: string = '0';
let rect: DOMRectReadOnly;
let id = 1;
const getId = () => `${id++}`;
const { screenToFlowCoordinate, flowToScreenCoordinate } = useSvelteFlow();
function handleConnectEnd({ detail: { event } }: { detail: { event: MouseEvent | TouchEvent } }) {
// See of connection landed inside the flow pane
const targetIsPane = event.target?.classList.contains('svelte-flow__pane');
if (targetIsPane) {
const id = getId();
const position = {
x: event.clientX,
y: event.clientY
};
const doubleTransformedPosition = flowToScreenCoordinate(screenToFlowCoordinate(position));
console.log(
'Is transforming in both directions (screen-flow, flow-screen) the same?',
position.x === doubleTransformedPosition.x && position.y === doubleTransformedPosition.y
);
const newNode: Node = {
id,
data: { label: `Node ${id}` },
// project the screen coordinates to pane coordinates
position: screenToFlowCoordinate(position),
// set the origin of the new node so it is centered
origin: [0.5, 0.0]
};
$nodes.push(newNode);
$edges.push({
source: connectingNodeId,
target: id,
id: `${connectingNodeId}--${id}`
});
$nodes = $nodes;
$edges = $edges;
}
}
</script>
<svelte:window />
<div class="wrapper" bind:contentRect={rect}>
<SvelteFlow
{nodes}
{edges}
fitView
fitViewOptions={{ padding: 2 }}
on:connectstart={({ detail: { nodeId } }) => {
// Memorize the nodeId you start draggin a connection line from a node
connectingNodeId = nodeId;
}}
on:connectend={handleConnectEnd}
/>
</div>
<style>
:global(.svelte-flow .svelte-flow__handle) {
width: 30px;
height: 14px;
border-radius: 3px;
background-color: #784be8;
}
:global(.svelte-flow .svelte-flow__handle-top) {
top: -10px;
}
:global(.svelte-flow .svelte-flow__handle-bottom) {
bottom: -10px;
}
:global(.svelte-flow .svelte-flow__node) {
height: 40px;
width: 150px;
justify-content: center;
align-items: center;
display: flex;
border-width: 2px;
font-weight: 700;
}
:global(.svelte-flow .svelte-flow__edge path, .svelte-flow__connectionline path) {
stroke-width: 2;
}
.wrapper {
height: 100vh;
width: 100vw;
}
</style>
@@ -0,0 +1,8 @@
<script lang="ts">
import { SvelteFlowProvider } from '@xyflow/svelte';
import Flow from './Flow.svelte';
</script>
<SvelteFlowProvider>
<Flow />
</SvelteFlowProvider>
@@ -0,0 +1,29 @@
// Template for ALL endpoints serving the code snippets
// No need to edit these inside /src/routes/**
// Will be overwritten by "pnpm run create:endpoints"
import { json } from '@sveltejs/kit';
export function POST() {
const files = import.meta.glob(['./*.js', './*.ts', './*.svelte', './*css', '!**/+server.ts'], {
as: 'raw',
eager: true
});
// Loose ./ for each filename
// +page.svelte becomes App.svelte for correct display in Sandpack
const filesClean: { [key: string]: string } = Object.entries(files).reduce(
(filesCleanAcc: { [key: string]: string }, [filename, file]) => {
if (filename === './+page.svelte') {
filesCleanAcc['App.svelte'] = file;
} else {
filesCleanAcc[filename.replace('./', '')] = file;
}
return filesCleanAcc;
},
{}
);
return json(filesClean);
}
@@ -0,0 +1,60 @@
<script lang="ts">
import { SvelteFlow, Background, Controls, useSvelteFlow } from '@xyflow/svelte';
import type { Edge, Node } from '@xyflow/svelte';
import { writable } from 'svelte/store';
import '@xyflow/svelte/dist/style.css';
import { initialNodes, initialEdges } from './nodes-and-edges';
const nodes = writable<Node[]>(initialNodes);
const edges = writable<Edge[]>(initialEdges);
const { getIntersectingNodes } = useSvelteFlow();
function onNodeDrag({ detail: { node } }) {
const intersections = getIntersectingNodes(node).map((n) => n.id);
$nodes.forEach((n) => {
n.class = intersections.includes(n.id) ? 'highlight' : '';
});
$nodes = $nodes;
}
</script>
<div style="height:100vh;">
<SvelteFlow {nodes} {edges} fitView class="intersection-flow" on:nodedrag={onNodeDrag}>
<Background />
<Controls />
</SvelteFlow>
</div>
<style>
:global(.svelte-flow__node.highlight) {
background-color: #ff0072 !important;
color: white;
}
:global(.intersection-flow .svelte-flow__node) {
display: flex;
justify-content: center;
align-items: center;
font-weight: 700;
border-radius: 1px;
border-width: 2px;
box-shadow: 6px 6px 0 1px rgba(0, 0, 0, 0.7);
}
:global(
.intersection-flow .svelte-flow__node.selected,
.intersection-flow .svelte-flow__node:hover,
.intersection-flow .svelte-flow__node:focus
) {
box-shadow: 6px 6px 0 1px rgba(0, 0, 0, 0.7);
background-color: #eee;
}
:global(.intersection-flow .svelte-flow__handle) {
display: none;
}
</style>
@@ -0,0 +1,28 @@
import type { Node, Edge } from '@xyflow/svelte';
export const initialNodes: Node[] = [
{
id: '1',
data: { label: 'Node 1' },
position: { x: 0, y: 0 },
style: 'width: 200px; height: 100px;'
},
{
id: '2',
data: { label: 'Node 2' },
position: { x: 0, y: 150 }
},
{
id: '3',
data: { label: 'Node 3' },
position: { x: 250, y: 0 }
},
{
id: '4',
data: { label: 'Node' },
position: { x: 350, y: 150 },
style: 'width: 50px; height: 50px;'
}
];
export const initialEdges: Edge[] = [];