feat!: Add hooks to store

* For easier access and to avoid context issues with injections hooks are put into the store
* hooks can be accessed and will emit events when the flow has bound its emit function to the hooks
* useHooks and useStore are not exported anymore! Instead, useVueFlow is provided, which will return an instance of the current vue flow store
* Rename NodeIdContextKey to NodeId
* Add addElements function to store to add elements without having to re-set the whole store
* use v-model for elements, re-set elements only if there's an actual change

Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
Braks
2021-11-18 21:24:20 +01:00
parent 0cca54e7e2
commit 99dbd4b2cc
14 changed files with 134 additions and 100 deletions
+1 -1
View File
@@ -5,4 +5,4 @@ export { default as useKeyPress } from './useKeyPress'
export { default as useZoomPanHelper } from './useZoomPanHelper'
export { default as useStore } from './useStore'
export { default as useWindow } from './useWindow'
export { default as useVueFlow } from './useVueFlow'
export { default as useVueFlow, initFlow } from './useVueFlow'
+23 -21
View File
@@ -1,8 +1,20 @@
import { Connection, Edge, Elements, EmitFunc, FlowHooks, FlowTransform, Node, OnConnectStartParams, FlowInstance } from '~/types'
import useStore from './useStore'
import {
Connection,
Edge,
Elements,
EmitFunc,
FlowHooks,
FlowTransform,
Node,
OnConnectStartParams,
FlowInstance,
FlowEvents,
} from '~/types'
import { Hooks } from '~/context'
// flow event hooks
const hooks = (): FlowHooks => {
export const createHooks = (): FlowHooks => {
return {
elementClick: createEventHook<{ event: MouseEvent; element: Node | Edge }>(),
elementsRemove: createEventHook<Elements>(),
@@ -45,33 +57,23 @@ const hooks = (): FlowHooks => {
edgeUpdateEnd: createEventHook<MouseEvent>(),
}
}
export const createHooks = (): FlowHooks & { bind: (emit: EmitFunc) => FlowHooks } => {
const eventHooks = hooks()
const bind = (emit: EmitFunc) => {
for (const [key, value] of Object.entries(eventHooks)) {
value.on((data: unknown) => {
emit(key as keyof FlowHooks, data)
})
}
return eventHooks
}
return {
...eventHooks,
bind,
const bind = (emit: EmitFunc, hooks: FlowHooks) => {
for (const [key, value] of Object.entries(hooks)) {
value.on((data: FlowEvents[keyof FlowHooks]) => {
emit(key as keyof FlowHooks, data)
})
}
}
export default (emit?: EmitFunc) => {
let hooks = inject(Hooks)!
if (!hooks) {
const store = useStore()
if (import.meta.env.DEV) console.warn('hooks context not found; creating default hooks')
if (!emit) console.error('no emit function found for hook context.')
else {
hooks = createHooks().bind(emit)
provide(Hooks, hooks)
}
hooks = store.hooks
if (typeof emit === 'function') bind(emit, hooks)
provide(Hooks, hooks)
}
return hooks
+1
View File
@@ -4,6 +4,7 @@ import { Store } from '~/context'
export default (options?: Partial<FlowOptions>) => {
let store = inject(Store)!
if (!store) {
if (import.meta.env.DEV) console.warn('store context not found; creating default store')
store = useFlowStore({
+5 -12
View File
@@ -1,22 +1,15 @@
import useHooks from './useHooks'
import useStore from './useStore'
import { FlowInstance } from '~/types'
import { EmitFunc } from '~/types'
export default () => {
export const initFlow = (emit: EmitFunc) => {
const store = useStore()
const hooks = useHooks()
const isReady = ref(false)
const instance = ref<FlowInstance>()
hooks.load.on((flow) => {
isReady.value = true
instance.value = flow
if (import.meta.env.DEV) console.log(`vue flow ${store.$id} ready.`)
})
const hooks = useHooks(emit)
return {
isReady,
instance,
store,
hooks,
}
}
export default () => useStore()