From 1d11c32f435682bb282d6312ba05a4e6c3504185 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 6 Aug 2025 14:24:32 +0200 Subject: [PATCH 01/15] add missing styles for react flow 12 attribution --- src/extensions/react-flow/_react-flow_v12.scss | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/extensions/react-flow/_react-flow_v12.scss b/src/extensions/react-flow/_react-flow_v12.scss index e96d8f9fb..74c5aac15 100644 --- a/src/extensions/react-flow/_react-flow_v12.scss +++ b/src/extensions/react-flow/_react-flow_v12.scss @@ -25,3 +25,19 @@ svg.react-flow__connectionline { .react-flow__background-pattern.cross { stroke: $eccgui-color-separation-divider; } + +.react-flow__attribution { + position: absolute; + right: 0; + bottom: 0; + z-index: 1; + padding: 2px 3px; + margin: 0; + font-size: 10px; + background: var(--xy-attribution-background-color, var(--xy-attribution-background-color-default)); +} + +.react-flow__attribution a { + color: #999; + text-decoration: none; +} From a230b0c35d6f1da3614b1c4b2f53f0c5d55cc030 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 6 Aug 2025 14:35:11 +0200 Subject: [PATCH 02/15] remove support for react flow v10 --- CHANGELOG.md | 8 + package.json | 1 - .../ReactFlow/ReactFlow.stories.tsx | 42 +-- src/cmem/react-flow/ReactFlow/ReactFlow.tsx | 36 +-- .../react-flow/ReactFlow/ReactFlowV10.tsx | 54 ---- src/cmem/react-flow/configuration/graph.ts | 6 +- src/cmem/react-flow/configuration/linking.ts | 6 +- src/cmem/react-flow/configuration/workflow.ts | 6 +- .../extensions/scrollOnDragHookV10.ts | 267 ------------------ .../react-flow/handles/HandleDefault.tsx | 13 +- src/extensions/react-flow/index.ts | 1 - .../react-flow/minimap/MiniMapV10.tsx | 154 ---------- .../react-flow/nodes/NodeContent.tsx | 5 - .../react-flow/nodes/NodeDefault.tsx | 4 +- src/extensions/react-flow/nodes/nodeUtils.tsx | 8 +- .../nodes/stories/NodeDefaultV10.stories.tsx | 128 --------- src/extensions/react-flow/versionsupport.ts | 9 +- yarn.lock | 208 +------------- 18 files changed, 29 insertions(+), 927 deletions(-) delete mode 100644 src/cmem/react-flow/ReactFlow/ReactFlowV10.tsx delete mode 100644 src/cmem/react-flow/extensions/scrollOnDragHookV10.ts delete mode 100644 src/extensions/react-flow/minimap/MiniMapV10.tsx delete mode 100644 src/extensions/react-flow/nodes/stories/NodeDefaultV10.stories.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c5784681..d854f9083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ This is a major release, and it might be not compatible with your current usage - ``: - outerDivAttributes parameter: Allows to set parameter of the container div element of the code complete field. +### Removed + +- support for React Flow v10 was completely removed + ### Fixed - : @@ -26,6 +30,10 @@ This is a major release, and it might be not compatible with your current usage - ``: - Add 'nopan', 'nowheel' and 'nodrag' classes to Modal's overlay classes in order to always prevent react-flow to react to drag and pan actions in modals. +### Deprecated + +- support for React Flow v9 will be removed + ## [24.3.0] - 2025-06-05 diff --git a/package.json b/package.json index 1a73b18be..b2727f5fc 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,6 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-flow-renderer": "9.7.4", - "react-flow-renderer-lts": "npm:react-flow-renderer@^10.3.17", "react-inlinesvg": "^3.0.3", "react-markdown": "^10.1.0", "react-markdown-deprecated": "npm:react-markdown@^8.0.7", diff --git a/src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx b/src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx index d0177a550..9db7a8822 100644 --- a/src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx +++ b/src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx @@ -6,16 +6,6 @@ import { FlowElement, Position, } from "react-flow-renderer"; -import { - Background as BackgroundV10, - BackgroundVariant as BackgroundVariantV10, - Edge as Edge10, - Node as Node10, - OnInit as OnInitV10, - ReactFlowInstance as ReactFlowInstanceV10, - useEdgesState as useEdgesState10, - useNodesState as useNodesState10, -} from "react-flow-renderer-lts"; import { Meta, StoryFn } from "@storybook/react"; import { fn } from "@storybook/test"; import { @@ -31,7 +21,6 @@ import { ApplicationContainer, EdgeTools, MiniMap, - MiniMapV10, MiniMapV12, NodeTools, ReactFlowExtended, @@ -425,7 +414,7 @@ export default { }, flowVersion: { control: "select", - options: [undefined, "v9", "v10", "v12"], + options: [undefined, "v9", "v12"], }, }, } as Meta; @@ -490,33 +479,6 @@ const ReactFlowExampleV9: FC = (args) => { ); }; -const ReactFlowExampleV10: FC = (args) => { - const [reactFlowInstance, setReactFlowInstance] = React.useState(undefined); - const [nodes, ,] = useNodesState10(nodeExamples[args.configuration ?? "unspecified"].nodes as Node10[]); - const [edges, ,] = useEdgesState10(nodeExamples[args.configuration ?? "unspecified"].edges as Edge10[]); - - const onInit: OnInitV10 = React.useCallback((_reactFlowInstance: ReactFlowInstanceV10) => { - setReactFlowInstance(_reactFlowInstance); - }, []); - - const reactFlowExtendedProps = { - ...args, - defaultZoom: 1, - nodes, - edges, - onInit, - } as ReactFlowExtendedProps; - - return ( - - - - - - - ); -}; - const ReactFlowExampleV12: FC = (args) => { const [nodes, ,] = useNodesState12(nodeExamples[args.configuration ?? "unspecified"].nodes as Node12[]); const [edges, ,] = useEdgesState12(nodeExamples[args.configuration ?? "unspecified"].edges as Edge12[]); @@ -549,8 +511,6 @@ const ReactFlowExample: FC = (args) => { case undefined: case "v9": return ; - case "v10": - return ; case "v12": return ; default: diff --git a/src/cmem/react-flow/ReactFlow/ReactFlow.tsx b/src/cmem/react-flow/ReactFlow/ReactFlow.tsx index 9357e97ef..0caa31bac 100644 --- a/src/cmem/react-flow/ReactFlow/ReactFlow.tsx +++ b/src/cmem/react-flow/ReactFlow/ReactFlow.tsx @@ -1,6 +1,5 @@ import React, {ReactElement, Ref} from "react"; import { KeyCode as KeyCodeV9 } from "react-flow-renderer"; -import { KeyCode as KeyCodeV10 } from "react-flow-renderer-lts"; import { KeyCode as KeyCodeV12} from "@xyflow/react"; import { CLASSPREFIX as eccgui } from "../../../configuration/constants"; @@ -8,14 +7,12 @@ import { ReactFlowMarkers } from "../../../extensions/react-flow/markers/ReactFl import { ReactFlowVersions } from "../../../extensions/react-flow/versionsupport"; import { ReactFlowHotkeyContext } from "../extensions/ReactFlowHotkeyContext"; import { useReactFlowScrollOnDragV9 } from "../extensions/scrollOnDragHook"; -import { useReactFlowScrollOnDragV10 } from "../extensions/scrollOnDragHookV10"; import * as graphConfig from "./../configuration/graph"; import * as linkingConfig from "./../configuration/linking"; import * as unspecifiedConfig from "./../configuration/unspecified"; import * as workflowConfig from "./../configuration/workflow"; import { ReactFlowV9Container, ReactFlowV9ContainerProps } from "./ReactFlowV9"; -import { ReactFlowV10Container, ReactFlowV10ContainerProps } from "./ReactFlowV10"; import { ReactFlowV12Container, ReactFlowV12ContainerProps } from "./ReactFlowV12"; export interface ReactFlowExtendedExtraProps { @@ -55,13 +52,6 @@ interface ReactFlowExtendedVersion9SupportProps { flowVersion?: ReactFlowVersions.V9; } -interface ReactFlowExtendedVersion10SupportProps { - /** - * Set version of `ReactFlow` that is used internally. - */ - flowVersion: ReactFlowVersions.V10; -} - interface ReactFlowExtendedVersion12SupportProps { /** * Set version of `ReactFlow` that is used internally. @@ -74,16 +64,15 @@ interface ReactFlowExtendedVersion12SupportProps { } export type ReactFlowExtendedPropsV9 = ReactFlowExtendedVersion9SupportProps & ReactFlowV9ContainerProps & ReactFlowExtendedExtraProps & ReactFlowExtendedScrollProps -export type ReactFlowExtendedPropsV10 = ReactFlowExtendedVersion10SupportProps & ReactFlowV10ContainerProps & ReactFlowExtendedExtraProps & ReactFlowExtendedScrollProps export type ReactFlowExtendedPropsV12 = ReactFlowExtendedVersion12SupportProps & ReactFlowV12ContainerProps & ReactFlowExtendedExtraProps -export type ReactFlowExtendedProps = ReactFlowExtendedPropsV9 | ReactFlowExtendedPropsV10 | ReactFlowExtendedPropsV12 +export type ReactFlowExtendedProps = ReactFlowExtendedPropsV9 | ReactFlowExtendedPropsV12 /** * `ReactFlow` container extension that includes pre-configured nodes and edges for * Corporate Memory tools. * - * @param T The concrete type of the corresponding version, i.e. either one of ReactFlowExtendedPropsV9, ReactFlowExtendedPropsV10 or ReactFlowExtendedPropsV12 + * @param T The concrete type of the corresponding version, i.e. either one of ReactFlowExtendedPropsV9 or ReactFlowExtendedPropsV12 */ const ReactFlowExtendedPlain = ({ configuration = "unspecified", @@ -157,14 +146,6 @@ const ReactFlowExtendedPlain = ({ zoomActivationKeyCode: hotKeysDisabled ? undefined : (zoomActivationKeyCode as KeyCodeV9), }; break; - case "v10": - keyCodeConfig = { - selectionKeyCode: hotKeysDisabled ? undefined : (selectionKeyCode as KeyCodeV10), - deleteKeyCode: hotKeysDisabled ? undefined : (deleteKeyCode as KeyCodeV10), - multiSelectionKeyCode: hotKeysDisabled ? undefined : (multiSelectionKeyCode as KeyCodeV10), - zoomActivationKeyCode: hotKeysDisabled ? undefined : (zoomActivationKeyCode as KeyCodeV10), - }; - break; case "v12": keyCodeConfig = { selectionKeyCode: hotKeysDisabled ? null : (selectionKeyCode as KeyCodeV12), @@ -183,12 +164,6 @@ const ReactFlowExtendedPlain = ({ scrollOnDrag, }); break; - case "v10": - scrollOnDragFunctions = useReactFlowScrollOnDragV10({ - reactFlowProps: originalProps as ReactFlowV10ContainerProps, - scrollOnDrag, - }); - break; // should not be necessary for v12 } @@ -207,13 +182,6 @@ const ReactFlowExtendedPlain = ({ ); - case "v10": - return ( - - {children} - - - ); case "v12": return ( diff --git a/src/cmem/react-flow/ReactFlow/ReactFlowV10.tsx b/src/cmem/react-flow/ReactFlow/ReactFlowV10.tsx deleted file mode 100644 index 5b72a62b8..000000000 --- a/src/cmem/react-flow/ReactFlow/ReactFlowV10.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from "react"; -import { - default as ReactFlowV10, - Edge, - Node, - ReactFlowProps as ReactFlowV10Props, - useEdgesState, - useNodesState, -} from "react-flow-renderer-lts"; - -import { CLASSPREFIX as eccgui } from "../../../configuration/constants"; - -export type ReactFlowV10ContainerProps = ReactFlowV10Props; - -/** - * Our own `ReactFlow` v10 container. - */ -export const ReactFlowV10Container = React.forwardRef( - ({ children, className, ...originalProps }, outerRef) => { - const innerRef = React.useRef(null); - React.useImperativeHandle(outerRef, () => innerRef.current!, []); - - const [nodesFallback, , onNodesChangeFallback] = useNodesState(originalProps.nodes || ([] as Node[])); - const [edgesFallback, , onEdgesChangeFallback] = useEdgesState(originalProps.edges || ([] as Edge[])); - - const missingNodesChangeCallback = - !!originalProps.nodes && !originalProps.onNodesChange - ? { - nodes: nodesFallback, - onNodesChange: onNodesChangeFallback, - } - : {}; - - const missingEdgesChangeCallback = - !!originalProps.edges && !originalProps.onEdgesChange - ? { - edges: edgesFallback, - onEdgesChange: onEdgesChangeFallback, - } - : {}; - - return ( - - {children} - - ); - } -); diff --git a/src/cmem/react-flow/configuration/graph.ts b/src/cmem/react-flow/configuration/graph.ts index b6c639c24..db5a9fcf4 100644 --- a/src/cmem/react-flow/configuration/graph.ts +++ b/src/cmem/react-flow/configuration/graph.ts @@ -1,8 +1,8 @@ import { EdgeDefault } from "./../../../extensions/react-flow/edges/EdgeDefault"; import { NodeDefault } from "./../../../extensions/react-flow/nodes/NodeDefault"; import { GRAPH_NODE_TYPES } from "./typing"; -import {ComponentType} from "react"; -import {NodeProps} from "react-flow-renderer-lts"; +//import {ComponentType} from "react"; +//import {NodeProps} from "react-flow-renderer-lts"; const edgeTypes = { default: EdgeDefault, @@ -16,7 +16,7 @@ const edgeTypes = { danger: EdgeDefault, }; -const nodeTypes: Record> = { +const nodeTypes: Record*/> = { default: NodeDefault, graph: NodeDefault, class: NodeDefault, diff --git a/src/cmem/react-flow/configuration/linking.ts b/src/cmem/react-flow/configuration/linking.ts index 036e475be..4a8326a78 100644 --- a/src/cmem/react-flow/configuration/linking.ts +++ b/src/cmem/react-flow/configuration/linking.ts @@ -2,8 +2,8 @@ import { EdgeStep } from "./../../../extensions/react-flow/edges/EdgeStep"; import { NodeDefault } from "./../../../extensions/react-flow/nodes/NodeDefault"; import { StickyNoteNode } from "./../nodes/StickyNoteNode"; import { LINKING_NODE_TYPES } from "./typing"; -import {ComponentType} from "react"; -import {NodeProps} from "react-flow-renderer-lts"; +//import {ComponentType} from "react"; +//import {NodeProps} from "react-flow-renderer-lts"; const edgeTypes = { default: EdgeStep, @@ -14,7 +14,7 @@ const edgeTypes = { danger: EdgeStep, }; -const nodeTypes: Record> = { +const nodeTypes: Record*/> = { default: NodeDefault, sourcepath: NodeDefault, targetpath: NodeDefault, diff --git a/src/cmem/react-flow/configuration/workflow.ts b/src/cmem/react-flow/configuration/workflow.ts index 14ff19a51..5a8621a89 100644 --- a/src/cmem/react-flow/configuration/workflow.ts +++ b/src/cmem/react-flow/configuration/workflow.ts @@ -2,8 +2,8 @@ import { EdgeStep } from "./../../../extensions/react-flow/edges/EdgeStep"; import { NodeDefault } from "./../../../extensions/react-flow/nodes/NodeDefault"; import { StickyNoteNode } from "./../nodes/StickyNoteNode"; import { WORKFLOW_NODE_TYPES } from "./typing"; -import {ComponentType} from "react"; -import {NodeProps} from "react-flow-renderer-lts"; +//import {ComponentType} from "react"; +//import {NodeProps} from "react-flow-renderer-lts"; const edgeTypes = { default: EdgeStep, @@ -12,7 +12,7 @@ const edgeTypes = { danger: EdgeStep, }; -const nodeTypes: Record> = { +const nodeTypes: Record*/> = { default: NodeDefault, dataset: NodeDefault, linking: NodeDefault, diff --git a/src/cmem/react-flow/extensions/scrollOnDragHookV10.ts b/src/cmem/react-flow/extensions/scrollOnDragHookV10.ts deleted file mode 100644 index 1685113f8..000000000 --- a/src/cmem/react-flow/extensions/scrollOnDragHookV10.ts +++ /dev/null @@ -1,267 +0,0 @@ -import React, { MouseEvent as ReactMouseEvent, useCallback } from "react"; -import { - Edge, - Node, - OnConnectStart, - OnConnectStartParams, - OnConnectStop, - OnInit, - ReactFlowInstance, - Transform, - useStore, -} from "react-flow-renderer-lts"; -import { HandleType } from "react-flow-renderer-lts/dist/esm/types/handles"; - -import { ReactFlowExtendedScrollProps } from "../ReactFlow/ReactFlow"; -import { ReactFlowV10ContainerProps } from "../ReactFlow/ReactFlowV10"; - -import { ScrollStateShared } from "./scrollOnDragHook"; - -interface IProps extends ReactFlowExtendedScrollProps { - /** The original react-flow props. */ - reactFlowProps: ReactFlowV10ContainerProps; -} - -interface ScrollState extends ScrollStateShared { - // The react-flow instance - reactFlowInstance?: ReactFlowInstance; -} - -type ReturnType = Pick< - ReactFlowV10ContainerProps, - | "onInit" - | "onNodeDragStart" - | "onNodeDragStop" - | "onConnectStart" - | "onConnectStop" - | "onSelectionDragStart" - | "onSelectionDragStop" - | "onEdgeUpdateStart" - | "onEdgeUpdateEnd" ->; - -/** Handles the scrolling of the react-flow canvas on all drag operations when the mouse pointer gets near or over the borders. - * The return value contains the wrapped react-flow callback functions that need to be handed over to the react-flow component. */ -export const useReactFlowScrollOnDragV10 = ({ reactFlowProps, scrollOnDrag }: IProps): ReturnType => { - /** Tracks the zoom on drag to border functionality. */ - const scrollState = React.useRef({ - reactFlowInstance: undefined, - currentX: 0, - currentY: 0, - currentZoom: 1, - loggedWarning: false, - scrollX: false, - scrollY: false, - draggingOperationActive: false, - }); - - const useStoreStateInternal = (): Transform => { - try { - return useStore((state) => state.transform); - } catch (ex) { - if (reactFlowProps.id && scrollOnDrag) { - // eslint-disable-next-line no-console - console.warn("Scroll on drag is not correctly working. Reason: " + ex); - } - return [0, 0, 1]; - } - }; - - /** The current position and zoom factor of the view port. */ - const [currentX, currentY, currentZoom] = useStoreStateInternal(); - scrollState.current.currentX = currentX; - scrollState.current.currentY = currentY; - scrollState.current.currentZoom = currentZoom; - - const originalOnInit = reactFlowProps.onInit; - const originalOnNodeDragStart = reactFlowProps.onNodeDragStart; - const originalOnNodeDragStop = reactFlowProps.onNodeDragStop; - const originalOnConnectStart = reactFlowProps.onConnectStart; - const originalOnConnectStop = reactFlowProps.onConnectStop; - const originalOnSelectionDragStart = reactFlowProps.onSelectionDragStart; - const originalOnSelectionDragStop = reactFlowProps.onSelectionDragStop; - const originalOnEdgeUpdateStart = reactFlowProps.onEdgeUpdateStart; - const originalOnEdgeUpdateEnd = reactFlowProps.onEdgeUpdateEnd; - - const scrollInterval = scrollOnDrag?.scrollInterval; - const scrollStepSize = scrollOnDrag?.scrollStepSize; - - const reactFlowInstanceId = reactFlowProps.id; - - const clearIntervalIfExists = React.useCallback(() => { - if (scrollState.current.scrollTaskId) { - clearInterval(scrollState.current.scrollTaskId); - } - }, []); - - const setScrolling = React.useCallback( - (active: boolean) => { - scrollState.current.draggingOperationActive = active; - if (!active) { - clearIntervalIfExists(); - } - }, - [clearIntervalIfExists] - ); - - // Handle scrolling if any operation is active e.g. connecting or dragging a node - React.useEffect(() => { - if (scrollInterval && scrollStepSize && reactFlowInstanceId) { - const handleScrolling = (event: MouseEvent) => { - const state = scrollState.current; - if (!state.draggingOperationActive) { - clearIntervalIfExists(); - return; - } - // Check if mouse pointer is outside of the canvas - const canvasElement = document.getElementById(reactFlowInstanceId); - if (!canvasElement) { - if (!state.loggedWarning) { - // eslint-disable-next-line no-console - console.warn("No element found with ID " + reactFlowInstanceId); - state.loggedWarning = true; - } - return; - } - const boundingRect = canvasElement.getBoundingClientRect(); - const xStepSize = boundingRect.width * scrollStepSize; - const yStepSize = boundingRect.height * scrollStepSize; - if ( - boundingRect.top > event.clientY || - boundingRect.bottom < event.clientY || - boundingRect.left > event.clientX || - boundingRect.right < event.clientX - ) { - const scrollX: number = - boundingRect.left > event.clientX - ? xStepSize - : boundingRect.right < event.clientX - ? -xStepSize - : 0; - const scrollY: number = - boundingRect.top > event.clientY - ? yStepSize - : boundingRect.bottom < event.clientY - ? -yStepSize - : 0; - if (state.scrollY === (scrollY !== 0) && state.scrollX === (scrollX !== 0)) { - // Nothing has changed, do not change interval function - return; - } - clearIntervalIfExists(); - state.scrollTaskId = setInterval(() => { - state.reactFlowInstance?.setViewport({ - x: state.currentX + scrollX, - y: state.currentY + scrollY, - zoom: state.currentZoom, - }); - }, scrollInterval); - } else { - clearIntervalIfExists(); - } - }; - const disableScrollingOnMouseUp = () => { - scrollState.current.draggingOperationActive = false; - clearIntervalIfExists(); - }; - document.addEventListener("mousemove", handleScrolling); - document.addEventListener("mouseup", disableScrollingOnMouseUp); - return () => { - document.removeEventListener("mousemove", handleScrolling); - document.removeEventListener("mouseup", disableScrollingOnMouseUp); - }; - } else { - return undefined; - } - }, [scrollInterval, scrollStepSize, reactFlowInstanceId, clearIntervalIfExists]); - - const onInit: OnInit = useCallback( - (rfi: ReactFlowInstance) => { - scrollState.current.reactFlowInstance = rfi; - originalOnInit?.(rfi); - }, - [originalOnInit] - ); - - /** Wrap original callbacks to turn scrolling on and off. */ - const onConnectStart: OnConnectStart = React.useCallback( - (event: ReactMouseEvent, params: OnConnectStartParams) => { - setScrolling(true); - originalOnConnectStart?.(event, params); - }, - [originalOnConnectStart, setScrolling] - ); - - const onConnectStop: OnConnectStop = React.useCallback( - (event: MouseEvent) => { - setScrolling(false); - originalOnConnectStop?.(event); - }, - [originalOnConnectStop, setScrolling] - ); - - const onNodeDragStart = React.useCallback( - (event: ReactMouseEvent, node: Node, nodes: Node[]) => { - setScrolling(true); - originalOnNodeDragStart?.(event, node, nodes); - }, - [originalOnNodeDragStart, setScrolling] - ); - - const onNodeDragStop = React.useCallback( - (event: ReactMouseEvent, node: Node, nodes: Node[]) => { - setScrolling(false); - originalOnNodeDragStop?.(event, node, nodes); - }, - [originalOnNodeDragStop, setScrolling] - ); - - const onSelectionDragStart = React.useCallback( - (event: ReactMouseEvent, nodes: Node[]) => { - setScrolling(true); - originalOnSelectionDragStart?.(event, nodes); - }, - [originalOnSelectionDragStart, setScrolling] - ); - - const onSelectionDragStop = React.useCallback( - (event: ReactMouseEvent, nodes: Node[]) => { - setScrolling(false); - originalOnSelectionDragStop?.(event, nodes); - }, - [originalOnSelectionDragStop, setScrolling] - ); - - const onEdgeUpdateStart = React.useCallback( - (event: ReactMouseEvent, edge: Edge, handleType: HandleType) => { - setScrolling(true); - originalOnEdgeUpdateStart?.(event, edge, handleType); - }, - [originalOnEdgeUpdateStart, setScrolling] - ); - - const onEdgeUpdateEnd = React.useCallback( - (event: MouseEvent, edge: Edge, handleType: HandleType) => { - setScrolling(false); - originalOnEdgeUpdateEnd?.(event, edge, handleType); - }, - [originalOnEdgeUpdateEnd, setScrolling] - ); - - if (!reactFlowProps.id || !scrollOnDrag) { - // No instance ID or config available, return empty object that will not overwrite any react-flow config parameters - return {}; - } else { - return { - onInit, - onNodeDragStart, - onNodeDragStop, - onConnectStart, - onConnectStop, - onSelectionDragStart, - onSelectionDragStop, - onEdgeUpdateStart, - onEdgeUpdateEnd, - }; - } -}; diff --git a/src/extensions/react-flow/handles/HandleDefault.tsx b/src/extensions/react-flow/handles/HandleDefault.tsx index 89334dd09..3d56a9319 100644 --- a/src/extensions/react-flow/handles/HandleDefault.tsx +++ b/src/extensions/react-flow/handles/HandleDefault.tsx @@ -1,6 +1,5 @@ import React, { memo } from "react"; import { Handle as HandleV9, HandleProps as ReactFlowHandleV9Props } from "react-flow-renderer"; -import { Handle as HandleV10, HandleProps as ReactFlowHandleV10Props } from "react-flow-renderer-lts"; import { Handle as HandleV12, HandleProps as ReactFlowHandleV12Props } from "@xyflow/react"; import { Classes as BlueprintClasses } from "@blueprintjs/core"; @@ -40,10 +39,6 @@ interface HandleExtensionProps * @deprecated (v26) use only `HandleDefaultProps` */ export interface HandleV9Props extends HandleExtensionProps, ReactFlowHandleV9Props {} -/** - * @deprecated (v26) use only `HandleDefaultProps` - */ -export interface HandleV10Props extends HandleExtensionProps, ReactFlowHandleV10Props {} /** * @deprecated (v26) use only `HandleDefaultProps` */ @@ -52,7 +47,7 @@ export interface HandleV12Props extends HandleExtensionProps, ReactFlowHandleV12 /** * Combined interface, later this will be only a copy of `HandleV12Props`. */ -export type HandleDefaultProps = HandleV9Props | HandleV10Props | HandleV12Props; +export type HandleDefaultProps = HandleV9Props | HandleV12Props; export const HandleDefault = memo( ({ flowVersion, data, tooltip, children, category, intent, ...handleProps }: HandleDefaultProps) => { @@ -147,12 +142,6 @@ export const HandleDefault = memo( {handleContent} ); - case "v10": - return ( - - {handleContent} - - ); case "v12": return ( diff --git a/src/extensions/react-flow/index.ts b/src/extensions/react-flow/index.ts index 8802c1bc4..2aafe19ad 100644 --- a/src/extensions/react-flow/index.ts +++ b/src/extensions/react-flow/index.ts @@ -16,7 +16,6 @@ export * from "./edges/EdgeDefs"; export * from "./edges/EdgeDefaultV12"; export * from "./markers/ReactFlowMarkers"; export * from "./minimap/MiniMap"; -export * from "./minimap/MiniMapV10"; export * from "./minimap/MiniMapV12"; export * from "./minimap/utils"; export * from "./versionsupport"; diff --git a/src/extensions/react-flow/minimap/MiniMapV10.tsx b/src/extensions/react-flow/minimap/MiniMapV10.tsx deleted file mode 100644 index 29ea6cf47..000000000 --- a/src/extensions/react-flow/minimap/MiniMapV10.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import React, { memo, useEffect } from "react"; -import { MiniMap as ReactFlowMiniMap, MiniMapProps as ReactFlowMiniMapProps, ReactFlowInstance, XYPosition } from "react-flow-renderer-lts"; -import { FlowTransform } from "react-flow-renderer/dist/types"; - -import { miniMapUtils } from "../minimap/utils"; -import {Viewport} from "react-flow-renderer-lts/dist/esm/types/general"; - -export interface MiniMapV10Props extends ReactFlowMiniMapProps { - /** - * React-Flow instance - */ - flowInstance?: ReactFlowInstance; - /** - * Enable navigating the react-flow canvas by dragging and clicking on the mini-map. - */ - enableNavigation?: boolean; - /** - * Properties are forwarded to the HTML `div` element used as minimap wrapper. - * Data attributes for test ids could be included here. - */ - wrapperProps?: Omit< - React.HTMLAttributes, - "onMouseDown" | "onMouseUp" | "onMouseMove" | "onMouseLeave" - >; -} - -interface configParams { - // Key has been pressed down over the mini-map and navigation mode has thus started - navigationOn: boolean; - // The mini-map element - minimapElement: Element | null; - // The react-flow element - flowElement: Element | null; -} - -let minimapCalcConf: configParams = { - navigationOn: false, - minimapElement: null, - flowElement: null, -}; - -/** An improved mini-map for react-flow that supports navigation via the mini-map. */ -export const MiniMapV10 = memo( - ({ - flowInstance, - enableNavigation = false, - maskColor = "#ddddddbb", - nodeClassName = miniMapUtils.nodeClassName, - nodeColor = miniMapUtils.nodeColor, - nodeStrokeColor = miniMapUtils.borderColor, - wrapperProps, - ...minimapProps - }: MiniMapV10Props) => { - const minimapWrapper = React.useRef(null); - - useEffect(() => { - const minimapDiv: HTMLDivElement | null = minimapWrapper.current; - if (enableNavigation && flowInstance && minimapDiv) { - minimapCalcConf = { - navigationOn: false, - minimapElement: minimapDiv.querySelector(".react-flow__minimap"), - flowElement: minimapDiv.closest(".react-flow"), - }; - } - }, [flowInstance, enableNavigation]); - - /** Changes the viewport of the react-flow view as given by the mini-maps canvas bounds. */ - const moveViewPort = React.useCallback((canvasBounds: DOMRect, canvasPosition: XYPosition) => { - if(!flowInstance) { - return - } - const zoom: number = flowInstance.getZoom() - const canvasNewState: FlowTransform & Viewport = { - zoom, - x: canvasPosition.x * zoom + canvasBounds.width / 2, - y: canvasPosition.y * zoom + canvasBounds.height / 2, - }; - const instanceStateV10 = flowInstance as ReactFlowInstance - instanceStateV10.setViewport(canvasNewState) - }, [flowInstance]) - - // sets the visible area of the canvas based on mouse movement on the mini-map - const handleMiniMapMouseMove = (event: any) => { - const minimapConfig = minimapCalcConf.minimapElement?.getAttribute("viewBox")?.split(" "); - if ( - minimapCalcConf.navigationOn && - minimapCalcConf.minimapElement && - minimapCalcConf.flowElement && - flowInstance && - minimapConfig - ) { - const minimapBounds = minimapCalcConf.minimapElement.getBoundingClientRect(); - const canvasBounds: DOMRect = minimapCalcConf.flowElement.getBoundingClientRect(); - - const minimapCoordinates = { - x0: parseInt(minimapConfig[0]), - y0: parseInt(minimapConfig[1]), - x1: parseInt(minimapConfig[2]) + parseInt(minimapConfig[0]), - y1: parseInt(minimapConfig[3]) + parseInt(minimapConfig[1]), - }; - const minimapClick = { - x: event.clientX - minimapBounds.left, - y: event.clientY - minimapBounds.top, - }; - const canvasPosition = { - x: - ((minimapCoordinates.x1 - minimapCoordinates.x0) / minimapBounds.width) * minimapClick.x * -1 - - minimapCoordinates.x0, - y: - ((minimapCoordinates.y1 - minimapCoordinates.y0) / minimapBounds.height) * minimapClick.y * -1 - - minimapCoordinates.y0, - }; - moveViewPort(canvasBounds, canvasPosition) - } - }; - - // sets the view for the user when clicked and finish navigation - const handleMiniMapMouseUp = (event: any) => { - handleMiniMapMouseMove(event); - minimapCalcConf.navigationOn = false; - }; - - // enables the mini-map fake drag effect see "handleMiniMapMouseMove" above. - const handleMiniMapMouseDown = () => { - if (enableNavigation && flowInstance) { - minimapCalcConf.navigationOn = true; - } - }; - - return ( -
- -
- ); - } -); diff --git a/src/extensions/react-flow/nodes/NodeContent.tsx b/src/extensions/react-flow/nodes/NodeContent.tsx index cc3f934b0..e006d17b1 100644 --- a/src/extensions/react-flow/nodes/NodeContent.tsx +++ b/src/extensions/react-flow/nodes/NodeContent.tsx @@ -1,6 +1,5 @@ import React from "react"; import { Position, useStoreState as getStoreStateFlowV9 } from "react-flow-renderer"; -import { useStore as getStoreStateFlowV10 } from "react-flow-renderer-lts"; import { useStore as getStoreStateFlowV12 } from "@xyflow/react"; import Color from "color"; import { Resizable } from "re-resizable"; @@ -234,7 +233,6 @@ type HandleStack = { [key: string]: HandleDefaultProps[] }; const defaultHandles = (flowVersion: ReacFlowVersionSupportProps["flowVersion"]): NodeContentHandleProps[] => { switch (flowVersion) { case "v9": - case "v10": case "v12": return [{ type: "target" }, { type: "source" }] as HandleDefaultProps[]; default: @@ -376,9 +374,6 @@ export function NodeContent>({ case "v9": [, , zoom] = getStoreStateFlowV9((state) => state.transform); break; - case "v10": - [, , zoom] = getStoreStateFlowV10((state) => state.transform); - break; case "v12": // we are calling a hook here conditionally. Not recommended, by the flowversion check is // is basically compile time determined. So we just do it. diff --git a/src/extensions/react-flow/nodes/NodeDefault.tsx b/src/extensions/react-flow/nodes/NodeDefault.tsx index 0537d680c..5b81a076e 100644 --- a/src/extensions/react-flow/nodes/NodeDefault.tsx +++ b/src/extensions/react-flow/nodes/NodeDefault.tsx @@ -1,6 +1,5 @@ import React, { memo } from "react"; import { NodeProps as ReactFlowNodeV9Props } from "react-flow-renderer"; -import { NodeProps as ReactFlowNodeV10Props } from "react-flow-renderer-lts"; import { NodeProps as ReactFlowNodeV12Props, Position } from "@xyflow/react"; import { Tooltip } from "../../../index"; @@ -17,10 +16,9 @@ interface NodeDefaultExtendedProps extends ReacFlowVersionS } type NodeDefaultV9Props = NodeDefaultExtendedProps & ReactFlowNodeV9Props; -type NodeDefaultV10Props = NodeDefaultExtendedProps & ReactFlowNodeV10Props; type NodeDefaultV12Props = NodeDefaultExtendedProps & Omit; -export type NodeDefaultProps = NodeDefaultV9Props | NodeDefaultV10Props | NodeDefaultV12Props; +export type NodeDefaultProps = NodeDefaultV9Props | NodeDefaultV12Props; /** * The `NodeDefault` element manages the display of React-Flow nodes. diff --git a/src/extensions/react-flow/nodes/nodeUtils.tsx b/src/extensions/react-flow/nodes/nodeUtils.tsx index e836dd842..9a2a10d67 100644 --- a/src/extensions/react-flow/nodes/nodeUtils.tsx +++ b/src/extensions/react-flow/nodes/nodeUtils.tsx @@ -1,6 +1,5 @@ import { CSSProperties } from "react"; import {Node as NodeV9, XYPosition as XYPositionV9} from "react-flow-renderer"; -import {Node as NodeV10, XYPosition as XYPositionV10} from "react-flow-renderer-lts"; import {Node as NodeV12, XYPosition as XYPositionV12} from "@xyflow/react"; import Color from "color"; import {NodeDimensions} from "./NodeContent"; @@ -13,15 +12,12 @@ interface StickyNoteBase { interface StickyNotePositionV9 { position: XYPositionV9 & NodeDimensions; } -interface StickyNotePositionV10 { - position: XYPositionV10 & NodeDimensions; -} interface StickyNotePositionV12 { position: XYPositionV12 & NodeDimensions; } /** A sticky note for display in the UI as returned from the backend. */ -export type StickyNote = (StickyNoteBase & StickyNotePositionV9) | (StickyNoteBase & StickyNotePositionV10) | (StickyNoteBase & StickyNotePositionV12); +export type StickyNote = (StickyNoteBase & StickyNotePositionV9) | (StickyNoteBase & StickyNotePositionV12); /** * converts a react-flow node with @@ -29,7 +25,7 @@ export type StickyNote = (StickyNoteBase & StickyNotePositionV9) | (StickyNoteBa * @param node * @returns {StickyNote} */ -const transformNodeToStickyNode = (node: NodeV9 | NodeV10 | NodeV12): StickyNote => { +const transformNodeToStickyNode = (node: NodeV9 | NodeV12): StickyNote => { return { id: node.id, content: node.data.businessData.stickyNote!, diff --git a/src/extensions/react-flow/nodes/stories/NodeDefaultV10.stories.tsx b/src/extensions/react-flow/nodes/stories/NodeDefaultV10.stories.tsx deleted file mode 100644 index f9c36baac..000000000 --- a/src/extensions/react-flow/nodes/stories/NodeDefaultV10.stories.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React from "react"; -import { Node, useNodesState } from "react-flow-renderer-lts"; -import { Meta, StoryFn } from "@storybook/react"; - -import { - ApplicationContainer, - NodeDefault, - ReactFlowExtended, - ReactFlowVersions, -} from "./../../../../../index"; -import { Default as NodeContentExample } from "./NodeContent.stories"; -import { nodeTypes } from "./nodeTypes"; - -export default { - title: "Extensions/React Flow V10/Node", - component: NodeDefault, - argTypes: { - id: { - control: "text", - description: "Internal node identifier.", - }, - position: { - type: { required: true }, - description: "Position on React-Flow canvas.", - table: { - type: { summary: "XYPosition" }, - }, - }, - type: { - control: "select", - description: "Key of the imported and connected `nodeTypes` to specify what node implementation is used.", - table: { - type: { summary: "string" }, - defaultValue: { summary: "default" }, - }, - options: Object.keys(nodeTypes), - mapping: Object.fromEntries(Object.keys(nodeTypes).map((type) => [type, type])), - }, - style: { - control: "object", - description: "css properties", - table: { - type: { summary: "React.CSSProperties" }, - }, - }, - className: { - control: "text", - description: "additional class name", - }, - targetPosition: { - description: "'left' | 'right' | 'top' | 'bottom' handle position", - table: { - type: { summary: "Position" }, - defaultValue: { summary: "Position.Left" }, - }, - }, - sourcePosition: { - description: "'left' | 'right' | 'top' | 'bottom' handle position", - table: { - type: { summary: "Position" }, - defaultValue: { summary: "Position.Right" }, - }, - }, - isHidden: { - control: "boolean", - description: "if true, the node will not be rendered", - table: { - type: { summary: "boolean" }, - defaultValue: { summary: "false" }, - }, - }, - draggable: { - control: "boolean", - description: "if option is not set, the node is draggable (overwrites general nodesDraggable option)", - table: { - type: { summary: "boolean" }, - defaultValue: { summary: "true" }, - }, - }, - connectable: { - control: "boolean", - description: "if option is not set, the node is connectable (overwrites general nodesConnectable option)", - table: { - type: { summary: "boolean" }, - defaultValue: { summary: "true" }, - }, - }, - selectable: { - control: "boolean", - description: "if option is not set, the node is selectable (overwrites general elementsSelectable option)", - table: { - type: { summary: "boolean" }, - defaultValue: { summary: "true" }, - }, - }, - dragHandle: { - control: "text", - description: "selector for specifying an element as a drag handle", - }, - }, -} as Meta; - -const NodeDefaultExample = (args: Node) => { - const [nodes /*onNodesChange*/, ,] = useNodesState([args] as Node[]); - - return ( - - - - ); -}; - -const Template: StoryFn = (args) => ; - -export const Default = Template.bind({}); -Default.args = { - id: "1", - type: "default", - data: NodeContentExample.args, - position: { x: 50, y: 50 }, -} as Node; diff --git a/src/extensions/react-flow/versionsupport.ts b/src/extensions/react-flow/versionsupport.ts index d4bd1a715..c0a750014 100644 --- a/src/extensions/react-flow/versionsupport.ts +++ b/src/extensions/react-flow/versionsupport.ts @@ -1,11 +1,9 @@ import { useStoreState as getStoreStateFlowV9 } from "react-flow-renderer"; -import { useStore as getStoreStateFlowV10 } from "react-flow-renderer-lts"; import { useStore as useStoreStateFlowV12 } from "@xyflow/react"; export const enum ReactFlowVersions { NONE = "none", // mainly here in case some ReactFlow components are used without any react flow containr V9 = "v9", - V10 = "v10", V12 = "v12", } @@ -13,7 +11,7 @@ export interface ReacFlowVersionSupportProps { /** * Specifies the context of the react flow renderer version that is used for the component. */ - flowVersion?: ReactFlowVersions.V9 | ReactFlowVersions.V10 | ReactFlowVersions.V12 | ReactFlowVersions.NONE; + flowVersion?: ReactFlowVersions.V9 | ReactFlowVersions.V12 | ReactFlowVersions.NONE; } export const useReactFlowVersion = () => { @@ -22,11 +20,6 @@ export const useReactFlowVersion = () => { return zoom ? ReactFlowVersions.V9 : ReactFlowVersions.NONE; // eslint-disable-next-line no-empty } catch {} - try { - const [, , zoom] = getStoreStateFlowV10((state) => state.transform); - return zoom ? ReactFlowVersions.V10 : ReactFlowVersions.NONE; - // eslint-disable-next-line no-empty - } catch {} try { const [, , zoom] = useStoreStateFlowV12((state) => state.transform); return zoom ? ReactFlowVersions.V12 : ReactFlowVersions.NONE; diff --git a/yarn.lock b/yarn.lock index c3982238e..b64d10241 100644 --- a/yarn.lock +++ b/yarn.lock @@ -965,7 +965,7 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.9", "@babel/runtime@^7.24.5", "@babel/runtime@^7.24.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.24.5", "@babel/runtime@^7.24.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.27.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== @@ -2645,99 +2645,18 @@ dependencies: "@types/node" "*" -"@types/d3-array@*": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" - integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== - -"@types/d3-axis@*": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.6.tgz#e760e5765b8188b1defa32bc8bb6062f81e4c795" - integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-brush@*": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.6.tgz#c2f4362b045d472e1b186cdbec329ba52bdaee6c" - integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-chord@*": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.6.tgz#1706ca40cf7ea59a0add8f4456efff8f8775793d" - integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== - "@types/d3-color@*": version "3.1.3" resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== -"@types/d3-contour@*": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.6.tgz#9ada3fa9c4d00e3a5093fed0356c7ab929604231" - integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== - dependencies: - "@types/d3-array" "*" - "@types/geojson" "*" - -"@types/d3-delaunay@*": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1" - integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== - -"@types/d3-dispatch@*": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz#096efdf55eb97480e3f5621ff9a8da552f0961e7" - integrity sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ== - -"@types/d3-drag@*", "@types/d3-drag@^3.0.7": +"@types/d3-drag@^3.0.7": version "3.0.7" resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.7.tgz#b13aba8b2442b4068c9a9e6d1d82f8bcea77fc02" integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== dependencies: "@types/d3-selection" "*" -"@types/d3-dsv@*": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" - integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== - -"@types/d3-ease@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" - integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== - -"@types/d3-fetch@*": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" - integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== - dependencies: - "@types/d3-dsv" "*" - -"@types/d3-force@*": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.10.tgz#6dc8fc6e1f35704f3b057090beeeb7ac674bff1a" - integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw== - -"@types/d3-format@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90" - integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== - -"@types/d3-geo@*": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" - integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== - dependencies: - "@types/geojson" "*" - -"@types/d3-hierarchy@*": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz#6023fb3b2d463229f2d680f9ac4b47466f71f17b" - integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== - "@types/d3-interpolate@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" @@ -2745,73 +2664,19 @@ dependencies: "@types/d3-color" "*" -"@types/d3-path@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a" - integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== - -"@types/d3-polygon@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz#dfae54a6d35d19e76ac9565bcb32a8e54693189c" - integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== - -"@types/d3-quadtree@*": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz#d4740b0fe35b1c58b66e1488f4e7ed02952f570f" - integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== - -"@types/d3-random@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-random/-/d3-random-3.0.3.tgz#ed995c71ecb15e0cd31e22d9d5d23942e3300cfb" - integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== - -"@types/d3-scale-chromatic@*": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#dc6d4f9a98376f18ea50bad6c39537f1b5463c39" - integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== - -"@types/d3-scale@*": - version "4.0.9" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb" - integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== - dependencies: - "@types/d3-time" "*" - "@types/d3-selection@*", "@types/d3-selection@^3.0.10": version "3.0.11" resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.11.tgz#bd7a45fc0a8c3167a631675e61bc2ca2b058d4a3" integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== -"@types/d3-shape@*": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.7.tgz#2b7b423dc2dfe69c8c93596e673e37443348c555" - integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== - dependencies: - "@types/d3-path" "*" - -"@types/d3-time-format@*": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz#d6bc1e6b6a7db69cccfbbdd4c34b70632d9e9db2" - integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== - -"@types/d3-time@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f" - integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== - -"@types/d3-timer@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" - integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== - -"@types/d3-transition@*", "@types/d3-transition@^3.0.8": +"@types/d3-transition@^3.0.8": version "3.0.9" resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.9.tgz#1136bc57e9ddb3c390dccc9b5ff3b7d2b8d94706" integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== dependencies: "@types/d3-selection" "*" -"@types/d3-zoom@*", "@types/d3-zoom@^3.0.8": +"@types/d3-zoom@^3.0.8": version "3.0.8" resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b" integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== @@ -2819,42 +2684,6 @@ "@types/d3-interpolate" "*" "@types/d3-selection" "*" -"@types/d3@^7.4.0": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@types/d3/-/d3-7.4.3.tgz#d4550a85d08f4978faf0a4c36b848c61eaac07e2" - integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== - dependencies: - "@types/d3-array" "*" - "@types/d3-axis" "*" - "@types/d3-brush" "*" - "@types/d3-chord" "*" - "@types/d3-color" "*" - "@types/d3-contour" "*" - "@types/d3-delaunay" "*" - "@types/d3-dispatch" "*" - "@types/d3-drag" "*" - "@types/d3-dsv" "*" - "@types/d3-ease" "*" - "@types/d3-fetch" "*" - "@types/d3-force" "*" - "@types/d3-format" "*" - "@types/d3-geo" "*" - "@types/d3-hierarchy" "*" - "@types/d3-interpolate" "*" - "@types/d3-path" "*" - "@types/d3-polygon" "*" - "@types/d3-quadtree" "*" - "@types/d3-random" "*" - "@types/d3-scale" "*" - "@types/d3-scale-chromatic" "*" - "@types/d3-selection" "*" - "@types/d3-shape" "*" - "@types/d3-time" "*" - "@types/d3-time-format" "*" - "@types/d3-timer" "*" - "@types/d3-transition" "*" - "@types/d3-zoom" "*" - "@types/debug@^4.0.0": version "4.1.12" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" @@ -2895,11 +2724,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== -"@types/geojson@*": - version "7946.0.16" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a" - integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== - "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -3065,11 +2889,6 @@ "@types/scheduler" "^0.16" csstype "^3.0.2" -"@types/resize-observer-browser@^0.1.7": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz#d3c98d788489d8376b7beac23863b1eebdd3c13c" - integrity sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ== - "@types/resolve@^1.20.2": version "1.20.6" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" @@ -9639,20 +9458,6 @@ react-fast-compare@^3.0.1, react-fast-compare@^3.2.2: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== -"react-flow-renderer-lts@npm:react-flow-renderer@^10.3.17": - version "10.3.17" - resolved "https://registry.yarnpkg.com/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz#06d6ecef5559ba5d3e64d2c8dcb74c43071d62b1" - integrity sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ== - dependencies: - "@babel/runtime" "^7.18.9" - "@types/d3" "^7.4.0" - "@types/resize-observer-browser" "^0.1.7" - classcat "^5.0.3" - d3-drag "^3.0.0" - d3-selection "^3.0.0" - d3-zoom "^3.0.0" - zustand "^3.7.2" - react-flow-renderer@9.7.4: version "9.7.4" resolved "https://registry.yarnpkg.com/react-flow-renderer/-/react-flow-renderer-9.7.4.tgz#11394c05ca953b650e2017d056c075fd3df9075c" @@ -11943,11 +11748,6 @@ yocto-queue@^1.0.0, yocto-queue@^1.1.1: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== -zustand@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.7.2.tgz#7b44c4f4a5bfd7a8296a3957b13e1c346f42514d" - integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA== - zustand@^4.4.0: version "4.5.6" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.6.tgz#6857d52af44874a79fb3408c9473f78367255c96" From f043a5015e206d246aab084a0ba0717711a36277 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 13 Aug 2025 16:26:46 +0200 Subject: [PATCH 03/15] include version splitter for react flow edges --- .../react-flow/edges/EdgeDefault.tsx | 58 +++++++++++++---- .../react-flow/edges/EdgeDefaultV12.tsx | 63 +++++-------------- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/src/extensions/react-flow/edges/EdgeDefault.tsx b/src/extensions/react-flow/edges/EdgeDefault.tsx index 65b7b2675..ccde4ab4f 100644 --- a/src/extensions/react-flow/edges/EdgeDefault.tsx +++ b/src/extensions/react-flow/edges/EdgeDefault.tsx @@ -4,9 +4,11 @@ import { EdgeProps as ReactFlowEdgeProps } from "react-flow-renderer/dist/types" import { intentClassName, IntentTypes } from "../../../common/Intent"; import { CLASSPREFIX as eccgui } from "../../../configuration/constants"; +import { ReactFlowVersions, useReactFlowVersion } from "../versionsupport"; import { nodeContentUtils } from "./../nodes/NodeContent"; import { NodeHighlightColor } from "./../nodes/sharedTypes"; +import { EdgeDefaultV12, EdgeDefaultV12Props } from "./EdgeDefaultV12"; import { drawEdgeStep, drawEdgeStraight } from "./utils"; export interface EdgeDefaultDataProps { @@ -30,11 +32,7 @@ export interface EdgeDefaultDataProps { * Direction of the SVG path is inversed. * This is important for the placement of the markers and the animation movement. */ - inversePath?: boolean; - /** - * Reference link to the SVG marker used for the start of the edge - */ - markerStart?: string; + inversePath?: boolean; // FIXME: diection of animation is not inverted /** * Callback handler that returns a React element used as edge title. */ @@ -46,19 +44,35 @@ export interface EdgeDefaultDataProps { edgeSvgProps?: React.SVGProps; } -export interface EdgeDefaultProps extends ReactFlowEdgeProps { +/** + * @deprecated (v26) v9 support is removed after v25 + */ +interface EdgeDefaultV9DataProps extends EdgeDefaultDataProps { + /** + * Reference link to the SVG marker used for the start of the edge + * @deprecated (v26) only necessary for react flow v9 + */ + markerStart?: string; +} + +/** + * @deprecated (v26) v9 support is removed after v25 + */ +interface EdgeDefaultV9Props extends ReactFlowEdgeProps { /** * Defining content and markers for the edge. */ - data?: EdgeDefaultDataProps; + data?: EdgeDefaultV9DataProps; /** * Callback handler that returns a SVG path as string to define how the edge is rendered. */ drawSvgPath?: (edge: ReactFlowEdgeProps) => string; } -export const EdgeDefault = memo( - ({ data = {}, drawSvgPath = drawEdgeStraight, ...edgeOriginalProperties }: EdgeDefaultProps) => { +export type EdgeDefaultProps = EdgeDefaultV9Props | EdgeDefaultV12Props; + +const EdgeDefaultV9 = memo( + ({ data = {}, drawSvgPath = drawEdgeStraight, ...edgeOriginalProperties }: EdgeDefaultV9Props) => { const { pathGlowWidth = 10, markerStart, strokeType, intent, highlightColor, edgeSvgProps } = data; const pathDisplay = drawSvgPath({ ...edgeOriginalProperties, data }); @@ -94,7 +108,11 @@ export const EdgeDefault = memo( return ( { + const flowVersionCheck = useReactFlowVersion(); + switch (flowVersionCheck) { + case "v9": + return ; + case "v12": + return ; + default: + return <>; + } +}); + const createEdgeDefaultClassName = ( { strokeType, intent, highlightColor }: EdgeDefaultDataProps, - baseClass = "react-flow__edge-path" + baseClass = "react-flow__edge-path", + flowVersion?: ReactFlowVersions ) => { const { highlightClassNameSuffix } = nodeContentUtils.evaluateHighlightColors("--edge-highlight", highlightColor); return ( baseClass + + (flowVersion ? ` react-flow__edge--${flowVersion}` : "") + (strokeType ? ` ${baseClass}--stroke-${strokeType}` : "") + (intent ? ` ${intentClassName(intent)}` : "") + (highlightClassNameSuffix.length > 0 diff --git a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx index 5ffed2cdc..86aa75a50 100644 --- a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx +++ b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx @@ -1,45 +1,20 @@ import { memo } from "react"; import React from "react"; -import { BaseEdge, Edge, EdgeProps, EdgeText, getBezierPath, getEdgeCenter } from "@xyflow/react"; +import { BaseEdge, Edge, EdgeProps, EdgeText, getBezierPath } from "@xyflow/react"; -import { IntentTypes } from "../../../common/Intent"; import { nodeContentUtils } from "../nodes/NodeContent"; -import { NodeHighlightColor } from "../nodes/sharedTypes"; +import { ReactFlowVersions } from "../versionsupport"; -import { edgeDefaultUtils } from "./EdgeDefault"; +import { EdgeDefaultDataProps, edgeDefaultUtils } from "./EdgeDefault"; -export type EdgeDefaultV12DataProps = Record & { - /** - * Overwrites the default style how the edge stroke is displayed. - */ - strokeType?: "solid" | "dashed" | "dotted" | "double" | "doubledashed"; - /** - * Feedback state of the node. - */ - intent?: IntentTypes; - /** - * Set the color of used highlights to mark the edge. - */ - highlightColor?: NodeHighlightColor | [NodeHighlightColor, NodeHighlightColor]; - /** - * Size of the "glow" effect when the edge is hovered. - */ - pathGlowWidth?: number; - /* - * Direction of the SVG path is inversed. - * This is important for the placement of the markers and the animation movement. - */ - inversePath?: boolean; - /** - * Callback handler that returns a React element used as edge title. - */ - renderLabel?: (edgeCenter: [number, number, number, number]) => React.ReactNode; - /** - * Properties are forwarded to the internally used SVG `g` element. - * Data attributes for test ids coud be included here. - */ - edgeSvgProps?: React.SVGProps; -}; +/** + * @deprecated (v26) use EdgeDefaultDataProps + */ +type EdgeDefaultV12DataProps = Record & EdgeDefaultDataProps; +/** + * @deprecated (v26) use EdgeDefaultProps + */ +export type EdgeDefaultV12Props = EdgeProps>; /** * This element cannot be used directly, it must be connected via a `edgeTypes` definition. @@ -63,7 +38,7 @@ export const EdgeDefaultV12 = memo( labelBgBorderRadius = 3, data = {}, ...edgeOriginalProperties - }: EdgeProps>) => { + }: EdgeDefaultV12Props) => { const { pathGlowWidth = 10, highlightColor, renderLabel, edgeSvgProps, intent, inversePath, strokeType } = data; const [edgePath, labelX, labelY] = getBezierPath({ @@ -81,19 +56,12 @@ export const EdgeDefaultV12 = memo( highlightColor ); - const edgeCenter = getEdgeCenter({ - sourceX, - sourceY, - targetX, - targetY, - }); - const renderedLabel = renderLabel?.([labelX, labelY, sourceX, targetX]) ?? (label ? ( Date: Thu, 14 Aug 2025 11:15:59 +0200 Subject: [PATCH 04/15] fix edge markers and add colors of intent states for v12 support --- src/extensions/react-flow/_react-flow.scss | 1 + .../react-flow/edges/EdgeDefaultV12.tsx | 16 ++++- src/extensions/react-flow/edges/EdgeDefs.tsx | 3 + .../edges/stories/EdgeDefaultV12.stories.tsx | 38 +++++------- .../markers/MarkerArrowClosedInverse.tsx | 3 + .../react-flow/markers/ReactFlowMarkers.tsx | 59 ++++++++++++++++++- .../react-flow/markers/_markers.scss | 27 +++++++++ 7 files changed, 119 insertions(+), 28 deletions(-) create mode 100644 src/extensions/react-flow/markers/_markers.scss diff --git a/src/extensions/react-flow/_react-flow.scss b/src/extensions/react-flow/_react-flow.scss index 3a331543a..0b182db41 100644 --- a/src/extensions/react-flow/_react-flow.scss +++ b/src/extensions/react-flow/_react-flow.scss @@ -1,6 +1,7 @@ @import "config"; @import "nodes/nodes"; @import "edges/edges"; +@import "markers/markers"; @import "handles/handles"; @import "minimap/minimap"; @import "react-flow_v12"; diff --git a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx index 86aa75a50..4256ab2c9 100644 --- a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx +++ b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx @@ -10,7 +10,7 @@ import { EdgeDefaultDataProps, edgeDefaultUtils } from "./EdgeDefault"; /** * @deprecated (v26) use EdgeDefaultDataProps */ -type EdgeDefaultV12DataProps = Record & EdgeDefaultDataProps; +export type EdgeDefaultV12DataProps = Record & EdgeDefaultDataProps; /** * @deprecated (v26) use EdgeDefaultProps */ @@ -71,6 +71,8 @@ export const EdgeDefaultV12 = memo( /> ) : null); + const appearance = "arrow-closed"; // test + return ( ( diff --git a/src/extensions/react-flow/edges/stories/EdgeDefaultV12.stories.tsx b/src/extensions/react-flow/edges/stories/EdgeDefaultV12.stories.tsx index 5716e5924..7192ccd62 100644 --- a/src/extensions/react-flow/edges/stories/EdgeDefaultV12.stories.tsx +++ b/src/extensions/react-flow/edges/stories/EdgeDefaultV12.stories.tsx @@ -1,12 +1,15 @@ import React, { useCallback, useState } from "react"; import { Meta, StoryFn } from "@storybook/react"; -import { addEdge, Edge, OnConnect, Position, ReactFlow, useEdgesState, useNodesState } from "@xyflow/react"; +import { addEdge, Edge, Node, OnConnect, Position, useEdgesState, useNodesState } from "@xyflow/react"; -import { NodeDefaultV12 } from "../../nodes/NodeDefaultV12"; -import { EdgeDefaultV12, EdgeDefaultV12DataProps as EdgeData } from "../EdgeDefaultV12"; -import { EdgeDefs } from "../EdgeDefs"; - -import { EdgeLabel, EdgeLabelObject } from "./../../../../../index"; +import { + EdgeDefaultV12, + EdgeDefaultV12DataProps as EdgeData, + EdgeLabel, + EdgeLabelObject, + ReactFlowExtended, + ReactFlowVersions, +} from "./../../../../../index"; /** * this is only a mock to get it as sub element in the table @@ -16,12 +19,6 @@ const EdgeDefaultDataProps = (data: EdgeData) => { return <>; }; -const edgeTypes = { - default: EdgeDefaultV12, -}; -const nodeTypes = { - default: NodeDefaultV12, -}; export default { title: "Extensions/React Flow V12/Edge", component: EdgeDefaultV12, @@ -76,17 +73,11 @@ const EdgeDefault = (args: Edge) => { }, position: { x: 600, y: 200 }, }, - ]); + ] as Node[]); const [edges, setEdges, onEdgesChange] = useEdgesState([ { ...args, - // sourceX: 150, - // sourceY: 0, - // targetX: 250, - // targetY: 0, - sourcePosition: Position.Left, - targetPosition: Position.Right, }, ]); @@ -102,17 +93,16 @@ const EdgeDefault = (args: Edge) => { ); return ( -
- - +
); diff --git a/src/extensions/react-flow/markers/MarkerArrowClosedInverse.tsx b/src/extensions/react-flow/markers/MarkerArrowClosedInverse.tsx index 713ee04ee..67bc0db69 100644 --- a/src/extensions/react-flow/markers/MarkerArrowClosedInverse.tsx +++ b/src/extensions/react-flow/markers/MarkerArrowClosedInverse.tsx @@ -1,5 +1,8 @@ import React, { FC } from "react"; +/** + * @deprecated (v26) only necessary for react flow v9, support will be removed + */ export const MarkerArrowClosedInverse: FC = () => { return ( { + /** + * Visual appearance of the marker. + */ + appearance?: ReactFlowMarkerAppearance; + /** + * Feedback state of the marker. + * SVG markers are reused by paths but they cannot inherit their state color automatically. + */ + intent?: IntentTypes; + /** + * If set, then the marker orientation is reversed. + * Can be used if a start marker should displayed similar to an end marker. + */ + reverse?: boolean; +} + +const ReactFlowMarker = ({ className, appearance = "arrow-closed", intent, reverse }: ReactFlowMarkerProps) => { + const markerDisplay: Record = { + "arrow-closed": ( + + ), + }; + + return ( + + {markerDisplay[appearance]} + + ); +}; + const ReactFlowMarkers: FC = () => { + const intents = ["none", "primary", "success", "warning", "danger", "info"] as IntentTypes[]; + return ( + {intents.map((intent) => ( + <> + + + + ))} ); }; -export { MarkerArrowClosedInverse, ReactFlowMarkers }; +export { MarkerArrowClosedInverse, ReactFlowMarkers, ReactFlowMarker }; diff --git a/src/extensions/react-flow/markers/_markers.scss b/src/extensions/react-flow/markers/_markers.scss new file mode 100644 index 000000000..3b684545e --- /dev/null +++ b/src/extensions/react-flow/markers/_markers.scss @@ -0,0 +1,27 @@ +marker[id|="react-flow__marker"] { + color: var(--marker-intent-color); + + &.#{$eccgui}-intent--none { + --marker-intent-color: #{$reactflow-edge-stroke-color-default}; + } + + &.#{$eccgui}-intent--primary { + --marker-intent-color: #{$eccgui-color-primary}; + } + + &.#{$eccgui}-intent--info { + --marker-intent-color: #{$eccgui-color-info-text}; + } + + &.#{$eccgui}-intent--success { + --marker-intent-color: #{$eccgui-color-success-text}; + } + + &.#{$eccgui}-intent--warning { + --marker-intent-color: #{$eccgui-color-warning-text}; + } + + &.#{$eccgui}-intent--danger { + --marker-intent-color: #{$eccgui-color-danger-text}; + } +} From 7f393d8aea7677857b6342e4c3269c5957e43642 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 14 Aug 2025 11:47:23 +0200 Subject: [PATCH 05/15] add property to v12 edge that can used to define the arrow marker, or remove it from the edge --- .../react-flow/edges/EdgeDefaultV12.tsx | 36 +++++++++++-------- .../edges/stories/EdgeDefaultV12.stories.tsx | 10 +++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx index 4256ab2c9..090be13e2 100644 --- a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx +++ b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx @@ -1,5 +1,4 @@ -import { memo } from "react"; -import React from "react"; +import React, { memo } from "react"; import { BaseEdge, Edge, EdgeProps, EdgeText, getBezierPath } from "@xyflow/react"; import { nodeContentUtils } from "../nodes/NodeContent"; @@ -10,7 +9,13 @@ import { EdgeDefaultDataProps, edgeDefaultUtils } from "./EdgeDefault"; /** * @deprecated (v26) use EdgeDefaultDataProps */ -export type EdgeDefaultV12DataProps = Record & EdgeDefaultDataProps; +export interface EdgeDefaultV12DataProps extends Record, EdgeDefaultDataProps { + /** + * Set the marker used on the start or end of the edge. + */ + markerAppearance?: "arrow-closed" | "none"; +} + /** * @deprecated (v26) use EdgeDefaultProps */ @@ -71,7 +76,19 @@ export const EdgeDefaultV12 = memo( /> ) : null); - const appearance = "arrow-closed"; // test + const appearance = data.markerAppearance ?? "arrow-closed"; + + const marker = + appearance !== "none" + ? { + markerStart: inversePath + ? `url(#react-flow__marker--${appearance}${intent ? `-${intent}` : "-none"}-reverse)` + : undefined, + markerEnd: !inversePath + ? `url(#react-flow__marker--${appearance}${intent ? `-${intent}` : "-none"}` + : undefined, + } + : {}; return ( { onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} - defaultZoom={1} /> ); @@ -125,6 +124,15 @@ const defaultEdge: Edge = { export const Default = Template.bind({}); Default.args = defaultEdge; +export const WithoutArrow = Template.bind({}); +WithoutArrow.args = { + ...Default.args, + id: "noarrow", + data: { + markerAppearance: "none", + }, +}; + export const CustomLabel = Template.bind({}); CustomLabel.args = { ...Default.args, From a8873a4d9b86b494cb9b26f75c06cc54fed1c8c0 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 14 Aug 2025 15:58:31 +0200 Subject: [PATCH 06/15] add ability to use different path layous for v12 edges, provide straight, step and bezier edges for configurations --- src/cmem/react-flow/configuration/graph.ts | 20 ++--- .../react-flow/edges/EdgeBezier.tsx | 47 ++++++++++++ .../react-flow/edges/EdgeDefault.tsx | 8 +- .../react-flow/edges/EdgeDefaultV12.tsx | 76 ++++++++++--------- src/extensions/react-flow/edges/EdgeStep.tsx | 47 ++++++++++-- .../react-flow/edges/EdgeStraight.tsx | 1 + src/extensions/react-flow/edges/edgeTypes.ts | 7 +- src/extensions/react-flow/edges/utils.ts | 20 ++++- src/extensions/react-flow/index.ts | 1 + 9 files changed, 167 insertions(+), 60 deletions(-) create mode 100644 src/extensions/react-flow/edges/EdgeBezier.tsx create mode 100644 src/extensions/react-flow/edges/EdgeStraight.tsx diff --git a/src/cmem/react-flow/configuration/graph.ts b/src/cmem/react-flow/configuration/graph.ts index db5a9fcf4..e7abf6028 100644 --- a/src/cmem/react-flow/configuration/graph.ts +++ b/src/cmem/react-flow/configuration/graph.ts @@ -1,19 +1,19 @@ -import { EdgeDefault } from "./../../../extensions/react-flow/edges/EdgeDefault"; +import { EdgeBezier } from "./../../../extensions/react-flow/edges/EdgeBezier"; import { NodeDefault } from "./../../../extensions/react-flow/nodes/NodeDefault"; import { GRAPH_NODE_TYPES } from "./typing"; //import {ComponentType} from "react"; //import {NodeProps} from "react-flow-renderer-lts"; const edgeTypes = { - default: EdgeDefault, - implicit: EdgeDefault, - import: EdgeDefault, - subclass: EdgeDefault, - subproperty: EdgeDefault, - rdftype: EdgeDefault, - success: EdgeDefault, - warning: EdgeDefault, - danger: EdgeDefault, + default: EdgeBezier, + implicit: EdgeBezier, + import: EdgeBezier, + subclass: EdgeBezier, + subproperty: EdgeBezier, + rdftype: EdgeBezier, + success: EdgeBezier, + warning: EdgeBezier, + danger: EdgeBezier, }; const nodeTypes: Record*/> = { diff --git a/src/extensions/react-flow/edges/EdgeBezier.tsx b/src/extensions/react-flow/edges/EdgeBezier.tsx new file mode 100644 index 000000000..f86419336 --- /dev/null +++ b/src/extensions/react-flow/edges/EdgeBezier.tsx @@ -0,0 +1,47 @@ +import React, { memo } from "react"; +import { Edge, EdgeProps, getBezierPath } from "@xyflow/react"; + +import { ReactFlowVersions, useReactFlowVersion } from "../versionsupport"; + +import { EdgeDefault, EdgeDefaultV9Props } from "./EdgeDefault"; +import { EdgeDefaultV12DataProps, EdgeDefaultV12Props } from "./EdgeDefaultV12"; + +interface EdgeBezierDataV12Props extends EdgeDefaultV12DataProps { + curvature?: number; +} + +/** + * @deprecated (v26) v9 support is removed after v25 + */ +export interface EdgeBezierV12Props + extends Omit, + EdgeProps> {} + +export type EdgeBezierProps = EdgeDefaultV9Props | EdgeBezierV12Props; + +/** + * This element cannot be used directly, it must be connected via a `edgeTypes` definition. + * Our v9 edges do not support bezier paths. + * @see https://reactflow.dev/docs/api/nodes/ + */ +export const EdgeBezier = memo((props: EdgeBezierProps) => { + const flowVersionCheck = useReactFlowVersion(); + switch (flowVersionCheck) { + case ReactFlowVersions.V9: + return ; + case ReactFlowVersions.V12: + return ( + { + return getBezierPath({ + ...params, + curvature: (props.data as EdgeBezierDataV12Props)?.curvature, + }); + }} + /> + ); + default: + return <>; + } +}); diff --git a/src/extensions/react-flow/edges/EdgeDefault.tsx b/src/extensions/react-flow/edges/EdgeDefault.tsx index ccde4ab4f..86660a558 100644 --- a/src/extensions/react-flow/edges/EdgeDefault.tsx +++ b/src/extensions/react-flow/edges/EdgeDefault.tsx @@ -47,7 +47,7 @@ export interface EdgeDefaultDataProps { /** * @deprecated (v26) v9 support is removed after v25 */ -interface EdgeDefaultV9DataProps extends EdgeDefaultDataProps { +export interface EdgeDefaultV9DataProps extends EdgeDefaultDataProps { /** * Reference link to the SVG marker used for the start of the edge * @deprecated (v26) only necessary for react flow v9 @@ -58,7 +58,7 @@ interface EdgeDefaultV9DataProps extends EdgeDefaultDataProps { /** * @deprecated (v26) v9 support is removed after v25 */ -interface EdgeDefaultV9Props extends ReactFlowEdgeProps { +export interface EdgeDefaultV9Props extends ReactFlowEdgeProps { /** * Defining content and markers for the edge. */ @@ -155,9 +155,9 @@ const EdgeDefaultV9 = memo( export const EdgeDefault = memo((props: EdgeDefaultProps) => { const flowVersionCheck = useReactFlowVersion(); switch (flowVersionCheck) { - case "v9": + case ReactFlowVersions.V9: return ; - case "v12": + case ReactFlowVersions.V12: return ; default: return <>; diff --git a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx index 090be13e2..e3cea9ed9 100644 --- a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx +++ b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx @@ -1,10 +1,11 @@ import React, { memo } from "react"; -import { BaseEdge, Edge, EdgeProps, EdgeText, getBezierPath } from "@xyflow/react"; +import { BaseEdge, Edge, EdgeProps, EdgeText, GetBezierPathParams } from "@xyflow/react"; import { nodeContentUtils } from "../nodes/NodeContent"; import { ReactFlowVersions } from "../versionsupport"; import { EdgeDefaultDataProps, edgeDefaultUtils } from "./EdgeDefault"; +import { getStraightPath } from "./utils"; /** * @deprecated (v26) use EdgeDefaultDataProps @@ -19,7 +20,14 @@ export interface EdgeDefaultV12DataProps extends Record, EdgeDe /** * @deprecated (v26) use EdgeDefaultProps */ -export type EdgeDefaultV12Props = EdgeProps>; +export type EdgeDefaultV12Props = EdgeProps> & { + /** + * Callback handler that returns SVG path and label position of the edge. + */ + getPath?: ( + edgeParams: Omit & Record + ) => [path: string, labelX: number, labelY: number, offsetX: number, offsetY: number]; +}; /** * This element cannot be used directly, it must be connected via a `edgeTypes` definition. @@ -42,11 +50,12 @@ export const EdgeDefaultV12 = memo( labelBgPadding = [5, 5], labelBgBorderRadius = 3, data = {}, + getPath = getStraightPath, ...edgeOriginalProperties }: EdgeDefaultV12Props) => { const { pathGlowWidth = 10, highlightColor, renderLabel, edgeSvgProps, intent, inversePath, strokeType } = data; - const [edgePath, labelX, labelY] = getBezierPath({ + const [edgePath, labelX, labelY] = getPath({ sourceX, sourceY, sourcePosition, @@ -92,48 +101,43 @@ export const EdgeDefaultV12 = memo( return ( - - {highlightColor && ( - - )} - - - + )} + {renderedLabel} ); diff --git a/src/extensions/react-flow/edges/EdgeStep.tsx b/src/extensions/react-flow/edges/EdgeStep.tsx index 4e9dfdc76..a0137bded 100644 --- a/src/extensions/react-flow/edges/EdgeStep.tsx +++ b/src/extensions/react-flow/edges/EdgeStep.tsx @@ -1,16 +1,51 @@ import React, { memo } from "react"; +import { Edge, EdgeProps, getSmoothStepPath } from "@xyflow/react"; -import { EdgeDefault, EdgeDefaultDataProps, EdgeDefaultProps } from "./EdgeDefault"; +import { ReactFlowVersions, useReactFlowVersion } from "../versionsupport"; + +import { EdgeDefault, EdgeDefaultV9DataProps, EdgeDefaultV9Props } from "./EdgeDefault"; +import { EdgeDefaultV12DataProps, EdgeDefaultV12Props } from "./EdgeDefaultV12"; import { drawEdgeStep } from "./utils"; -interface EdgeStepDataProps extends EdgeDefaultDataProps { +interface EdgeStepDataV9Props extends EdgeDefaultV9DataProps { + stepCornerRadius?: number; +} +interface EdgeStepDataV12Props extends EdgeDefaultV12DataProps { stepCornerRadius?: number; } -export interface EdgeStepProps extends EdgeDefaultProps { - data?: EdgeStepDataProps; +/** + * @deprecated (v26) v9 support is removed after v25 + */ +export interface EdgeStepV9Props extends EdgeDefaultV9Props { + data?: EdgeStepDataV9Props; } +/** + * @deprecated (v26) v9 support is removed after v25 + */ +export interface EdgeStepV12Props extends Omit, EdgeProps> {} + +export type EdgeStepProps = EdgeStepV9Props | EdgeStepV12Props; -export const EdgeStep = memo((edge: EdgeStepProps) => { - return ; +/** + * This element cannot be used directly, it must be connected via a `edgeTypes` definition. + * @see https://reactflow.dev/docs/api/nodes/ + */ +export const EdgeStep = memo((props: EdgeStepProps) => { + const flowVersionCheck = useReactFlowVersion(); + switch (flowVersionCheck) { + case ReactFlowVersions.V9: + return ; + case ReactFlowVersions.V12: + return ( + { + return getSmoothStepPath({ ...params, borderRadius: props.data?.stepCornerRadius ?? 7 }); + }} + /> + ); + default: + return <>; + } }); diff --git a/src/extensions/react-flow/edges/EdgeStraight.tsx b/src/extensions/react-flow/edges/EdgeStraight.tsx new file mode 100644 index 000000000..72685db16 --- /dev/null +++ b/src/extensions/react-flow/edges/EdgeStraight.tsx @@ -0,0 +1 @@ +export { EdgeDefault as EdgeStraight } from "./EdgeDefault"; diff --git a/src/extensions/react-flow/edges/edgeTypes.ts b/src/extensions/react-flow/edges/edgeTypes.ts index 0a15ff455..1a3718a24 100644 --- a/src/extensions/react-flow/edges/edgeTypes.ts +++ b/src/extensions/react-flow/edges/edgeTypes.ts @@ -7,13 +7,14 @@ import { EdgeDefault } from "./EdgeDefault"; import { EdgeStep } from "./EdgeStep"; +import { EdgeStraight } from "./EdgeStraight"; -/** - * @deprecated (v25) will be removed without replacement, define it yourself or use `) => { + const path = drawEdgeStraight(params as EdgeDefaultProps); + const [labelX, labelY, offsetX, offsetY] = getEdgeCenter({ + sourceX: params.sourceX, + sourceY: params.sourceY, + targetX: params.targetX, + targetY: params.targetY, + }); + return [path, labelX, labelY, offsetX, offsetY] as [ + path: string, + labelX: number, + labelY: number, + offsetX: number, + offsetY: number + ]; +}; + export const drawEdgeStep = ({ sourceX, sourceY, diff --git a/src/extensions/react-flow/index.ts b/src/extensions/react-flow/index.ts index 2aafe19ad..7f6e9378f 100644 --- a/src/extensions/react-flow/index.ts +++ b/src/extensions/react-flow/index.ts @@ -10,6 +10,7 @@ export * from "./edges/EdgeDefault"; export * from "./edges/EdgeDefaultV12"; export * from "./edges/EdgeDefs"; export * from "./edges/EdgeStep"; +export * from "./edges/EdgeStraight"; export * from "./edges/EdgeTools"; export * from "./edges/EdgeLabel"; export * from "./edges/EdgeDefs"; From ff44c99c2d86c0b831269db17d4f57d23c8eadf6 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 14 Aug 2025 16:40:41 +0200 Subject: [PATCH 07/15] update changelog --- CHANGELOG.md | 23 +++++++++++++++++--- src/extensions/react-flow/edges/EdgeDefs.tsx | 2 +- src/extensions/react-flow/edges/edgeTypes.ts | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1530fef9e..496e7453c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p This is a major release, and it might be not compatible with your current usage of our library. Please read about the necessary changes in the section about how to migrate. +### Added + +- `` + - it's basically `` without any special configs +- `` + - only supported for v12, in v9 as straight edge is used + - use `curvature` property in the edge `data` object to define the bezier layout (0..1, default: 0.25) +- `` + - the `data` object provides `markerAppearance` to set and remove the edge arrows + ### Removed - support for React Flow v10 was completely removed @@ -15,11 +25,18 @@ This is a major release, and it might be not compatible with your current usage ### Fixed - ``: - - Add 'nopan', 'nowheel' and 'nodrag' classes to Modal's overlay classes in order to always prevent react-flow to react to drag and pan actions in modals. + - Add 'nopan', 'nowheel' and 'nodrag' classes to Modal's overlay classes in order to always prevent react-flow to react to drag and pan actions in modals. + +### Changed + +- `` and `` + - support now v9 and v12 of react flow ### Deprecated -- support for React Flow v9 will be removed +- support for React Flow v9 will be removed in v26 +- `` + - use `` or build it on single `` ## [24.4.0] - 2025-08-07 @@ -138,7 +155,7 @@ If you use Jest then you can use the same aliases for the `moduleNameMapper` con ### Migration from v24 to v25 -- remove deprecated components, properties and imports from your project, if the info cannot be found here then it was already mentioned in **Deprecated** sections of the v24.* changelogs. +- remove deprecated components, properties and imports from your project, if the info cannot be found here then it was already mentioned in **Deprecated** sections of the v24.\* changelogs. - we changed the integration of the supported react flow versions, formerly names `legacy` and `next` resources were renamed to more precise `v9` and `v10`, please see all info in the section about changes ## [24.1.0] - 2025-04-16 diff --git a/src/extensions/react-flow/edges/EdgeDefs.tsx b/src/extensions/react-flow/edges/EdgeDefs.tsx index d83e0121c..bc77e038b 100644 --- a/src/extensions/react-flow/edges/EdgeDefs.tsx +++ b/src/extensions/react-flow/edges/EdgeDefs.tsx @@ -1,7 +1,7 @@ import React from "react"; /** - * @deprecated (v26) use `` */ export const EdgeDefs = React.memo(() => ( diff --git a/src/extensions/react-flow/edges/edgeTypes.ts b/src/extensions/react-flow/edges/edgeTypes.ts index 1a3718a24..1a510d8c3 100644 --- a/src/extensions/react-flow/edges/edgeTypes.ts +++ b/src/extensions/react-flow/edges/edgeTypes.ts @@ -10,7 +10,7 @@ import { EdgeStep } from "./EdgeStep"; import { EdgeStraight } from "./EdgeStraight"; /** - * @deprecated (v25) will be removed without replacement, define it yourself or use `` with `configuration` option. */ export const edgeTypes = { default: EdgeDefault, From c19393403b4e68246d8d6d605fdb432c4265c689 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 14 Aug 2025 16:44:42 +0200 Subject: [PATCH 08/15] export bezier edge and use straigh edge for default react flow configuration --- src/cmem/react-flow/configuration/unspecified.ts | 3 ++- src/extensions/react-flow/index.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cmem/react-flow/configuration/unspecified.ts b/src/cmem/react-flow/configuration/unspecified.ts index 28ae0c019..0d7774937 100644 --- a/src/cmem/react-flow/configuration/unspecified.ts +++ b/src/cmem/react-flow/configuration/unspecified.ts @@ -1,10 +1,11 @@ import { EdgeDefault } from "./../../../extensions/react-flow/edges/EdgeDefault"; import { EdgeStep } from "./../../../extensions/react-flow/edges/EdgeStep"; +import { EdgeStraight } from "./../../../extensions/react-flow/edges/EdgeStraight"; import { NodeDefault } from "./../../../extensions/react-flow/nodes/NodeDefault"; export const edgeTypes = { default: EdgeDefault, - straight: EdgeDefault, + straight: EdgeStraight, step: EdgeStep, }; diff --git a/src/extensions/react-flow/index.ts b/src/extensions/react-flow/index.ts index 7f6e9378f..dffa51373 100644 --- a/src/extensions/react-flow/index.ts +++ b/src/extensions/react-flow/index.ts @@ -6,6 +6,7 @@ export * from "./nodes/nodeUtils"; export * from "./handles/HandleDefault"; export * from "./handles/HandleContent"; export * from "./handles/HandleTools"; +export * from "./edges/EdgeBezier"; export * from "./edges/EdgeDefault"; export * from "./edges/EdgeDefaultV12"; export * from "./edges/EdgeDefs"; From 2736da6caee6287c8f0024c9fc2e6707da774201 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 14 Aug 2025 17:15:46 +0200 Subject: [PATCH 09/15] adjust minimap and attribution position --- src/extensions/react-flow/_react-flow_v12.scss | 11 ++++++----- src/extensions/react-flow/minimap/_minimap.scss | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/extensions/react-flow/_react-flow_v12.scss b/src/extensions/react-flow/_react-flow_v12.scss index 74c5aac15..60b124a84 100644 --- a/src/extensions/react-flow/_react-flow_v12.scss +++ b/src/extensions/react-flow/_react-flow_v12.scss @@ -30,14 +30,15 @@ svg.react-flow__connectionline { position: absolute; right: 0; bottom: 0; - z-index: 1; - padding: 2px 3px; + z-index: 10; + padding: $eccgui-size-inline-whitespace * 0.5 $eccgui-size-inline-whitespace; margin: 0; - font-size: 10px; - background: var(--xy-attribution-background-color, var(--xy-attribution-background-color-default)); + font-size: $eccgui-size-typo-caption * 0.61; + background: transparent; + opacity: $eccgui-opacity-muted; } .react-flow__attribution a { - color: #999; + color: $eccgui-color-workspace-text; text-decoration: none; } diff --git a/src/extensions/react-flow/minimap/_minimap.scss b/src/extensions/react-flow/minimap/_minimap.scss index 736d80ee7..dffff8774 100644 --- a/src/extensions/react-flow/minimap/_minimap.scss +++ b/src/extensions/react-flow/minimap/_minimap.scss @@ -1,4 +1,6 @@ .react-flow__minimap { + right: $eccgui-size-block-whitespace * 0.5 !important; + bottom: $eccgui-size-block-whitespace !important; border: solid 1px $eccgui-color-separation-divider; & > svg { From dbe3b59a02f7ee992e73085a40fb8dca97e0935e Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 19 Aug 2025 11:29:59 +0200 Subject: [PATCH 10/15] minimal fix for the offset problem of new connection lines when editor is zoomed in/out --- src/extensions/react-flow/_react-flow.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/extensions/react-flow/_react-flow.scss b/src/extensions/react-flow/_react-flow.scss index 0b182db41..0e4974f18 100644 --- a/src/extensions/react-flow/_react-flow.scss +++ b/src/extensions/react-flow/_react-flow.scss @@ -6,6 +6,10 @@ @import "minimap/minimap"; @import "react-flow_v12"; +.react-flow__viewport { + transform-origin: 0 0; +} + .react-flow__background { border: solid 1px $eccgui-color-separation-divider; } From 76745a2d6adacc9f059606da1f11ff94bcc75045 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 19 Aug 2025 12:52:13 +0200 Subject: [PATCH 11/15] provide component that is used as default element for new connection lines in React Flow v12 --- CHANGELOG.md | 4 ++ .../react-flow/ReactFlow/ReactFlowV12.tsx | 2 + src/extensions/react-flow/edges/EdgeNew.tsx | 52 +++++++++++++++++++ src/extensions/react-flow/index.ts | 1 + .../react-flow/markers/ReactFlowMarkers.tsx | 2 +- .../react-flow/markers/_markers.scss | 4 ++ 6 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/extensions/react-flow/edges/EdgeNew.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 496e7453c..c238289f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ This is a major release, and it might be not compatible with your current usage - use `curvature` property in the edge `data` object to define the bezier layout (0..1, default: 0.25) - `` - the `data` object provides `markerAppearance` to set and remove the edge arrows +- `` + - component for React Flow v12, displaying new connection lines ### Removed @@ -31,6 +33,8 @@ This is a major release, and it might be not compatible with your current usage - `` and `` - support now v9 and v12 of react flow +- `` + - use `` by default for new connection lines, you can overwrite it by setting `connectionLineComponent` to `undefined` ### Deprecated diff --git a/src/cmem/react-flow/ReactFlow/ReactFlowV12.tsx b/src/cmem/react-flow/ReactFlow/ReactFlowV12.tsx index 83a06d316..23b22e2fb 100644 --- a/src/cmem/react-flow/ReactFlow/ReactFlowV12.tsx +++ b/src/cmem/react-flow/ReactFlow/ReactFlowV12.tsx @@ -9,6 +9,7 @@ import { } from "@xyflow/react"; import { CLASSPREFIX as eccgui } from "../../../configuration/constants"; +import { EdgeNew } from "./../../../extensions/react-flow/edges/EdgeNew"; export type ReactFlowV12ContainerProps = ReactFlowV12Props; @@ -43,6 +44,7 @@ export const ReactFlowV12Container = React.forwardRef { + + const { + connectionLineType, + fromX, + fromY, + toX, + toY, + connectionStatus, + fromPosition, + toPosition, + } = edgeNewProps; + + let EdgeType; + + switch(connectionLineType) { + case ConnectionLineType.Step: + case ConnectionLineType.SmoothStep: + EdgeType = EdgeStep; + break; + case ConnectionLineType.Bezier: + case ConnectionLineType.SimpleBezier: + EdgeType = EdgeBezier; + break; + default: + EdgeType = EdgeStraight; + } + + return ; +}; + diff --git a/src/extensions/react-flow/index.ts b/src/extensions/react-flow/index.ts index dffa51373..2ef91634a 100644 --- a/src/extensions/react-flow/index.ts +++ b/src/extensions/react-flow/index.ts @@ -12,6 +12,7 @@ export * from "./edges/EdgeDefaultV12"; export * from "./edges/EdgeDefs"; export * from "./edges/EdgeStep"; export * from "./edges/EdgeStraight"; +export * from "./edges/EdgeNew"; export * from "./edges/EdgeTools"; export * from "./edges/EdgeLabel"; export * from "./edges/EdgeDefs"; diff --git a/src/extensions/react-flow/markers/ReactFlowMarkers.tsx b/src/extensions/react-flow/markers/ReactFlowMarkers.tsx index 628f864dc..2f99a0c08 100644 --- a/src/extensions/react-flow/markers/ReactFlowMarkers.tsx +++ b/src/extensions/react-flow/markers/ReactFlowMarkers.tsx @@ -53,7 +53,7 @@ const ReactFlowMarker = ({ className, appearance = "arrow-closed", intent, rever }; const ReactFlowMarkers: FC = () => { - const intents = ["none", "primary", "success", "warning", "danger", "info"] as IntentTypes[]; + const intents = ["none", "primary", "accent", "success", "warning", "danger", "info" ] as IntentTypes[]; return ( diff --git a/src/extensions/react-flow/markers/_markers.scss b/src/extensions/react-flow/markers/_markers.scss index 3b684545e..82f4f6244 100644 --- a/src/extensions/react-flow/markers/_markers.scss +++ b/src/extensions/react-flow/markers/_markers.scss @@ -9,6 +9,10 @@ marker[id|="react-flow__marker"] { --marker-intent-color: #{$eccgui-color-primary}; } + &.#{$eccgui}-intent--accent { + --marker-intent-color: #{$eccgui-color-accent}; + } + &.#{$eccgui}-intent--info { --marker-intent-color: #{$eccgui-color-info-text}; } From bc2bafa4b41088ea4148ebc4d2dce1539316bf33 Mon Sep 17 00:00:00 2001 From: Mariia Kovsharova Date: Tue, 19 Aug 2025 12:21:35 +0200 Subject: [PATCH 12/15] Added missed styles from the original package --- src/extensions/react-flow/_react-flow_v12.scss | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/extensions/react-flow/_react-flow_v12.scss b/src/extensions/react-flow/_react-flow_v12.scss index 60b124a84..dfcc3c137 100644 --- a/src/extensions/react-flow/_react-flow_v12.scss +++ b/src/extensions/react-flow/_react-flow_v12.scss @@ -1,13 +1,15 @@ -.react-flow__edges svg:not(.#{$eccgui}-icon) { +// needed styles from "@xyflow/react/dist/style.css" to ensure proper functionality + +svg.react-flow__connectionline { position: absolute; + z-index: 1001; overflow: visible; - pointer-events: none; } -svg.react-flow__connectionline { +.react-flow .react-flow__edges svg { position: absolute; - z-index: 1001; overflow: visible; + pointer-events: none; } .react-flow__background-pattern { From 5612b32812f04c9057d0c22da00e53226ba4a848 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 19 Aug 2025 14:07:33 +0200 Subject: [PATCH 13/15] include some v12 base styles --- src/extensions/react-flow/_config.scss | 1 + src/extensions/react-flow/_react-flow.scss | 8 - .../react-flow/_react-flow_v12.scss | 176 +++++++++++++++++- 3 files changed, 173 insertions(+), 12 deletions(-) diff --git a/src/extensions/react-flow/_config.scss b/src/extensions/react-flow/_config.scss index d5855aaf4..f07e25a0e 100644 --- a/src/extensions/react-flow/_config.scss +++ b/src/extensions/react-flow/_config.scss @@ -1,3 +1,4 @@ +$reactflow-background-color: $card-background-color !default; $reactflow-node-basesize: $button-height !default; $reactflow-node-largesize: mini-units(6) !default; $reactflow-node-border-color: $eccgui-color-workspace-text !default; diff --git a/src/extensions/react-flow/_react-flow.scss b/src/extensions/react-flow/_react-flow.scss index 0e4974f18..21f6f4f4e 100644 --- a/src/extensions/react-flow/_react-flow.scss +++ b/src/extensions/react-flow/_react-flow.scss @@ -5,11 +5,3 @@ @import "handles/handles"; @import "minimap/minimap"; @import "react-flow_v12"; - -.react-flow__viewport { - transform-origin: 0 0; -} - -.react-flow__background { - border: solid 1px $eccgui-color-separation-divider; -} diff --git a/src/extensions/react-flow/_react-flow_v12.scss b/src/extensions/react-flow/_react-flow_v12.scss index dfcc3c137..3a39599ee 100644 --- a/src/extensions/react-flow/_react-flow_v12.scss +++ b/src/extensions/react-flow/_react-flow_v12.scss @@ -1,4 +1,97 @@ -// needed styles from "@xyflow/react/dist/style.css" to ensure proper functionality +/** + * We need some styles from "@xyflow/react/dist/style.css" to ensure proper functionality. + * Some of them are directly included to the component styles. + * Other stuff is here. + * Colors are removed or altered. + */ + +.react-flow { + direction: ltr; +} + +.react-flow__pane { + z-index: 1; +} + +.react-flow__pane.draggable { + cursor: grab; +} + +.react-flow__pane.dragging { + cursor: grabbing; +} + +.react-flow__pane.selection { + cursor: pointer; +} + +.react-flow__viewport { + z-index: 2; + pointer-events: none; + transform-origin: 0 0; +} + +.react-flow__renderer { + z-index: 4; +} + +.react-flow__selection { + z-index: 6; +} + +.react-flow__controls { + display: flex; + flex-direction: column; +} + +.react-flow__controls.horizontal { + flex-direction: row; +} + +.react-flow__controls-button { + display: flex; + justify-content: center; + cursor: pointer; + user-select: none; +} + +.react-flow__controls-button svg { + width: 100%; + max-width: 12px; + max-height: 12px; + fill: currentcolor; +} + +.react-flow .react-flow__edges { + position: absolute; +} + +.react-flow .react-flow__edges svg { + position: absolute; + overflow: visible; + pointer-events: none; +} + +.react-flow__edge { + pointer-events: visiblestroke; +} + +.react-flow__edge.inactive { + pointer-events: none; +} + +.react-flow__edge-textwrapper { + pointer-events: all; +} + +.react-flow__edge .react-flow__edge-text { + pointer-events: none; + user-select: none; +} + +.react-flow__connection { + pointer-events: none; +} svg.react-flow__connectionline { position: absolute; @@ -6,14 +99,89 @@ svg.react-flow__connectionline { overflow: visible; } -.react-flow .react-flow__edges svg { +.react-flow__nodes { + pointer-events: none; + transform-origin: 0 0; +} + +.react-flow__node { position: absolute; - overflow: visible; + box-sizing: border-box; + pointer-events: all; + cursor: default; + user-select: none; + transform-origin: 0 0; +} + +.react-flow__node.selectable { + cursor: pointer; +} + +.react-flow__node.draggable { + pointer-events: all; + cursor: grab; +} + +.react-flow__node.draggable.dragging { + cursor: grabbing; +} + +.react-flow__nodesselection { + z-index: 3; + pointer-events: none; + transform-origin: left top; +} + +.react-flow__nodesselection-rect { + position: absolute; + pointer-events: all; + cursor: grab; +} + +.react-flow__handle.connectingfrom { + pointer-events: all; +} + +.react-flow__handle.connectionindicator { + pointer-events: all; +} + +.react-flow__edgeupdater { + pointer-events: all; + cursor: move; +} + +.react-flow__minimap-svg { + display: block; +} + +.react-flow__node.selectable:focus, +.react-flow__node.selectable:focus-visible { + outline: none; +} + +.react-flow__nodesselection-rect:focus, +.react-flow__nodesselection-rect:focus-visible, +.react-flow__selection:focus, +.react-flow__selection:focus-visible { + outline: none; +} + +.react-flow__controls-button:disabled { + pointer-events: none; +} + +// -- adjustments + +.react-flow__background { + z-index: -1; pointer-events: none; + background-color: $reactflow-background-color; + border: solid 1px $eccgui-color-separation-divider; } .react-flow__background-pattern { - opacity: 0.39; + opacity: $eccgui-opacity-ghostly; } .react-flow__background-pattern.dots { From df1f21a7eb60150ca16a5a480e71a242281479df Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 20 Aug 2025 11:49:47 +0200 Subject: [PATCH 14/15] update package lock --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index d34dca533..7e60a6071 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1375,7 +1375,7 @@ "@lezer/common" "^1.0.2" "@lezer/css" "^1.1.7" -"@codemirror/lang-html@^6.0.0": +"@codemirror/lang-html@^6.0.0", "@codemirror/lang-html@^6.4.9": version "6.4.9" resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-6.4.9.tgz#d586f2cc9c341391ae07d1d7c545990dfa069727" integrity sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q== From 370d9c7b8c9eb78d05c647ce1618c76e309d1a76 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 21 Aug 2025 15:20:53 +0200 Subject: [PATCH 15/15] Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c238289f0..9f947eb42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This is a major release, and it might be not compatible with your current usage ### Added -- `` +- `` - it's basically `` without any special configs - `` - only supported for v12, in v9 as straight edge is used