diff --git a/CHANGELOG.md b/CHANGELOG.md index c1771ba7e..9f947eb42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,39 @@ 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 +- `` + - component for React Flow v12, displaying new connection lines + +### Removed + +- support for React Flow v10 was completely removed + ### 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 +- `` + - use `` by default for new connection lines, you can overwrite it by setting `connectionLineComponent` to `undefined` + +### Deprecated + +- support for React Flow v9 will be removed in v26 +- `` + - use `` or build it on single `` ## [24.4.0] - 2025-08-07 @@ -130,7 +159,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/package.json b/package.json index b8f2ad331..9ec76cb67 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,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/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 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/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/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/_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 3a331543a..21f6f4f4e 100644 --- a/src/extensions/react-flow/_react-flow.scss +++ b/src/extensions/react-flow/_react-flow.scss @@ -1,10 +1,7 @@ @import "config"; @import "nodes/nodes"; @import "edges/edges"; +@import "markers/markers"; @import "handles/handles"; @import "minimap/minimap"; @import "react-flow_v12"; - -.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 e96d8f9fb..3a39599ee 100644 --- a/src/extensions/react-flow/_react-flow_v12.scss +++ b/src/extensions/react-flow/_react-flow_v12.scss @@ -1,17 +1,187 @@ -.react-flow__edges svg:not(.#{$eccgui}-icon) { +/** + * 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; z-index: 1001; overflow: visible; } +.react-flow__nodes { + pointer-events: none; + transform-origin: 0 0; +} + +.react-flow__node { + position: absolute; + 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 { @@ -25,3 +195,20 @@ 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: 10; + padding: $eccgui-size-inline-whitespace * 0.5 $eccgui-size-inline-whitespace; + margin: 0; + font-size: $eccgui-size-typo-caption * 0.61; + background: transparent; + opacity: $eccgui-opacity-muted; +} + +.react-flow__attribution a { + color: $eccgui-color-workspace-text; + text-decoration: none; +} 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 65b7b2675..86660a558 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 + */ +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 + */ + markerStart?: string; +} + +/** + * @deprecated (v26) v9 support is removed after v25 + */ +export 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 ReactFlowVersions.V9: + return ; + case ReactFlowVersions.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..e3cea9ed9 100644 --- a/src/extensions/react-flow/edges/EdgeDefaultV12.tsx +++ b/src/extensions/react-flow/edges/EdgeDefaultV12.tsx @@ -1,44 +1,32 @@ -import { memo } from "react"; -import React from "react"; -import { BaseEdge, Edge, EdgeProps, EdgeText, getBezierPath, getEdgeCenter } from "@xyflow/react"; +import React, { memo } from "react"; +import { BaseEdge, Edge, EdgeProps, EdgeText, GetBezierPathParams } 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"; +import { getStraightPath } from "./utils"; -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; +/** + * @deprecated (v26) use EdgeDefaultDataProps + */ +export interface EdgeDefaultV12DataProps extends Record, EdgeDefaultDataProps { /** - * Callback handler that returns a React element used as edge title. + * Set the marker used on the start or end of the edge. */ - renderLabel?: (edgeCenter: [number, number, number, number]) => React.ReactNode; + markerAppearance?: "arrow-closed" | "none"; +} + +/** + * @deprecated (v26) use EdgeDefaultProps + */ +export type EdgeDefaultV12Props = EdgeProps> & { /** - * Properties are forwarded to the internally used SVG `g` element. - * Data attributes for test ids coud be included here. + * Callback handler that returns SVG path and label position of the edge. */ - edgeSvgProps?: React.SVGProps; + getPath?: ( + edgeParams: Omit & Record + ) => [path: string, labelX: number, labelY: number, offsetX: number, offsetY: number]; }; /** @@ -62,11 +50,12 @@ export const EdgeDefaultV12 = memo( labelBgPadding = [5, 5], labelBgBorderRadius = 3, data = {}, + getPath = getStraightPath, ...edgeOriginalProperties - }: EdgeProps>) => { + }: EdgeDefaultV12Props) => { const { pathGlowWidth = 10, highlightColor, renderLabel, edgeSvgProps, intent, inversePath, strokeType } = data; - const [edgePath, labelX, labelY] = getBezierPath({ + const [edgePath, labelX, labelY] = getPath({ sourceX, sourceY, sourcePosition, @@ -81,19 +70,12 @@ export const EdgeDefaultV12 = memo( highlightColor ); - const edgeCenter = getEdgeCenter({ - sourceX, - sourceY, - targetX, - targetY, - }); - const renderedLabel = renderLabel?.([labelX, labelY, sourceX, targetX]) ?? (label ? ( ) : null); + 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 ( - - {highlightColor && ( - - )} - - - + )} + {renderedLabel} ); diff --git a/src/extensions/react-flow/edges/EdgeDefs.tsx b/src/extensions/react-flow/edges/EdgeDefs.tsx index aa3d2a440..bc77e038b 100644 --- a/src/extensions/react-flow/edges/EdgeDefs.tsx +++ b/src/extensions/react-flow/edges/EdgeDefs.tsx @@ -1,5 +1,8 @@ import React from "react"; +/** + * @deprecated (v26) use `` + */ export const EdgeDefs = React.memo(() => ( diff --git a/src/extensions/react-flow/edges/EdgeNew.tsx b/src/extensions/react-flow/edges/EdgeNew.tsx new file mode 100644 index 000000000..9c97d34e1 --- /dev/null +++ b/src/extensions/react-flow/edges/EdgeNew.tsx @@ -0,0 +1,52 @@ +import React from "react"; +import { + ConnectionLineComponentProps, + ConnectionLineType, +} from "@xyflow/react"; +import { EdgeStraight, EdgeStep, EdgeBezier, EdgeDefaultV12Props } from "./../index"; + +import { CLASSPREFIX as eccgui } from "../../../configuration/constants"; + +export const EdgeNew = (edgeNewProps: ConnectionLineComponentProps) => { + + 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/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..1a510d8c3 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 `` with `configuration` option. */ export const edgeTypes = { default: EdgeDefault, - straight: EdgeDefault, + straight: EdgeStraight, step: EdgeStep, success: EdgeDefault, diff --git a/src/extensions/react-flow/edges/stories/EdgeDefaultV12.stories.tsx b/src/extensions/react-flow/edges/stories/EdgeDefaultV12.stories.tsx index 5716e5924..b2f4acfd4 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,14 +93,12 @@ const EdgeDefault = (args: Edge) => { ); return ( -
- - + ) => { + 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/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..2ef91634a 100644 --- a/src/extensions/react-flow/index.ts +++ b/src/extensions/react-flow/index.ts @@ -6,17 +6,19 @@ 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"; export * from "./edges/EdgeStep"; +export * from "./edges/EdgeStraight"; +export * from "./edges/EdgeNew"; export * from "./edges/EdgeTools"; export * from "./edges/EdgeLabel"; 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/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", "accent", "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..82f4f6244 --- /dev/null +++ b/src/extensions/react-flow/markers/_markers.scss @@ -0,0 +1,31 @@ +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--accent { + --marker-intent-color: #{$eccgui-color-accent}; + } + + &.#{$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}; + } +} 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/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 { diff --git a/src/extensions/react-flow/nodes/NodeContent.tsx b/src/extensions/react-flow/nodes/NodeContent.tsx index 1eb98d1a0..7879ee654 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 1b4164965..7e60a6071 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1104,7 +1104,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== @@ -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== @@ -2979,99 +2979,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" @@ -3079,73 +2998,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== @@ -3153,42 +3018,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" @@ -3229,11 +3058,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" @@ -3399,11 +3223,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" @@ -10157,20 +9976,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" @@ -12496,11 +12301,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"