Refactor(types): unify node and edge handling (#3978)
* refactor(types): unify node and edge type behaviour * chore(changelogs): update * chore(examples): cleanup
This commit is contained in:
@@ -212,6 +212,7 @@ export function EdgeWrapper<EdgeType extends Edge = Edge>({
|
||||
id={id}
|
||||
source={edge.source}
|
||||
target={edge.target}
|
||||
type={edge.type}
|
||||
selected={edge.selected}
|
||||
animated={edge.animated}
|
||||
label={edge.label}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { ComponentType } from 'react';
|
||||
import type { EdgeProps, EdgeTypes } from '../../types';
|
||||
import type { EdgeTypes } from '../../types';
|
||||
import {
|
||||
BezierEdgeInternal,
|
||||
StraightEdgeInternal,
|
||||
@@ -9,11 +8,11 @@ import {
|
||||
} from '../Edges';
|
||||
|
||||
export const builtinEdgeTypes: EdgeTypes = {
|
||||
default: BezierEdgeInternal as ComponentType<EdgeProps>,
|
||||
straight: StraightEdgeInternal as ComponentType<EdgeProps>,
|
||||
step: StepEdgeInternal as ComponentType<EdgeProps>,
|
||||
smoothstep: SmoothStepEdgeInternal as ComponentType<EdgeProps>,
|
||||
simplebezier: SimpleBezierEdgeInternal as ComponentType<EdgeProps>,
|
||||
default: BezierEdgeInternal,
|
||||
straight: StraightEdgeInternal,
|
||||
step: StepEdgeInternal,
|
||||
smoothstep: SmoothStepEdgeInternal,
|
||||
simplebezier: SimpleBezierEdgeInternal,
|
||||
};
|
||||
|
||||
export const nullPosition = {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
memo,
|
||||
forwardRef,
|
||||
type HTMLAttributes,
|
||||
type MouseEvent as ReactMouseEvent,
|
||||
type TouchEvent as ReactTouchEvent,
|
||||
type ForwardedRef,
|
||||
memo,
|
||||
forwardRef,
|
||||
} from 'react';
|
||||
import cc from 'classcat';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { ComponentType } from 'react';
|
||||
import type { NodeProps, XYPosition } from '@xyflow/system';
|
||||
import type { XYPosition } from '@xyflow/system';
|
||||
|
||||
import { InputNode } from '../Nodes/InputNode';
|
||||
import { DefaultNode } from '../Nodes/DefaultNode';
|
||||
@@ -15,10 +14,10 @@ export const arrowKeyDiffs: Record<string, XYPosition> = {
|
||||
};
|
||||
|
||||
export const builtinNodeTypes: NodeTypes = {
|
||||
input: InputNode as ComponentType<NodeProps>,
|
||||
default: DefaultNode as ComponentType<NodeProps>,
|
||||
output: OutputNode as ComponentType<NodeProps>,
|
||||
group: GroupNode as ComponentType<NodeProps>,
|
||||
input: InputNode,
|
||||
default: DefaultNode,
|
||||
output: OutputNode,
|
||||
group: GroupNode,
|
||||
};
|
||||
|
||||
export function getNodeInlineStyleDimensions<NodeType extends Node = Node>(
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Position, type NodeProps } from '@xyflow/system';
|
||||
import { Position } from '@xyflow/system';
|
||||
|
||||
import { Handle } from '../../components/Handle';
|
||||
import type { BuiltInNode, NodeProps } from '../../types/nodes';
|
||||
|
||||
export function DefaultNode({
|
||||
data,
|
||||
isConnectable,
|
||||
targetPosition = Position.Top,
|
||||
sourcePosition = Position.Bottom,
|
||||
}: NodeProps) {
|
||||
}: NodeProps<BuiltInNode>) {
|
||||
return (
|
||||
<>
|
||||
<Handle type="target" position={targetPosition} isConnectable={isConnectable} />
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Position, type NodeProps } from '@xyflow/system';
|
||||
import { Position } from '@xyflow/system';
|
||||
|
||||
import { Handle } from '../../components/Handle';
|
||||
import type { BuiltInNode, NodeProps } from '../../types/nodes';
|
||||
|
||||
export function InputNode({ data, isConnectable, sourcePosition = Position.Bottom }: NodeProps) {
|
||||
export function InputNode({ data, isConnectable, sourcePosition = Position.Bottom }: NodeProps<BuiltInNode>) {
|
||||
return (
|
||||
<>
|
||||
{data?.label}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Position, type NodeProps } from '@xyflow/system';
|
||||
import { Position } from '@xyflow/system';
|
||||
|
||||
import { Handle } from '../../components/Handle';
|
||||
import type { BuiltInNode, NodeProps } from '../../types/nodes';
|
||||
|
||||
export function OutputNode({ data, isConnectable, targetPosition = Position.Top }: NodeProps) {
|
||||
export function OutputNode({ data, isConnectable, targetPosition = Position.Top }: NodeProps<BuiltInNode>) {
|
||||
return (
|
||||
<>
|
||||
<Handle type="target" position={targetPosition} isConnectable={isConnectable} />
|
||||
|
||||
@@ -64,7 +64,6 @@ export {
|
||||
SelectionMode,
|
||||
type SelectionRect,
|
||||
type OnError,
|
||||
type NodeProps,
|
||||
type NodeOrigin,
|
||||
type OnSelectionDrag,
|
||||
Position,
|
||||
|
||||
@@ -98,10 +98,10 @@ export type EdgeTextProps = HTMLAttributes<SVGElement> &
|
||||
* Custom edge component props
|
||||
* @public
|
||||
*/
|
||||
export type EdgeProps<
|
||||
EdgeData extends Record<string, unknown> = Record<string, unknown>,
|
||||
EdgeType extends string | undefined = string | undefined
|
||||
> = Pick<Edge<EdgeData, EdgeType>, 'id' | 'animated' | 'data' | 'style' | 'selected' | 'source' | 'target'> &
|
||||
export type EdgeProps<EdgeType extends Edge = Edge> = Pick<
|
||||
EdgeType,
|
||||
'id' | 'animated' | 'data' | 'style' | 'selected' | 'source' | 'target'
|
||||
> &
|
||||
EdgePosition &
|
||||
EdgeLabelOptions & {
|
||||
sourceHandleId?: string | null;
|
||||
|
||||
@@ -10,18 +10,18 @@ import {
|
||||
SetCenter,
|
||||
FitBounds,
|
||||
XYPosition,
|
||||
NodeProps,
|
||||
OnBeforeDeleteBase,
|
||||
Connection,
|
||||
} from '@xyflow/system';
|
||||
|
||||
import type { NodeChange, EdgeChange, Node, Edge, ReactFlowInstance, EdgeProps } from '.';
|
||||
import type { NodeChange, EdgeChange, Node, Edge, ReactFlowInstance, EdgeProps, NodeProps } from '.';
|
||||
|
||||
// this is needed, to use generics + forwardRef
|
||||
declare module 'react' {
|
||||
function forwardRef<T, P>(
|
||||
render: (props: P, ref: React.Ref<T>) => React.ReactNode | null
|
||||
): (props: P & React.RefAttributes<T>) => React.ReactNode | null;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function forwardRef<T, P = {}>(
|
||||
render: (props: P, ref: React.Ref<T>) => React.ReactElement | null
|
||||
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
|
||||
}
|
||||
|
||||
export type OnNodesChange<NodeType extends Node = Node> = (changes: NodeChange<NodeType>[]) => void;
|
||||
@@ -34,8 +34,28 @@ export type OnDelete<NodeType extends Node = Node, EdgeType extends Edge = Edge>
|
||||
edges: EdgeType[];
|
||||
}) => void;
|
||||
|
||||
export type NodeTypes = { [key: string]: ComponentType<NodeProps> };
|
||||
export type EdgeTypes = { [key: string]: ComponentType<EdgeProps> };
|
||||
export type NodeTypes = Record<
|
||||
string,
|
||||
ComponentType<
|
||||
NodeProps & {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
data: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type: any;
|
||||
}
|
||||
>
|
||||
>;
|
||||
export type EdgeTypes = Record<
|
||||
string,
|
||||
ComponentType<
|
||||
EdgeProps & {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
data: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type: any;
|
||||
}
|
||||
>
|
||||
>;
|
||||
|
||||
export type UnselectNodesAndEdgesParams = {
|
||||
nodes?: Node[];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
|
||||
import type { CoordinateExtent, NodeBase, NodeOrigin, OnError } from '@xyflow/system';
|
||||
import type { CoordinateExtent, NodeBase, NodeOrigin, OnError, NodeProps as NodePropsBase } from '@xyflow/system';
|
||||
|
||||
import { NodeTypes } from './general';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { NodeTypes } from './general';
|
||||
*/
|
||||
export type Node<
|
||||
NodeData extends Record<string, unknown> = Record<string, unknown>,
|
||||
NodeType extends string | undefined = string | undefined
|
||||
NodeType extends string = string
|
||||
> = NodeBase<NodeData, NodeType> & {
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
@@ -49,3 +49,5 @@ export type NodeWrapperProps<NodeType extends Node> = {
|
||||
};
|
||||
|
||||
export type BuiltInNode = Node<{ label: string }, 'input' | 'output' | 'default'>;
|
||||
|
||||
export type NodeProps<NodeType extends Node = Node> = NodePropsBase<NodeType>;
|
||||
|
||||
Reference in New Issue
Block a user