refactor(react/svelte): cleanup types
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { CSSProperties } from 'react';
|
import { CSSProperties } from 'react';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const style: CSSProperties = { display: 'none' };
|
const style: CSSProperties = { display: 'none' };
|
||||||
const ariaLiveStyle: CSSProperties = {
|
const ariaLiveStyle: CSSProperties = {
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ import {
|
|||||||
Position,
|
Position,
|
||||||
ConnectionLineType,
|
ConnectionLineType,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
type ConnectionLineComponent,
|
|
||||||
type ConnectionStatus,
|
type ConnectionStatus,
|
||||||
type HandleType,
|
type HandleType,
|
||||||
type ReactFlowState,
|
|
||||||
type ReactFlowStore,
|
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
import { getBezierPath, getSmoothStepPath } from '@reactflow/edge-utils';
|
import { getBezierPath, getSmoothStepPath } from '@reactflow/edge-utils';
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
|
import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
|
||||||
|
import type { ConnectionLineComponent, ReactFlowState, ReactFlowStore } from '../../types';
|
||||||
|
|
||||||
type ConnectionLineProps = {
|
type ConnectionLineProps = {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
|
const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { isNumeric } from '@reactflow/utils';
|
import { isNumeric } from '@reactflow/utils';
|
||||||
import type { BaseEdgeProps } from '@reactflow/system';
|
|
||||||
|
import type { BaseEdgeProps } from '../../types';
|
||||||
|
|
||||||
import EdgeText from './EdgeText';
|
import EdgeText from './EdgeText';
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Position, type BezierEdgeProps } from '@reactflow/system';
|
import { Position } from '@reactflow/system';
|
||||||
import { getBezierPath } from '@reactflow/edge-utils';
|
import { getBezierPath } from '@reactflow/edge-utils';
|
||||||
|
|
||||||
import BaseEdge from './BaseEdge';
|
import BaseEdge from './BaseEdge';
|
||||||
|
import type { BezierEdgeProps } from '../../types';
|
||||||
|
|
||||||
const BezierEdge = memo(
|
const BezierEdge = memo(
|
||||||
({
|
({
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { memo, useRef, useState, useEffect } from 'react';
|
import { memo, useRef, useState, useEffect, type FC, type PropsWithChildren } from 'react';
|
||||||
import type { FC, PropsWithChildren } from 'react';
|
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { EdgeTextProps, Rect } from '@reactflow/system';
|
import type { Rect } from '@reactflow/system';
|
||||||
|
|
||||||
|
import type { EdgeTextProps } from '../../types';
|
||||||
|
|
||||||
const EdgeText: FC<PropsWithChildren<EdgeTextProps>> = ({
|
const EdgeText: FC<PropsWithChildren<EdgeTextProps>> = ({
|
||||||
x,
|
x,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Position, type EdgeProps } from '@reactflow/system';
|
import { Position } from '@reactflow/system';
|
||||||
import { getBezierEdgeCenter } from '@reactflow/edge-utils';
|
import { getBezierEdgeCenter } from '@reactflow/edge-utils';
|
||||||
|
|
||||||
import BaseEdge from './BaseEdge';
|
import BaseEdge from './BaseEdge';
|
||||||
|
import type { EdgeProps } from '../../types';
|
||||||
|
|
||||||
export interface GetSimpleBezierPathParams {
|
export interface GetSimpleBezierPathParams {
|
||||||
sourceX: number;
|
sourceX: number;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Position, type SmoothStepEdgeProps } from '@reactflow/system';
|
import { Position } from '@reactflow/system';
|
||||||
import { getSmoothStepPath } from '@reactflow/edge-utils';
|
import { getSmoothStepPath } from '@reactflow/edge-utils';
|
||||||
|
|
||||||
import BaseEdge from './BaseEdge';
|
import BaseEdge from './BaseEdge';
|
||||||
|
import type { SmoothStepEdgeProps } from '../../types';
|
||||||
|
|
||||||
const SmoothStepEdge = memo(
|
const SmoothStepEdge = memo(
|
||||||
({
|
({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import type { SmoothStepEdgeProps } from '@reactflow/system';
|
|
||||||
|
|
||||||
import SmoothStepEdge from './SmoothStepEdge';
|
import SmoothStepEdge from './SmoothStepEdge';
|
||||||
|
import type { SmoothStepEdgeProps } from '../../types';
|
||||||
|
|
||||||
const StepEdge = memo((props: SmoothStepEdgeProps) => (
|
const StepEdge = memo((props: SmoothStepEdgeProps) => (
|
||||||
<SmoothStepEdge
|
<SmoothStepEdge
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import type { EdgeProps } from '@reactflow/system';
|
|
||||||
import { getStraightPath } from '@reactflow/edge-utils';
|
import { getStraightPath } from '@reactflow/edge-utils';
|
||||||
|
|
||||||
import BaseEdge from './BaseEdge';
|
import BaseEdge from './BaseEdge';
|
||||||
|
import type { EdgeProps } from '../../types';
|
||||||
|
|
||||||
const StraightEdge = memo(
|
const StraightEdge = memo(
|
||||||
({
|
({
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||||
import { StoreApi } from 'zustand';
|
import { StoreApi } from 'zustand';
|
||||||
import type { Edge, ReactFlowState } from '@reactflow/system';
|
|
||||||
|
import type { Edge, ReactFlowState } from '../../types';
|
||||||
|
|
||||||
export function getMouseHandler(
|
export function getMouseHandler(
|
||||||
id: string,
|
id: string,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { memo, useState, useMemo, useRef } from 'react';
|
import { memo, useState, useMemo, useRef, type ComponentType, type KeyboardEvent } from 'react';
|
||||||
import type { ComponentType, KeyboardEvent } from 'react';
|
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { getMarkerId, elementSelectionKeys } from '@reactflow/utils';
|
import { getMarkerId, elementSelectionKeys } from '@reactflow/utils';
|
||||||
import type { EdgeProps, WrapEdgeProps, Connection } from '@reactflow/system';
|
import type { Connection } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStoreApi } from '../../hooks/useStore';
|
import { useStoreApi } from '../../hooks/useStore';
|
||||||
import { ARIA_EDGE_DESC_KEY } from '../A11yDescriptions';
|
import { ARIA_EDGE_DESC_KEY } from '../A11yDescriptions';
|
||||||
import { handlePointerDown } from '../Handle/handler';
|
import { handlePointerDown } from '../Handle/handler';
|
||||||
import { EdgeAnchor } from './EdgeAnchor';
|
import { EdgeAnchor } from './EdgeAnchor';
|
||||||
import { getMouseHandler } from './utils';
|
import { getMouseHandler } from './utils';
|
||||||
|
import type { EdgeProps, WrapEdgeProps } from '../../types';
|
||||||
|
|
||||||
export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||||
const EdgeWrapper = ({
|
const EdgeWrapper = ({
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
pointToRendererPoint,
|
pointToRendererPoint,
|
||||||
rendererPointToPoint,
|
rendererPointToPoint,
|
||||||
} from '@reactflow/utils';
|
} from '@reactflow/utils';
|
||||||
import type { OnConnect, HandleType, ReactFlowState, Connection } from '@reactflow/system';
|
import type { OnConnect, HandleType, Connection } from '@reactflow/system';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ConnectionHandle,
|
ConnectionHandle,
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
resetRecentHandle,
|
resetRecentHandle,
|
||||||
ValidConnectionFunc,
|
ValidConnectionFunc,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
export function handlePointerDown({
|
export function handlePointerDown({
|
||||||
event,
|
event,
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { memo, HTMLAttributes, forwardRef, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
import { memo, HTMLAttributes, forwardRef, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import { errorMessages, Position, type HandleProps, type Connection, type ReactFlowState } from '@reactflow/system';
|
import { errorMessages, Position, type HandleProps, type Connection } from '@reactflow/system';
|
||||||
import { getHostForElement, isMouseEvent, addEdge } from '@reactflow/utils';
|
import { getHostForElement, isMouseEvent } from '@reactflow/utils';
|
||||||
|
|
||||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||||
import { useNodeId } from '../../contexts/NodeIdContext';
|
import { useNodeId } from '../../contexts/NodeIdContext';
|
||||||
import { handlePointerDown } from './handler';
|
import { handlePointerDown } from './handler';
|
||||||
import { isValidHandle } from './utils';
|
import { isValidHandle } from './utils';
|
||||||
|
import { addEdge } from '../../utils';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const alwaysValid = () => true;
|
const alwaysValid = () => true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
||||||
import { internalsSymbol, ConnectionMode, ConnectionStatus } from '@reactflow/system';
|
import {
|
||||||
import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '@reactflow/system';
|
internalsSymbol,
|
||||||
|
ConnectionMode,
|
||||||
|
ConnectionStatus,
|
||||||
|
type Connection,
|
||||||
|
type HandleType,
|
||||||
|
type XYPosition,
|
||||||
|
type NodeHandleBounds,
|
||||||
|
} from '@reactflow/system';
|
||||||
import { getEventPosition } from '@reactflow/utils';
|
import { getEventPosition } from '@reactflow/utils';
|
||||||
|
|
||||||
|
import type { Node } from '../../types';
|
||||||
|
|
||||||
export type ConnectionHandle = {
|
export type ConnectionHandle = {
|
||||||
id: string | null;
|
id: string | null;
|
||||||
type: HandleType;
|
type: HandleType;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { MouseEvent } from 'react';
|
import { MouseEvent } from 'react';
|
||||||
import { StoreApi } from 'zustand';
|
import { StoreApi } from 'zustand';
|
||||||
import { getDimensions } from '@reactflow/utils';
|
import { getDimensions } from '@reactflow/utils';
|
||||||
import { Position, type HandleElement, type Node, type NodeOrigin, type ReactFlowState } from '@reactflow/system';
|
import { Position, type HandleElement, type NodeOrigin } from '@reactflow/system';
|
||||||
|
|
||||||
|
import type { Node, ReactFlowState } from '../../types';
|
||||||
|
|
||||||
export const getHandleBounds = (
|
export const getHandleBounds = (
|
||||||
selector: string,
|
selector: string,
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { useEffect, useRef, memo } from 'react';
|
import { useEffect, useRef, memo, type ComponentType, type MouseEvent, type KeyboardEvent } from 'react';
|
||||||
import type { ComponentType, MouseEvent, KeyboardEvent } from 'react';
|
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { elementSelectionKeys, isInputDOMNode } from '@reactflow/utils';
|
import { elementSelectionKeys, isInputDOMNode } from '@reactflow/utils';
|
||||||
import type { NodeProps, WrapNodeProps, XYPosition } from '@reactflow/system';
|
import type { NodeProps, XYPosition } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStoreApi } from '../../hooks/useStore';
|
import { useStoreApi } from '../../hooks/useStore';
|
||||||
import { Provider } from '../../contexts/NodeIdContext';
|
import { Provider } from '../../contexts/NodeIdContext';
|
||||||
@@ -10,6 +9,7 @@ import { ARIA_NODE_DESC_KEY } from '../A11yDescriptions';
|
|||||||
import useDrag from '../../hooks/useDrag';
|
import useDrag from '../../hooks/useDrag';
|
||||||
import useUpdateNodePositions from '../../hooks/useUpdateNodePositions';
|
import useUpdateNodePositions from '../../hooks/useUpdateNodePositions';
|
||||||
import { getMouseHandler, handleNodeClick } from './utils';
|
import { getMouseHandler, handleNodeClick } from './utils';
|
||||||
|
import type { WrapNodeProps } from '../../types';
|
||||||
|
|
||||||
export const arrowKeyDiffs: Record<string, XYPosition> = {
|
export const arrowKeyDiffs: Record<string, XYPosition> = {
|
||||||
ArrowUp: { x: 0, y: -1 },
|
ArrowUp: { x: 0, y: -1 },
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import type { MouseEvent, KeyboardEvent } from 'react';
|
|||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import { getRectOfNodes } from '@reactflow/utils';
|
import { getRectOfNodes } from '@reactflow/utils';
|
||||||
import type { Node, ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||||
import useDrag from '../../hooks/useDrag';
|
import useDrag from '../../hooks/useDrag';
|
||||||
import { arrowKeyDiffs } from '../Nodes/wrapNode';
|
import { arrowKeyDiffs } from '../Nodes/wrapNode';
|
||||||
import useUpdateNodePositions from '../../hooks/useUpdateNodePositions';
|
import useUpdateNodePositions from '../../hooks/useUpdateNodePositions';
|
||||||
|
import type { Node, ReactFlowState } from '../../types';
|
||||||
|
|
||||||
export interface NodesSelectionProps {
|
export interface NodesSelectionProps {
|
||||||
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
|
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import type { HTMLAttributes, ReactNode } from 'react';
|
import type { HTMLAttributes, ReactNode } from 'react';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import type { PanelPosition, ReactFlowState } from '@reactflow/system';
|
import type { PanelPosition } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
export type PanelProps = HTMLAttributes<HTMLDivElement> & {
|
export type PanelProps = HTMLAttributes<HTMLDivElement> & {
|
||||||
position: PanelPosition;
|
position: PanelPosition;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { useRef } from 'react';
|
import { useRef, type FC, type PropsWithChildren } from 'react';
|
||||||
import type { FC, PropsWithChildren } from 'react';
|
|
||||||
import { StoreApi } from 'zustand';
|
import { StoreApi } from 'zustand';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { Provider } from '../../contexts/RFStoreContext';
|
import { Provider } from '../../contexts/RFStoreContext';
|
||||||
import { createRFStore } from '../../store';
|
import { createRFStore } from '../../store';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const ReactFlowProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
|
const ReactFlowProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||||
const storeRef = useRef<StoreApi<ReactFlowState> | null>(null);
|
const storeRef = useRef<StoreApi<ReactFlowState> | null>(null);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { memo, useEffect } from 'react';
|
import { memo, useEffect } from 'react';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import type { ReactFlowState, OnSelectionChangeFunc, Node, Edge } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||||
|
import type { ReactFlowState, OnSelectionChangeFunc, Node, Edge } from '../../types';
|
||||||
|
|
||||||
type SelectionListenerProps = {
|
type SelectionListenerProps = {
|
||||||
onSelectionChange?: OnSelectionChangeFunc;
|
onSelectionChange?: OnSelectionChangeFunc;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { StoreApi } from 'zustand';
|
import { StoreApi } from 'zustand';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import type { Node, Edge, ReactFlowState, CoordinateExtent, ReactFlowProps, ReactFlowStore } from '@reactflow/system';
|
import type { CoordinateExtent } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||||
|
import type { Node, Edge, ReactFlowState, ReactFlowProps, ReactFlowStore } from '../../types';
|
||||||
|
|
||||||
type StoreUpdaterProps = Pick<
|
type StoreUpdaterProps = Pick<
|
||||||
ReactFlowProps,
|
ReactFlowProps,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
userSelectionActive: s.userSelectionActive,
|
userSelectionActive: s.userSelectionActive,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import type { EdgeMarker, ReactFlowState } from '@reactflow/system';
|
import type { EdgeMarker } from '@reactflow/system';
|
||||||
import { getMarkerId } from '@reactflow/utils';
|
import { getMarkerId } from '@reactflow/utils';
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
import { useMarkerSymbol } from './MarkerSymbols';
|
import { useMarkerSymbol } from './MarkerSymbols';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
type MarkerProps = EdgeMarker & {
|
type MarkerProps = EdgeMarker & {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { memo, ReactNode } from 'react';
|
import { memo, ReactNode } from 'react';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { errorMessages, ConnectionMode, Position, type Edge, type ReactFlowState } from '@reactflow/system';
|
import { errorMessages, ConnectionMode, Position } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
import useVisibleEdges from '../../hooks/useVisibleEdges';
|
import useVisibleEdges from '../../hooks/useVisibleEdges';
|
||||||
import MarkerDefinitions from './MarkerDefinitions';
|
import MarkerDefinitions from './MarkerDefinitions';
|
||||||
import { getEdgePositions, getHandle, getNodeData } from './utils';
|
import { getEdgePositions, getHandle, getNodeData } from './utils';
|
||||||
|
|
||||||
import { GraphViewProps } from '../GraphView';
|
import { GraphViewProps } from '../GraphView';
|
||||||
|
import type { Edge, ReactFlowState } from '../../types';
|
||||||
|
|
||||||
type EdgeRendererProps = Pick<
|
type EdgeRendererProps = Pick<
|
||||||
GraphViewProps,
|
GraphViewProps,
|
||||||
|
|||||||
@@ -2,12 +2,8 @@ import type { ComponentType } from 'react';
|
|||||||
import {
|
import {
|
||||||
internalsSymbol,
|
internalsSymbol,
|
||||||
Position,
|
Position,
|
||||||
type EdgeProps,
|
|
||||||
type EdgeTypes,
|
|
||||||
type EdgeTypesWrapped,
|
|
||||||
type HandleElement,
|
type HandleElement,
|
||||||
type NodeHandleBounds,
|
type NodeHandleBounds,
|
||||||
type Node,
|
|
||||||
type Rect,
|
type Rect,
|
||||||
type Transform,
|
type Transform,
|
||||||
type XYPosition,
|
type XYPosition,
|
||||||
@@ -16,6 +12,7 @@ import { rectToBox } from '@reactflow/utils';
|
|||||||
|
|
||||||
import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, SimpleBezierEdge } from '../../components/Edges';
|
import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, SimpleBezierEdge } from '../../components/Edges';
|
||||||
import wrapEdge from '../../components/Edges/wrapEdge';
|
import wrapEdge from '../../components/Edges/wrapEdge';
|
||||||
|
import type { EdgeProps, EdgeTypes, EdgeTypesWrapped, Node } from '../../types';
|
||||||
|
|
||||||
export type CreateEdgeTypes = (edgeTypes: EdgeTypes) => EdgeTypesWrapped;
|
export type CreateEdgeTypes = (edgeTypes: EdgeTypes) => EdgeTypesWrapped;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { memo, type ReactNode } from 'react';
|
import { memo, type ReactNode } from 'react';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
|
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
|
||||||
@@ -8,6 +7,7 @@ import { GraphViewProps } from '../GraphView';
|
|||||||
import ZoomPane from '../ZoomPane';
|
import ZoomPane from '../ZoomPane';
|
||||||
import Pane from '../Pane';
|
import Pane from '../Pane';
|
||||||
import NodesSelection from '../../components/NodesSelection';
|
import NodesSelection from '../../components/NodesSelection';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
export type FlowRendererProps = Omit<
|
export type FlowRendererProps = Omit<
|
||||||
GraphViewProps,
|
GraphViewProps,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import type { EdgeTypesWrapped, NodeTypesWrapped, ReactFlowProps } from '@reactflow/system';
|
|
||||||
|
|
||||||
import FlowRenderer from '../FlowRenderer';
|
import FlowRenderer from '../FlowRenderer';
|
||||||
import NodeRenderer from '../NodeRenderer';
|
import NodeRenderer from '../NodeRenderer';
|
||||||
@@ -7,6 +6,7 @@ import EdgeRenderer from '../EdgeRenderer';
|
|||||||
import ViewportWrapper from '../Viewport';
|
import ViewportWrapper from '../Viewport';
|
||||||
import useOnInitHandler from '../../hooks/useOnInitHandler';
|
import useOnInitHandler from '../../hooks/useOnInitHandler';
|
||||||
import ConnectionLine from '../../components/ConnectionLine';
|
import ConnectionLine from '../../components/ConnectionLine';
|
||||||
|
import type { EdgeTypesWrapped, NodeTypesWrapped, ReactFlowProps } from '../../types';
|
||||||
|
|
||||||
export type GraphViewProps = Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges' | 'nodeTypes' | 'edgeTypes'> &
|
export type GraphViewProps = Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges' | 'nodeTypes' | 'edgeTypes'> &
|
||||||
Required<
|
Required<
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { memo, useMemo, useEffect, useRef } from 'react';
|
import { memo, useMemo, useEffect, useRef, type ComponentType } from 'react';
|
||||||
import type { ComponentType } from 'react';
|
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import { internalsSymbol, errorMessages, Position, type ReactFlowState, type WrapNodeProps } from '@reactflow/system';
|
import { internalsSymbol, errorMessages, Position } from '@reactflow/system';
|
||||||
import { clampPosition } from '@reactflow/utils';
|
import { clampPosition } from '@reactflow/utils';
|
||||||
|
|
||||||
import useVisibleNodes from '../../hooks/useVisibleNodes';
|
import useVisibleNodes from '../../hooks/useVisibleNodes';
|
||||||
@@ -9,6 +8,7 @@ import { useStore } from '../../hooks/useStore';
|
|||||||
import { containerStyle } from '../../styles';
|
import { containerStyle } from '../../styles';
|
||||||
import { GraphViewProps } from '../GraphView';
|
import { GraphViewProps } from '../GraphView';
|
||||||
import { getPositionWithOrigin } from './utils';
|
import { getPositionWithOrigin } from './utils';
|
||||||
|
import type { ReactFlowState, WrapNodeProps } from '../../types';
|
||||||
|
|
||||||
type NodeRendererProps = Pick<
|
type NodeRendererProps = Pick<
|
||||||
GraphViewProps,
|
GraphViewProps,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import type { ComponentType } from 'react';
|
import type { ComponentType } from 'react';
|
||||||
import type { NodeTypes, NodeProps, NodeTypesWrapped, NodeOrigin, XYPosition } from '@reactflow/system';
|
import type { NodeProps, NodeOrigin, XYPosition } from '@reactflow/system';
|
||||||
|
|
||||||
import DefaultNode from '../../components/Nodes/DefaultNode';
|
import DefaultNode from '../../components/Nodes/DefaultNode';
|
||||||
import InputNode from '../../components/Nodes/InputNode';
|
import InputNode from '../../components/Nodes/InputNode';
|
||||||
import OutputNode from '../../components/Nodes/OutputNode';
|
import OutputNode from '../../components/Nodes/OutputNode';
|
||||||
import GroupNode from '../../components/Nodes/GroupNode';
|
import GroupNode from '../../components/Nodes/GroupNode';
|
||||||
import wrapNode from '../../components/Nodes/wrapNode';
|
import wrapNode from '../../components/Nodes/wrapNode';
|
||||||
|
import type { NodeTypes, NodeTypesWrapped } from '../../types';
|
||||||
|
|
||||||
export type CreateNodeTypes = (nodeTypes: NodeTypes) => NodeTypesWrapped;
|
export type CreateNodeTypes = (nodeTypes: NodeTypes) => NodeTypesWrapped;
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,17 @@
|
|||||||
* The user selection rectangle gets displayed when a user drags the mouse while pressing shift
|
* The user selection rectangle gets displayed when a user drags the mouse while pressing shift
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { memo, useRef, MouseEvent as ReactMouseEvent, ReactNode } from 'react';
|
import { memo, useRef, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { getConnectedEdges, getNodesInside, getEventPosition } from '@reactflow/utils';
|
import { getNodesInside, getEventPosition } from '@reactflow/utils';
|
||||||
import {
|
import { SelectionMode } from '@reactflow/system';
|
||||||
SelectionMode,
|
|
||||||
type ReactFlowProps,
|
|
||||||
type ReactFlowState,
|
|
||||||
type NodeChange,
|
|
||||||
type EdgeChange,
|
|
||||||
} from '@reactflow/system';
|
|
||||||
|
|
||||||
import UserSelection from '../../components/UserSelection';
|
import UserSelection from '../../components/UserSelection';
|
||||||
import { containerStyle } from '../../styles';
|
import { containerStyle } from '../../styles';
|
||||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||||
import { getSelectionChanges } from '../../utils/changes';
|
import { getSelectionChanges, getConnectedEdges } from '../../utils';
|
||||||
|
import type { ReactFlowProps, ReactFlowState, NodeChange, EdgeChange, Node } from '../../types';
|
||||||
|
|
||||||
type PaneProps = {
|
type PaneProps = {
|
||||||
isSelecting: boolean;
|
isSelecting: boolean;
|
||||||
@@ -135,7 +130,7 @@ const Pane = memo(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onMouseMove = (event: ReactMouseEvent): void => {
|
const onMouseMove = (event: ReactMouseEvent): void => {
|
||||||
const { userSelectionRect, nodeInternals, edges, transform, onNodesChange, onEdgesChange, nodeOrigin, getNodes } =
|
const { userSelectionRect, edges, transform, onNodesChange, onEdgesChange, nodeOrigin, getNodes } =
|
||||||
store.getState();
|
store.getState();
|
||||||
if (!isSelecting || !containerBounds.current || !userSelectionRect) {
|
if (!isSelecting || !containerBounds.current || !userSelectionRect) {
|
||||||
return;
|
return;
|
||||||
@@ -156,8 +151,8 @@ const Pane = memo(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const nodes = getNodes();
|
const nodes = getNodes();
|
||||||
const selectedNodes = getNodesInside(
|
const selectedNodes = getNodesInside<Node>(
|
||||||
nodeInternals,
|
nodes,
|
||||||
nextUserSelectRect,
|
nextUserSelectRect,
|
||||||
transform,
|
transform,
|
||||||
selectionMode === SelectionMode.Partial,
|
selectionMode === SelectionMode.Partial,
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
import { forwardRef } from 'react';
|
import { forwardRef, type CSSProperties } from 'react';
|
||||||
import type { CSSProperties } from 'react';
|
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import {
|
import {
|
||||||
ConnectionLineType,
|
ConnectionLineType,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
PanOnScrollMode,
|
PanOnScrollMode,
|
||||||
SelectionMode,
|
SelectionMode,
|
||||||
type EdgeTypes,
|
|
||||||
type EdgeTypesWrapped,
|
|
||||||
type NodeOrigin,
|
type NodeOrigin,
|
||||||
type NodeTypes,
|
|
||||||
type NodeTypesWrapped,
|
|
||||||
type ReactFlowProps,
|
|
||||||
type ReactFlowRefType,
|
|
||||||
type Viewport,
|
type Viewport,
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
|
import { infiniteExtent } from '@reactflow/utils';
|
||||||
|
|
||||||
import Attribution from '../../components/Attribution';
|
import Attribution from '../../components/Attribution';
|
||||||
import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, SimpleBezierEdge } from '../../components/Edges';
|
import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, SimpleBezierEdge } from '../../components/Edges';
|
||||||
@@ -29,8 +23,15 @@ import { createEdgeTypes } from '../EdgeRenderer/utils';
|
|||||||
import { createNodeTypes } from '../NodeRenderer/utils';
|
import { createNodeTypes } from '../NodeRenderer/utils';
|
||||||
import GraphView from '../GraphView';
|
import GraphView from '../GraphView';
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
import { infiniteExtent } from '../../store/initialState';
|
|
||||||
import { useNodeOrEdgeTypes } from './utils';
|
import { useNodeOrEdgeTypes } from './utils';
|
||||||
|
import type {
|
||||||
|
EdgeTypes,
|
||||||
|
EdgeTypesWrapped,
|
||||||
|
NodeTypes,
|
||||||
|
NodeTypesWrapped,
|
||||||
|
ReactFlowProps,
|
||||||
|
ReactFlowRefType,
|
||||||
|
} from '../../types';
|
||||||
|
|
||||||
const defaultNodeTypes: NodeTypes = {
|
const defaultNodeTypes: NodeTypes = {
|
||||||
input: InputNode,
|
input: InputNode,
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import { useMemo, useRef } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import {
|
import { errorMessages } from '@reactflow/system';
|
||||||
errorMessages,
|
|
||||||
type EdgeTypes,
|
|
||||||
type EdgeTypesWrapped,
|
|
||||||
type NodeTypes,
|
|
||||||
type NodeTypesWrapped,
|
|
||||||
} from '@reactflow/system';
|
|
||||||
import { devWarn } from '@reactflow/utils';
|
import { devWarn } from '@reactflow/utils';
|
||||||
|
|
||||||
import { CreateEdgeTypes } from '../EdgeRenderer/utils';
|
import { CreateEdgeTypes } from '../EdgeRenderer/utils';
|
||||||
import { CreateNodeTypes } from '../NodeRenderer/utils';
|
import { CreateNodeTypes } from '../NodeRenderer/utils';
|
||||||
|
import type { EdgeTypes, EdgeTypesWrapped, NodeTypes, NodeTypesWrapped } from '../../types';
|
||||||
|
|
||||||
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: NodeTypes, createTypes: CreateNodeTypes): NodeTypesWrapped;
|
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: NodeTypes, createTypes: CreateNodeTypes): NodeTypesWrapped;
|
||||||
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: EdgeTypes, createTypes: CreateEdgeTypes): EdgeTypesWrapped;
|
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: EdgeTypes, createTypes: CreateEdgeTypes): EdgeTypesWrapped;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
|
const selector = (s: ReactFlowState) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import { zoom, zoomIdentity } from 'd3-zoom';
|
import { zoom, zoomIdentity, type D3ZoomEvent } from 'd3-zoom';
|
||||||
import type { D3ZoomEvent } from 'd3-zoom';
|
|
||||||
import { select, pointer } from 'd3-selection';
|
import { select, pointer } from 'd3-selection';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import { clamp } from '@reactflow/utils';
|
import { clamp } from '@reactflow/utils';
|
||||||
import { type Viewport, type ReactFlowState, CoordinateExtent, PanOnScrollMode } from '@reactflow/system';
|
import { CoordinateExtent, PanOnScrollMode, type Viewport } from '@reactflow/system';
|
||||||
|
|
||||||
import useKeyPress from '../../hooks/useKeyPress';
|
import useKeyPress from '../../hooks/useKeyPress';
|
||||||
import useResizeHandler from '../../hooks/useResizeHandler';
|
import useResizeHandler from '../../hooks/useResizeHandler';
|
||||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||||
import { containerStyle } from '../../styles';
|
import { containerStyle } from '../../styles';
|
||||||
import type { FlowRendererProps } from '../FlowRenderer';
|
import type { FlowRendererProps } from '../FlowRenderer';
|
||||||
|
import type { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
type ZoomPaneProps = Omit<
|
type ZoomPaneProps = Omit<
|
||||||
FlowRendererProps,
|
FlowRendererProps,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState, type RefObject, type MouseEvent } from 'react';
|
||||||
import type { RefObject, MouseEvent } from 'react';
|
|
||||||
import { drag } from 'd3-drag';
|
import { drag } from 'd3-drag';
|
||||||
import { select } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
import { calcAutoPan, getEventPosition } from '@reactflow/utils';
|
import { calcAutoPan, getEventPosition } from '@reactflow/utils';
|
||||||
import type { NodeDragItem, Node, SelectionDragHandler, UseDragEvent, XYPosition } from '@reactflow/system';
|
import type { NodeDragItem, UseDragEvent, XYPosition } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStoreApi } from '../../hooks/useStore';
|
import { useStoreApi } from '../../hooks/useStore';
|
||||||
import { getDragItems, getEventHandlerParams, hasSelector, calcNextPosition } from './utils';
|
import { getDragItems, getEventHandlerParams, hasSelector, calcNextPosition } from './utils';
|
||||||
import { handleNodeClick } from '../../components/Nodes/utils';
|
import { handleNodeClick } from '../../components/Nodes/utils';
|
||||||
import useGetPointerPosition from '../useGetPointerPosition';
|
import useGetPointerPosition from '../useGetPointerPosition';
|
||||||
|
import type { Node, SelectionDragHandler } from '../../types';
|
||||||
|
|
||||||
export type UseDragData = { dx: number; dy: number };
|
export type UseDragData = { dx: number; dy: number };
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import type { RefObject } from 'react';
|
|||||||
import {
|
import {
|
||||||
errorMessages,
|
errorMessages,
|
||||||
type CoordinateExtent,
|
type CoordinateExtent,
|
||||||
type Node,
|
|
||||||
type NodeDragItem,
|
type NodeDragItem,
|
||||||
type NodeInternals,
|
|
||||||
type NodeOrigin,
|
type NodeOrigin,
|
||||||
type OnError,
|
type OnError,
|
||||||
type XYPosition,
|
type XYPosition,
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
import { clampPosition, isNumeric, getNodePositionWithOrigin } from '@reactflow/utils';
|
import { clampPosition, isNumeric, getNodePositionWithOrigin } from '@reactflow/utils';
|
||||||
|
|
||||||
|
import type { Node, NodeInternals } from '../../types';
|
||||||
|
|
||||||
export function isParentSelected(node: Node, nodeInternals: NodeInternals): boolean {
|
export function isParentSelected(node: Node, nodeInternals: NodeInternals): boolean {
|
||||||
if (!node.parentNode) {
|
if (!node.parentNode) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { Edge, ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../hooks/useStore';
|
import { useStore } from '../hooks/useStore';
|
||||||
|
import type { Edge, ReactFlowState } from '../types';
|
||||||
|
|
||||||
const edgesSelector = (state: ReactFlowState) => state.edges;
|
const edgesSelector = (state: ReactFlowState) => state.edges;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useStore } from '../hooks/useStore';
|
import { useStore } from '../hooks/useStore';
|
||||||
import type { Node, ReactFlowState } from '@reactflow/system';
|
|
||||||
|
import type { Node, ReactFlowState } from '../types';
|
||||||
|
|
||||||
const nodesSelector = (state: ReactFlowState) => state.getNodes();
|
const nodesSelector = (state: ReactFlowState) => state.getNodes();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { useState, useCallback, type SetStateAction, type Dispatch } from 'react';
|
import { useState, useCallback, type SetStateAction, type Dispatch } from 'react';
|
||||||
import type { Node, NodeChange, Edge, EdgeChange } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { applyNodeChanges, applyEdgeChanges } from '../utils/changes';
|
import { applyNodeChanges, applyEdgeChanges } from '../utils/changes';
|
||||||
|
import type { Node, NodeChange, Edge, EdgeChange } from '../types';
|
||||||
|
|
||||||
type ApplyChanges<ItemType, ChangesType> = (changes: ChangesType[], items: ItemType[]) => ItemType[];
|
type ApplyChanges<ItemType, ChangesType> = (changes: ChangesType[], items: ItemType[]) => ItemType[];
|
||||||
type OnChange<ChangesType> = (changes: ChangesType[]) => void;
|
type OnChange<ChangesType> = (changes: ChangesType[]) => void;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { internalsSymbol, type ReactFlowState } from '@reactflow/system';
|
import { internalsSymbol } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStore } from './useStore';
|
import { useStore } from './useStore';
|
||||||
|
import type { ReactFlowState } from '../types';
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => {
|
const selector = (s: ReactFlowState) => {
|
||||||
if (s.nodeInternals.size === 0) {
|
if (s.nodeInternals.size === 0) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import type { OnInit } from '@reactflow/system';
|
|
||||||
|
|
||||||
import useReactFlow from './useReactFlow';
|
import useReactFlow from './useReactFlow';
|
||||||
|
import type { OnInit } from '../types';
|
||||||
|
|
||||||
function useOnInitHandler(onInit: OnInit | undefined) {
|
function useOnInitHandler(onInit: OnInit | undefined) {
|
||||||
const rfInstance = useReactFlow();
|
const rfInstance = useReactFlow();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import type { OnSelectionChangeFunc } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStoreApi } from './useStore';
|
import { useStoreApi } from './useStore';
|
||||||
|
import type { OnSelectionChangeFunc } from '../types';
|
||||||
|
|
||||||
export type UseOnSelectionChangeOptions = {
|
export type UseOnSelectionChangeOptions = {
|
||||||
onChange?: OnSelectionChangeFunc;
|
onChange?: OnSelectionChangeFunc;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { getConnectedEdges, getOverlappingArea, isRectObject, nodeToRect } from '@reactflow/utils';
|
import { getOverlappingArea, isRectObject, nodeToRect } from '@reactflow/utils';
|
||||||
|
import type { Rect } from '@reactflow/system';
|
||||||
|
|
||||||
|
import useViewportHelper from './useViewportHelper';
|
||||||
|
import { useStoreApi } from '../hooks/useStore';
|
||||||
|
import { getConnectedEdges } from '../utils';
|
||||||
import type {
|
import type {
|
||||||
ReactFlowInstance,
|
ReactFlowInstance,
|
||||||
Instance,
|
Instance,
|
||||||
@@ -11,11 +16,7 @@ import type {
|
|||||||
EdgeRemoveChange,
|
EdgeRemoveChange,
|
||||||
NodeChange,
|
NodeChange,
|
||||||
Node,
|
Node,
|
||||||
Rect,
|
} from '../types';
|
||||||
} from '@reactflow/system';
|
|
||||||
|
|
||||||
import useViewportHelper from './useViewportHelper';
|
|
||||||
import { useStoreApi } from '../hooks/useStore';
|
|
||||||
|
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
export default function useReactFlow<NodeData = any, EdgeData = any>(): ReactFlowInstance<NodeData, EdgeData> {
|
export default function useReactFlow<NodeData = any, EdgeData = any>(): ReactFlowInstance<NodeData, EdgeData> {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { useContext, useMemo } from 'react';
|
import { useContext, useMemo } from 'react';
|
||||||
import { useStore as useZustandStore, type StoreApi } from 'zustand';
|
import { useStore as useZustandStore, type StoreApi } from 'zustand';
|
||||||
import { errorMessages, type ReactFlowState } from '@reactflow/system';
|
import { errorMessages } from '@reactflow/system';
|
||||||
|
|
||||||
import StoreContext from '../contexts/RFStoreContext';
|
import StoreContext from '../contexts/RFStoreContext';
|
||||||
|
import type { ReactFlowState } from '../types';
|
||||||
|
|
||||||
const zustandErrorMessage = errorMessages['001']();
|
const zustandErrorMessage = errorMessages['001']();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import type { Viewport, ReactFlowState } from '@reactflow/system';
|
import type { Viewport } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStore } from '../hooks/useStore';
|
import { useStore } from '../hooks/useStore';
|
||||||
|
import type { ReactFlowState } from '../types';
|
||||||
|
|
||||||
const viewportSelector = (state: ReactFlowState) => ({
|
const viewportSelector = (state: ReactFlowState) => ({
|
||||||
x: state.transform[0],
|
x: state.transform[0],
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ import { useMemo } from 'react';
|
|||||||
import { zoomIdentity } from 'd3-zoom';
|
import { zoomIdentity } from 'd3-zoom';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import { pointToRendererPoint, getTransformForBounds, getD3Transition, fitView } from '@reactflow/utils';
|
import { pointToRendererPoint, getTransformForBounds, getD3Transition, fitView } from '@reactflow/utils';
|
||||||
import type { ViewportHelperFunctions, ReactFlowState, XYPosition } from '@reactflow/system';
|
import type { XYPosition } from '@reactflow/system';
|
||||||
|
|
||||||
import { useStoreApi, useStore } from '../hooks/useStore';
|
import { useStoreApi, useStore } from '../hooks/useStore';
|
||||||
|
import type { ViewportHelperFunctions, ReactFlowState } from '../types';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { internalsSymbol, type ReactFlowState, type NodeInternals, type Edge } from '@reactflow/system';
|
import { internalsSymbol } from '@reactflow/system';
|
||||||
import { isNumeric } from '@reactflow/utils';
|
import { isNumeric } from '@reactflow/utils';
|
||||||
|
|
||||||
import { useStore } from '../hooks/useStore';
|
import { useStore } from '../hooks/useStore';
|
||||||
import { isEdgeVisible } from '../container/EdgeRenderer/utils';
|
import { isEdgeVisible } from '../container/EdgeRenderer/utils';
|
||||||
|
import { type ReactFlowState, type NodeInternals, type Edge } from '../types';
|
||||||
|
|
||||||
const defaultEdgeTree = [{ level: 0, isMaxLevel: true, edges: [] }];
|
const defaultEdgeTree = [{ level: 0, isMaxLevel: true, edges: [] }];
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { getNodesInside } from '@reactflow/utils';
|
import { getNodesInside } from '@reactflow/utils';
|
||||||
import type { ReactFlowState } from '@reactflow/system';
|
|
||||||
|
|
||||||
import { useStore } from '../hooks/useStore';
|
import { useStore } from '../hooks/useStore';
|
||||||
|
import type { Node, ReactFlowState } from '../types';
|
||||||
|
|
||||||
function useVisibleNodes(onlyRenderVisible: boolean) {
|
function useVisibleNodes(onlyRenderVisible: boolean) {
|
||||||
const nodes = useStore(
|
const nodes = useStore(
|
||||||
useCallback(
|
useCallback(
|
||||||
(s: ReactFlowState) =>
|
(s: ReactFlowState) =>
|
||||||
onlyRenderVisible
|
onlyRenderVisible
|
||||||
? getNodesInside(s.nodeInternals, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true)
|
? getNodesInside<Node>(s.getNodes(), { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true)
|
||||||
: s.getNodes(),
|
: s.getNodes(),
|
||||||
[onlyRenderVisible]
|
[onlyRenderVisible]
|
||||||
)
|
)
|
||||||
|
|||||||
+13
-18
@@ -8,22 +8,6 @@ export { default as SimpleBezierEdge, getSimpleBezierPath } from './components/E
|
|||||||
export { default as SmoothStepEdge } from './components/Edges/SmoothStepEdge';
|
export { default as SmoothStepEdge } from './components/Edges/SmoothStepEdge';
|
||||||
export { default as BaseEdge } from './components/Edges/BaseEdge';
|
export { default as BaseEdge } from './components/Edges/BaseEdge';
|
||||||
|
|
||||||
export {
|
|
||||||
isNode,
|
|
||||||
isEdge,
|
|
||||||
addEdge,
|
|
||||||
getOutgoers,
|
|
||||||
getIncomers,
|
|
||||||
getConnectedEdges,
|
|
||||||
updateEdge,
|
|
||||||
getTransformForBounds,
|
|
||||||
getRectOfNodes,
|
|
||||||
getNodePositionWithOrigin,
|
|
||||||
rectToBox,
|
|
||||||
boxToRect,
|
|
||||||
getBoundsOfRects,
|
|
||||||
} from '@reactflow/utils';
|
|
||||||
export { applyNodeChanges, applyEdgeChanges } from './utils/changes';
|
|
||||||
export { default as ReactFlowProvider } from './components/ReactFlowProvider';
|
export { default as ReactFlowProvider } from './components/ReactFlowProvider';
|
||||||
export { default as Panel } from './components/Panel';
|
export { default as Panel } from './components/Panel';
|
||||||
export { default as EdgeLabelRenderer } from './components/EdgeLabelRenderer';
|
export { default as EdgeLabelRenderer } from './components/EdgeLabelRenderer';
|
||||||
@@ -41,7 +25,18 @@ export { default as useOnSelectionChange } from './hooks/useOnSelectionChange';
|
|||||||
export { default as useNodesInitialized } from './hooks/useNodesInitialized';
|
export { default as useNodesInitialized } from './hooks/useNodesInitialized';
|
||||||
export { default as useGetPointerPosition } from './hooks/useGetPointerPosition';
|
export { default as useGetPointerPosition } from './hooks/useGetPointerPosition';
|
||||||
export { useNodeId } from './contexts/NodeIdContext';
|
export { useNodeId } from './contexts/NodeIdContext';
|
||||||
export * from '@reactflow/system';
|
|
||||||
export * from '@reactflow/edge-utils';
|
export * from '@reactflow/edge-utils';
|
||||||
|
export * from '@reactflow/system';
|
||||||
|
export {
|
||||||
|
getTransformForBounds,
|
||||||
|
getRectOfNodes,
|
||||||
|
getNodePositionWithOrigin,
|
||||||
|
rectToBox,
|
||||||
|
boxToRect,
|
||||||
|
getBoundsOfRects,
|
||||||
|
} from '@reactflow/utils';
|
||||||
|
|
||||||
// export * from './types';
|
export { applyNodeChanges, applyEdgeChanges } from './utils/changes';
|
||||||
|
export { isNode, isEdge, getIncomers, getOutgoers, addEdge, updateEdge, getConnectedEdges } from './utils/general';
|
||||||
|
|
||||||
|
export * from './types';
|
||||||
|
|||||||
@@ -3,18 +3,9 @@ import { zoomIdentity } from 'd3-zoom';
|
|||||||
import { clampPosition, getDimensions, fitView } from '@reactflow/utils';
|
import { clampPosition, getDimensions, fitView } from '@reactflow/utils';
|
||||||
import {
|
import {
|
||||||
internalsSymbol,
|
internalsSymbol,
|
||||||
type ReactFlowState,
|
|
||||||
type Node,
|
|
||||||
type Edge,
|
|
||||||
type NodeDimensionUpdate,
|
type NodeDimensionUpdate,
|
||||||
type CoordinateExtent,
|
type CoordinateExtent,
|
||||||
type NodeDimensionChange,
|
|
||||||
type EdgeSelectionChange,
|
|
||||||
type NodeSelectionChange,
|
|
||||||
type NodePositionChange,
|
|
||||||
type NodeDragItem,
|
type NodeDragItem,
|
||||||
type UnselectNodesAndEdgesParams,
|
|
||||||
type NodeChange,
|
|
||||||
type XYPosition,
|
type XYPosition,
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
|
|
||||||
@@ -22,6 +13,17 @@ import { applyNodeChanges, createSelectionChange, getSelectionChanges } from '..
|
|||||||
import { getHandleBounds } from '../components/Nodes/utils';
|
import { getHandleBounds } from '../components/Nodes/utils';
|
||||||
import { createNodeInternals, updateAbsoluteNodePositions, updateNodesAndEdgesSelections } from './utils';
|
import { createNodeInternals, updateAbsoluteNodePositions, updateNodesAndEdgesSelections } from './utils';
|
||||||
import initialState from './initialState';
|
import initialState from './initialState';
|
||||||
|
import type {
|
||||||
|
ReactFlowState,
|
||||||
|
Node,
|
||||||
|
Edge,
|
||||||
|
NodeDimensionChange,
|
||||||
|
EdgeSelectionChange,
|
||||||
|
NodeSelectionChange,
|
||||||
|
NodePositionChange,
|
||||||
|
UnselectNodesAndEdgesParams,
|
||||||
|
NodeChange,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
const createRFStore = () =>
|
const createRFStore = () =>
|
||||||
createStore<ReactFlowState>((set, get) => ({
|
createStore<ReactFlowState>((set, get) => ({
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import { devWarn } from '@reactflow/utils';
|
import { devWarn, infiniteExtent } from '@reactflow/utils';
|
||||||
import { ConnectionMode, type CoordinateExtent, type ReactFlowStore } from '@reactflow/system';
|
import { ConnectionMode } from '@reactflow/system';
|
||||||
|
|
||||||
export const infiniteExtent: CoordinateExtent = [
|
import type { ReactFlowStore } from '../types';
|
||||||
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
|
||||||
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
|
||||||
];
|
|
||||||
|
|
||||||
const initialState: ReactFlowStore = {
|
const initialState: ReactFlowStore = {
|
||||||
rfId: '1',
|
rfId: '1',
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
import type { StoreApi } from 'zustand';
|
import type { StoreApi } from 'zustand';
|
||||||
import {
|
import { internalsSymbol, type XYZPosition, type NodeOrigin } from '@reactflow/system';
|
||||||
internalsSymbol,
|
|
||||||
type Edge,
|
|
||||||
type EdgeSelectionChange,
|
|
||||||
type Node,
|
|
||||||
type NodeInternals,
|
|
||||||
type NodeSelectionChange,
|
|
||||||
type ReactFlowState,
|
|
||||||
type XYZPosition,
|
|
||||||
type NodeOrigin,
|
|
||||||
} from '@reactflow/system';
|
|
||||||
import { isNumeric, getNodePositionWithOrigin } from '@reactflow/utils';
|
import { isNumeric, getNodePositionWithOrigin } from '@reactflow/utils';
|
||||||
|
|
||||||
|
import type { Edge, EdgeSelectionChange, Node, NodeInternals, NodeSelectionChange, ReactFlowState } from '../types';
|
||||||
|
|
||||||
type ParentNodes = Record<string, boolean>;
|
type ParentNodes = Record<string, boolean>;
|
||||||
|
|
||||||
function calculateXYZPosition(
|
function calculateXYZPosition(
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
import type { XYPosition, Dimensions } from './utils';
|
import type { XYPosition, Dimensions } from '@reactflow/system';
|
||||||
import type { Node } from './nodes';
|
|
||||||
import type { Edge } from './edges';
|
import type { Node, Edge } from '.';
|
||||||
|
|
||||||
export type NodeDimensionChange = {
|
export type NodeDimensionChange = {
|
||||||
id: string;
|
id: string;
|
||||||
+18
-16
@@ -1,4 +1,22 @@
|
|||||||
import type { CSSProperties, HTMLAttributes, MouseEvent as ReactMouseEvent, WheelEvent } from 'react';
|
import type { CSSProperties, HTMLAttributes, MouseEvent as ReactMouseEvent, WheelEvent } from 'react';
|
||||||
|
import type {
|
||||||
|
ConnectionMode,
|
||||||
|
ConnectionLineType,
|
||||||
|
OnConnect,
|
||||||
|
CoordinateExtent,
|
||||||
|
KeyCode,
|
||||||
|
PanOnScrollMode,
|
||||||
|
ProOptions,
|
||||||
|
PanelPosition,
|
||||||
|
OnMove,
|
||||||
|
OnMoveStart,
|
||||||
|
OnMoveEnd,
|
||||||
|
Viewport,
|
||||||
|
NodeOrigin,
|
||||||
|
HandleType,
|
||||||
|
SelectionMode,
|
||||||
|
OnError,
|
||||||
|
} from '@reactflow/system';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
OnSelectionChangeFunc,
|
OnSelectionChangeFunc,
|
||||||
@@ -6,37 +24,21 @@ import type {
|
|||||||
EdgeTypes,
|
EdgeTypes,
|
||||||
Node,
|
Node,
|
||||||
Edge,
|
Edge,
|
||||||
ConnectionMode,
|
|
||||||
ConnectionLineType,
|
|
||||||
ConnectionLineComponent,
|
ConnectionLineComponent,
|
||||||
OnConnectStart,
|
OnConnectStart,
|
||||||
OnConnectEnd,
|
OnConnectEnd,
|
||||||
OnConnect,
|
|
||||||
CoordinateExtent,
|
|
||||||
KeyCode,
|
|
||||||
PanOnScrollMode,
|
|
||||||
OnEdgeUpdateFunc,
|
OnEdgeUpdateFunc,
|
||||||
OnInit,
|
OnInit,
|
||||||
ProOptions,
|
|
||||||
PanelPosition,
|
|
||||||
DefaultEdgeOptions,
|
DefaultEdgeOptions,
|
||||||
FitViewOptions,
|
FitViewOptions,
|
||||||
OnNodesDelete,
|
OnNodesDelete,
|
||||||
OnEdgesDelete,
|
OnEdgesDelete,
|
||||||
OnNodesChange,
|
OnNodesChange,
|
||||||
OnEdgesChange,
|
OnEdgesChange,
|
||||||
OnMove,
|
|
||||||
OnMoveStart,
|
|
||||||
OnMoveEnd,
|
|
||||||
NodeDragHandler,
|
NodeDragHandler,
|
||||||
NodeMouseHandler,
|
NodeMouseHandler,
|
||||||
SelectionDragHandler,
|
SelectionDragHandler,
|
||||||
Viewport,
|
|
||||||
NodeOrigin,
|
|
||||||
EdgeMouseHandler,
|
EdgeMouseHandler,
|
||||||
HandleType,
|
|
||||||
SelectionMode,
|
|
||||||
OnError,
|
|
||||||
} from '.';
|
} from '.';
|
||||||
|
|
||||||
export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
|
export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
|
import type { CSSProperties, HTMLAttributes, ReactNode, MouseEvent as ReactMouseEvent, ComponentType } from 'react';
|
||||||
|
import type {
|
||||||
|
BaseEdge,
|
||||||
|
BezierPathOptions,
|
||||||
|
Position,
|
||||||
|
SmoothStepPathOptions,
|
||||||
|
DefaultEdgeOptionsBase,
|
||||||
|
HandleType,
|
||||||
|
Connection,
|
||||||
|
ConnectionLineType,
|
||||||
|
HandleElement,
|
||||||
|
ConnectionStatus,
|
||||||
|
} from '@reactflow/system';
|
||||||
|
|
||||||
|
import { Node } from '.';
|
||||||
|
|
||||||
|
export type EdgeLabelOptions = {
|
||||||
|
label?: string | ReactNode;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
labelBgPadding?: [number, number];
|
||||||
|
labelBgBorderRadius?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DefaultEdge<EdgeData = any> = BaseEdge<EdgeData> & {
|
||||||
|
style?: CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
sourceNode?: Node;
|
||||||
|
targetNode?: Node;
|
||||||
|
} & EdgeLabelOptions;
|
||||||
|
|
||||||
|
type SmoothStepEdgeType<T> = DefaultEdge<T> & {
|
||||||
|
type: 'smoothstep';
|
||||||
|
pathOptions?: SmoothStepPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
type BezierEdgeType<T> = DefaultEdge<T> & {
|
||||||
|
type: 'default';
|
||||||
|
pathOptions?: BezierPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Edge<T = any> = DefaultEdge<T> | SmoothStepEdgeType<T> | BezierEdgeType<T>;
|
||||||
|
|
||||||
|
export type EdgeMouseHandler = (event: ReactMouseEvent, edge: Edge) => void;
|
||||||
|
|
||||||
|
export type WrapEdgeProps<T = any> = Omit<Edge<T>, 'sourceHandle' | 'targetHandle'> & {
|
||||||
|
onClick?: EdgeMouseHandler;
|
||||||
|
onEdgeDoubleClick?: EdgeMouseHandler;
|
||||||
|
sourceHandleId?: string | null;
|
||||||
|
targetHandleId?: string | null;
|
||||||
|
sourceX: number;
|
||||||
|
sourceY: number;
|
||||||
|
targetX: number;
|
||||||
|
targetY: number;
|
||||||
|
sourcePosition: Position;
|
||||||
|
targetPosition: Position;
|
||||||
|
elementsSelectable?: boolean;
|
||||||
|
onEdgeUpdate?: OnEdgeUpdateFunc;
|
||||||
|
onContextMenu?: EdgeMouseHandler;
|
||||||
|
onMouseEnter?: EdgeMouseHandler;
|
||||||
|
onMouseMove?: EdgeMouseHandler;
|
||||||
|
onMouseLeave?: EdgeMouseHandler;
|
||||||
|
edgeUpdaterRadius?: number;
|
||||||
|
onEdgeUpdateStart?: (event: ReactMouseEvent, edge: Edge, handleType: HandleType) => void;
|
||||||
|
onEdgeUpdateEnd?: (event: MouseEvent | TouchEvent, edge: Edge, handleType: HandleType) => void;
|
||||||
|
rfId?: string;
|
||||||
|
isFocusable: boolean;
|
||||||
|
pathOptions?: BezierPathOptions | SmoothStepPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DefaultEdgeOptions = DefaultEdgeOptionsBase<Edge>;
|
||||||
|
|
||||||
|
export type EdgeTextProps = HTMLAttributes<SVGElement> &
|
||||||
|
EdgeLabelOptions & {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
// props that get passed to a custom edge
|
||||||
|
export type EdgeProps<T = any> = Pick<
|
||||||
|
Edge<T>,
|
||||||
|
'id' | 'animated' | 'data' | 'style' | 'selected' | 'source' | 'target'
|
||||||
|
> &
|
||||||
|
Pick<
|
||||||
|
WrapEdgeProps,
|
||||||
|
| 'sourceX'
|
||||||
|
| 'sourceY'
|
||||||
|
| 'targetX'
|
||||||
|
| 'targetY'
|
||||||
|
| 'sourcePosition'
|
||||||
|
| 'targetPosition'
|
||||||
|
| 'sourceHandleId'
|
||||||
|
| 'targetHandleId'
|
||||||
|
| 'interactionWidth'
|
||||||
|
> &
|
||||||
|
EdgeLabelOptions & {
|
||||||
|
markerStart?: string;
|
||||||
|
markerEnd?: string;
|
||||||
|
// @TODO: how can we get better types for pathOptions?
|
||||||
|
pathOptions?: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BaseEdgeProps = Pick<EdgeProps, 'style' | 'markerStart' | 'markerEnd' | 'interactionWidth'> &
|
||||||
|
EdgeLabelOptions & {
|
||||||
|
labelX?: number;
|
||||||
|
labelY?: number;
|
||||||
|
path: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SmoothStepEdgeProps<T = any> = EdgeProps<T> & {
|
||||||
|
pathOptions?: SmoothStepPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BezierEdgeProps<T = any> = EdgeProps<T> & {
|
||||||
|
pathOptions?: BezierPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OnEdgeUpdateFunc<T = any> = (oldEdge: Edge<T>, newConnection: Connection) => void;
|
||||||
|
|
||||||
|
export type ConnectionLineComponentProps = {
|
||||||
|
connectionLineStyle?: CSSProperties;
|
||||||
|
connectionLineType: ConnectionLineType;
|
||||||
|
fromNode?: Node;
|
||||||
|
fromHandle?: HandleElement;
|
||||||
|
fromX: number;
|
||||||
|
fromY: number;
|
||||||
|
toX: number;
|
||||||
|
toY: number;
|
||||||
|
fromPosition: Position;
|
||||||
|
toPosition: Position;
|
||||||
|
connectionStatus: ConnectionStatus | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConnectionLineComponent = ComponentType<ConnectionLineComponentProps>;
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type {
|
||||||
|
MouseEvent as ReactMouseEvent,
|
||||||
|
TouchEvent as ReactTouchEvent,
|
||||||
|
ComponentType,
|
||||||
|
MemoExoticComponent,
|
||||||
|
} from 'react';
|
||||||
|
import {
|
||||||
|
FitViewParamsBase,
|
||||||
|
FitViewOptionsBase,
|
||||||
|
NodeProps,
|
||||||
|
OnConnectStartParams,
|
||||||
|
ZoomInOut,
|
||||||
|
ZoomTo,
|
||||||
|
SetViewport,
|
||||||
|
GetZoom,
|
||||||
|
GetViewport,
|
||||||
|
SetCenter,
|
||||||
|
FitBounds,
|
||||||
|
Project,
|
||||||
|
} from '@reactflow/system';
|
||||||
|
|
||||||
|
import type { NodeChange, EdgeChange, Node, WrapNodeProps, Edge, EdgeProps, WrapEdgeProps, ReactFlowInstance } from '.';
|
||||||
|
|
||||||
|
export type OnNodesChange = (changes: NodeChange[]) => void;
|
||||||
|
export type OnEdgesChange = (changes: EdgeChange[]) => void;
|
||||||
|
|
||||||
|
export type OnNodesDelete = (nodes: Node[]) => void;
|
||||||
|
export type OnEdgesDelete = (edges: Edge[]) => void;
|
||||||
|
|
||||||
|
export type NodeTypes = { [key: string]: ComponentType<NodeProps> };
|
||||||
|
export type NodeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentType<WrapNodeProps>> };
|
||||||
|
export type EdgeTypes = { [key: string]: ComponentType<EdgeProps> };
|
||||||
|
export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentType<WrapEdgeProps>> };
|
||||||
|
|
||||||
|
export type UnselectNodesAndEdgesParams = {
|
||||||
|
nodes?: Node[];
|
||||||
|
edges?: Edge[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OnSelectionChangeParams = {
|
||||||
|
nodes: Node[];
|
||||||
|
edges: Edge[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OnSelectionChangeFunc = (params: OnSelectionChangeParams) => void;
|
||||||
|
|
||||||
|
export type OnConnectStart = (event: ReactMouseEvent | ReactTouchEvent, params: OnConnectStartParams) => void;
|
||||||
|
export type OnConnectEnd = (event: MouseEvent | TouchEvent) => void;
|
||||||
|
|
||||||
|
export type FitViewParams = FitViewParamsBase<Node>;
|
||||||
|
export type FitViewOptions = FitViewOptionsBase<Node>;
|
||||||
|
export type FitView = (fitViewOptions?: FitViewOptions) => boolean;
|
||||||
|
export type OnInit<NodeData = any, EdgeData = any> = (reactFlowInstance: ReactFlowInstance<NodeData, EdgeData>) => void;
|
||||||
|
|
||||||
|
export type ViewportHelperFunctions = {
|
||||||
|
zoomIn: ZoomInOut;
|
||||||
|
zoomOut: ZoomInOut;
|
||||||
|
zoomTo: ZoomTo;
|
||||||
|
getZoom: GetZoom;
|
||||||
|
setViewport: SetViewport;
|
||||||
|
getViewport: GetViewport;
|
||||||
|
fitView: FitView;
|
||||||
|
setCenter: SetCenter;
|
||||||
|
fitBounds: FitBounds;
|
||||||
|
project: Project;
|
||||||
|
viewportInitialized: boolean;
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export * from './nodes';
|
||||||
|
export * from './edges';
|
||||||
|
export * from './changes';
|
||||||
|
export * from './component-props';
|
||||||
|
export * from './general';
|
||||||
|
export * from './store';
|
||||||
|
export * from './instance';
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
/* eslint-disable @typescript-eslint/no-namespace */
|
/* eslint-disable @typescript-eslint/no-namespace */
|
||||||
import { ViewportHelperFunctions, Viewport, Node, Edge, Rect } from '.';
|
import type { Rect, Viewport } from '@reactflow/system';
|
||||||
|
import type { Node, Edge, ViewportHelperFunctions } from '.';
|
||||||
|
|
||||||
export type ReactFlowJsonObject<NodeData = any, EdgeData = any> = {
|
export type ReactFlowJsonObject<NodeData = any, EdgeData = any> = {
|
||||||
nodes: Node<NodeData>[];
|
nodes: Node<NodeData>[];
|
||||||
@@ -12,6 +13,7 @@ export type DeleteElementsOptions = {
|
|||||||
nodes?: (Partial<Node> & { id: Node['id'] })[];
|
nodes?: (Partial<Node> & { id: Node['id'] })[];
|
||||||
edges?: (Partial<Edge> & { id: Edge['id'] })[];
|
edges?: (Partial<Edge> & { id: Edge['id'] })[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export namespace Instance {
|
export namespace Instance {
|
||||||
export type GetNodes<NodeData> = () => Node<NodeData>[];
|
export type GetNodes<NodeData> = () => Node<NodeData>[];
|
||||||
export type SetNodes<NodeData> = (
|
export type SetNodes<NodeData> = (
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
|
||||||
|
import type { BaseNode } from '@reactflow/system';
|
||||||
|
|
||||||
|
export type Node<NodeData = any, NodeType extends string | undefined = string | undefined> = BaseNode<
|
||||||
|
NodeData,
|
||||||
|
NodeType
|
||||||
|
> & {
|
||||||
|
style?: CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
resizing?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NodeMouseHandler = (event: ReactMouseEvent, node: Node) => void;
|
||||||
|
export type NodeDragHandler = (event: ReactMouseEvent, node: Node, nodes: Node[]) => void;
|
||||||
|
export type SelectionDragHandler = (event: ReactMouseEvent, nodes: Node[]) => void;
|
||||||
|
|
||||||
|
export type WrapNodeProps<NodeData = any> = Pick<
|
||||||
|
Node<NodeData>,
|
||||||
|
'id' | 'data' | 'style' | 'className' | 'dragHandle' | 'sourcePosition' | 'targetPosition' | 'hidden' | 'ariaLabel'
|
||||||
|
> &
|
||||||
|
Required<Pick<Node<NodeData>, 'selected' | 'type' | 'zIndex'>> & {
|
||||||
|
isConnectable: boolean;
|
||||||
|
xPos: number;
|
||||||
|
yPos: number;
|
||||||
|
xPosOrigin: number;
|
||||||
|
yPosOrigin: number;
|
||||||
|
initialized: boolean;
|
||||||
|
isSelectable: boolean;
|
||||||
|
isDraggable: boolean;
|
||||||
|
isFocusable: boolean;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
|
onClick?: NodeMouseHandler;
|
||||||
|
onDoubleClick?: NodeMouseHandler;
|
||||||
|
onMouseEnter?: NodeMouseHandler;
|
||||||
|
onMouseMove?: NodeMouseHandler;
|
||||||
|
onMouseLeave?: NodeMouseHandler;
|
||||||
|
onContextMenu?: NodeMouseHandler;
|
||||||
|
resizeObserver: ResizeObserver | null;
|
||||||
|
isParent: boolean;
|
||||||
|
noDragClassName: string;
|
||||||
|
noPanClassName: string;
|
||||||
|
rfId: string;
|
||||||
|
disableKeyboardA11y: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NodeInternals = Map<string, Node>;
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
import {
|
||||||
|
ConnectionMode,
|
||||||
|
ConnectionStatus,
|
||||||
|
CoordinateExtent,
|
||||||
|
D3SelectionInstance,
|
||||||
|
D3ZoomInstance,
|
||||||
|
HandleType,
|
||||||
|
NodeDimensionUpdate,
|
||||||
|
NodeDragItem,
|
||||||
|
NodeOrigin,
|
||||||
|
OnConnect,
|
||||||
|
OnError,
|
||||||
|
OnViewportChange,
|
||||||
|
SelectionRect,
|
||||||
|
SnapGrid,
|
||||||
|
StartHandle,
|
||||||
|
Transform,
|
||||||
|
XYPosition,
|
||||||
|
} from '@reactflow/system';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
NodeDragHandler,
|
||||||
|
Edge,
|
||||||
|
Node,
|
||||||
|
NodeChange,
|
||||||
|
OnNodesChange,
|
||||||
|
OnEdgesChange,
|
||||||
|
NodeInternals,
|
||||||
|
OnConnectStart,
|
||||||
|
OnConnectEnd,
|
||||||
|
SelectionDragHandler,
|
||||||
|
DefaultEdgeOptions,
|
||||||
|
FitViewOptions,
|
||||||
|
OnNodesDelete,
|
||||||
|
OnEdgesDelete,
|
||||||
|
OnSelectionChangeFunc,
|
||||||
|
UnselectNodesAndEdgesParams,
|
||||||
|
} from '.';
|
||||||
|
|
||||||
|
export type ReactFlowStore = {
|
||||||
|
rfId: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
transform: Transform;
|
||||||
|
nodeInternals: NodeInternals;
|
||||||
|
edges: Edge[];
|
||||||
|
onNodesChange: OnNodesChange | null;
|
||||||
|
onEdgesChange: OnEdgesChange | null;
|
||||||
|
hasDefaultNodes: boolean;
|
||||||
|
hasDefaultEdges: boolean;
|
||||||
|
domNode: HTMLDivElement | null;
|
||||||
|
paneDragging: boolean;
|
||||||
|
noPanClassName: string;
|
||||||
|
|
||||||
|
d3Zoom: D3ZoomInstance | null;
|
||||||
|
d3Selection: D3SelectionInstance | null;
|
||||||
|
d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined;
|
||||||
|
minZoom: number;
|
||||||
|
maxZoom: number;
|
||||||
|
translateExtent: CoordinateExtent;
|
||||||
|
nodeExtent: CoordinateExtent;
|
||||||
|
nodeOrigin: NodeOrigin;
|
||||||
|
|
||||||
|
nodesSelectionActive: boolean;
|
||||||
|
userSelectionActive: boolean;
|
||||||
|
userSelectionRect: SelectionRect | null;
|
||||||
|
|
||||||
|
connectionNodeId: string | null;
|
||||||
|
connectionHandleId: string | null;
|
||||||
|
connectionHandleType: HandleType | null;
|
||||||
|
connectionPosition: XYPosition;
|
||||||
|
connectionStatus: ConnectionStatus | null;
|
||||||
|
connectionMode: ConnectionMode;
|
||||||
|
|
||||||
|
snapToGrid: boolean;
|
||||||
|
snapGrid: SnapGrid;
|
||||||
|
|
||||||
|
nodesDraggable: boolean;
|
||||||
|
nodesConnectable: boolean;
|
||||||
|
nodesFocusable: boolean;
|
||||||
|
edgesFocusable: boolean;
|
||||||
|
elementsSelectable: boolean;
|
||||||
|
elevateNodesOnSelect: boolean;
|
||||||
|
|
||||||
|
multiSelectionActive: boolean;
|
||||||
|
|
||||||
|
connectionStartHandle: StartHandle | null;
|
||||||
|
|
||||||
|
onNodeDragStart?: NodeDragHandler;
|
||||||
|
onNodeDrag?: NodeDragHandler;
|
||||||
|
onNodeDragStop?: NodeDragHandler;
|
||||||
|
|
||||||
|
onSelectionDragStart?: SelectionDragHandler;
|
||||||
|
onSelectionDrag?: SelectionDragHandler;
|
||||||
|
onSelectionDragStop?: SelectionDragHandler;
|
||||||
|
|
||||||
|
onConnect?: OnConnect;
|
||||||
|
onConnectStart?: OnConnectStart;
|
||||||
|
onConnectEnd?: OnConnectEnd;
|
||||||
|
|
||||||
|
onClickConnectStart?: OnConnectStart;
|
||||||
|
onClickConnectEnd?: OnConnectEnd;
|
||||||
|
|
||||||
|
connectOnClick: boolean;
|
||||||
|
defaultEdgeOptions?: DefaultEdgeOptions;
|
||||||
|
|
||||||
|
fitViewOnInit: boolean;
|
||||||
|
fitViewOnInitDone: boolean;
|
||||||
|
fitViewOnInitOptions: FitViewOptions | undefined;
|
||||||
|
|
||||||
|
onNodesDelete?: OnNodesDelete;
|
||||||
|
onEdgesDelete?: OnEdgesDelete;
|
||||||
|
onError?: OnError;
|
||||||
|
|
||||||
|
// event handlers
|
||||||
|
onViewportChangeStart?: OnViewportChange;
|
||||||
|
onViewportChange?: OnViewportChange;
|
||||||
|
onViewportChangeEnd?: OnViewportChange;
|
||||||
|
|
||||||
|
onSelectionChange?: OnSelectionChangeFunc;
|
||||||
|
|
||||||
|
ariaLiveMessage: string;
|
||||||
|
autoPanOnConnect: boolean;
|
||||||
|
autoPanOnNodeDrag: boolean;
|
||||||
|
connectionRadius: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ReactFlowActions = {
|
||||||
|
setNodes: (nodes: Node[]) => void;
|
||||||
|
getNodes: () => Node[];
|
||||||
|
setEdges: (edges: Edge[]) => void;
|
||||||
|
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => void;
|
||||||
|
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||||
|
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged: boolean, dragging: boolean) => void;
|
||||||
|
resetSelectedElements: () => void;
|
||||||
|
unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
|
||||||
|
addSelectedNodes: (nodeIds: string[]) => void;
|
||||||
|
addSelectedEdges: (edgeIds: string[]) => void;
|
||||||
|
setMinZoom: (minZoom: number) => void;
|
||||||
|
setMaxZoom: (maxZoom: number) => void;
|
||||||
|
setTranslateExtent: (translateExtent: CoordinateExtent) => void;
|
||||||
|
setNodeExtent: (nodeExtent: CoordinateExtent) => void;
|
||||||
|
cancelConnection: () => void;
|
||||||
|
reset: () => void;
|
||||||
|
triggerNodeChanges: (changes: NodeChange[]) => void;
|
||||||
|
panBy: (delta: XYPosition) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ReactFlowState = ReactFlowStore & ReactFlowActions;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type { Node, Edge, EdgeChange, NodeChange } from '@reactflow/system';
|
import type { Node, Edge, EdgeChange, NodeChange } from '../types';
|
||||||
|
|
||||||
function handleParentExpand(res: any[], updateItem: any) {
|
function handleParentExpand(res: any[], updateItem: any) {
|
||||||
const parent = res.find((e) => e.id === updateItem.parentNode);
|
const parent = res.find((e) => e.id === updateItem.parentNode);
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import {
|
||||||
|
isNodeBase,
|
||||||
|
isEdgeBase,
|
||||||
|
addEdgeBase,
|
||||||
|
getOutgoersBase,
|
||||||
|
getIncomersBase,
|
||||||
|
updateEdgeBase,
|
||||||
|
getConnectedEdgesBase,
|
||||||
|
} from '@reactflow/utils';
|
||||||
|
import type { Edge, Node } from '../types';
|
||||||
|
|
||||||
|
export const isNode = isNodeBase<Node, Edge>;
|
||||||
|
export const isEdge = isEdgeBase<Node, Edge>;
|
||||||
|
export const getOutgoers = getOutgoersBase<Node, Edge>;
|
||||||
|
export const getIncomers = getIncomersBase<Node, Edge>;
|
||||||
|
export const addEdge = addEdgeBase<Edge>;
|
||||||
|
export const updateEdge = updateEdgeBase<Edge>;
|
||||||
|
export const getConnectedEdges = getConnectedEdgesBase<Node, Edge>;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './changes';
|
||||||
|
export * from './general';
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { get, type Writable } from 'svelte/store';
|
import { get, type Writable } from 'svelte/store';
|
||||||
import { drag as d3Drag, type D3DragEvent, type SubjectPosition } from 'd3-drag';
|
import { drag as d3Drag, type D3DragEvent, type SubjectPosition } from 'd3-drag';
|
||||||
import { select } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
import type { XYPosition, CoordinateExtent, Transform, Node as RFNode } from '@reactflow/system';
|
import type { XYPosition, CoordinateExtent, Transform } from '@reactflow/system';
|
||||||
|
|
||||||
import { getDragItems, hasSelector, calcNextPosition } from './utils';
|
import { getDragItems, hasSelector, calcNextPosition } from './utils';
|
||||||
import type { Node } from '$lib/types';
|
import type { Node } from '$lib/types';
|
||||||
@@ -62,7 +62,7 @@ export default function drag(
|
|||||||
|
|
||||||
dragItems = dragItems.map((n) => {
|
dragItems = dragItems.map((n) => {
|
||||||
const nextPosition = { x: x - n.distance.x, y: y - n.distance.y };
|
const nextPosition = { x: x - n.distance.x, y: y - n.distance.y };
|
||||||
const updatedPos = calcNextPosition(n, nextPosition, get(nodes) as RFNode[]);
|
const updatedPos = calcNextPosition(n, nextPosition, get(nodes));
|
||||||
|
|
||||||
// we want to make sure that we only fire a change event when there is a changes
|
// we want to make sure that we only fire a change event when there is a changes
|
||||||
hasChange =
|
hasChange =
|
||||||
@@ -89,7 +89,7 @@ export default function drag(
|
|||||||
const pointerPos = getPointerPosition(event);
|
const pointerPos = getPointerPosition(event);
|
||||||
console.log(pointerPos);
|
console.log(pointerPos);
|
||||||
lastPos = pointerPos;
|
lastPos = pointerPos;
|
||||||
dragItems = getDragItems(get(nodes) as RFNode[], pointerPos, nodeId);
|
dragItems = getDragItems(get(nodes), pointerPos, nodeId);
|
||||||
})
|
})
|
||||||
.on('drag', (event: UseDragEvent) => {
|
.on('drag', (event: UseDragEvent) => {
|
||||||
const pointerPos = getPointerPosition(event);
|
const pointerPos = getPointerPosition(event);
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
import type {
|
import type { CoordinateExtent, NodeDragItem, NodeOrigin, XYPosition } from '@reactflow/system';
|
||||||
CoordinateExtent,
|
import { clampPosition, isNumeric } from '@reactflow/utils';
|
||||||
Node,
|
|
||||||
NodeDragItem,
|
|
||||||
NodeInternals,
|
|
||||||
NodeOrigin,
|
|
||||||
XYPosition
|
|
||||||
} from '@reactflow/system';
|
|
||||||
|
|
||||||
import { clampPosition, isNumeric } from '../../../utils';
|
import type { Node } from '$lib/types';
|
||||||
|
|
||||||
export function isParentSelected(node: Node, nodes: Node[]): boolean {
|
export function isParentSelected(node: Node, nodes: Node[]): boolean {
|
||||||
if (!node.parentNode) {
|
if (!node.parentNode) {
|
||||||
@@ -122,31 +116,3 @@ export function calcNextPosition(
|
|||||||
positionAbsolute
|
positionAbsolute
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns two params:
|
|
||||||
// 1. the dragged node (or the first of the list, if we are dragging a node selection)
|
|
||||||
// 2. array of selected nodes (for multi selections)
|
|
||||||
export function getEventHandlerParams({
|
|
||||||
nodeId,
|
|
||||||
dragItems,
|
|
||||||
nodeInternals
|
|
||||||
}: {
|
|
||||||
nodeId?: string;
|
|
||||||
dragItems: NodeDragItem[];
|
|
||||||
nodeInternals: NodeInternals;
|
|
||||||
}): [Node, Node[]] {
|
|
||||||
const extentedDragItems: Node[] = dragItems.map((n) => {
|
|
||||||
const node = nodeInternals.get(n.id)!;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...node,
|
|
||||||
position: n.position,
|
|
||||||
positionAbsolute: n.positionAbsolute
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return [
|
|
||||||
nodeId ? extentedDragItems.find((n) => n.id === nodeId)! : extentedDragItems[0],
|
|
||||||
extentedDragItems
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type { Writable } from 'svelte/store';
|
import type { Writable } from 'svelte/store';
|
||||||
import { select } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
import { zoom as d3Zoom, zoomIdentity } from 'd3-zoom';
|
import { zoom as d3Zoom, zoomIdentity, type D3ZoomEvent } from 'd3-zoom';
|
||||||
import type { D3ZoomEvent } from 'd3-zoom';
|
|
||||||
import type { D3SelectionInstance, D3ZoomInstance, Transform } from '@reactflow/system';
|
import type { D3SelectionInstance, D3ZoomInstance, Transform } from '@reactflow/system';
|
||||||
|
|
||||||
const isWrappedWithClass = (event: any, className: string | undefined) =>
|
const isWrappedWithClass = (event: any, className: string | undefined) =>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { get, type Writable } from 'svelte/store';
|
||||||
import {
|
import {
|
||||||
getHostForElement,
|
getHostForElement,
|
||||||
calcAutoPan,
|
calcAutoPan,
|
||||||
@@ -10,7 +11,6 @@ import type {
|
|||||||
HandleType,
|
HandleType,
|
||||||
Connection,
|
Connection,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
Node,
|
|
||||||
XYPosition,
|
XYPosition,
|
||||||
Transform
|
Transform
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
@@ -25,8 +25,7 @@ import {
|
|||||||
type ConnectionHandle,
|
type ConnectionHandle,
|
||||||
type ValidConnectionFunc
|
type ValidConnectionFunc
|
||||||
} from './utils';
|
} from './utils';
|
||||||
import { get, type Writable } from 'svelte/store';
|
import type { ConnectionData, Node } from '$lib/types';
|
||||||
import type { ConnectionData } from '$lib/types';
|
|
||||||
|
|
||||||
export function handlePointerDown({
|
export function handlePointerDown({
|
||||||
event,
|
event,
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
type $$Props = HandleProps;
|
type $$Props = HandleProps;
|
||||||
|
|
||||||
|
export let id: $$Props['id'] = undefined;
|
||||||
export let type: $$Props['type'] = 'source';
|
export let type: $$Props['type'] = 'source';
|
||||||
export let position: $$Props['position'] = Position.Top;
|
export let position: $$Props['position'] = Position.Top;
|
||||||
export let id: $$Props['id'] = undefined;
|
|
||||||
export let isConnectable: $$Props['isConnectable'] = true;
|
export let isConnectable: $$Props['isConnectable'] = true;
|
||||||
export let isValidConnection: $$Props['isValidConnection'] = (_: Connection) => true;
|
export let isValidConnection: $$Props['isValidConnection'] = (_: Connection) => true;
|
||||||
let className: string | null = null;
|
let className: string | null = null;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { internalsSymbol, ConnectionMode, type ConnectionStatus } from '@reactflow/system';
|
import { internalsSymbol, ConnectionMode, type ConnectionStatus } from '@reactflow/system';
|
||||||
import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '@reactflow/system';
|
import type { Connection, HandleType, XYPosition, NodeHandleBounds } from '@reactflow/system';
|
||||||
import { getEventPosition } from '@reactflow/utils';
|
import { getEventPosition } from '@reactflow/utils';
|
||||||
|
|
||||||
|
import type { Node } from '$lib/types';
|
||||||
|
|
||||||
export type ConnectionHandle = {
|
export type ConnectionHandle = {
|
||||||
id: string | null;
|
id: string | null;
|
||||||
type: HandleType;
|
type: HandleType;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { BaseEdgeProps } from '$lib/types';
|
|
||||||
import EdgeLabelRenderer from '$lib/components/EdgeLabelRenderer/index.svelte';
|
import EdgeLabelRenderer from '$lib/components/EdgeLabelRenderer/index.svelte';
|
||||||
|
import type { BaseEdgeProps } from '$lib/types';
|
||||||
|
|
||||||
type $$Props = BaseEdgeProps;
|
type $$Props = BaseEdgeProps;
|
||||||
|
|
||||||
export let path: $$Props['path'];
|
export let path: $$Props['path'] = '';
|
||||||
export let label: $$Props['label'];
|
export let label: $$Props['label'] = undefined;
|
||||||
export let labelX: $$Props['labelX'];
|
export let labelX: $$Props['labelX'] = undefined;
|
||||||
export let labelY: $$Props['labelY'];
|
export let labelY: $$Props['labelY'] = undefined;
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = 20;
|
export let interactionWidth: $$Props['interactionWidth'] = 20;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
import BezierEdge from '$lib/components/edges/StraightEdge.svelte';
|
import BezierEdge from '$lib/components/edges/StraightEdge.svelte';
|
||||||
import type { EdgeProps, WrapEdgeProps } from '$lib/types';
|
import type { EdgeProps, EdgeLayouted } from '$lib/types';
|
||||||
|
|
||||||
type $$Props = WrapEdgeProps;
|
type $$Props = EdgeLayouted;
|
||||||
|
|
||||||
export let id: $$Props['id'];
|
export let id: $$Props['id'];
|
||||||
export let type: $$Props['type'] = 'default';
|
export let type: $$Props['type'] = 'default';
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
export let sourceY: $$Props['sourceY'] = 0;
|
export let sourceY: $$Props['sourceY'] = 0;
|
||||||
export let targetX: $$Props['targetX'] = 0;
|
export let targetX: $$Props['targetX'] = 0;
|
||||||
export let targetY: $$Props['targetY'] = 0;
|
export let targetY: $$Props['targetY'] = 0;
|
||||||
|
export let sourceHandleId: $$Props['sourceHandleId'] = undefined;
|
||||||
|
export let targetHandleId: $$Props['targetHandleId'] = undefined;
|
||||||
export let sourcePosition: $$Props['sourcePosition'] = Position.Bottom;
|
export let sourcePosition: $$Props['sourcePosition'] = Position.Bottom;
|
||||||
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
||||||
export let animated: $$Props['animated'] = false;
|
export let animated: $$Props['animated'] = false;
|
||||||
|
|||||||
@@ -30,8 +30,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
import { SelectionMode, type Node, type Edge } from '@reactflow/system';
|
import { SelectionMode } from '@reactflow/system';
|
||||||
import { getConnectedEdges, getEventPosition, getNodesInside } from '@reactflow/utils';
|
import { getEventPosition, getNodesInside } from '@reactflow/utils';
|
||||||
|
|
||||||
|
import { getConnectedEdges} from '$lib/utils';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
nodes,
|
nodes,
|
||||||
@@ -107,8 +110,8 @@
|
|||||||
height: Math.abs(mousePos.y - startY)
|
height: Math.abs(mousePos.y - startY)
|
||||||
};
|
};
|
||||||
|
|
||||||
selectedNodes = getNodesInside(
|
selectedNodes = getNodesInside<Node>(
|
||||||
new Map($nodes.map((node) => [node.id, node])),
|
$nodes,
|
||||||
nextUserSelectRect,
|
nextUserSelectRect,
|
||||||
$transform,
|
$transform,
|
||||||
selectionMode === SelectionMode.Partial,
|
selectionMode === SelectionMode.Partial,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { setContext, onMount } from 'svelte';
|
import { setContext, onMount } from 'svelte';
|
||||||
|
import { ConnectionLineType } from '@reactflow/system';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { key, createStore } from '$lib/store';
|
import { key, createStore } from '$lib/store';
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
export let nodeTypes: $$Props['nodeTypes'] = undefined;
|
export let nodeTypes: $$Props['nodeTypes'] = undefined;
|
||||||
export let selectionKey: $$Props['selectionKey'] = undefined;
|
export let selectionKey: $$Props['selectionKey'] = undefined;
|
||||||
export let deleteKey: $$Props['deleteKey'] = undefined;
|
export let deleteKey: $$Props['deleteKey'] = undefined;
|
||||||
export let connectionLineType: $$Props['connectionLineType'] = undefined;
|
export let connectionLineType: $$Props['connectionLineType'] = ConnectionLineType.Bezier;
|
||||||
|
|
||||||
let className: $$Props['class'] = undefined;
|
let className: $$Props['class'] = undefined;
|
||||||
export { className as class };
|
export { className as class };
|
||||||
@@ -51,27 +52,6 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// $: {
|
|
||||||
// const updatableProps = {
|
|
||||||
// defaultEdgeOptions,
|
|
||||||
// connectionMode,
|
|
||||||
// snapToGrid,
|
|
||||||
// snapGrid,
|
|
||||||
// nodesDraggable,
|
|
||||||
// connectOnClick,
|
|
||||||
// fitViewOnInit: fitView,
|
|
||||||
// fitViewOnInitOptions: fitViewOptions,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Object.keys(updatableProps).forEach((key) => {
|
|
||||||
// store.update((state) => ({
|
|
||||||
// ...state,
|
|
||||||
// [key]: valuesToUpdate[key],
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
store.setNodes(nodes);
|
store.setNodes(nodes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ export { Controls, ControlButton } from '$lib/plugins/Controls';
|
|||||||
export { Background, BackgroundVariant } from '$lib/plugins/Background';
|
export { Background, BackgroundVariant } from '$lib/plugins/Background';
|
||||||
export { Minimap } from '$lib/plugins/Minimap';
|
export { Minimap } from '$lib/plugins/Minimap';
|
||||||
export { default as Panel } from '$lib/container/Panel/index.svelte';
|
export { default as Panel } from '$lib/container/Panel/index.svelte';
|
||||||
|
|
||||||
export * from '$lib/types';
|
export * from '$lib/types';
|
||||||
|
export * from '$lib/utils';
|
||||||
|
|
||||||
export default SvelteFlow;
|
export default SvelteFlow;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { derived } from 'svelte/store';
|
||||||
import { getBezierPath, getSmoothStepPath, getStraightPath } from '@reactflow/edge-utils';
|
import { getBezierPath, getSmoothStepPath, getStraightPath } from '@reactflow/edge-utils';
|
||||||
import { ConnectionLineType, ConnectionMode, Position } from '@reactflow/system';
|
import { ConnectionLineType, ConnectionMode, Position, internalsSymbol } from '@reactflow/system';
|
||||||
|
|
||||||
import type { SvelteFlowStoreState } from './types';
|
import type { SvelteFlowStoreState } from './types';
|
||||||
import { derived } from 'svelte/store';
|
|
||||||
|
|
||||||
const oppositePosition = {
|
const oppositePosition = {
|
||||||
[Position.Left]: Position.Right,
|
[Position.Left]: Position.Right,
|
||||||
@@ -20,21 +20,21 @@ export function getConnectionPath(store: SvelteFlowStoreState) {
|
|||||||
store.nodes,
|
store.nodes,
|
||||||
store.transform
|
store.transform
|
||||||
],
|
],
|
||||||
([$connection, $connectionLineType, $connectionMode, $nodes, $transform]) => {
|
([connection, connectionLineType, connectionMode, nodes, transform]) => {
|
||||||
if (!$connection.nodeId) {
|
if (!connection.nodeId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromNode = $nodes.find((n) => n.id === $connection.nodeId);
|
const fromNode = nodes.find((n) => n.id === connection.nodeId);
|
||||||
const fromHandleBounds = fromNode?.[internalsSymbol]?.handleBounds;
|
const fromHandleBounds = fromNode?.[internalsSymbol]?.handleBounds;
|
||||||
const handleBoundsStrict = fromHandleBounds?.[$connection.handleType || 'source'] || [];
|
const handleBoundsStrict = fromHandleBounds?.[connection.handleType || 'source'] || [];
|
||||||
const handleBoundsLoose = handleBoundsStrict
|
const handleBoundsLoose = handleBoundsStrict
|
||||||
? handleBoundsStrict
|
? handleBoundsStrict
|
||||||
: fromHandleBounds?.[$connection.handleType === 'source' ? 'target' : 'source']!;
|
: fromHandleBounds?.[connection.handleType === 'source' ? 'target' : 'source']!;
|
||||||
const handleBounds =
|
const handleBounds =
|
||||||
$connectionMode === ConnectionMode.Strict ? handleBoundsStrict : handleBoundsLoose;
|
connectionMode === ConnectionMode.Strict ? handleBoundsStrict : handleBoundsLoose;
|
||||||
const fromHandle = $connection.handleId
|
const fromHandle = connection.handleId
|
||||||
? handleBounds.find((d) => d.id === $connection.handleId)
|
? handleBounds.find((d) => d.id === connection.handleId)
|
||||||
: handleBounds[0];
|
: handleBounds[0];
|
||||||
const fromHandleX = fromHandle
|
const fromHandleX = fromHandle
|
||||||
? fromHandle.x + fromHandle.width / 2
|
? fromHandle.x + fromHandle.width / 2
|
||||||
@@ -49,22 +49,22 @@ export function getConnectionPath(store: SvelteFlowStoreState) {
|
|||||||
sourceX: fromX,
|
sourceX: fromX,
|
||||||
sourceY: fromY,
|
sourceY: fromY,
|
||||||
sourcePosition: fromPosition,
|
sourcePosition: fromPosition,
|
||||||
targetX: (($connection.position?.x ?? 0) - $transform[0]) / $transform[2],
|
targetX: ((connection.position?.x ?? 0) - transform[0]) / transform[2],
|
||||||
targetY: (($connection.position?.y ?? 0) - $transform[1]) / $transform[2],
|
targetY: ((connection.position?.y ?? 0) - transform[1]) / transform[2],
|
||||||
targetPosition: toPosition
|
targetPosition: toPosition
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = '';
|
let path = '';
|
||||||
|
|
||||||
if ($connectionLineType === ConnectionLineType.Bezier) {
|
if (connectionLineType === ConnectionLineType.Bezier) {
|
||||||
// we assume the destination position is opposite to the source position
|
// we assume the destination position is opposite to the source position
|
||||||
[path] = getBezierPath(pathParams);
|
[path] = getBezierPath(pathParams);
|
||||||
} else if ($connectionLineType === ConnectionLineType.Step) {
|
} else if (connectionLineType === ConnectionLineType.Step) {
|
||||||
[path] = getSmoothStepPath({
|
[path] = getSmoothStepPath({
|
||||||
...pathParams,
|
...pathParams,
|
||||||
borderRadius: 0
|
borderRadius: 0
|
||||||
});
|
});
|
||||||
} else if ($connectionLineType === ConnectionLineType.SmoothStep) {
|
} else if (connectionLineType === ConnectionLineType.SmoothStep) {
|
||||||
[path] = getSmoothStepPath(pathParams);
|
[path] = getSmoothStepPath(pathParams);
|
||||||
} else {
|
} else {
|
||||||
[path] = getStraightPath(pathParams);
|
[path] = getStraightPath(pathParams);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { derived } from 'svelte/store';
|
|||||||
import { Position } from '@reactflow/system';
|
import { Position } from '@reactflow/system';
|
||||||
|
|
||||||
import { getEdgePositions, getHandle, getNodeData } from '$lib/container/EdgeRenderer/utils';
|
import { getEdgePositions, getHandle, getNodeData } from '$lib/container/EdgeRenderer/utils';
|
||||||
import type { WrapEdgeProps } from '$lib/types';
|
import type { EdgeLayouted } from '$lib/types';
|
||||||
import type { SvelteFlowStoreState } from './types';
|
import type { SvelteFlowStoreState } from './types';
|
||||||
|
|
||||||
export function getEdgesLayouted(store: SvelteFlowStoreState) {
|
export function getEdgesLayouted(store: SvelteFlowStoreState) {
|
||||||
@@ -56,6 +56,6 @@ export function getEdgesLayouted(store: SvelteFlowStoreState) {
|
|||||||
targetHandleId
|
targetHandleId
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter((e) => e !== null) as WrapEdgeProps[];
|
.filter((e) => e !== null) as EdgeLayouted[];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
import { zoomIdentity } from 'd3-zoom';
|
||||||
import {
|
import {
|
||||||
type Transform,
|
type Transform,
|
||||||
type NodeDragItem,
|
type NodeDragItem,
|
||||||
@@ -7,23 +8,14 @@ import {
|
|||||||
internalsSymbol,
|
internalsSymbol,
|
||||||
type NodeOrigin,
|
type NodeOrigin,
|
||||||
type ViewportHelperFunctionOptions,
|
type ViewportHelperFunctionOptions,
|
||||||
type Node as RFNode,
|
|
||||||
type Connection,
|
type Connection,
|
||||||
type XYPosition,
|
type XYPosition,
|
||||||
type CoordinateExtent
|
type CoordinateExtent
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
import {
|
import { fitView as fitViewUtil, getD3Transition, getDimensions } from '@reactflow/utils';
|
||||||
fitView as fitViewUtil,
|
|
||||||
getConnectedEdges,
|
|
||||||
getD3Transition,
|
|
||||||
getDimensions,
|
|
||||||
addEdge as addEdgeUtil
|
|
||||||
} from '@reactflow/utils';
|
|
||||||
import { zoomIdentity } from 'd3-zoom';
|
|
||||||
|
|
||||||
import { getHandleBounds } from '../../utils';
|
import { getHandleBounds, getConnectedEdges, addEdge as addEdgeUtil } from '$lib/utils';
|
||||||
import type { EdgeTypes, NodeTypes, Node, Edge, ConnectionData } from '$lib/types';
|
import type { EdgeTypes, NodeTypes, Node, Edge, ConnectionData } from '$lib/types';
|
||||||
|
|
||||||
import { getEdgesLayouted } from './edges-layouted';
|
import { getEdgesLayouted } from './edges-layouted';
|
||||||
import { getConnectionPath } from './connection-path';
|
import { getConnectionPath } from './connection-path';
|
||||||
import { initConnectionData, initialStoreState } from './initial-store';
|
import { initConnectionData, initialStoreState } from './initial-store';
|
||||||
@@ -170,7 +162,7 @@ export function createStore({
|
|||||||
|
|
||||||
return fitViewUtil(
|
return fitViewUtil(
|
||||||
{
|
{
|
||||||
nodes: get(store.nodes) as RFNode[],
|
nodes: get(store.nodes),
|
||||||
width: get(store.width),
|
width: get(store.width),
|
||||||
height: get(store.height),
|
height: get(store.height),
|
||||||
minZoom: 0.2,
|
minZoom: 0.2,
|
||||||
@@ -227,7 +219,7 @@ export function createStore({
|
|||||||
const initialHitEdges = deletableEdges.filter((e) => edgeIds.includes(e.id));
|
const initialHitEdges = deletableEdges.filter((e) => edgeIds.includes(e.id));
|
||||||
|
|
||||||
if (nodesToRemove || initialHitEdges) {
|
if (nodesToRemove || initialHitEdges) {
|
||||||
const connectedEdges = getConnectedEdges(nodesToRemove as RFNode[], deletableEdges);
|
const connectedEdges = getConnectedEdges(nodesToRemove, deletableEdges);
|
||||||
const edgesToRemove = [...initialHitEdges, ...connectedEdges];
|
const edgesToRemove = [...initialHitEdges, ...connectedEdges];
|
||||||
const edgeIdsToRemove = edgesToRemove.reduce<string[]>((res, edge) => {
|
const edgeIdsToRemove = edgesToRemove.reduce<string[]>((res, edge) => {
|
||||||
if (!res.includes(edge.id)) {
|
if (!res.includes(edge.id)) {
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import {
|
|||||||
type D3SelectionInstance,
|
type D3SelectionInstance,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
ConnectionLineType,
|
ConnectionLineType,
|
||||||
|
type SelectionRect,
|
||||||
type Transform,
|
type Transform,
|
||||||
type NodeOrigin,
|
type NodeOrigin
|
||||||
type Rect
|
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
|
|
||||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||||
import InputNode from '$lib/components/nodes/InputNode.svelte';
|
import InputNode from '$lib/components/nodes/InputNode.svelte';
|
||||||
import OutputNode from '$lib/components/nodes/OutputNode.svelte';
|
import OutputNode from '$lib/components/nodes/OutputNode.svelte';
|
||||||
import type { Node, Edge, ConnectionData, NodeTypes, EdgeTypes } from '$lib/types';
|
import type { Node, Edge, ConnectionData, NodeTypes, EdgeTypes, EdgeLayouted } from '$lib/types';
|
||||||
import BezierEdge from '$lib/components/edges/BezierEdge.svelte';
|
import BezierEdge from '$lib/components/edges/BezierEdge.svelte';
|
||||||
import StraightEdge from '$lib/components/edges/StraightEdge.svelte';
|
import StraightEdge from '$lib/components/edges/StraightEdge.svelte';
|
||||||
import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte';
|
import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte';
|
||||||
@@ -29,7 +29,7 @@ export const initConnectionData = {
|
|||||||
export const initialStoreState = {
|
export const initialStoreState = {
|
||||||
nodes: writable<Node[]>([]),
|
nodes: writable<Node[]>([]),
|
||||||
edges: writable<Edge[]>([]),
|
edges: writable<Edge[]>([]),
|
||||||
edgesLayouted: readable<Edge[]>([]),
|
edgesLayouted: readable<EdgeLayouted[]>([]),
|
||||||
height: writable<number>(500),
|
height: writable<number>(500),
|
||||||
width: writable<number>(500),
|
width: writable<number>(500),
|
||||||
nodeOrigin: writable<NodeOrigin>([0.5, 0.5]),
|
nodeOrigin: writable<NodeOrigin>([0.5, 0.5]),
|
||||||
@@ -39,7 +39,7 @@ export const initialStoreState = {
|
|||||||
}),
|
}),
|
||||||
id: writable<string | null>(null),
|
id: writable<string | null>(null),
|
||||||
dragging: writable<boolean>(false),
|
dragging: writable<boolean>(false),
|
||||||
selectionRect: writable<(Rect & { startX: number; startY: number }) | null>(null),
|
selectionRect: writable<SelectionRect | null>(null),
|
||||||
selectionKeyPressed: writable<boolean>(false),
|
selectionKeyPressed: writable<boolean>(false),
|
||||||
multiselectionKeyPressed: writable<boolean>(false),
|
multiselectionKeyPressed: writable<boolean>(false),
|
||||||
deleteKeyPressed: writable<boolean>(false),
|
deleteKeyPressed: writable<boolean>(false),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {
|
|||||||
NodeDragItem
|
NodeDragItem
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
|
|
||||||
import { initialStoreState } from './initial-store';
|
import type { initialStoreState } from './initial-store';
|
||||||
import type { Node, Edge, ConnectionData } from '$lib/types';
|
import type { Node, Edge, ConnectionData } from '$lib/types';
|
||||||
|
|
||||||
export type SvelteFlowStoreActions = {
|
export type SvelteFlowStoreActions = {
|
||||||
@@ -1,4 +1,66 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type { SvelteComponentTyped } from 'svelte';
|
import type { SvelteComponentTyped } from 'svelte';
|
||||||
import type { EdgeProps } from '$lib/types';
|
import type {
|
||||||
|
BaseEdge,
|
||||||
|
BezierPathOptions,
|
||||||
|
Position,
|
||||||
|
SmoothStepPathOptions
|
||||||
|
} from '@reactflow/system';
|
||||||
|
|
||||||
|
import type { Node } from '$lib/types';
|
||||||
|
|
||||||
|
export type DefaultEdge<EdgeData = any> = BaseEdge<EdgeData> & {
|
||||||
|
label?: string;
|
||||||
|
style?: string;
|
||||||
|
class?: string;
|
||||||
|
sourceNode?: Node;
|
||||||
|
targetNode?: Node;
|
||||||
|
};
|
||||||
|
|
||||||
|
type SmoothStepEdgeType<T> = DefaultEdge<T> & {
|
||||||
|
type: 'smoothstep';
|
||||||
|
pathOptions?: SmoothStepPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
type BezierEdgeType<T> = DefaultEdge<T> & {
|
||||||
|
type: 'default';
|
||||||
|
pathOptions?: BezierPathOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Edge<T = any> = DefaultEdge<T> | SmoothStepEdgeType<T> | BezierEdgeType<T>;
|
||||||
|
|
||||||
|
export type EdgeLayouted = Omit<Edge, 'sourceHandle' | 'targetHandle'> & {
|
||||||
|
sourceX: number;
|
||||||
|
sourceY: number;
|
||||||
|
targetX: number;
|
||||||
|
targetY: number;
|
||||||
|
sourcePosition: Position;
|
||||||
|
targetPosition: Position;
|
||||||
|
sourceHandleId?: string;
|
||||||
|
targetHandleId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EdgeProps = Pick<
|
||||||
|
EdgeLayouted,
|
||||||
|
| 'id'
|
||||||
|
| 'source'
|
||||||
|
| 'target'
|
||||||
|
| 'sourceX'
|
||||||
|
| 'sourceY'
|
||||||
|
| 'targetX'
|
||||||
|
| 'targetY'
|
||||||
|
| 'sourcePosition'
|
||||||
|
| 'targetPosition'
|
||||||
|
| 'animated'
|
||||||
|
| 'selected'
|
||||||
|
| 'label'
|
||||||
|
| 'interactionWidth'
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type BaseEdgeProps = Pick<EdgeProps, 'interactionWidth' | 'label'> & {
|
||||||
|
path: string;
|
||||||
|
labelX?: number;
|
||||||
|
labelY?: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type EdgeTypes = Record<string, typeof SvelteComponentTyped<EdgeProps>>;
|
export type EdgeTypes = Record<string, typeof SvelteComponentTyped<EdgeProps>>;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { Node, NodeTypes } from './nodes';
|
|
||||||
import type { ShortcutModifierDefinition } from '@svelte-put/shortcut';
|
import type { ShortcutModifierDefinition } from '@svelte-put/shortcut';
|
||||||
import type { ConnectionLineType, Edge, HandleType, XYPosition } from '@reactflow/system';
|
import type { ConnectionLineType, HandleType, XYPosition } from '@reactflow/system';
|
||||||
|
|
||||||
|
import type { Node, NodeTypes, Edge } from '.';
|
||||||
|
|
||||||
export type KeyModifier = ShortcutModifierDefinition;
|
export type KeyModifier = ShortcutModifierDefinition;
|
||||||
export type KeyDefinitionObject = { key: string; modifier?: KeyModifier };
|
export type KeyDefinitionObject = { key: string; modifier?: KeyModifier };
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
export type {
|
|
||||||
Position,
|
|
||||||
XYPosition,
|
|
||||||
Edge,
|
|
||||||
BaseEdgeProps,
|
|
||||||
WrapEdgeProps,
|
|
||||||
EdgeProps
|
|
||||||
} from '@reactflow/system';
|
|
||||||
|
|
||||||
export * from './nodes';
|
export * from './nodes';
|
||||||
export * from './edges';
|
export * from './edges';
|
||||||
export * from './general';
|
export * from './general';
|
||||||
|
|||||||
@@ -1,33 +1,17 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
import type { SvelteComponentTyped } from 'svelte';
|
import type { SvelteComponentTyped } from 'svelte';
|
||||||
import type { internalsSymbol, NodeHandleBounds, Position, XYPosition } from '@reactflow/system';
|
import type { BaseNode } from '@reactflow/system';
|
||||||
|
|
||||||
// @todo: currently the helper function only like Node from '@reactflow/core'
|
// @todo: currently the helper function only like Node from '@reactflow/core'
|
||||||
// we need a base node type or helpes that accept Node like types
|
// we need a base node type or helpes that accept Node like types
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export type Node<NodeData = any> = {
|
export type Node<
|
||||||
id: string;
|
NodeData = any,
|
||||||
type: string;
|
NodeType extends string | undefined = string | undefined
|
||||||
data: NodeData;
|
> = BaseNode<NodeData, NodeType> & {
|
||||||
position: XYPosition;
|
|
||||||
sourcePosition?: Position;
|
|
||||||
targetPosition?: Position;
|
|
||||||
positionAbsolute?: XYPosition;
|
|
||||||
|
|
||||||
width?: number;
|
|
||||||
height?: number;
|
|
||||||
selected?: boolean;
|
|
||||||
class?: string;
|
class?: string;
|
||||||
style?: string;
|
style?: string;
|
||||||
deletable?: boolean;
|
|
||||||
// not supported yet
|
|
||||||
parentNode?: string;
|
|
||||||
|
|
||||||
// only used internally
|
|
||||||
[internalsSymbol]?: {
|
|
||||||
z?: number;
|
|
||||||
handleBounds?: NodeHandleBounds;
|
|
||||||
isParent?: boolean;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import type { HandleElement, Position } from '@reactflow/system';
|
||||||
|
import {
|
||||||
|
isNodeBase,
|
||||||
|
isEdgeBase,
|
||||||
|
addEdgeBase,
|
||||||
|
getOutgoersBase,
|
||||||
|
getIncomersBase,
|
||||||
|
updateEdgeBase,
|
||||||
|
getConnectedEdgesBase,
|
||||||
|
getDimensions
|
||||||
|
} from '@reactflow/utils';
|
||||||
|
import type { Edge, Node } from '$lib/types';
|
||||||
|
|
||||||
|
export const isNode = isNodeBase<Node, Edge>;
|
||||||
|
export const isEdge = isEdgeBase<Node, Edge>;
|
||||||
|
export const getOutgoers = getOutgoersBase<Node, Edge>;
|
||||||
|
export const getIncomers = getIncomersBase<Node, Edge>;
|
||||||
|
export const addEdge = addEdgeBase<Edge>;
|
||||||
|
export const updateEdge = updateEdgeBase<Edge>;
|
||||||
|
export const getConnectedEdges = getConnectedEdgesBase<Node, Edge>;
|
||||||
|
|
||||||
|
export const getHandleBounds = (
|
||||||
|
selector: string,
|
||||||
|
nodeElement: HTMLDivElement,
|
||||||
|
zoom: number
|
||||||
|
): HandleElement[] | null => {
|
||||||
|
const handles = nodeElement.querySelectorAll(selector);
|
||||||
|
|
||||||
|
if (!handles || !handles.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlesArray = Array.from(handles) as HTMLDivElement[];
|
||||||
|
const nodeBounds = nodeElement.getBoundingClientRect();
|
||||||
|
|
||||||
|
return handlesArray.map((handle): HandleElement => {
|
||||||
|
const handleBounds = handle.getBoundingClientRect();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: handle.getAttribute('data-handleid'),
|
||||||
|
position: handle.getAttribute('data-handlepos') as unknown as Position,
|
||||||
|
x: (handleBounds.left - nodeBounds.left) / zoom,
|
||||||
|
y: (handleBounds.top - nodeBounds.top) / zoom,
|
||||||
|
...getDimensions(handle)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
import {
|
|
||||||
type CoordinateExtent,
|
|
||||||
type Dimensions,
|
|
||||||
type XYPosition,
|
|
||||||
type Node,
|
|
||||||
type XYZPosition,
|
|
||||||
type HandleElement,
|
|
||||||
internalsSymbol,
|
|
||||||
Position
|
|
||||||
} from '@reactflow/system';
|
|
||||||
|
|
||||||
export const clamp = (val: number, min = 0, max = 1): number => Math.min(Math.max(val, min), max);
|
|
||||||
|
|
||||||
export const clampPosition = (position: XYPosition = { x: 0, y: 0 }, extent: CoordinateExtent) => ({
|
|
||||||
x: clamp(position.x, extent[0][0], extent[1][0]),
|
|
||||||
y: clamp(position.y, extent[0][1], extent[1][1])
|
|
||||||
});
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
export const isNumeric = (n: any): n is number => !isNaN(n) && isFinite(n);
|
|
||||||
|
|
||||||
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
|
|
||||||
width: node.offsetWidth,
|
|
||||||
height: node.offsetHeight
|
|
||||||
});
|
|
||||||
|
|
||||||
type ParentNodes = Record<string, boolean>;
|
|
||||||
|
|
||||||
function calculateXYZPosition(node: Node, nodes: Node[], result: XYZPosition): XYZPosition {
|
|
||||||
if (!node.parentNode) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const parentNode = nodes.find((n) => n.id === node.parentNode)!;
|
|
||||||
const parentNodePosition = parentNode.positionAbsolute!;
|
|
||||||
|
|
||||||
return calculateXYZPosition(parentNode, nodes, {
|
|
||||||
x: (result.x ?? 0) + parentNodePosition.x,
|
|
||||||
y: (result.y ?? 0) + parentNodePosition.y,
|
|
||||||
z:
|
|
||||||
(parentNode[internalsSymbol]?.z ?? 0) > (result.z ?? 0)
|
|
||||||
? parentNode[internalsSymbol]?.z ?? 0
|
|
||||||
: result.z ?? 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateAbsoluteNodePositions(nodes: Node[], parentNodes?: ParentNodes) {
|
|
||||||
nodes.forEach((node) => {
|
|
||||||
if (node.parentNode) {
|
|
||||||
throw new Error(`Parent node ${node.parentNode} not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.parentNode || parentNodes?.[node.id]) {
|
|
||||||
const { x, y, z } = calculateXYZPosition(node, nodes, {
|
|
||||||
...node.position,
|
|
||||||
z: node[internalsSymbol]?.z ?? 0
|
|
||||||
});
|
|
||||||
|
|
||||||
node.positionAbsolute = {
|
|
||||||
x,
|
|
||||||
y
|
|
||||||
};
|
|
||||||
|
|
||||||
node[internalsSymbol]!.z = z;
|
|
||||||
|
|
||||||
if (parentNodes?.[node.id]) {
|
|
||||||
node[internalsSymbol]!.isParent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getHandleBounds = (
|
|
||||||
selector: string,
|
|
||||||
nodeElement: HTMLDivElement,
|
|
||||||
zoom: number
|
|
||||||
): HandleElement[] | null => {
|
|
||||||
const handles = nodeElement.querySelectorAll(selector);
|
|
||||||
|
|
||||||
if (!handles || !handles.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlesArray = Array.from(handles) as HTMLDivElement[];
|
|
||||||
const nodeBounds = nodeElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
return handlesArray.map((handle): HandleElement => {
|
|
||||||
const handleBounds = handle.getBoundingClientRect();
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: handle.getAttribute('data-handleid'),
|
|
||||||
position: handle.getAttribute('data-handlepos') as unknown as Position,
|
|
||||||
x: (handleBounds.left - nodeBounds.left) / zoom,
|
|
||||||
y: (handleBounds.top - nodeBounds.top) / zoom,
|
|
||||||
...getDimensions(handle)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -4,11 +4,13 @@
|
|||||||
"description": "Core system of React Flow.",
|
"description": "Core system of React Flow.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
|
"svelte",
|
||||||
"node-based UI",
|
"node-based UI",
|
||||||
"graph",
|
"graph",
|
||||||
"diagram",
|
"diagram",
|
||||||
"workflow",
|
"workflow",
|
||||||
"react-flow"
|
"react-flow",
|
||||||
|
"svelte-flow"
|
||||||
],
|
],
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
@@ -41,18 +43,11 @@
|
|||||||
"@types/d3-selection": "^3.0.3",
|
"@types/d3-selection": "^3.0.3",
|
||||||
"@types/d3-zoom": "^3.0.1"
|
"@types/d3-zoom": "^3.0.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=17",
|
|
||||||
"react-dom": ">=17"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@reactflow/eslint-config": "workspace:*",
|
"@reactflow/eslint-config": "workspace:*",
|
||||||
"@reactflow/rollup-config": "workspace:*",
|
"@reactflow/rollup-config": "workspace:*",
|
||||||
"@reactflow/tsconfig": "workspace:*",
|
"@reactflow/tsconfig": "workspace:*",
|
||||||
"@types/node": "^18.7.16",
|
"@types/node": "^18.7.16",
|
||||||
"@types/react": ">=17",
|
|
||||||
"@types/react-dom": ">=17",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"typescript": "^4.9.4"
|
"typescript": "^4.9.4"
|
||||||
},
|
},
|
||||||
"rollup": {
|
"rollup": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Edge, HandleElement } from './types';
|
import { BaseEdge, HandleElement } from './types';
|
||||||
|
|
||||||
export const errorMessages = {
|
export const errorMessages = {
|
||||||
'001': () =>
|
'001': () =>
|
||||||
@@ -11,7 +11,7 @@ export const errorMessages = {
|
|||||||
'006': () => "Can't create edge. An edge needs a source and a target.",
|
'006': () => "Can't create edge. An edge needs a source and a target.",
|
||||||
'007': (id: string) => `The old edge with id=${id} does not exist.`,
|
'007': (id: string) => `The old edge with id=${id} does not exist.`,
|
||||||
'009': (type: string) => `Marker type "${type}" doesn't exist.`,
|
'009': (type: string) => `Marker type "${type}" doesn't exist.`,
|
||||||
'008': (sourceHandle: HandleElement | null, edge: Edge) =>
|
'008': (sourceHandle: HandleElement | null, edge: BaseEdge) =>
|
||||||
`Couldn't create edge for ${!sourceHandle ? 'source' : 'target'} handle id: "${
|
`Couldn't create edge for ${!sourceHandle ? 'source' : 'target'} handle id: "${
|
||||||
!sourceHandle ? edge.sourceHandle : edge.targetHandle
|
!sourceHandle ? edge.sourceHandle : edge.targetHandle
|
||||||
}", edge id: ${edge.id}.`,
|
}", edge id: ${edge.id}.`,
|
||||||
|
|||||||
@@ -1,34 +1,15 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
import type { CSSProperties, ComponentType, HTMLAttributes, ReactNode, MouseEvent as ReactMouseEvent } from 'react';
|
export type BaseEdge<EdgeData = any> = {
|
||||||
|
|
||||||
import { ConnectionStatus, Position } from '.';
|
|
||||||
import type { Connection, HandleElement, HandleType, Node } from '.';
|
|
||||||
|
|
||||||
type EdgeLabelOptions = {
|
|
||||||
label?: string | ReactNode;
|
|
||||||
labelStyle?: CSSProperties;
|
|
||||||
labelShowBg?: boolean;
|
|
||||||
labelBgStyle?: CSSProperties;
|
|
||||||
labelBgPadding?: [number, number];
|
|
||||||
labelBgBorderRadius?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
// interface for the user edge items
|
|
||||||
type DefaultEdge<T = any> = {
|
|
||||||
id: string;
|
id: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
source: string;
|
source: string;
|
||||||
target: string;
|
target: string;
|
||||||
sourceHandle?: string | null;
|
sourceHandle?: string | null;
|
||||||
targetHandle?: string | null;
|
targetHandle?: string | null;
|
||||||
style?: CSSProperties;
|
|
||||||
animated?: boolean;
|
animated?: boolean;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
deletable?: boolean;
|
deletable?: boolean;
|
||||||
data?: T;
|
data?: EdgeData;
|
||||||
className?: string;
|
|
||||||
sourceNode?: Node;
|
|
||||||
targetNode?: Node;
|
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
markerStart?: EdgeMarkerType;
|
markerStart?: EdgeMarkerType;
|
||||||
markerEnd?: EdgeMarkerType;
|
markerEnd?: EdgeMarkerType;
|
||||||
@@ -36,106 +17,22 @@ type DefaultEdge<T = any> = {
|
|||||||
ariaLabel?: string;
|
ariaLabel?: string;
|
||||||
interactionWidth?: number;
|
interactionWidth?: number;
|
||||||
focusable?: boolean;
|
focusable?: boolean;
|
||||||
} & EdgeLabelOptions;
|
};
|
||||||
|
|
||||||
export type SmoothStepPathOptions = {
|
export type SmoothStepPathOptions = {
|
||||||
offset?: number;
|
offset?: number;
|
||||||
borderRadius?: number;
|
borderRadius?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SmoothStepEdgeType<T> = DefaultEdge<T> & {
|
|
||||||
type: 'smoothstep';
|
|
||||||
pathOptions?: SmoothStepPathOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BezierPathOptions = {
|
export type BezierPathOptions = {
|
||||||
curvature?: number;
|
curvature?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BezierEdgeType<T> = DefaultEdge<T> & {
|
export type DefaultEdgeOptionsBase<EdgeType extends BaseEdge> = Omit<
|
||||||
type: 'default';
|
EdgeType,
|
||||||
pathOptions?: BezierPathOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Edge<T = any> = DefaultEdge<T> | SmoothStepEdgeType<T> | BezierEdgeType<T>;
|
|
||||||
|
|
||||||
export type DefaultEdgeOptions = Omit<
|
|
||||||
Edge,
|
|
||||||
'id' | 'source' | 'target' | 'sourceHandle' | 'targetHandle' | 'sourceNode' | 'targetNode'
|
'id' | 'source' | 'target' | 'sourceHandle' | 'targetHandle' | 'sourceNode' | 'targetNode'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type EdgeMouseHandler = (event: ReactMouseEvent, edge: Edge) => void;
|
|
||||||
|
|
||||||
export type WrapEdgeProps<T = any> = Omit<Edge<T>, 'sourceHandle' | 'targetHandle'> & {
|
|
||||||
onClick?: EdgeMouseHandler;
|
|
||||||
onEdgeDoubleClick?: EdgeMouseHandler;
|
|
||||||
sourceHandleId?: string | null;
|
|
||||||
targetHandleId?: string | null;
|
|
||||||
sourceX: number;
|
|
||||||
sourceY: number;
|
|
||||||
targetX: number;
|
|
||||||
targetY: number;
|
|
||||||
sourcePosition: Position;
|
|
||||||
targetPosition: Position;
|
|
||||||
elementsSelectable?: boolean;
|
|
||||||
onEdgeUpdate?: OnEdgeUpdateFunc;
|
|
||||||
onContextMenu?: EdgeMouseHandler;
|
|
||||||
onMouseEnter?: EdgeMouseHandler;
|
|
||||||
onMouseMove?: EdgeMouseHandler;
|
|
||||||
onMouseLeave?: EdgeMouseHandler;
|
|
||||||
edgeUpdaterRadius?: number;
|
|
||||||
onEdgeUpdateStart?: (event: ReactMouseEvent, edge: Edge, handleType: HandleType) => void;
|
|
||||||
onEdgeUpdateEnd?: (event: MouseEvent | TouchEvent, edge: Edge, handleType: HandleType) => void;
|
|
||||||
rfId?: string;
|
|
||||||
isFocusable: boolean;
|
|
||||||
pathOptions?: BezierPathOptions | SmoothStepPathOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
// props that get passed to a custom edge
|
|
||||||
export type EdgeProps<T = any> = Pick<
|
|
||||||
Edge<T>,
|
|
||||||
'id' | 'animated' | 'data' | 'style' | 'selected' | 'source' | 'target'
|
|
||||||
> &
|
|
||||||
Pick<
|
|
||||||
WrapEdgeProps,
|
|
||||||
| 'sourceX'
|
|
||||||
| 'sourceY'
|
|
||||||
| 'targetX'
|
|
||||||
| 'targetY'
|
|
||||||
| 'sourcePosition'
|
|
||||||
| 'targetPosition'
|
|
||||||
| 'sourceHandleId'
|
|
||||||
| 'targetHandleId'
|
|
||||||
| 'interactionWidth'
|
|
||||||
> &
|
|
||||||
EdgeLabelOptions & {
|
|
||||||
markerStart?: string;
|
|
||||||
markerEnd?: string;
|
|
||||||
// @TODO: how can we get better types for pathOptions?
|
|
||||||
pathOptions?: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BaseEdgeProps = Pick<EdgeProps, 'style' | 'markerStart' | 'markerEnd' | 'interactionWidth'> &
|
|
||||||
EdgeLabelOptions & {
|
|
||||||
labelX?: number;
|
|
||||||
labelY?: number;
|
|
||||||
path: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SmoothStepEdgeProps<T = any> = EdgeProps<T> & {
|
|
||||||
pathOptions?: SmoothStepPathOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BezierEdgeProps<T = any> = EdgeProps<T> & {
|
|
||||||
pathOptions?: BezierPathOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EdgeTextProps = HTMLAttributes<SVGElement> &
|
|
||||||
EdgeLabelOptions & {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum ConnectionLineType {
|
export enum ConnectionLineType {
|
||||||
Bezier = 'default',
|
Bezier = 'default',
|
||||||
Straight = 'straight',
|
Straight = 'straight',
|
||||||
@@ -144,24 +41,6 @@ export enum ConnectionLineType {
|
|||||||
SimpleBezier = 'simplebezier',
|
SimpleBezier = 'simplebezier',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConnectionLineComponentProps = {
|
|
||||||
connectionLineStyle?: CSSProperties;
|
|
||||||
connectionLineType: ConnectionLineType;
|
|
||||||
fromNode?: Node;
|
|
||||||
fromHandle?: HandleElement;
|
|
||||||
fromX: number;
|
|
||||||
fromY: number;
|
|
||||||
toX: number;
|
|
||||||
toY: number;
|
|
||||||
fromPosition: Position;
|
|
||||||
toPosition: Position;
|
|
||||||
connectionStatus: ConnectionStatus | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ConnectionLineComponent = ComponentType<ConnectionLineComponentProps>;
|
|
||||||
|
|
||||||
export type OnEdgeUpdateFunc<T = any> = (oldEdge: Edge<T>, newConnection: Connection) => void;
|
|
||||||
|
|
||||||
export type EdgeMarker = {
|
export type EdgeMarker = {
|
||||||
type: MarkerType;
|
type: MarkerType;
|
||||||
color?: string;
|
color?: string;
|
||||||
|
|||||||
@@ -1,45 +1,12 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type {
|
|
||||||
MouseEvent as ReactMouseEvent,
|
|
||||||
TouchEvent as ReactTouchEvent,
|
|
||||||
ComponentType,
|
|
||||||
MemoExoticComponent,
|
|
||||||
} from 'react';
|
|
||||||
import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3';
|
import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3';
|
||||||
|
|
||||||
import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils';
|
import type { XYPosition, Rect } from './utils';
|
||||||
import type { NodeChange, EdgeChange } from './changes';
|
import type { BaseNode, NodeOrigin } from './nodes';
|
||||||
import type {
|
import type { HandleType } from './handles';
|
||||||
Node,
|
|
||||||
NodeInternals,
|
|
||||||
NodeDimensionUpdate,
|
|
||||||
NodeProps,
|
|
||||||
WrapNodeProps,
|
|
||||||
NodeDragItem,
|
|
||||||
NodeDragHandler,
|
|
||||||
SelectionDragHandler,
|
|
||||||
NodeOrigin,
|
|
||||||
} from './nodes';
|
|
||||||
import type { Edge, EdgeProps, WrapEdgeProps } from './edges';
|
|
||||||
import type { HandleType, StartHandle } from './handles';
|
|
||||||
import type { DefaultEdgeOptions } from '.';
|
|
||||||
import type { ReactFlowInstance } from './instance';
|
|
||||||
|
|
||||||
export type NodeTypes = { [key: string]: ComponentType<NodeProps> };
|
|
||||||
export type NodeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentType<WrapNodeProps>> };
|
|
||||||
export type EdgeTypes = { [key: string]: ComponentType<EdgeProps> };
|
|
||||||
export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentType<WrapEdgeProps>> };
|
|
||||||
|
|
||||||
export type FitView = (fitViewOptions?: FitViewOptions) => boolean;
|
|
||||||
|
|
||||||
export type Project = (position: XYPosition) => XYPosition;
|
export type Project = (position: XYPosition) => XYPosition;
|
||||||
|
|
||||||
export type OnNodesChange = (changes: NodeChange[]) => void;
|
|
||||||
export type OnEdgesChange = (changes: EdgeChange[]) => void;
|
|
||||||
|
|
||||||
export type OnNodesDelete = (nodes: Node[]) => void;
|
|
||||||
export type OnEdgesDelete = (edges: Edge[]) => void;
|
|
||||||
|
|
||||||
export type OnMove = (event: MouseEvent | TouchEvent, viewport: Viewport) => void;
|
export type OnMove = (event: MouseEvent | TouchEvent, viewport: Viewport) => void;
|
||||||
export type OnMoveStart = OnMove;
|
export type OnMoveStart = OnMove;
|
||||||
export type OnMoveEnd = OnMove;
|
export type OnMoveEnd = OnMove;
|
||||||
@@ -52,8 +19,6 @@ export type SetViewport = (viewport: Viewport, options?: ViewportHelperFunctionO
|
|||||||
export type SetCenter = (x: number, y: number, options?: SetCenterOptions) => void;
|
export type SetCenter = (x: number, y: number, options?: SetCenterOptions) => void;
|
||||||
export type FitBounds = (bounds: Rect, options?: FitBoundsOptions) => void;
|
export type FitBounds = (bounds: Rect, options?: FitBoundsOptions) => void;
|
||||||
|
|
||||||
export type OnInit<NodeData = any, EdgeData = any> = (reactFlowInstance: ReactFlowInstance<NodeData, EdgeData>) => void;
|
|
||||||
|
|
||||||
export interface Connection {
|
export interface Connection {
|
||||||
source: string | null;
|
source: string | null;
|
||||||
target: string | null;
|
target: string | null;
|
||||||
@@ -70,8 +35,8 @@ export enum ConnectionMode {
|
|||||||
|
|
||||||
export type OnConnect = (connection: Connection) => void;
|
export type OnConnect = (connection: Connection) => void;
|
||||||
|
|
||||||
export type FitViewParams = {
|
export type FitViewParamsBase<NodeType extends BaseNode> = {
|
||||||
nodes: Node[];
|
nodes: NodeType[];
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
nodeOrigin: NodeOrigin;
|
nodeOrigin: NodeOrigin;
|
||||||
@@ -81,13 +46,13 @@ export type FitViewParams = {
|
|||||||
maxZoom: number;
|
maxZoom: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FitViewOptions = {
|
export type FitViewOptionsBase<NodeType extends BaseNode> = {
|
||||||
padding?: number;
|
padding?: number;
|
||||||
includeHiddenNodes?: boolean;
|
includeHiddenNodes?: boolean;
|
||||||
minZoom?: number;
|
minZoom?: number;
|
||||||
maxZoom?: number;
|
maxZoom?: number;
|
||||||
duration?: number;
|
duration?: number;
|
||||||
nodes?: (Partial<Node> & { id: Node['id'] })[];
|
nodes?: (Partial<NodeType> & { id: NodeType['id'] })[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnConnectStartParams = {
|
export type OnConnectStartParams = {
|
||||||
@@ -96,9 +61,6 @@ export type OnConnectStartParams = {
|
|||||||
handleType: HandleType | null;
|
handleType: HandleType | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnConnectStart = (event: ReactMouseEvent | ReactTouchEvent, params: OnConnectStartParams) => void;
|
|
||||||
export type OnConnectEnd = (event: MouseEvent | TouchEvent) => void;
|
|
||||||
|
|
||||||
export type Viewport = {
|
export type Viewport = {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
@@ -127,150 +89,13 @@ export type FitBoundsOptions = ViewportHelperFunctionOptions & {
|
|||||||
padding?: number;
|
padding?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UnselectNodesAndEdgesParams = {
|
|
||||||
nodes?: Node[];
|
|
||||||
edges?: Edge[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type OnViewportChange = (viewport: Viewport) => void;
|
export type OnViewportChange = (viewport: Viewport) => void;
|
||||||
|
|
||||||
export type ViewportHelperFunctions = {
|
|
||||||
zoomIn: ZoomInOut;
|
|
||||||
zoomOut: ZoomInOut;
|
|
||||||
zoomTo: ZoomTo;
|
|
||||||
getZoom: GetZoom;
|
|
||||||
setViewport: SetViewport;
|
|
||||||
getViewport: GetViewport;
|
|
||||||
fitView: FitView;
|
|
||||||
setCenter: SetCenter;
|
|
||||||
fitBounds: FitBounds;
|
|
||||||
project: Project;
|
|
||||||
viewportInitialized: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type D3ZoomInstance = ZoomBehavior<Element, unknown>;
|
export type D3ZoomInstance = ZoomBehavior<Element, unknown>;
|
||||||
export type D3SelectionInstance = D3Selection<Element, unknown, null, undefined>;
|
export type D3SelectionInstance = D3Selection<Element, unknown, null, undefined>;
|
||||||
|
|
||||||
export type ReactFlowStore = {
|
|
||||||
rfId: string;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
transform: Transform;
|
|
||||||
nodeInternals: NodeInternals;
|
|
||||||
edges: Edge[];
|
|
||||||
onNodesChange: OnNodesChange | null;
|
|
||||||
onEdgesChange: OnEdgesChange | null;
|
|
||||||
hasDefaultNodes: boolean;
|
|
||||||
hasDefaultEdges: boolean;
|
|
||||||
domNode: HTMLDivElement | null;
|
|
||||||
paneDragging: boolean;
|
|
||||||
noPanClassName: string;
|
|
||||||
|
|
||||||
d3Zoom: D3ZoomInstance | null;
|
|
||||||
d3Selection: D3SelectionInstance | null;
|
|
||||||
d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined;
|
|
||||||
minZoom: number;
|
|
||||||
maxZoom: number;
|
|
||||||
translateExtent: CoordinateExtent;
|
|
||||||
nodeExtent: CoordinateExtent;
|
|
||||||
nodeOrigin: NodeOrigin;
|
|
||||||
|
|
||||||
nodesSelectionActive: boolean;
|
|
||||||
userSelectionActive: boolean;
|
|
||||||
userSelectionRect: SelectionRect | null;
|
|
||||||
|
|
||||||
connectionNodeId: string | null;
|
|
||||||
connectionHandleId: string | null;
|
|
||||||
connectionHandleType: HandleType | null;
|
|
||||||
connectionPosition: XYPosition;
|
|
||||||
connectionStatus: ConnectionStatus | null;
|
|
||||||
connectionMode: ConnectionMode;
|
|
||||||
|
|
||||||
snapToGrid: boolean;
|
|
||||||
snapGrid: SnapGrid;
|
|
||||||
|
|
||||||
nodesDraggable: boolean;
|
|
||||||
nodesConnectable: boolean;
|
|
||||||
nodesFocusable: boolean;
|
|
||||||
edgesFocusable: boolean;
|
|
||||||
elementsSelectable: boolean;
|
|
||||||
elevateNodesOnSelect: boolean;
|
|
||||||
|
|
||||||
multiSelectionActive: boolean;
|
|
||||||
|
|
||||||
connectionStartHandle: StartHandle | null;
|
|
||||||
|
|
||||||
onNodeDragStart?: NodeDragHandler;
|
|
||||||
onNodeDrag?: NodeDragHandler;
|
|
||||||
onNodeDragStop?: NodeDragHandler;
|
|
||||||
|
|
||||||
onSelectionDragStart?: SelectionDragHandler;
|
|
||||||
onSelectionDrag?: SelectionDragHandler;
|
|
||||||
onSelectionDragStop?: SelectionDragHandler;
|
|
||||||
|
|
||||||
onConnect?: OnConnect;
|
|
||||||
onConnectStart?: OnConnectStart;
|
|
||||||
onConnectEnd?: OnConnectEnd;
|
|
||||||
|
|
||||||
onClickConnectStart?: OnConnectStart;
|
|
||||||
onClickConnectEnd?: OnConnectEnd;
|
|
||||||
|
|
||||||
connectOnClick: boolean;
|
|
||||||
defaultEdgeOptions?: DefaultEdgeOptions;
|
|
||||||
|
|
||||||
fitViewOnInit: boolean;
|
|
||||||
fitViewOnInitDone: boolean;
|
|
||||||
fitViewOnInitOptions: FitViewOptions | undefined;
|
|
||||||
|
|
||||||
onNodesDelete?: OnNodesDelete;
|
|
||||||
onEdgesDelete?: OnEdgesDelete;
|
|
||||||
onError?: OnError;
|
|
||||||
|
|
||||||
// event handlers
|
|
||||||
onViewportChangeStart?: OnViewportChange;
|
|
||||||
onViewportChange?: OnViewportChange;
|
|
||||||
onViewportChangeEnd?: OnViewportChange;
|
|
||||||
|
|
||||||
onSelectionChange?: OnSelectionChangeFunc;
|
|
||||||
|
|
||||||
ariaLiveMessage: string;
|
|
||||||
autoPanOnConnect: boolean;
|
|
||||||
autoPanOnNodeDrag: boolean;
|
|
||||||
connectionRadius: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ReactFlowActions = {
|
|
||||||
setNodes: (nodes: Node[]) => void;
|
|
||||||
getNodes: () => Node[];
|
|
||||||
setEdges: (edges: Edge[]) => void;
|
|
||||||
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => void;
|
|
||||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
|
||||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged: boolean, dragging: boolean) => void;
|
|
||||||
resetSelectedElements: () => void;
|
|
||||||
unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
|
|
||||||
addSelectedNodes: (nodeIds: string[]) => void;
|
|
||||||
addSelectedEdges: (edgeIds: string[]) => void;
|
|
||||||
setMinZoom: (minZoom: number) => void;
|
|
||||||
setMaxZoom: (maxZoom: number) => void;
|
|
||||||
setTranslateExtent: (translateExtent: CoordinateExtent) => void;
|
|
||||||
setNodeExtent: (nodeExtent: CoordinateExtent) => void;
|
|
||||||
cancelConnection: () => void;
|
|
||||||
reset: () => void;
|
|
||||||
triggerNodeChanges: (changes: NodeChange[]) => void;
|
|
||||||
panBy: (delta: XYPosition) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ReactFlowState = ReactFlowStore & ReactFlowActions;
|
|
||||||
|
|
||||||
export type UpdateNodeInternals = (nodeId: string) => void;
|
export type UpdateNodeInternals = (nodeId: string) => void;
|
||||||
|
|
||||||
export type OnSelectionChangeParams = {
|
|
||||||
nodes: Node[];
|
|
||||||
edges: Edge[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type OnSelectionChangeFunc = (params: OnSelectionChangeParams) => void;
|
|
||||||
|
|
||||||
export type PanelPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
export type PanelPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
||||||
|
|
||||||
export type ProOptions = {
|
export type ProOptions = {
|
||||||
|
|||||||
@@ -2,22 +2,23 @@ import type { XYPosition, Position, Dimensions, OnConnect, Connection } from '.'
|
|||||||
|
|
||||||
export type HandleType = 'source' | 'target';
|
export type HandleType = 'source' | 'target';
|
||||||
|
|
||||||
export interface HandleElement extends XYPosition, Dimensions {
|
export type HandleElement = XYPosition &
|
||||||
id?: string | null;
|
Dimensions & {
|
||||||
position: Position;
|
id?: string | null;
|
||||||
}
|
position: Position;
|
||||||
|
};
|
||||||
|
|
||||||
export interface StartHandle {
|
export type StartHandle = {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
type: HandleType;
|
type: HandleType;
|
||||||
handleId?: string | null;
|
handleId?: string | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface HandleProps {
|
export type HandleProps = {
|
||||||
type: HandleType;
|
type: HandleType;
|
||||||
position: Position;
|
position: Position;
|
||||||
isConnectable?: boolean;
|
isConnectable?: boolean;
|
||||||
onConnect?: OnConnect;
|
onConnect?: OnConnect;
|
||||||
isValidConnection?: (connection: Connection) => boolean;
|
isValidConnection?: (connection: Connection) => boolean;
|
||||||
id?: string;
|
id?: string;
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -2,7 +2,4 @@ export * from './general';
|
|||||||
export * from './nodes';
|
export * from './nodes';
|
||||||
export * from './edges';
|
export * from './edges';
|
||||||
export * from './handles';
|
export * from './handles';
|
||||||
export * from './changes';
|
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
export * from './instance';
|
|
||||||
export * from './component-props';
|
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
|
|
||||||
|
|
||||||
import { internalsSymbol } from '../';
|
import { internalsSymbol } from '../';
|
||||||
import type { XYPosition, Position, CoordinateExtent, HandleElement } from '.';
|
import type { XYPosition, Position, CoordinateExtent, HandleElement } from '.';
|
||||||
|
|
||||||
// interface for the user node items
|
// this is stuff that all nodes share independent of the framework
|
||||||
export type Node<T = any, U extends string | undefined = string | undefined> = {
|
export type BaseNode<T = any, U extends string | undefined = string | undefined> = {
|
||||||
id: string;
|
id: string;
|
||||||
position: XYPosition;
|
position: XYPosition;
|
||||||
data: T;
|
data: T;
|
||||||
type?: U;
|
type?: U;
|
||||||
style?: CSSProperties;
|
|
||||||
className?: string;
|
|
||||||
sourcePosition?: Position;
|
sourcePosition?: Position;
|
||||||
targetPosition?: Position;
|
targetPosition?: Position;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
@@ -31,7 +27,6 @@ export type Node<T = any, U extends string | undefined = string | undefined> = {
|
|||||||
positionAbsolute?: XYPosition;
|
positionAbsolute?: XYPosition;
|
||||||
ariaLabel?: string;
|
ariaLabel?: string;
|
||||||
focusable?: boolean;
|
focusable?: boolean;
|
||||||
resizing?: boolean;
|
|
||||||
|
|
||||||
// only used internally
|
// only used internally
|
||||||
[internalsSymbol]?: {
|
[internalsSymbol]?: {
|
||||||
@@ -41,44 +36,17 @@ export type Node<T = any, U extends string | undefined = string | undefined> = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeMouseHandler = (event: ReactMouseEvent, node: Node) => void;
|
|
||||||
export type NodeDragHandler = (event: ReactMouseEvent, node: Node, nodes: Node[]) => void;
|
|
||||||
export type SelectionDragHandler = (event: ReactMouseEvent, nodes: Node[]) => void;
|
|
||||||
|
|
||||||
export type WrapNodeProps<T = any> = Pick<
|
|
||||||
Node<T>,
|
|
||||||
'id' | 'data' | 'style' | 'className' | 'dragHandle' | 'sourcePosition' | 'targetPosition' | 'hidden' | 'ariaLabel'
|
|
||||||
> &
|
|
||||||
Required<Pick<Node<T>, 'selected' | 'type' | 'zIndex'>> & {
|
|
||||||
isConnectable: boolean;
|
|
||||||
xPos: number;
|
|
||||||
yPos: number;
|
|
||||||
xPosOrigin: number;
|
|
||||||
yPosOrigin: number;
|
|
||||||
initialized: boolean;
|
|
||||||
isSelectable: boolean;
|
|
||||||
isDraggable: boolean;
|
|
||||||
isFocusable: boolean;
|
|
||||||
selectNodesOnDrag: boolean;
|
|
||||||
onClick?: NodeMouseHandler;
|
|
||||||
onDoubleClick?: NodeMouseHandler;
|
|
||||||
onMouseEnter?: NodeMouseHandler;
|
|
||||||
onMouseMove?: NodeMouseHandler;
|
|
||||||
onMouseLeave?: NodeMouseHandler;
|
|
||||||
onContextMenu?: NodeMouseHandler;
|
|
||||||
resizeObserver: ResizeObserver | null;
|
|
||||||
isParent: boolean;
|
|
||||||
noDragClassName: string;
|
|
||||||
noPanClassName: string;
|
|
||||||
rfId: string;
|
|
||||||
disableKeyboardA11y: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
// props that get passed to a custom node
|
// props that get passed to a custom node
|
||||||
export type NodeProps<T = any> = Pick<
|
export type NodeProps<T = any> = {
|
||||||
WrapNodeProps<T>,
|
id: BaseNode['id'];
|
||||||
'id' | 'data' | 'dragHandle' | 'type' | 'selected' | 'isConnectable' | 'xPos' | 'yPos' | 'zIndex'
|
data: T;
|
||||||
> & {
|
dragHandle: BaseNode['dragHandle'];
|
||||||
|
type: BaseNode['type'];
|
||||||
|
selected: BaseNode['selected'];
|
||||||
|
isConnectable: BaseNode['connectable'];
|
||||||
|
zIndex: BaseNode['zIndex'];
|
||||||
|
xPos: number;
|
||||||
|
yPos: number;
|
||||||
dragging: boolean;
|
dragging: boolean;
|
||||||
targetPosition?: Position;
|
targetPosition?: Position;
|
||||||
sourcePosition?: Position;
|
sourcePosition?: Position;
|
||||||
@@ -95,8 +63,6 @@ export type NodeDimensionUpdate = {
|
|||||||
forceUpdate?: boolean;
|
forceUpdate?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeInternals = Map<string, Node>;
|
|
||||||
|
|
||||||
export type NodeBounds = XYPosition & {
|
export type NodeBounds = XYPosition & {
|
||||||
width: number | null;
|
width: number | null;
|
||||||
height: number | null;
|
height: number | null;
|
||||||
|
|||||||
@@ -5,24 +5,24 @@ export enum Position {
|
|||||||
Bottom = 'bottom',
|
Bottom = 'bottom',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface XYPosition {
|
export type XYPosition = {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type XYZPosition = XYPosition & { z: number };
|
export type XYZPosition = XYPosition & { z: number };
|
||||||
|
|
||||||
export interface Dimensions {
|
export type Dimensions = {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface Rect extends Dimensions, XYPosition {}
|
export type Rect = Dimensions & XYPosition;
|
||||||
|
|
||||||
export interface Box extends XYPosition {
|
export type Box = XYPosition & {
|
||||||
x2: number;
|
x2: number;
|
||||||
y2: number;
|
y2: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type Transform = [number, number, number];
|
export type Transform = [number, number, number];
|
||||||
|
|
||||||
|
|||||||
+63
-44
@@ -5,27 +5,32 @@ import { zoomIdentity } from 'd3-zoom';
|
|||||||
import { boxToRect, clamp, devWarn, getBoundsOfBoxes, getOverlappingArea, rectToBox } from './utils';
|
import { boxToRect, clamp, devWarn, getBoundsOfBoxes, getOverlappingArea, rectToBox } from './utils';
|
||||||
import {
|
import {
|
||||||
errorMessages,
|
errorMessages,
|
||||||
type Node,
|
|
||||||
type Edge,
|
|
||||||
type Connection,
|
type Connection,
|
||||||
type EdgeMarkerType,
|
type EdgeMarkerType,
|
||||||
type Transform,
|
type Transform,
|
||||||
type XYPosition,
|
type XYPosition,
|
||||||
type Rect,
|
type Rect,
|
||||||
type NodeInternals,
|
|
||||||
type NodeOrigin,
|
type NodeOrigin,
|
||||||
FitViewParams,
|
BaseNode,
|
||||||
FitViewOptions,
|
BaseEdge,
|
||||||
|
FitViewParamsBase,
|
||||||
|
FitViewOptionsBase,
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
|
|
||||||
export const isEdge = (element: Node | Connection | Edge): element is Edge =>
|
export const isEdgeBase = <NodeType extends BaseNode = BaseNode, EdgeType extends BaseEdge = BaseEdge>(
|
||||||
'id' in element && 'source' in element && 'target' in element;
|
element: NodeType | Connection | EdgeType
|
||||||
|
): element is EdgeType => 'id' in element && 'source' in element && 'target' in element;
|
||||||
|
|
||||||
export const isNode = (element: Node | Connection | Edge): element is Node =>
|
export const isNodeBase = <NodeType extends BaseNode = BaseNode, EdgeType extends BaseEdge = BaseEdge>(
|
||||||
'id' in element && !('source' in element) && !('target' in element);
|
element: NodeType | Connection | EdgeType
|
||||||
|
): element is NodeType => 'id' in element && !('source' in element) && !('target' in element);
|
||||||
|
|
||||||
export const getOutgoers = <T = any, U extends T = T>(node: Node<U>, nodes: Node<T>[], edges: Edge[]): Node<T>[] => {
|
export const getOutgoersBase = <NodeType extends BaseNode = BaseNode, EdgeType extends BaseEdge = BaseEdge>(
|
||||||
if (!isNode(node)) {
|
node: NodeType,
|
||||||
|
nodes: NodeType[],
|
||||||
|
edges: EdgeType[]
|
||||||
|
): NodeType[] => {
|
||||||
|
if (!isNodeBase(node)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,8 +38,12 @@ export const getOutgoers = <T = any, U extends T = T>(node: Node<U>, nodes: Node
|
|||||||
return nodes.filter((n) => outgoerIds.includes(n.id));
|
return nodes.filter((n) => outgoerIds.includes(n.id));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getIncomers = <T = any, U extends T = T>(node: Node<U>, nodes: Node<T>[], edges: Edge[]): Node<T>[] => {
|
export const getIncomersBase = <NodeType extends BaseNode = BaseNode, EdgeType extends BaseEdge = BaseEdge>(
|
||||||
if (!isNode(node)) {
|
node: NodeType,
|
||||||
|
nodes: NodeType[],
|
||||||
|
edges: EdgeType[]
|
||||||
|
): NodeType[] => {
|
||||||
|
if (!isNodeBase(node)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +51,7 @@ export const getIncomers = <T = any, U extends T = T>(node: Node<U>, nodes: Node
|
|||||||
return nodes.filter((n) => incomersIds.includes(n.id));
|
return nodes.filter((n) => incomersIds.includes(n.id));
|
||||||
};
|
};
|
||||||
|
|
||||||
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection): string =>
|
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection | BaseEdge): string =>
|
||||||
`reactflow__edge-${source}${sourceHandle || ''}-${target}${targetHandle || ''}`;
|
`reactflow__edge-${source}${sourceHandle || ''}-${target}${targetHandle || ''}`;
|
||||||
|
|
||||||
export const getMarkerId = (marker: EdgeMarkerType | undefined, rfId?: string): string => {
|
export const getMarkerId = (marker: EdgeMarkerType | undefined, rfId?: string): string => {
|
||||||
@@ -62,7 +71,7 @@ export const getMarkerId = (marker: EdgeMarkerType | undefined, rfId?: string):
|
|||||||
.join('&')}`;
|
.join('&')}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const connectionExists = (edge: Edge, edges: Edge[]) => {
|
const connectionExists = (edge: BaseEdge, edges: BaseEdge[]) => {
|
||||||
return edges.some(
|
return edges.some(
|
||||||
(el) =>
|
(el) =>
|
||||||
el.source === edge.source &&
|
el.source === edge.source &&
|
||||||
@@ -72,21 +81,24 @@ const connectionExists = (edge: Edge, edges: Edge[]) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addEdge = (edgeParams: Edge | Connection, edges: Edge[]): Edge[] => {
|
export const addEdgeBase = <EdgeType extends BaseEdge>(
|
||||||
|
edgeParams: EdgeType | Connection,
|
||||||
|
edges: EdgeType[]
|
||||||
|
): EdgeType[] => {
|
||||||
if (!edgeParams.source || !edgeParams.target) {
|
if (!edgeParams.source || !edgeParams.target) {
|
||||||
devWarn('006', errorMessages['006']());
|
devWarn('006', errorMessages['006']());
|
||||||
|
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
let edge: Edge;
|
let edge: EdgeType;
|
||||||
if (isEdge(edgeParams)) {
|
if (isEdgeBase(edgeParams)) {
|
||||||
edge = { ...edgeParams };
|
edge = { ...edgeParams };
|
||||||
} else {
|
} else {
|
||||||
edge = {
|
edge = {
|
||||||
...edgeParams,
|
...edgeParams,
|
||||||
id: getEdgeId(edgeParams),
|
id: getEdgeId(edgeParams),
|
||||||
} as Edge;
|
} as EdgeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connectionExists(edge, edges)) {
|
if (connectionExists(edge, edges)) {
|
||||||
@@ -96,14 +108,18 @@ export const addEdge = (edgeParams: Edge | Connection, edges: Edge[]): Edge[] =>
|
|||||||
return edges.concat(edge);
|
return edges.concat(edge);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateEdge = (oldEdge: Edge, newConnection: Connection, edges: Edge[]): Edge[] => {
|
export const updateEdgeBase = <EdgeType extends BaseEdge>(
|
||||||
|
oldEdge: EdgeType,
|
||||||
|
newConnection: Connection,
|
||||||
|
edges: EdgeType[]
|
||||||
|
): EdgeType[] => {
|
||||||
if (!newConnection.source || !newConnection.target) {
|
if (!newConnection.source || !newConnection.target) {
|
||||||
devWarn('006', errorMessages['006']());
|
devWarn('006', errorMessages['006']());
|
||||||
|
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundEdge = edges.find((e) => e.id === oldEdge.id) as Edge;
|
const foundEdge = edges.find((e) => e.id === oldEdge.id) as EdgeType;
|
||||||
|
|
||||||
if (!foundEdge) {
|
if (!foundEdge) {
|
||||||
devWarn('007', errorMessages['007'](oldEdge.id));
|
devWarn('007', errorMessages['007'](oldEdge.id));
|
||||||
@@ -119,7 +135,7 @@ export const updateEdge = (oldEdge: Edge, newConnection: Connection, edges: Edge
|
|||||||
target: newConnection.target,
|
target: newConnection.target,
|
||||||
sourceHandle: newConnection.sourceHandle,
|
sourceHandle: newConnection.sourceHandle,
|
||||||
targetHandle: newConnection.targetHandle,
|
targetHandle: newConnection.targetHandle,
|
||||||
} as Edge;
|
} as EdgeType;
|
||||||
|
|
||||||
return edges.filter((e) => e.id !== oldEdge.id).concat(edge);
|
return edges.filter((e) => e.id !== oldEdge.id).concat(edge);
|
||||||
};
|
};
|
||||||
@@ -153,7 +169,7 @@ export const rendererPointToPoint = ({ x, y }: XYPosition, [tx, ty, tScale]: Tra
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getNodePositionWithOrigin = (
|
export const getNodePositionWithOrigin = (
|
||||||
node: Node | undefined,
|
node: BaseNode | undefined,
|
||||||
nodeOrigin: NodeOrigin = [0, 0]
|
nodeOrigin: NodeOrigin = [0, 0]
|
||||||
): XYPosition & { positionAbsolute: XYPosition } => {
|
): XYPosition & { positionAbsolute: XYPosition } => {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@@ -186,7 +202,7 @@ export const getNodePositionWithOrigin = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRectOfNodes = (nodes: Node[], nodeOrigin: NodeOrigin = [0, 0]): Rect => {
|
export const getRectOfNodes = (nodes: BaseNode[], nodeOrigin: NodeOrigin = [0, 0]): Rect => {
|
||||||
if (nodes.length === 0) {
|
if (nodes.length === 0) {
|
||||||
return { x: 0, y: 0, width: 0, height: 0 };
|
return { x: 0, y: 0, width: 0, height: 0 };
|
||||||
}
|
}
|
||||||
@@ -210,15 +226,15 @@ export const getRectOfNodes = (nodes: Node[], nodeOrigin: NodeOrigin = [0, 0]):
|
|||||||
return boxToRect(box);
|
return boxToRect(box);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getNodesInside = (
|
export const getNodesInside = <NodeType extends BaseNode>(
|
||||||
nodeInternals: NodeInternals,
|
nodes: NodeType[],
|
||||||
rect: Rect,
|
rect: Rect,
|
||||||
[tx, ty, tScale]: Transform = [0, 0, 1],
|
[tx, ty, tScale]: Transform = [0, 0, 1],
|
||||||
partially = false,
|
partially = false,
|
||||||
// set excludeNonSelectableNodes if you want to pay attention to the nodes "selectable" attribute
|
// set excludeNonSelectableNodes if you want to pay attention to the nodes "selectable" attribute
|
||||||
excludeNonSelectableNodes = false,
|
excludeNonSelectableNodes = false,
|
||||||
nodeOrigin: NodeOrigin = [0, 0]
|
nodeOrigin: NodeOrigin = [0, 0]
|
||||||
): Node[] => {
|
): NodeType[] => {
|
||||||
const paneRect = {
|
const paneRect = {
|
||||||
x: (rect.x - tx) / tScale,
|
x: (rect.x - tx) / tScale,
|
||||||
y: (rect.y - ty) / tScale,
|
y: (rect.y - ty) / tScale,
|
||||||
@@ -226,13 +242,11 @@ export const getNodesInside = (
|
|||||||
height: rect.height / tScale,
|
height: rect.height / tScale,
|
||||||
};
|
};
|
||||||
|
|
||||||
const visibleNodes: Node[] = [];
|
const visibleNodes = nodes.reduce<NodeType[]>((res, node) => {
|
||||||
|
|
||||||
nodeInternals.forEach((node) => {
|
|
||||||
const { width, height, selectable = true, hidden = false } = node;
|
const { width, height, selectable = true, hidden = false } = node;
|
||||||
|
|
||||||
if ((excludeNonSelectableNodes && !selectable) || hidden) {
|
if ((excludeNonSelectableNodes && !selectable) || hidden) {
|
||||||
return false;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { positionAbsolute } = getNodePositionWithOrigin(node, nodeOrigin);
|
const { positionAbsolute } = getNodePositionWithOrigin(node, nodeOrigin);
|
||||||
@@ -252,14 +266,19 @@ export const getNodesInside = (
|
|||||||
const isVisible = notInitialized || partiallyVisible || overlappingArea >= area;
|
const isVisible = notInitialized || partiallyVisible || overlappingArea >= area;
|
||||||
|
|
||||||
if (isVisible || node.dragging) {
|
if (isVisible || node.dragging) {
|
||||||
visibleNodes.push(node);
|
res.push(node);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
return res;
|
||||||
|
}, []);
|
||||||
|
|
||||||
return visibleNodes;
|
return visibleNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getConnectedEdges = (nodes: Node[], edges: Edge[]): Edge[] => {
|
export const getConnectedEdgesBase = <NodeType extends BaseNode = BaseNode, EdgeType extends BaseEdge = BaseEdge>(
|
||||||
|
nodes: NodeType[],
|
||||||
|
edges: EdgeType[]
|
||||||
|
): EdgeType[] => {
|
||||||
const nodeIds = nodes.map((node) => node.id);
|
const nodeIds = nodes.map((node) => node.id);
|
||||||
|
|
||||||
return edges.filter((edge) => nodeIds.includes(edge.source) || nodeIds.includes(edge.target));
|
return edges.filter((edge) => nodeIds.includes(edge.source) || nodeIds.includes(edge.target));
|
||||||
@@ -289,15 +308,15 @@ export const getD3Transition = (selection: D3Selection<Element, unknown, null, u
|
|||||||
return selection.transition().duration(duration);
|
return selection.transition().duration(duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fitView(
|
export function fitView<Params extends FitViewParamsBase<BaseNode>, Options extends FitViewOptionsBase<BaseNode>>(
|
||||||
{ nodes, width, height, d3Zoom, d3Selection, nodeOrigin, minZoom, maxZoom }: FitViewParams,
|
{ nodes, width, height, d3Zoom, d3Selection, nodeOrigin, minZoom, maxZoom }: Params,
|
||||||
options: FitViewOptions = {}
|
options?: Options
|
||||||
) {
|
) {
|
||||||
const filteredNodes = nodes.filter((n) => {
|
const filteredNodes = nodes.filter((n) => {
|
||||||
const isVisible = options.includeHiddenNodes ? n.width && n.height : !n.hidden;
|
const isVisible = options?.includeHiddenNodes ? n.width && n.height : !n.hidden;
|
||||||
|
|
||||||
if (options.nodes?.length) {
|
if (options?.nodes?.length) {
|
||||||
return isVisible && options.nodes.some((optionNode) => optionNode.id === n.id);
|
return isVisible && options?.nodes.some((optionNode) => optionNode.id === n.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isVisible;
|
return isVisible;
|
||||||
@@ -312,14 +331,14 @@ export function fitView(
|
|||||||
bounds,
|
bounds,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
options.minZoom ?? minZoom,
|
options?.minZoom ?? minZoom,
|
||||||
options.maxZoom ?? maxZoom,
|
options?.maxZoom ?? maxZoom,
|
||||||
options.padding ?? 0.1
|
options?.padding ?? 0.1
|
||||||
);
|
);
|
||||||
|
|
||||||
const nextTransform = zoomIdentity.translate(x, y).scale(zoom);
|
const nextTransform = zoomIdentity.translate(x, y).scale(zoom);
|
||||||
|
|
||||||
if (typeof options.duration === 'number' && options.duration > 0) {
|
if (typeof options?.duration === 'number' && options.duration > 0) {
|
||||||
d3Zoom.transform(getD3Transition(d3Selection, options.duration), nextTransform);
|
d3Zoom.transform(getD3Transition(d3Selection, options.duration), nextTransform);
|
||||||
} else {
|
} else {
|
||||||
d3Zoom.transform(d3Selection, nextTransform);
|
d3Zoom.transform(d3Selection, nextTransform);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type {
|
|||||||
MouseEvent as ReactMouseEvent,
|
MouseEvent as ReactMouseEvent,
|
||||||
TouchEvent as ReactTouchEvent,
|
TouchEvent as ReactTouchEvent,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import type { Dimensions, Node, XYPosition, CoordinateExtent, Box, Rect } from '@reactflow/system';
|
import type { Dimensions, XYPosition, CoordinateExtent, Box, Rect, BaseNode } from '@reactflow/system';
|
||||||
|
|
||||||
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
|
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
|
||||||
width: node.offsetWidth,
|
width: node.offsetWidth,
|
||||||
@@ -60,7 +60,7 @@ export const boxToRect = ({ x, y, x2, y2 }: Box): Rect => ({
|
|||||||
height: y2 - y,
|
height: y2 - y,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const nodeToRect = (node: Node): Rect => ({
|
export const nodeToRect = (node: BaseNode): Rect => ({
|
||||||
...(node.positionAbsolute || { x: 0, y: 0 }),
|
...(node.positionAbsolute || { x: 0, y: 0 }),
|
||||||
width: node.width || 0,
|
width: node.width || 0,
|
||||||
height: node.height || 0,
|
height: node.height || 0,
|
||||||
@@ -125,3 +125,8 @@ export const getEventPosition = (
|
|||||||
y: evtY - (bounds?.top ?? 0),
|
y: evtY - (bounds?.top ?? 0),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const infiniteExtent: CoordinateExtent = [
|
||||||
|
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
||||||
|
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||||
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user