Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core,nodes)!: use xyflow provided NodeBase to extend Node type #1587

Draft
wants to merge 2 commits into
base: refactor/xyflow-system
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 3 additions & 53 deletions packages/core/src/types/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,12 @@ import type {
} from './connection'
import type { PanOnScrollMode } from './zoom'
import type { EdgeTypesObject, NodeTypesObject } from './components'
import type { CustomEvent, EdgeMouseEvent, EdgeUpdateEvent, MouseTouchEvent, NodeDragEvent, NodeMouseEvent } from './hooks'
import type { EdgeMouseEvent, EdgeUpdateEvent, MouseTouchEvent, NodeDragEvent, NodeMouseEvent } from './hooks'
import type { ValidConnectionFunc } from './handle'
import type { EdgeChange, NodeChange } from './changes'
import type { VueFlowStore } from './store'

// todo: should be object type
export type ElementData = any

/**
* @deprecated - will be removed in the next major version
* A flow element (after parsing into state)
*/
export type FlowElement<
NodeData = ElementData,
EdgeData = ElementData,
NodeEvents extends Record<string, CustomEvent> = any,
EdgeEvents extends Record<string, CustomEvent> = any,
> = GraphNode<NodeData, NodeEvents> | GraphEdge<EdgeData, EdgeEvents>

/**
* @deprecated - will be removed in the next major version
* An array of flow elements (after parsing into state)
*/
export type FlowElements<
NodeData = ElementData,
EdgeData = ElementData,
NodeEvents extends Record<string, CustomEvent> = any,
EdgeEvents extends Record<string, CustomEvent> = any,
> = FlowElement<NodeData, EdgeData, NodeEvents, EdgeEvents>[]

/** Initial elements (before parsing into state) */
export type Element<
NodeData = ElementData,
EdgeData = ElementData,
NodeEvents extends Record<string, CustomEvent> = any,
EdgeEvents extends Record<string, CustomEvent> = any,
> = Node<NodeData, NodeEvents> | Edge<EdgeData, EdgeEvents>

export type Elements<
NodeData = ElementData,
EdgeData = ElementData,
NodeEvents extends Record<string, CustomEvent> = any,
EdgeEvents extends Record<string, CustomEvent> = any,
> = Element<NodeData, EdgeData, NodeEvents, EdgeEvents>[]

export type MaybeElement = Node | Edge | Connection | FlowElement | Element
export type MaybeElement = Node | Edge | Connection | Element

