diff --git a/src/types/actions.ts b/src/types/actions.ts new file mode 100644 index 00000000..85a11cb2 --- /dev/null +++ b/src/types/actions.ts @@ -0,0 +1,25 @@ +import { Dimensions, Elements, XYPosition } from './types' +import { NodeDiffUpdate, NodeDimensionUpdate, NodeExtent, NodePosUpdate, TranslateExtent } from './node' +import { InitD3ZoomPayload } from './panel' +import { SetConnectionId } from './connection' + +export interface RevueFlowActions { + setElements: (elements: Elements) => void + updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void + updateNodePos: (payload: NodePosUpdate) => void + updateNodePosDiff: (payload: NodeDiffUpdate) => void + setUserSelection: (mousePos: XYPosition) => void + updateUserSelection: (mousePos: XYPosition) => void + unsetUserSelection: () => void + addSelectedElements: (elements: Elements) => void + initD3Zoom: (payload: InitD3ZoomPayload) => void + setMinZoom: (zoom: number) => void + setMaxZoom: (zoom: number) => void + setTranslateExtent: (translateExtent: TranslateExtent) => void + setNodeExtent: (nodeExtent: NodeExtent) => void + resetSelectedElements: () => void + unsetNodesSelection: () => void + updateSize: (size: Dimensions) => void + setConnectionNodeId: (payload: SetConnectionId) => void + setInteractive: (isInteractive: boolean) => void +} diff --git a/src/types/connection.ts b/src/types/connection.ts new file mode 100644 index 00000000..dacc7f02 --- /dev/null +++ b/src/types/connection.ts @@ -0,0 +1,50 @@ +import { ComponentPublicInstance } from 'vue' +import { ElementId, HandleType, Position } from './types' + +export enum ConnectionLineType { + Bezier = 'default', + Straight = 'straight', + Step = 'step', + SmoothStep = 'smoothstep', +} + +export interface Connection { + source: ElementId | null + target: ElementId | null + sourceHandle: ElementId | null + targetHandle: ElementId | null +} + +export type ConnectionLineComponentProps = { + sourceX: number + sourceY: number + sourcePosition?: Position + targetX: number + targetY: number + targetPosition?: Position + connectionLineStyle?: any + connectionLineType: ConnectionLineType +} + +export type ConnectionLineComponent = ComponentPublicInstance + +export type OnConnectFunc = (connection: Connection) => void +export type OnConnectStartParams = { + nodeId: ElementId | null + handleId: ElementId | null + handleType: HandleType | null +} +export type OnConnectStartFunc = (event: MouseEvent, params: OnConnectStartParams) => void +export type OnConnectStopFunc = (event: MouseEvent) => void +export type OnConnectEndFunc = (event: MouseEvent) => void + +export enum ConnectionMode { + Strict = 'strict', + Loose = 'loose', +} + +export type SetConnectionId = { + connectionNodeId: ElementId | null + connectionHandleId: ElementId | null + connectionHandleType: HandleType | null +} diff --git a/src/types/edge.ts b/src/types/edge.ts new file mode 100644 index 00000000..e1ac5266 --- /dev/null +++ b/src/types/edge.ts @@ -0,0 +1,69 @@ +import { ComponentPublicInstance, HTMLAttributes, VNode } from 'vue' +import { ArrowHeadType, ElementId, Position } from './types' +import { Connection } from './connection' + +export interface Edge { + id: ElementId + type?: string + source: ElementId + target: ElementId + sourceHandle?: ElementId | null + targetHandle?: ElementId | null + label?: string | VNode + labelStyle?: any + labelShowBg?: boolean + labelBgStyle?: any + labelBgPadding?: [number, number] + labelBgBorderRadius?: number + style?: any + animated?: boolean + arrowHeadType?: ArrowHeadType + isHidden?: boolean + data?: T + className?: string +} + +export interface EdgeProps { + id: ElementId + source: ElementId + target: ElementId + sourceX: number + sourceY: number + targetX: number + targetY: number + selected?: boolean + animated?: boolean + sourcePosition: Position + targetPosition: Position + label?: string | VNode + labelStyle?: any + labelShowBg?: boolean + labelBgStyle?: any + labelBgPadding?: [number, number] + labelBgBorderRadius?: number + style?: any + arrowHeadType?: ArrowHeadType + markerEndId?: string + data?: T + sourceHandleId?: ElementId | null + targetHandleId?: ElementId | null +} + +export interface EdgeSmoothStepProps extends EdgeProps { + borderRadius?: number +} + +export interface EdgeTextProps extends HTMLAttributes { + x: number + y: number + label?: string | VNode + labelStyle?: any + labelShowBg?: boolean + labelBgStyle?: any + labelBgPadding?: [number, number] + labelBgBorderRadius?: number +} + +export type EdgeType = ComponentPublicInstance + +export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void diff --git a/src/types/handle.ts b/src/types/handle.ts new file mode 100644 index 00000000..55c539ed --- /dev/null +++ b/src/types/handle.ts @@ -0,0 +1,18 @@ +import { Dimensions, ElementId, Position, XYPosition } from './types' +import { Connection, OnConnectFunc } from './connection' + +export type HandleType = 'source' | 'target' + +export interface HandleElement extends XYPosition, Dimensions { + id?: ElementId | null + position: Position +} + +export interface HandleProps { + type: HandleType + position: Position + isConnectable?: boolean + onConnect?: OnConnectFunc + isValidConnection?: (connection: Connection) => boolean + id?: ElementId +} diff --git a/src/types/index.ts b/src/types/index.ts index b16d7611..22eb789f 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,425 +1,8 @@ -import { Selection as D3Selection, ZoomBehavior } from 'd3' -import { CSSProperties, DefineComponent, HTMLAttributes, VNode } from 'vue' -import { Store } from 'pinia' - -export type ElementId = string - -export type FlowElement = Node | Edge - -export type Elements = Array> - -export type Transform = [number, number, number] - -export enum Position { - Left = 'left', - Top = 'top', - Right = 'right', - Bottom = 'bottom' -} - -export interface XYPosition { - x: number - y: number -} - -export interface Dimensions { - width: number - height: number -} - -export interface Rect extends Dimensions, XYPosition {} - -export interface Box extends XYPosition { - x2: number - y2: number -} - -export type SnapGrid = [number, number] - -export interface Node { - id: ElementId - position: XYPosition - type?: string - __rf: { - position: XYPosition - isDragging?: boolean - width: number | null - height: number | null - handleBounds?: any - } - data?: T - style?: any - className?: string - targetPosition?: Position - sourcePosition?: Position - isHidden?: boolean - draggable?: boolean - selectable?: boolean - connectable?: boolean -} - -export enum ArrowHeadType { - Arrow = 'arrow', - ArrowClosed = 'arrowclosed' -} - -export interface Edge { - id: ElementId - type?: string - source: ElementId - target: ElementId - sourceHandle?: ElementId | null - targetHandle?: ElementId | null - label?: string | VNode - labelStyle?: any - labelShowBg?: boolean - labelBgStyle?: any - labelBgPadding?: [number, number] - labelBgBorderRadius?: number - style?: any - animated?: boolean - arrowHeadType?: ArrowHeadType - isHidden?: boolean - data?: T - className?: string -} - -export enum BackgroundVariant { - Lines = 'lines', - Dots = 'dots' -} - -export type HandleType = 'source' | 'target' - -export type NodeType = DefineComponent - -export type EdgeType = DefineComponent - -export interface SelectionRect extends Rect { - startX: number - startY: number - draw: boolean -} - -export interface EdgeProps { - id: ElementId - source: ElementId - target: ElementId - sourceX: number - sourceY: number - targetX: number - targetY: number - selected?: boolean - animated?: boolean - sourcePosition: Position - targetPosition: Position - label?: string | VNode - labelStyle?: any - labelShowBg?: boolean - labelBgStyle?: any - labelBgPadding?: [number, number] - labelBgBorderRadius?: number - style?: any - arrowHeadType?: ArrowHeadType - markerEndId?: string - data?: T - sourceHandleId?: ElementId | null - targetHandleId?: ElementId | null -} - -export interface EdgeSmoothStepProps extends EdgeProps { - borderRadius?: number -} - -export interface EdgeTextProps extends HTMLAttributes { - x: number - y: number - label?: string | VNode - labelStyle?: any - labelShowBg?: boolean - labelBgStyle?: any - labelBgPadding?: [number, number] - labelBgBorderRadius?: number -} - -export interface NodeProps { - id: ElementId - type: string - data: T - selected: boolean - isConnectable: boolean - xPos?: number - yPos?: number - targetPosition?: Position - sourcePosition?: Position - isDragging?: boolean -} - -export type FitViewParams = { - padding?: number - includeHiddenNodes?: boolean - minZoom?: number - maxZoom?: number -} - -export type FlowExportObject = { - elements: Elements - position: [number, number] - zoom: number -} - -export type FitViewFunc = (fitViewOptions?: FitViewParams) => void -export type ProjectFunc = (position: XYPosition) => XYPosition -export type ToObjectFunc = () => FlowExportObject - -export type OnLoadParams = { - zoomIn: () => void - zoomOut: () => void - zoomTo: (zoomLevel: number) => void - fitView: FitViewFunc - project: ProjectFunc - getElements: () => Elements - setTransform: (transform: FlowTransform) => void - toObject: ToObjectFunc -} - -export type OnLoadFunc = (params: OnLoadParams) => void - -export interface Connection { - source: ElementId | null - target: ElementId | null - sourceHandle: ElementId | null - targetHandle: ElementId | null -} - -export enum ConnectionMode { - Strict = 'strict', - Loose = 'loose' -} - -export enum ConnectionLineType { - Bezier = 'default', - Straight = 'straight', - Step = 'step', - SmoothStep = 'smoothstep' -} - -export type ConnectionLineComponentProps = { - sourceX: number - sourceY: number - sourcePosition?: Position - targetX: number - targetY: number - targetPosition?: Position - connectionLineStyle?: any - connectionLineType: ConnectionLineType -} - -export type ConnectionLineComponent = DefineComponent - -export type OnConnectFunc = (connection: Connection) => void -export type OnConnectStartParams = { - nodeId: ElementId | null - handleId: ElementId | null - handleType: HandleType | null -} -export type OnConnectStartFunc = (event: MouseEvent, params: OnConnectStartParams) => void -export type OnConnectStopFunc = (event: MouseEvent) => void -export type OnConnectEndFunc = (event: MouseEvent) => void - -export type SetConnectionId = { - connectionNodeId: ElementId | null - connectionHandleId: ElementId | null - connectionHandleType: HandleType | null -} - -export interface HandleElement extends XYPosition, Dimensions { - id?: ElementId | null - position: Position -} - -export interface HandleProps { - type: HandleType - position: Position - isConnectable?: boolean - onConnect?: OnConnectFunc - isValidConnection?: (connection: Connection) => boolean - id?: ElementId -} - -export type NodePosUpdate = { - id: ElementId - pos: XYPosition -} - -export type NodeDiffUpdate = { - id?: ElementId - diff?: XYPosition - isDragging?: boolean -} - -export type FlowTransform = { - x: number - y: number - zoom: number -} - -export type TranslateExtent = [[number, number], [number, number]] -export type NodeExtent = TranslateExtent - -export type KeyCode = number | string - -export enum PanOnScrollMode { - Free = 'free', - Vertical = 'vertical', - Horizontal = 'horizontal' -} - -export interface ZoomPanHelperFunctions { - zoomIn: () => void - zoomOut: () => void - zoomTo: (zoomLevel: number) => void - transform: (transform: FlowTransform) => void - fitView: FitViewFunc - setCenter: (x: number, y: number, zoom?: number) => void - fitBounds: (bounds: Rect, padding?: number) => void - project: (position: XYPosition) => XYPosition -} - -export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void - -export type NodeDimensionUpdate = { - id: ElementId - nodeElement: HTMLDivElement - forceUpdate?: boolean -} - -export type InitD3ZoomPayload = { - d3Zoom: ZoomBehavior - d3Selection: D3Selection - d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined - transform: Transform -} - -export interface RevueFlowState { - width: number - height: number - transform: Transform - nodes: Node[] - edges: Edge[] - selectedElements: Elements | null - selectedNodesBbox: Rect - - d3Zoom: ZoomBehavior | null - d3Selection: D3Selection | null - d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined - minZoom: number - maxZoom: number - translateExtent: TranslateExtent - nodeExtent: NodeExtent - - nodesSelectionActive: boolean - selectionActive: boolean - - userSelectionRect: SelectionRect - - connectionNodeId: ElementId | null - connectionHandleId: ElementId | null - connectionHandleType: HandleType | null - connectionPosition: XYPosition - connectionMode: ConnectionMode - - snapToGrid: boolean - snapGrid: SnapGrid - - nodesDraggable: boolean - nodesConnectable: boolean - elementsSelectable: boolean - - multiSelectionActive: boolean - - revueFlowVersion: string - - onConnect?: OnConnectFunc - onConnectStart?: OnConnectStartFunc - onConnectStop?: OnConnectStopFunc - onConnectEnd?: OnConnectEndFunc -} - -export type RevueFlowActions = { - setElements: (elements: Elements) => void - updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void - updateNodePos: (payload: NodePosUpdate) => void - updateNodePosDiff: (payload: NodeDiffUpdate) => void - setUserSelection: (mousePos: XYPosition) => void - updateUserSelection: (mousePos: XYPosition) => void - unsetUserSelection: () => void - addSelectedElements: (elements: Elements) => void - initD3Zoom: (payload: InitD3ZoomPayload) => void - setMinZoom: (zoom: number) => void - setMaxZoom: (zoom: number) => void - setTranslateExtent: (translateExtent: TranslateExtent) => void - setNodeExtent: (nodeExtent: NodeExtent) => void - resetSelectedElements: () => void - unsetNodesSelection: () => void - updateSize: (size: Dimensions) => void - setConnectionNodeId: (payload: SetConnectionId) => void - setInteractive: (isInteractive: boolean) => void -} - -export type RevueFlowStore = Store - -export type UpdateNodeInternals = (nodeId: ElementId) => void - -export interface RevueFlowProps extends Omit { - modelValue: Elements - nodeTypes?: Record - edgeTypes?: Record - connectionMode?: ConnectionMode - connectionLineType?: ConnectionLineType - connectionLineStyle?: CSSProperties - connectionLineComponent?: ConnectionLineComponent - deleteKeyCode?: KeyCode - selectionKeyCode?: KeyCode - multiSelectionKeyCode?: KeyCode - zoomActivationKeyCode?: KeyCode - snapToGrid?: boolean - snapGrid?: [number, number] - onlyRenderVisibleElements?: boolean - nodesDraggable?: boolean - nodesConnectable?: boolean - elementsSelectable?: boolean - selectNodesOnDrag?: boolean - paneMoveable?: boolean - minZoom?: number - maxZoom?: number - defaultZoom?: number - defaultPosition?: [number, number] - translateExtent?: TranslateExtent - nodeExtent?: NodeExtent - arrowHeadColor?: string - markerEndId?: string - zoomOnScroll?: boolean - zoomOnPinch?: boolean - panOnScroll?: boolean - panOnScrollSpeed?: number - panOnScrollMode?: PanOnScrollMode - zoomOnDoubleClick?: boolean - edgeUpdaterRadius?: number - nodeTypesId?: string - edgeTypesId?: string -} - -export interface GraphViewProps extends Required { - selectionKeyCode: KeyCode - deleteKeyCode: KeyCode - multiSelectionKeyCode: KeyCode - connectionLineType: ConnectionLineType - snapToGrid: boolean - snapGrid: [number, number] - onlyRenderVisibleElements: boolean - defaultZoom: number - defaultPosition: [number, number] - arrowHeadColor: string - selectNodesOnDrag: boolean -} +export * from './types' +export * from './actions' +export * from './connection' +export * from './edge' +export * from './handle' +export * from './node' +export * from './panel' +export * from './store' diff --git a/src/types/node.ts b/src/types/node.ts new file mode 100644 index 00000000..9813f548 --- /dev/null +++ b/src/types/node.ts @@ -0,0 +1,60 @@ +import { ComponentPublicInstance } from 'vue' +import { XYPosition } from './types' +import { ElementId, Position } from './index' + +export interface Node { + id: ElementId + position: XYPosition + type?: string + __rf: { + position: XYPosition + isDragging?: boolean + width: number | null + height: number | null + handleBounds?: any + } + data?: T + style?: any + className?: string + targetPosition?: Position + sourcePosition?: Position + isHidden?: boolean + draggable?: boolean + selectable?: boolean + connectable?: boolean +} + +export type NodePosUpdate = { + id: ElementId + pos: XYPosition +} + +export type NodeDiffUpdate = { + id?: ElementId + diff?: XYPosition + isDragging?: boolean +} + +export type TranslateExtent = [[number, number], [number, number]] +export type NodeExtent = TranslateExtent + +export type NodeDimensionUpdate = { + id: ElementId + nodeElement: HTMLDivElement + forceUpdate?: boolean +} + +export interface NodeProps { + id: ElementId + type: string + data: T + selected: boolean + isConnectable: boolean + xPos?: number + yPos?: number + targetPosition?: Position + sourcePosition?: Position + isDragging?: boolean +} + +export type NodeType = ComponentPublicInstance diff --git a/src/types/panel.ts b/src/types/panel.ts new file mode 100644 index 00000000..d1538e17 --- /dev/null +++ b/src/types/panel.ts @@ -0,0 +1,28 @@ +import { Selection as D3Selection, ZoomBehavior } from 'd3' +import { FitViewFunc, FlowTransform, Rect, Transform, XYPosition } from './types' + +export type KeyCode = number | string + +export enum PanOnScrollMode { + Free = 'free', + Vertical = 'vertical', + Horizontal = 'horizontal', +} + +export interface ZoomPanHelperFunctions { + zoomIn: () => void + zoomOut: () => void + zoomTo: (zoomLevel: number) => void + transform: (transform: FlowTransform) => void + fitView: FitViewFunc + setCenter: (x: number, y: number, zoom?: number) => void + fitBounds: (bounds: Rect, padding?: number) => void + project: (position: XYPosition) => XYPosition +} + +export type InitD3ZoomPayload = { + d3Zoom: ZoomBehavior + d3Selection: D3Selection + d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined + transform: Transform +} diff --git a/src/types/store.ts b/src/types/store.ts new file mode 100644 index 00000000..869e4895 --- /dev/null +++ b/src/types/store.ts @@ -0,0 +1,55 @@ +import { ZoomBehavior, Selection } from 'd3' +import { Store } from 'pinia' +import { ElementId, Elements, Rect, SelectionRect, SnapGrid, Transform, XYPosition } from './types' +import { HandleType } from './handle' +import { ConnectionMode, OnConnectEndFunc, OnConnectFunc, OnConnectStartFunc, OnConnectStopFunc } from './connection' +import { Edge } from './edge' +import { Node, NodeExtent, TranslateExtent } from './node' +import { RevueFlowActions } from './actions' + +export interface RevueFlowState { + width: number + height: number + transform: Transform + nodes: Node[] + edges: Edge[] + selectedElements: Elements | null + selectedNodesBbox: Rect + + d3Zoom: ZoomBehavior | null + d3Selection: Selection | null + d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined + minZoom: number + maxZoom: number + translateExtent: TranslateExtent + nodeExtent: NodeExtent + + nodesSelectionActive: boolean + selectionActive: boolean + + userSelectionRect: SelectionRect + + connectionNodeId: ElementId | null + connectionHandleId: ElementId | null + connectionHandleType: HandleType | null + connectionPosition: XYPosition + connectionMode: ConnectionMode + + snapToGrid: boolean + snapGrid: SnapGrid + + nodesDraggable: boolean + nodesConnectable: boolean + elementsSelectable: boolean + + multiSelectionActive: boolean + + revueFlowVersion: string + + onConnect?: OnConnectFunc + onConnectStart?: OnConnectStartFunc + onConnectStop?: OnConnectStopFunc + onConnectEnd?: OnConnectEndFunc +} + +export type RevueFlowStore = Store diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 00000000..fa787f73 --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,83 @@ +import { Edge } from './edge' +import { Node } from './node' + +export type ElementId = string + +export type FlowElement = Node | Edge + +export type Elements = Array> + +export type Transform = [number, number, number] + +export enum Position { + Left = 'left', + Top = 'top', + Right = 'right', + Bottom = 'bottom', +} + +export interface XYPosition { + x: number + y: number +} + +export interface Dimensions { + width: number + height: number +} + +export interface Rect extends Dimensions, XYPosition {} + +export type SnapGrid = [number, number] + +export enum ArrowHeadType { + Arrow = 'arrow', + ArrowClosed = 'arrowclosed', +} + +export enum BackgroundVariant { + Lines = 'lines', + Dots = 'dots', +} + +export interface SelectionRect extends Rect { + startX: number + startY: number + draw: boolean +} + +export type FitViewParams = { + padding?: number + includeHiddenNodes?: boolean + minZoom?: number + maxZoom?: number +} + +export type FlowExportObject = { + elements: Elements + position: [number, number] + zoom: number +} + +export type FlowTransform = { + x: number + y: number + zoom: number +} + +export type FitViewFunc = (fitViewOptions?: FitViewParams) => void +export type ProjectFunc = (position: XYPosition) => XYPosition +export type ToObjectFunc = () => FlowExportObject + +export type OnLoadParams = { + zoomIn: () => void + zoomOut: () => void + zoomTo: (zoomLevel: number) => void + fitView: FitViewFunc + project: ProjectFunc + getElements: () => Elements + setTransform: (transform: FlowTransform) => void + toObject: ToObjectFunc +} + +export type OnLoadFunc = (params: OnLoadParams) => void