From 7193b55ff2add22333b5be41073772511a5ebdf2 Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 27 Nov 2023 11:29:43 +0100 Subject: [PATCH 1/6] chore(examples): cleanup --- examples/svelte/src/components/Header/Header.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/svelte/src/components/Header/Header.svelte b/examples/svelte/src/components/Header/Header.svelte index 7d229796..ad34d289 100644 --- a/examples/svelte/src/components/Header/Header.svelte +++ b/examples/svelte/src/components/Header/Header.svelte @@ -4,7 +4,7 @@ const routes = [ 'add-node-on-drop', - 'colormode', + 'color-mode', 'custom-connection-line', 'customnode', 'dagre', From 1eea7209a3b73bf4b90f49d3134ebdca6e209a0a Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 28 Nov 2023 14:45:21 +0100 Subject: [PATCH 2/6] fix(svelte) fix getIntersectingNodes, closes #3675 --- packages/svelte/src/lib/hooks/useSvelteFlow.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/svelte/src/lib/hooks/useSvelteFlow.ts b/packages/svelte/src/lib/hooks/useSvelteFlow.ts index fb1419ec..3c266f43 100644 --- a/packages/svelte/src/lib/hooks/useSvelteFlow.ts +++ b/packages/svelte/src/lib/hooks/useSvelteFlow.ts @@ -136,12 +136,12 @@ export function useSvelteFlow(): { ) => { const [nodeRect, node, isRect] = getNodeRect(nodeOrRect); - if (!nodeRect || !node) { + if (!nodeRect) { return []; } return (nodesToIntersect || get(nodes)).filter((n) => { - if (!isRect && (n.id === node.id || !n.computed?.positionAbsolute)) { + if (!isRect && (n.id === node!.id || !n.computed?.positionAbsolute)) { return false; } From 3f94dfa84cdab9aae690599214a6c1650f06d3d6 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 28 Nov 2023 15:48:19 +0100 Subject: [PATCH 3/6] feat(svelte) added onedgecreate function --- .../svelte/src/routes/examples/edges/+page.svelte | 11 ++++++++++- .../svelte/src/lib/components/Handle/Handle.svelte | 11 ++++++++++- .../src/lib/container/SvelteFlow/SvelteFlow.svelte | 2 ++ packages/svelte/src/lib/container/SvelteFlow/types.ts | 5 ++++- packages/svelte/src/lib/container/SvelteFlow/utils.ts | 1 + packages/svelte/src/lib/store/initial-store.ts | 6 ++++-- packages/svelte/src/lib/types/general.ts | 4 +++- 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/examples/svelte/src/routes/examples/edges/+page.svelte b/examples/svelte/src/routes/examples/edges/+page.svelte index 403b0ef6..575984ca 100644 --- a/examples/svelte/src/routes/examples/edges/+page.svelte +++ b/examples/svelte/src/routes/examples/edges/+page.svelte @@ -145,7 +145,16 @@ ]); - + { + console.log('on edge create', e); + return e; + }} +> diff --git a/packages/svelte/src/lib/components/Handle/Handle.svelte b/packages/svelte/src/lib/components/Handle/Handle.svelte index 655bcc6b..7d3010bd 100644 --- a/packages/svelte/src/lib/components/Handle/Handle.svelte +++ b/packages/svelte/src/lib/components/Handle/Handle.svelte @@ -55,6 +55,7 @@ isValidConnection, lib, addEdge, + onedgecreate, panBy, cancelConnection, updateConnection, @@ -80,8 +81,16 @@ cancelConnection, panBy, onConnect: (connection) => { - addEdge(connection); + if ($onedgecreate) { + const modifiedConnection = $onedgecreate(connection); + if (modifiedConnection) { + addEdge(modifiedConnection); + dispatch('connect', { connection }); + } + return; + } + addEdge(connection); // @todo: should we change/ improve the stuff we are passing here? // instead of source/target we could pass fromNodeId, fromHandleId, etc dispatch('connect', { connection }); diff --git a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte index 59bff1f4..21ceec49 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte +++ b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte @@ -71,6 +71,7 @@ export let autoPanOnNodeDrag: $$Props['autoPanOnNodeDrag'] = true; export let onerror: $$Props['onerror'] = undefined; export let ondelete: $$Props['ondelete'] = undefined; + export let onedgecreate: $$Props['onedgecreate'] = undefined; export let attributionPosition: $$Props['attributionPosition'] = undefined; export let proOptions: $$Props['proOptions'] = undefined; export let defaultEdgeOptions: $$Props['defaultEdgeOptions'] = undefined; @@ -149,6 +150,7 @@ autoPanOnNodeDrag, onerror, ondelete, + onedgecreate, connectionMode, nodeDragThreshold }; diff --git a/packages/svelte/src/lib/container/SvelteFlow/types.ts b/packages/svelte/src/lib/container/SvelteFlow/types.ts index daab48e9..9116dc60 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/types.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/types.ts @@ -26,7 +26,8 @@ import type { EdgeTypes, DefaultEdgeOptions, FitViewOptions, - OnDelete + OnDelete, + OnEdgeCreate } from '$lib/types'; import type { Writable } from 'svelte/store'; @@ -89,4 +90,6 @@ export type SvelteFlowProps = DOMAttributes & { onMoveEnd?: OnMoveEnd; onerror?: OnError; ondelete?: OnDelete; + + onedgecreate?: OnEdgeCreate; }; diff --git a/packages/svelte/src/lib/container/SvelteFlow/utils.ts b/packages/svelte/src/lib/container/SvelteFlow/utils.ts index 9abdb3e9..0281cd55 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/utils.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/utils.ts @@ -64,6 +64,7 @@ export type UpdatableStoreProps = { connectionMode?: UnwrapWritable; onerror?: UnwrapWritable; ondelete?: UnwrapWritable; + onedgecreate?: UnwrapWritable; nodeDragThreshold?: UnwrapWritable; }; diff --git a/packages/svelte/src/lib/store/initial-store.ts b/packages/svelte/src/lib/store/initial-store.ts index dbbb17fc..8f358cf9 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -35,7 +35,8 @@ import type { Node, Edge, FitViewOptions, - OnDelete + OnDelete, + OnEdgeCreate } from '$lib/types'; import { createNodesStore, createEdgesStore } from './utils'; import { initConnectionProps, type ConnectionProps } from './derived-connection-props'; @@ -130,6 +131,7 @@ export const getInitialStore = ({ lib: readable('svelte'), onlyRenderVisibleElements: writable(false), onerror: writable(devWarn), - ondelete: writable(undefined) + ondelete: writable(undefined), + onedgecreate: writable(undefined) }; }; diff --git a/packages/svelte/src/lib/types/general.ts b/packages/svelte/src/lib/types/general.ts index 14764318..62666705 100644 --- a/packages/svelte/src/lib/types/general.ts +++ b/packages/svelte/src/lib/types/general.ts @@ -4,7 +4,8 @@ import type { HandleType, Position, XYPosition, - ConnectingHandle + ConnectingHandle, + Connection } from '@xyflow/system'; import type { Node } from './nodes'; @@ -35,3 +36,4 @@ export type HandleComponentProps = { export type FitViewOptions = FitViewOptionsBase; export type OnDelete = (params: { nodes: Node[]; edges: Edge[] }) => void; +export type OnEdgeCreate = (connection: Connection) => Edge | Connection | void; From a1e585fdccce432e237ad85b45d459223d0ec38c Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 28 Nov 2023 16:35:44 +0100 Subject: [PATCH 4/6] refactor(css-vars): prefix with xy and fix bgColor prop closes #3669 --- .../react/src/examples/ColorMode/index.tsx | 2 + .../react/src/examples/ColorMode/style.css | 0 .../routes/examples/customnode/+page.svelte | 2 +- .../Background/Background.tsx | 4 +- .../additional-components/MiniMap/MiniMap.tsx | 8 +- .../lib/plugins/Background/Background.svelte | 4 +- .../lib/plugins/Controls/ControlButton.svelte | 10 +- .../src/lib/plugins/Minimap/Minimap.svelte | 8 +- packages/system/src/styles/base.css | 24 ++-- packages/system/src/styles/init.css | 108 ++++++++--------- packages/system/src/styles/style.css | 109 +++++++++--------- 11 files changed, 144 insertions(+), 135 deletions(-) create mode 100644 examples/react/src/examples/ColorMode/style.css diff --git a/examples/react/src/examples/ColorMode/index.tsx b/examples/react/src/examples/ColorMode/index.tsx index f867c650..eae8ad86 100644 --- a/examples/react/src/examples/ColorMode/index.tsx +++ b/examples/react/src/examples/ColorMode/index.tsx @@ -15,6 +15,8 @@ import { Position, } from '@xyflow/react'; +import './style.css'; + const nodeDefaults = { sourcePosition: Position.Right, targetPosition: Position.Left, diff --git a/examples/react/src/examples/ColorMode/style.css b/examples/react/src/examples/ColorMode/style.css new file mode 100644 index 00000000..e69de29b diff --git a/examples/svelte/src/routes/examples/customnode/+page.svelte b/examples/svelte/src/routes/examples/customnode/+page.svelte index 14130a47..123932f9 100644 --- a/examples/svelte/src/routes/examples/customnode/+page.svelte +++ b/examples/svelte/src/routes/examples/customnode/+page.svelte @@ -85,7 +85,7 @@ {nodes} {edges} {nodeTypes} - style="--background-color: {$bgColor}" + style="--xy-background-color: {$bgColor}" fitView on:connect={onConnect} > diff --git a/packages/react/src/additional-components/Background/Background.tsx b/packages/react/src/additional-components/Background/Background.tsx index 843daf19..3e71d723 100644 --- a/packages/react/src/additional-components/Background/Background.tsx +++ b/packages/react/src/additional-components/Background/Background.tsx @@ -55,8 +55,8 @@ function Background({ { ...style, ...containerStyle, - '--background-color-props': bgColor, - '--background-pattern-color-props': color, + '--xy-background-color-props': bgColor, + '--xy-background-pattern-color-props': color, } as CSSProperties } ref={ref} diff --git a/packages/react/src/additional-components/MiniMap/MiniMap.tsx b/packages/react/src/additional-components/MiniMap/MiniMap.tsx index 33848836..8d1f0538 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMap.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMap.tsx @@ -129,10 +129,10 @@ function MiniMap({ style={ { ...style, - '--minimap-mask-color-props': typeof maskColor === 'string' ? maskColor : undefined, - '--minimap-node-background-color-props': typeof nodeColor === 'string' ? nodeColor : undefined, - '--minimap-node-stroke-color-props': typeof nodeStrokeColor === 'string' ? nodeStrokeColor : undefined, - '--minimap-node-stroke-width-props': typeof nodeStrokeWidth === 'string' ? nodeStrokeWidth : undefined, + '--xy-minimap-mask-color-props': typeof maskColor === 'string' ? maskColor : undefined, + '--xy-minimap-node-background-color-props': typeof nodeColor === 'string' ? nodeColor : undefined, + '--xy-minimap-node-stroke-color-props': typeof nodeStrokeColor === 'string' ? nodeStrokeColor : undefined, + '--xy-minimap-node-stroke-width-props': typeof nodeStrokeWidth === 'string' ? nodeStrokeWidth : undefined, } as CSSProperties } className={cc(['react-flow__minimap', className])} diff --git a/packages/svelte/src/lib/plugins/Background/Background.svelte b/packages/svelte/src/lib/plugins/Background/Background.svelte index 67689ab9..c6a67d48 100644 --- a/packages/svelte/src/lib/plugins/Background/Background.svelte +++ b/packages/svelte/src/lib/plugins/Background/Background.svelte @@ -45,8 +45,8 @@ diff --git a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte index 67f93698..7b2896d8 100644 --- a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte +++ b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte @@ -94,10 +94,10 @@ viewBox="{x} {y} {viewboxWidth} {viewboxHeight}" role="img" aria-labelledby={labelledBy} - style:--minimap-background-color-props={bgColor} - style:--minimap-mask-color-props={maskColor} - style:--minimap-mask-stroke-color-props={maskStrokeColor} - style:--minimap-mask-stroke-width-props={maskStrokeWidth} + style:--xy-minimap-background-color-props={bgColor} + style:--xy-minimap-mask-color-props={maskColor} + style:--xy-minimap-mask-stroke-color-props={maskStrokeColor} + style:--xy-minimap-mask-stroke-width-props={maskStrokeWidth} use:interactive={{ panZoom: $panZoom, viewport, diff --git a/packages/system/src/styles/base.css b/packages/system/src/styles/base.css index 1cb026b6..3a5afe6c 100644 --- a/packages/system/src/styles/base.css +++ b/packages/system/src/styles/base.css @@ -1,38 +1,38 @@ .xy-flow { - --node-border-default: 1px solid #bbb; - --node-border-selected-default: 1px solid #555; + --xy-node-border-default: 1px solid #bbb; + --xy-node-border-selected-default: 1px solid #555; - --handle-background-color-default: #333; + --xy-handle-background-color-default: #333; - --selection-background-color-default: rgba(150, 150, 180, 0.1); - --selection-border-default: 1px dotted rgba(155, 155, 155, 0.8); + --xy-selection-background-color-default: rgba(150, 150, 180, 0.1); + --xy-selection-border-default: 1px dotted rgba(155, 155, 155, 0.8); } .xy-flow.dark { - --node-color-default: #f8f8f8; + --xy-node-color-default: #f8f8f8; } .xy-flow__handle { - background-color: var(--handle-background-color, var(--handle-background-color-default)); + background-color: var(--xy-handle-background-color, var(--xy-handle-background-color-default)); } .xy-flow__node-input, .xy-flow__node-default, .xy-flow__node-output, .xy-flow__node-group { - border: var(--node-border, var(--node-border-default)); - color: var(--node-color, var(--node-color-default)); + border: var(--xy-node-border, var(--xy-node-border-default)); + color: var(--xy-node-color, var(--xy-node-color-default)); &.selected, &:focus, &:focus-visible { outline: none; - border: var(--node-border-selected, var(--node-border-selected-default)); + border: var(--xy-node-border-selected, var(--xy-node-border-selected-default)); } } .xy-flow__nodesselection-rect, .xy-flow__selection { - background: var(--selection-background-color, var(--selection-background-color-default)); - border: var(--selection-border, var(--selection-border-default)); + background: var(--xy-selection-background-color, var(--xy-selection-background-color-default)); + border: var(--xy-selection-border, var(--xy-selection-border-default)); } diff --git a/packages/system/src/styles/init.css b/packages/system/src/styles/init.css index 474b1322..2aff146f 100644 --- a/packages/system/src/styles/init.css +++ b/packages/system/src/styles/init.css @@ -1,51 +1,55 @@ /* these are the necessary styles for React/Svelte Flow, they get used by base.css and style.css */ .xy-flow { - --edge-stroke-default: #b1b1b7; - --edge-stroke-width-default: 1; - --edge-stroke-selected-default: #555; + --xy-edge-stroke-default: #b1b1b7; + --xy-edge-stroke-width-default: 1; + --xy-edge-stroke-selected-default: #555; - --connectionline-stroke-default: #b1b1b7; - --connectionline-stroke-width-default: 1; + --xy-connectionline-stroke-default: #b1b1b7; + --xy-connectionline-stroke-width-default: 1; - --attribution-background-color-default: rgba(255, 255, 255, 0.5); + --xy-attribution-background-color-default: rgba(255, 255, 255, 0.5); - --minimap-background-color-default: #fff; - --minimap-mask-background-color-default: rgb(240, 240, 240, 0.6); - --minimap-node-background-color-default: #e2e2e2; - --minimap-node-stroke-color-default: transparent; - --minimap-node-stroke-width-default: 2; + --xy-minimap-background-color-default: #fff; + --xy-minimap-mask-background-color-default: rgb(240, 240, 240, 0.6); + --xy-minimap-node-background-color-default: #e2e2e2; + --xy-minimap-node-stroke-color-default: transparent; + --xy-minimap-node-stroke-width-default: 2; - --background-color-default: transparent; - --background-pattern-dots-color-default: #91919a; - --background-pattern-lines-color-default: #eee; - --background-pattern-cross-color-default: #e2e2e2; + --xy-background-color-default: transparent; + --xy-background-pattern-dots-color-default: #91919a; + --xy-background-pattern-lines-color-default: #eee; + --xy-background-pattern-cross-color-default: #e2e2e2; } .xy-flow.dark { - --edge-stroke-default: #3c3c3c; - --edge-stroke-width-default: 1; - --edge-stroke-selected-default: #727272; + --xy-edge-stroke-default: #3c3c3c; + --xy-edge-stroke-width-default: 1; + --xy-edge-stroke-selected-default: #727272; - --connectionline-stroke-default: #b1b1b7; - --connectionline-stroke-width-default: 1; + --xy-connectionline-stroke-default: #b1b1b7; + --xy-connectionline-stroke-width-default: 1; - --attribution-background-color-default: rgba(150, 150, 150, 0.25); + --xy-attribution-background-color-default: rgba(150, 150, 150, 0.25); - --minimap-background-color-default: #141414; - --minimap-mask-background-color-default: rgb(60, 60, 60, 0.6); - --minimap-node-background-color-default: #2b2b2b; - --minimap-node-stroke-color-default: transparent; - --minimap-node-stroke-width-default: 2; + --xy-minimap-background-color-default: #141414; + --xy-minimap-mask-background-color-default: rgb(60, 60, 60, 0.6); + --xy-minimap-node-background-color-default: #2b2b2b; + --xy-minimap-node-stroke-color-default: transparent; + --xy-minimap-node-stroke-width-default: 2; - --background-color-default: #141414; - --background-pattern-dots-color-default: #777; - --background-pattern-lines-color-default: #777; - --background-pattern-cross-color-default: #777; + --xy-background-color-default: #141414; + --xy-background-pattern-dots-color-default: #777; + --xy-background-pattern-lines-color-default: #777; + --xy-background-pattern-cross-color-default: #777; } .xy-flow { - background-color: var(--background-color-props, var(--background-color-default, 'transparent')); + background-color: var(--xy-background-color, var(--xy-background-color-default)); +} + +.xy-flow__background { + background-color: var(--xy-background-color, var(--xy-background-color-props, var(--xy-background-color-default))); } .xy-flow__container { @@ -94,14 +98,14 @@ } .xy-flow__edge-path { - stroke: var(--edge-stroke, var(--edge-stroke-default)); - stroke-width: var(--edge-stroke-width, var(--edge-stroke-width-default)); + stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default)); + stroke-width: var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default)); fill: none; } .xy-flow__connection-path { - stroke: var(--connectionline-stroke, var(--connectionline-stroke-default)); - stroke-width: var(--connectionline-stroke-width, var(--connectionline-stroke-width-default)); + stroke: var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default)); + stroke-width: var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default)); fill: none; } @@ -132,7 +136,7 @@ &.selected .xy-flow__edge-path, &:focus .xy-flow__edge-path, &:focus-visible .xy-flow__edge-path { - stroke: var(--edge-stroke-selected, var(--edge-stroke-selected-default)); + stroke: var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default)); } &-textwrapper { @@ -266,7 +270,7 @@ .xy-flow__attribution { font-size: 10px; - background: var(--attribution-background-color, var(--attribution-background-color-default)); + background: var(--xy-attribution-background-color, var(--xy-attribution-background-color-default)); padding: 2px 3px; margin: 0; @@ -293,27 +297,27 @@ } .xy-flow__minimap { - background: var(--minimap-background-color, var(--minimap-background-color-default)); + background: var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)); &-mask { fill: var( - --minimap-mask-background-color-props, - var(--minimap-mask-background-color, var(--minimap-mask-background-color-default)) + --xy-minimap-mask-background-color-props, + var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) ); } &-node { fill: var( - --minimap-node-background-color-props, - var(--minimap-node-background-color, var(--minimap-node-background-color-default)) + --xy-minimap-node-background-color-props, + var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) ); stroke: var( - --minimap-node-stroke-color-props, - var(--minimap-node-stroke-color, var(--minimap-node-stroke-color-default)) + --xy-minimap-node-stroke-color-props, + var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) ); stroke-width: var( - --minimap-node-stroke-width-props, - var(--minimap-node-stroke-width, var(--minimap-node-stroke-width-default)) + --xy-minimap-node-stroke-width-props, + var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) ); } } @@ -326,22 +330,22 @@ .xy-flow__background-pattern { &.dots { fill: var( - --background-pattern-color-props, - var(--background-pattern-color, var(--background-pattern-dots-color-default)) + --xy-background-pattern-color-props, + var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) ); } &.lines { stroke: var( - --background-pattern-color-props, - var(--background-pattern-color, var(--background-pattern-lines-color-default)) + --xy-background-pattern-color-props, + var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) ); } &.cross { stroke: var( - --background-pattern-color-props, - var(--background-pattern-color, var(--background-pattern-cross-color-default)) + --xy-background-pattern-color-props, + var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) ); } } diff --git a/packages/system/src/styles/style.css b/packages/system/src/styles/style.css index e88cc3f1..880ebaf7 100644 --- a/packages/system/src/styles/style.css +++ b/packages/system/src/styles/style.css @@ -1,46 +1,46 @@ .xy-flow { - --node-color-default: inherit; - --node-border-default: 1px solid #1a192b; - --node-background-color-default: #fff; - --node-group-background-color-default: rgba(240, 240, 240, 0.25); - --node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, 0.08); - --node-boxshadow-selected-default: 0 0 0 0.5px #1a192b; - --node-border-radius-default: 3px; + --xy-node-color-default: inherit; + --xy-node-border-default: 1px solid #1a192b; + --xy-node-background-color-default: #fff; + --xy-node-group-background-color-default: rgba(240, 240, 240, 0.25); + --xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, 0.08); + --xy-node-boxshadow-selected-default: 0 0 0 0.5px #1a192b; + --xy-node-border-radius-default: 3px; - --handle-background-color-default: #1a192b; - --handle-border-color-default: #fff; + --xy-handle-background-color-default: #1a192b; + --xy-handle-border-color-default: #fff; - --selection-background-color-default: rgba(0, 89, 220, 0.08); - --selection-border-default: 1px dotted rgba(0, 89, 220, 0.8); + --xy-selection-background-color-default: rgba(0, 89, 220, 0.08); + --xy-selection-border-default: 1px dotted rgba(0, 89, 220, 0.8); - --controls-button-background-color-default: #fefefe; - --controls-button-background-color-hover-default: #f4f4f4; - --controls-button-color-default: inherit; - --controls-button-color-hover-default: inherit; - --controls-button-border-color-default: #eee; - --controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08); + --xy-controls-button-background-color-default: #fefefe; + --xy-controls-button-background-color-hover-default: #f4f4f4; + --xy-controls-button-color-default: inherit; + --xy-controls-button-color-hover-default: inherit; + --xy-controls-button-border-color-default: #eee; + --xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08); } .xy-flow.dark { - --node-color-default: #f8f8f8; - --node-border-default: 1px solid #3c3c3c; - --node-background-color-default: #1e1e1e; - --node-group-background-color-default: rgba(240, 240, 240, 0.25); - --node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, 0.08); - --node-boxshadow-selected-default: 0 0 0 0.5px #999; + --xy-node-color-default: #f8f8f8; + --xy-node-border-default: 1px solid #3c3c3c; + --xy-node-background-color-default: #1e1e1e; + --xy-node-group-background-color-default: rgba(240, 240, 240, 0.25); + --xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, 0.08); + --xy-node-boxshadow-selected-default: 0 0 0 0.5px #999; - --handle-background-color-default: #bebebe; - --handle-border-color-default: #1e1e1e; + --xy-handle-background-color-default: #bebebe; + --xy-handle-border-color-default: #1e1e1e; - --selection-background-color-default: rgba(200, 200, 220, 0.08); - --selection-border-default: 1px dotted rgba(200, 200, 220, 0.8); + --xy-selection-background-color-default: rgba(200, 200, 220, 0.08); + --xy-selection-border-default: 1px dotted rgba(200, 200, 220, 0.8); - --controls-button-background-color-default: #2b2b2b; - --controls-button-background-color-hover-default: #3e3e3e; - --controls-button-color-default: #f8f8f8; - --controls-button-color-hover-default: #fff; - --controls-button-border-color-default: #5b5b5b; - --controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08); + --xy-controls-button-background-color-default: #2b2b2b; + --xy-controls-button-background-color-hover-default: #3e3e3e; + --xy-controls-button-color-default: #f8f8f8; + --xy-controls-button-color-hover-default: #fff; + --xy-controls-button-border-color-default: #5b5b5b; + --xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08); } .xy-flow__edge { @@ -67,35 +67,35 @@ .xy-flow__node-output, .xy-flow__node-group { padding: 10px; - border-radius: var(--node-border-radius, var(--node-border-radius-default)); + border-radius: var(--xy-node-border-radius, var(--xy-node-border-radius-default)); width: 150px; font-size: 12px; - color: var(--node-color, var(--node-color-default)); + color: var(--xy-node-color, var(--xy-node-color-default)); text-align: center; - border: var(--node-border, var(--node-border-default)); - background-color: var(--node-background-color, var(--node-background-color-default)); + border: var(--xy-node-border, var(--xy-node-border-default)); + background-color: var(--xy-node-background-color, var(--xy-node-background-color-default)); &.selectable { &:hover { - box-shadow: var(--node-boxshadow-hover, var(--node-boxshadow-hover-default)); + box-shadow: var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default)); } &.selected, &:focus, &:focus-visible { - box-shadow: var(--node-boxshadow-selected, var(--node-boxshadow-selected-default)); + box-shadow: var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default)); } } } .xy-flow__node-group { - background-color: var(--node-group-background-color, var(--node-group-background-color-default)); + background-color: var(--xy-node-group-background-color, var(--xy-node-group-background-color-default)); } .xy-flow__nodesselection-rect, .xy-flow__selection { - background: var(--selection-background-color, var(--selection-background-color-default)); - border: var(--selection-border, var(--selection-border-default)); + background: var(--xy-selection-background-color, var(--xy-selection-background-color-default)); + border: var(--xy-selection-border, var(--xy-selection-border-default)); &:focus, &:focus-visible { @@ -106,34 +106,37 @@ .xy-flow__handle { width: 6px; height: 6px; - background-color: var(--handle-background-color, var(--handle-background-color-default)); - border: 1px solid var(--handle-border-color, var(--handle-border-color-default)); + background-color: var(--xy-handle-background-color, var(--xy-handle-background-color-default)); + border: 1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default)); border-radius: 100%; } .xy-flow__controls { - box-shadow: var(--controls-box-shadow, var(--controls-box-shadow-default)); + box-shadow: var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default)); &-button { border: none; - background: var(--controls-button-background-color, var(--controls-button-background-color-default)); + background: var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default)); border-bottom: 1px solid var( - --controls-button-border-color-props, - var(--controls-button-border-color, var(--controls-button-border-color-default)) + --xy-controls-button-border-color-props, + var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) ); - color: var(--controls-button-color-props, var(--controls-button-color, var(--controls-button-color-default))); + color: var( + --xy-controls-button-color-props, + var(--xy-controls-button-color, var(--xy-controls-button-color-default)) + ); cursor: pointer; user-select: none; &:hover { background: var( - --controls-button-background-color-hover-props, - var(--controls-button-background-color-hover, var(--controls-button-background-color-hover-default)) + --xy-controls-button-background-color-hover-props, + var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) ); color: var( - --controls-button-color-hover-props, - var(--controls-button-color-hover, var(--controls-button-color-hover-default)) + --xy-controls-button-color-hover-props, + var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) ); } From 1d7803aff7a0812c3f07a559defc69fbdcf59e2b Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 28 Nov 2023 16:50:17 +0100 Subject: [PATCH 5/6] chore(svelte/onConnect): cleanup --- .../svelte/src/lib/components/Handle/Handle.svelte | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/svelte/src/lib/components/Handle/Handle.svelte b/packages/svelte/src/lib/components/Handle/Handle.svelte index 7d3010bd..745a0f28 100644 --- a/packages/svelte/src/lib/components/Handle/Handle.svelte +++ b/packages/svelte/src/lib/components/Handle/Handle.svelte @@ -80,20 +80,17 @@ updateConnection, cancelConnection, panBy, - onConnect: (connection) => { - if ($onedgecreate) { - const modifiedConnection = $onedgecreate(connection); - if (modifiedConnection) { - addEdge(modifiedConnection); - dispatch('connect', { connection }); - } + onConnect: (_connection) => { + let connection = $onedgecreate ? $onedgecreate(_connection) : _connection; + + if (!connection) { return; } addEdge(connection); // @todo: should we change/ improve the stuff we are passing here? // instead of source/target we could pass fromNodeId, fromHandleId, etc - dispatch('connect', { connection }); + dispatch('connect', { connection: _connection }); }, onConnectStart: (event, startParams) => { dispatch('connectstart', { From 95acea54d1dfab616a42ee1900797377c87d123d Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 29 Nov 2023 16:33:57 +0100 Subject: [PATCH 6/6] chore(react/svelte): cleanup edge creation --- .../src/routes/examples/edges/+page.svelte | 19 +++++++++++++++---- .../src/lib/components/Handle/Handle.svelte | 10 +++++----- packages/system/src/utils/edges/general.ts | 10 +++++++++- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/examples/svelte/src/routes/examples/edges/+page.svelte b/examples/svelte/src/routes/examples/edges/+page.svelte index 575984ca..f201a02d 100644 --- a/examples/svelte/src/routes/examples/edges/+page.svelte +++ b/examples/svelte/src/routes/examples/edges/+page.svelte @@ -6,7 +6,8 @@ Background, BackgroundVariant, MiniMap, - MarkerType + MarkerType, + type Connection } from '@xyflow/svelte'; import '@xyflow/svelte/dist/style.css'; @@ -143,6 +144,12 @@ } } ]); + + $: console.log('edges', $edges); + + function getEdgeId(connection: Connection) { + return `edge-${connection.source}-${connection.target}}`; + } { - console.log('on edge create', e); - return e; + onedgecreate={(connection) => { + console.log('on edge create', connection); + + return { + ...connection, + id: getEdgeId(connection) + }; }} > diff --git a/packages/svelte/src/lib/components/Handle/Handle.svelte b/packages/svelte/src/lib/components/Handle/Handle.svelte index 745a0f28..e4b6a823 100644 --- a/packages/svelte/src/lib/components/Handle/Handle.svelte +++ b/packages/svelte/src/lib/components/Handle/Handle.svelte @@ -80,17 +80,17 @@ updateConnection, cancelConnection, panBy, - onConnect: (_connection) => { - let connection = $onedgecreate ? $onedgecreate(_connection) : _connection; + onConnect: (connection) => { + const edge = $onedgecreate ? $onedgecreate(connection) : connection; - if (!connection) { + if (!edge) { return; } - addEdge(connection); + addEdge(edge); // @todo: should we change/ improve the stuff we are passing here? // instead of source/target we could pass fromNodeId, fromHandleId, etc - dispatch('connect', { connection: _connection }); + dispatch('connect', { connection }); }, onConnectStart: (event, startParams) => { dispatch('connectstart', { diff --git a/packages/system/src/utils/edges/general.ts b/packages/system/src/utils/edges/general.ts index bdffbbd8..9ffd8e24 100644 --- a/packages/system/src/utils/edges/general.ts +++ b/packages/system/src/utils/edges/general.ts @@ -112,7 +112,7 @@ export function isEdgeVisible({ sourceNode, targetNode, width, height, transform } const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection | EdgeBase): string => - `xyflow__edge-${source}${sourceHandle || ''}-${target}${targetHandle || ''}`; + `xy-edge__${source}${sourceHandle || ''}-${target}${targetHandle || ''}`; const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => { return edges.some( @@ -148,6 +148,14 @@ export const addEdgeBase = ( return edges; } + if (edge.sourceHandle === null) { + delete edge.sourceHandle; + } + + if (edge.targetHandle === null) { + delete edge.targetHandle; + } + return edges.concat(edge); };