diff --git a/src/composables/useVueFlow.ts b/src/composables/useVueFlow.ts index 46d34108..2db2d743 100644 --- a/src/composables/useVueFlow.ts +++ b/src/composables/useVueFlow.ts @@ -96,6 +96,8 @@ export default (options?: FlowOptions): UseVueFlow => { const store = useStore(options) return { store, - hooks: store.hooks, + applyNodeChanges: (changes) => applyNodeChanges(changes, store.nodes), + applyEdgeChanges: (changes) => applyEdgeChanges(changes, store.edges), + ...store.hooksOn, } } diff --git a/src/store/store.ts b/src/store/store.ts index faaaa3b7..80602344 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -2,7 +2,7 @@ import { getCurrentInstance } from 'vue' import useState, { initialState } from './state' import useActions from './actions' import useGetters from './getters' -import { FlowExportObject, FlowOptions, FlowState, FlowStore, Store } from '~/types' +import { FlowExportObject, FlowHooksOn, FlowOptions, FlowState, FlowStore, Store } from '~/types' import { StoreSymbol } from '~/context' import { onLoadToObject } from '~/utils' @@ -10,9 +10,15 @@ const useFlowStore = (id: string, preloadedState: FlowState): Store => { const state = reactive(useState(preloadedState)) const getters = useGetters(state) const actions = useActions(state, getters) + const hooksOn: FlowHooksOn = {} + Object.entries(state.hooks).forEach(([n, h]) => { + const name = `On${n.charAt(0).toUpperCase() + n.slice(1)}` + hooksOn[name] = h.on as any + }) return { id, state, + hooksOn, ...toRefs(state), ...getters, ...actions, diff --git a/src/types/flow.ts b/src/types/flow.ts index 220a76da..b75b26c3 100644 --- a/src/types/flow.ts +++ b/src/types/flow.ts @@ -3,6 +3,8 @@ import { GraphEdge, Edge } from './edge' import { GraphNode, CoordinateExtent, Node } from './node' import { ConnectionLineType, ConnectionMode } from './connection' import { KeyCode, PanOnScrollMode, UseZoomPanHelper } from './zoom' +import { FlowStore } from './store' +import { EdgeChange, FlowHooksOn, NodeChange } from './hooks' export type FlowElement = GraphNode | GraphEdge export type FlowElements = FlowElement[] @@ -116,3 +118,9 @@ export interface FlowProps { } export type FlowOptions = FlowProps + +export type UseVueFlow = { + store: FlowStore + applyNodeChanges: (changes: NodeChange[]) => void + applyEdgeChanges: (changes: EdgeChange[]) => void +} & FlowHooksOn diff --git a/src/types/hooks.ts b/src/types/hooks.ts index 8625f564..2293a3ee 100644 --- a/src/types/hooks.ts +++ b/src/types/hooks.ts @@ -1,16 +1,42 @@ import { EventHook } from '@vueuse/core' import { MouseTouchEvent } from '@braks/revue-draggable' -import { FlowInstance, FlowElements } from './flow' +import { FlowInstance, Dimensions, XYPosition, XYZPosition } from './flow' import { GraphEdge } from './edge' -import { GraphNode } from './node' +import { GraphNode, HandleBounds } from './node' import { Connection, OnConnectStartParams } from './connection' import { FlowTransform } from './zoom' -export type FlowHook = EventHook +export type NodeDimensionChange = { + id: string + type: 'dimensions' + dimensions?: Dimensions + position?: XYPosition + handleBounds?: HandleBounds + computedPosition?: XYZPosition + dragging?: boolean +} + +export type NodeSelectionChange = { + id: string + type: 'select' + selected: boolean +} + +export type NodeRemoveChange = { + id: string + type: 'remove' +} + +export type NodeChange = NodeDimensionChange | NodeSelectionChange | NodeRemoveChange + +export type EdgeSelectionChange = NodeSelectionChange +export type EdgeRemoveChange = NodeRemoveChange +export type EdgeChange = EdgeSelectionChange | EdgeRemoveChange export interface FlowEvents { + nodesChange: NodeChange[] + edgesChange: EdgeChange[] elementClick: { event: MouseTouchEvent; element: GraphNode | GraphEdge } - elementsRemove: FlowElements nodeDoubleClick: { event: MouseTouchEvent; node: GraphNode } nodeClick: { event: MouseTouchEvent; node: GraphNode } nodeMouseEnter: { event: MouseEvent; node: GraphNode } @@ -26,8 +52,7 @@ export interface FlowEvents { } & { [key in keyof OnConnectStartParams]: OnConnectStartParams[key] } connectStop: MouseEvent connectEnd: MouseEvent - load: FlowInstance - elementsProcessed: FlowElements + paneReady: FlowInstance move: FlowTransform | undefined moveStart: FlowTransform | undefined moveEnd: FlowTransform | undefined @@ -50,6 +75,9 @@ export interface FlowEvents { edgeUpdateEnd: { event: MouseEvent; edge: GraphEdge } } +export type FlowHook = EventHook + export type FlowHooks = { [key in keyof FlowEvents]: FlowHook } +export type FlowHooksOn = { [key in keyof FlowEvents as `On${Capitalize}`]: FlowHook['on'] } export type EmitFunc = (name: keyof T, ...args: any[]) => void diff --git a/src/types/store.ts b/src/types/store.ts index 2dcdadba..e9844e2c 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -6,7 +6,7 @@ import { ConnectionLineType, ConnectionMode, SetConnectionId } from './connectio import { Edge, GraphEdge } from './edge' import { GraphNode, CoordinateExtent, Node } from './node' import { D3Selection, D3Zoom, D3ZoomHandler, KeyCode, PanOnScrollMode } from './zoom' -import { FlowHooks } from './hooks' +import { FlowHooks, FlowHooksOn } from './hooks' export interface FlowState extends Omit, 'id'> { hooks: FlowHooks @@ -100,7 +100,7 @@ export interface FlowGetters { getSelectedEdges: ComputedRef[]> } -export type Store = { id: string; state: FlowState } & ToRefs> & +export type Store = { id: string; state: FlowState; hooksOn: FlowHooksOn } & ToRefs> & FlowActions & FlowGetters export type FlowStore = UnwrapNestedRefs>