export interface CustomThemeVars {
[key: string]: string | number | undefined
Expand All @@ -75,12 +35,8 @@ export type CSSVars =
| '--vf-handle'

export type ThemeVars = { [key in CSSVars]?: CSSProperties['color'] }
export type Styles = CSSProperties & ThemeVars & CustomThemeVars
/** @deprecated will be removed in the next major version */
export type ClassFunc<ElementType extends FlowElement = FlowElement> = (element: ElementType) => string | void

/** @deprecated will be removed in the next major version */
export type StyleFunc<ElementType extends FlowElement = FlowElement> = (element: ElementType) => Styles | void
export type Styles = CSSProperties & ThemeVars & CustomThemeVars

/** Handle Positions */
export enum Position {
Expand Down Expand Up @@ -142,11 +98,6 @@ export interface FlowExportObject {

export interface FlowProps {
id?: string
/**
* all elements (nodes + edges)
* @deprecated use {@link FlowProps.nodes} & {@link FlowProps.nodes} instead
*/
modelValue?: Elements
nodes?: Node[]
edges?: Edge[]
/** either use the edgeTypes prop to define your edge-types or use slots (<template #edge-mySpecialType="props">) */
Expand Down Expand Up @@ -306,7 +257,6 @@ export interface FlowEmits {
(event: 'nodeDragStop', nodeDragEvent: NodeDragEvent): void

/** v-model event definitions */
(event: 'update:modelValue', value: FlowElements): void
(event: 'update:nodes', value: GraphNode[]): void
(event: 'update:edges', value: GraphEdge[]): void
}
Expand Down
191 changes: 15 additions & 176 deletions packages/core/src/types/node.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Component, VNode } from 'vue'
import type { ClassFunc, Dimensions, ElementData, Position, StyleFunc, Styles, XYPosition, XYZPosition } from './flow'
import type { NodeComponent } from './components'
import type { HandleConnectable, HandleElement, ValidConnectionFunc } from './handle'
import type { CustomEvent, NodeEventsHandler, NodeEventsOn } from './hooks'
import type { NodeBase, NodeProps as NodePropsBase } from '@xyflow/system'
import type { Styles } from './flow'
import type { HandleConnectable, HandleElement } from './handle'

export type ElementData = Record<string, unknown>

/** Defined as [[x-from, y-from], [x-to, y-to]] */
export type CoordinateExtent = [extentFrom: [fromX: number, fromY: number], extentTo: [toX: number, toY: number]]
Expand All @@ -23,185 +23,24 @@ export interface NodeHandleBounds {
target?: HandleElement[]
}

/** @deprecated will be removed in next major release */
export type WidthFunc = (node: GraphNode) => number | string | void

/** @deprecated will be removed in next major release */
export type HeightFunc = (node: GraphNode) => number | string | void

export interface Node<Data = ElementData, CustomEvents extends Record<string, CustomEvent> = any, Type extends string = string> {
/** Unique node id */
id: string
/**
* @deprecated - will be removed in next major release and replaced with `{ data: { label: string | VNode | Component } }`
* A node label
*/
label?: string | VNode | Component
/** initial node position x, y */
position: XYPosition
/** node type, can be a default type or a custom type */
type?: Type
/** handle position */
targetPosition?: Position
/** handle position */
sourcePosition?: Position
/** Disable/enable dragging node */
draggable?: boolean
/** Disable/enable selecting node */
selectable?: boolean
/**
* The node data structure that gets used for the nodes prop.
* @public
*/
export interface Node<NodeData extends ElementData = ElementData, NodeType extends string = string>
extends Omit<NodeBase<NodeData, NodeType>, 'connectable' | 'extent' | 'origin'> {
/** Disable/enable connecting node */
connectable?: HandleConnectable
/** Disable/enable focusing node (a11y) */
focusable?: boolean
/** Disable/enable deleting node */
deletable?: boolean
/** element selector as drag handle for node (can only be dragged from the dragHandle el) */
dragHandle?: string
/**
* @deprecated will be removed in next major release
* called when used as target for new connection
*/
isValidTargetPos?: ValidConnectionFunc
/**
* @deprecated will be removed in next major release
* called when used as source for new connection
*/
isValidSourcePos?: ValidConnectionFunc
/** define node extent, i.e. area in which node can be moved */
extent?: CoordinateExtent | CoordinateExtentRange | 'parent'
/** expands parent area to fit child node */
expandParent?: boolean
/**
* todo: rename to `parentId` in next major release
* define node as a child node by setting a parent node id
*/
parentNode?: string
/**
* Fixed width of node, applied as style
* You can pass a number which will be used in pixel values (width: 300 -> width: 300px)
* or pass a string with units (width: `10rem` -> width: 10rem)
*/
width?: number | string | WidthFunc
/**
* Fixed height of node, applied as style
* You can pass a number which will be used in pixel values (height: 300 -> height: 300px)
* or pass a string with units (height: `10rem` -> height: 10rem)
*/
height?: number | string | HeightFunc

/** Additional class names, can be a string or a callback returning a string (receives current flow element) */
class?: string | string[] | Record<string, any> | ClassFunc<GraphNode<Data, CustomEvents>>
class?: string | string[] | Record<string, any>
/** Additional styles, can be an object or a callback returning an object (receives current flow element) */
style?: Styles | StyleFunc<GraphNode<Data, CustomEvents>>
/** Is node hidden */
hidden?: boolean
/**
* @deprecated - will be removed in the next major release
* overwrites current node type
*/
template?: NodeComponent
/** Additional data that is passed to your custom components */
data?: Data
/**
* @deprecated - will be removed in the next major release
* contextual and custom events that are passed to your custom components
*/
events?: Partial<NodeEventsHandler<CustomEvents>>
zIndex?: number
ariaLabel?: string
}

export interface GraphNode<
Data = ElementData,
CustomEvents extends Record<string, CustomEvent> = any,
Type extends string = string,
> extends Node<Data, CustomEvents, Type> {
/** absolute position in relation to parent elements + z-index */
computedPosition: XYZPosition
handleBounds: NodeHandleBounds
/** node width, height */
dimensions: Dimensions
isParent: boolean
selected: boolean
resizing: boolean
dragging: boolean
data: Data
/** @deprecated will be removed in the next major version */
events: Partial<NodeEventsHandler<CustomEvents>>
type: Type
style?: Styles
}

/** these props are passed to node components */
export interface NodeProps<Data = ElementData, CustomEvents = object, Type extends string = string> {
/** unique node id */
id: string
/** node type */
type: Type
/** is node selected */
selected: boolean
export interface NodeProps<NodeType extends NodeBase = NodeBase> extends Omit<NodePropsBase<NodeType>, 'isConnectable'> {
/** can node handles be connected, you need to forward this to your handles for this prop to have any effect */
connectable: HandleConnectable
/**
* @deprecated - will be removed in next major release and replaced with `computedPosition`
* node x, y (relative) position on graph
*/
position: XYPosition
/** dom element dimensions (width, height) */
dimensions: Dimensions
/**
* @deprecated - will be removed in next major release and replaced with `{ data: { label: string | VNode | Component } }`
* node label, either pass a string or a VNode
* For example like this: `h('div', props, children)`)
* Object is just a type-hack for Vue, ignore that
*/
label?: string | VNode | Component | object
/**
* @deprecated will be removed in next major release
* called when used as target for new connection
*/
isValidTargetPos?: ValidConnectionFunc
/**
* @deprecated will be removed in next major release
* called when used as source for new connection
*/
isValidSourcePos?: ValidConnectionFunc
/**
* @deprecated - will be removed in next major release. Use `parentNodeId` instead
* parent node id
*/
parent?: string
/**
* todo: rename to `parentId` in next major release
* parent node id
*/
parentNodeId?: string
/** is node currently dragging */
dragging: boolean
/** is node currently resizing */
resizing: boolean
/** node z-index */
zIndex: number
/** handle position */
targetPosition?: Position
/** handle position */
sourcePosition?: Position
/** drag handle query selector */
dragHandle?: string

/** additional data of node */
data: Data
/**
* @deprecated - will be removed in next major release
* contextual and custom events of node
*/
events: NodeEventsOn<CustomEvents>
isConnectable: HandleConnectable
}

/**
* Transform a Node type to a GraphNode type
*/
export type ToGraphNode<T extends Node> = GraphNode<
T extends Node<infer Data> ? Data : never,
T extends Node<any, infer Events> ? Events : never,
T extends Node<any, any, infer Type> ? Type : never
>