From 85c6266a0eda7d24b4e46ecfd1dbe814551488d5 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Mon, 28 Jul 2025 13:27:21 +0200 Subject: [PATCH 1/9] Style Arrow Heads Edge Markers with CSS Variables --- .../src/routes/examples/edges/+page.svelte | 40 +++++++++++++++++++ .../container/EdgeRenderer/MarkerSymbols.tsx | 36 ++++++----------- .../MarkerDefinition/Marker.svelte | 8 ++-- packages/system/src/styles/init.css | 7 ++++ 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/examples/svelte/src/routes/examples/edges/+page.svelte b/examples/svelte/src/routes/examples/edges/+page.svelte index 18c21a14..7649d63e 100644 --- a/examples/svelte/src/routes/examples/edges/+page.svelte +++ b/examples/svelte/src/routes/examples/edges/+page.svelte @@ -51,6 +51,18 @@ type: 'output', data: { label: 'Output 9' }, position: { x: 675, y: 500 } + }, + { + id: '10', + type: 'output', + data: { label: 'Output 10' }, + position: { x: 825, y: 400 } + }, + { + id: '11', + type: 'output', + data: { label: 'Output 11' }, + position: { x: 825, y: 300 } } ]); @@ -129,6 +141,27 @@ label: 'hi', labelStyle: 'background: red; font-weight: 700; padding: 5px;', style: 'stroke: #ffcc0' + }, + { + id: 'e4-10', + source: '4', + target: '10', + label: 'Explicit Red Color (should override CSS)', + markerEnd: { + type: MarkerType.ArrowClosed, + color: '#ff0000' + } + }, + { + id: 'e4-11', + source: '4', + target: '11', + label: 'No Explicit Color (should use CSS variable)', + markerEnd: { + type: MarkerType.ArrowClosed, + // To use CSS variable, set color to null + color: null + } } ]); @@ -163,3 +196,10 @@ + + diff --git a/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx b/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx index 6b59d04e..974d009e 100644 --- a/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx +++ b/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx @@ -6,33 +6,21 @@ import { useStoreApi } from '../../hooks/useStore'; type SymbolProps = Omit; const ArrowSymbol = ({ color = 'none', strokeWidth = 1 }: SymbolProps) => { - return ( - - ); + const style = { + strokeWidth, + ...(color !== 'none' && { stroke: color, fill: color }), + }; + + return ; }; const ArrowClosedSymbol = ({ color = 'none', strokeWidth = 1 }: SymbolProps) => { - return ( - - ); + const style = { + strokeWidth, + ...(color !== 'none' && { stroke: color, fill: color }), + }; + + return ; }; export const MarkerSymbols = { diff --git a/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/Marker.svelte b/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/Marker.svelte index 71412ec0..da670557 100644 --- a/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/Marker.svelte +++ b/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/Marker.svelte @@ -11,6 +11,9 @@ color, strokeWidth }: MarkerProps = $props(); + + // Create inline styles when explicit color is provided + const polylineStyle = color ? `stroke: ${color}; fill: ${color};` : ''; {#if type === MarkerType.Arrow} {:else if type === MarkerType.ArrowClosed} {/if} diff --git a/packages/system/src/styles/init.css b/packages/system/src/styles/init.css index 2d342000..b1a7d14b 100644 --- a/packages/system/src/styles/init.css +++ b/packages/system/src/styles/init.css @@ -165,6 +165,13 @@ user-select: none; } } + +/* Arrowhead marker styles - use CSS custom properties as default */ +.xy-flow__arrowhead polyline { + fill: var(--xy-edge-stroke, var(--xy-edge-stroke-default)); + stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default)); +} + .xy-flow__connection { pointer-events: none; From a4fc108bbbe0f43881ebc012b18ce613149c50b5 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Mon, 28 Jul 2025 13:35:30 +0200 Subject: [PATCH 2/9] react test --- examples/react/src/examples/Edges/index.tsx | 86 +++++++++++++++------ 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/examples/react/src/examples/Edges/index.tsx b/examples/react/src/examples/Edges/index.tsx index 6e18d24a..5ef76859 100644 --- a/examples/react/src/examples/Edges/index.tsx +++ b/examples/react/src/examples/Edges/index.tsx @@ -70,6 +70,18 @@ const initialNodes: Node[] = [ data: { label: 'Output 10' }, position: { x: 50, y: 400 }, }, + { + id: '11', + type: 'output', + data: { label: 'Output 11' }, + position: { x: 825, y: 400 }, + }, + { + id: '12', + type: 'output', + data: { label: 'Output 12' }, + position: { x: 825, y: 300 }, + }, ]; const initialEdges: Edge[] = [ @@ -182,6 +194,26 @@ const initialEdges: Edge[] = [ height: 20, }, }, + { + id: 'e4-11', + source: '4', + target: '11', + label: 'Explicit Red Color (should override CSS)', + markerEnd: { + type: MarkerType.ArrowClosed, + color: '#ff0000', + }, + }, + { + id: 'e4-12', + source: '4', + target: '12', + label: 'No Explicit Color (should use CSS variable)', + markerEnd: { + type: MarkerType.ArrowClosed, + color: null, + }, + }, ]; const edgeTypes: EdgeTypes = { @@ -205,28 +237,38 @@ const EdgesFlow = () => { const onConnect = useCallback((params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)), [setEdges]); return ( - - - - - +
+ + + + + + +
); }; From 0a0d171daa7654330235cdbb9f80fd7f7a9d11a8 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Mon, 28 Jul 2025 16:05:20 +0200 Subject: [PATCH 3/9] update examples --- examples/react/src/examples/Edges/index.tsx | 14 ++++++++----- .../src/routes/examples/edges/+page.svelte | 20 ++++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/examples/react/src/examples/Edges/index.tsx b/examples/react/src/examples/Edges/index.tsx index 5ef76859..820a48c5 100644 --- a/examples/react/src/examples/Edges/index.tsx +++ b/examples/react/src/examples/Edges/index.tsx @@ -198,20 +198,22 @@ const initialEdges: Edge[] = [ id: 'e4-11', source: '4', target: '11', - label: 'Explicit Red Color (should override CSS)', + label: 'Explicit Blue Prop Color (should override CSS)', + className: 'css-variable-edge', markerEnd: { type: MarkerType.ArrowClosed, - color: '#ff0000', + color: '#0000ff', }, }, { id: 'e4-12', source: '4', target: '12', - label: 'No Explicit Color (should use CSS variable)', + label: 'Marker No Prop Color (should use CSS variable)', + className: 'css-variable-edge', markerEnd: { type: MarkerType.ArrowClosed, - color: null, + color: undefined, }, }, ]; @@ -240,10 +242,12 @@ const EdgesFlow = () => {
@@ -182,6 +190,7 @@ bind:edges {edgeTypes} fitView + {defaultEdgeOptions} nodeDragThreshold={2} onbeforeconnect={(connection) => { console.log('on edge create', connection); @@ -198,8 +207,9 @@ From d6e5135c7c574b175c12b6dc6c244f8ecc8fe850 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Mon, 28 Jul 2025 16:30:53 +0200 Subject: [PATCH 4/9] make it more visible --- examples/react/src/examples/Edges/index.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/react/src/examples/Edges/index.tsx b/examples/react/src/examples/Edges/index.tsx index 820a48c5..8239f202 100644 --- a/examples/react/src/examples/Edges/index.tsx +++ b/examples/react/src/examples/Edges/index.tsx @@ -203,6 +203,8 @@ const initialEdges: Edge[] = [ markerEnd: { type: MarkerType.ArrowClosed, color: '#0000ff', + width: 40, + height: 40, }, }, { @@ -214,6 +216,8 @@ const initialEdges: Edge[] = [ markerEnd: { type: MarkerType.ArrowClosed, color: undefined, + width: 40, + height: 40, }, }, ]; @@ -239,7 +243,7 @@ const EdgesFlow = () => { const onConnect = useCallback((params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)), [setEdges]); return ( -
+ <>