refactor(core): add overloads to useVueFlow (#1481)

* refactor(core): add overloads to `useVueFlow`

* chore(changeset): add

* chore(core): cleanup
This commit is contained in:
Braks
2024-06-18 12:29:29 +02:00
parent 9b4e3b2656
commit 4fe1a7b541
5 changed files with 37 additions and 26 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@vue-flow/core": minor
---
Add overloads to `useVueFlow`. Allows calling `useVueFlow` with an `id` string only while emitting a deprecation warning for using the options obj.
+19 -8
View File
@@ -1,8 +1,8 @@
import { tryOnScopeDispose } from '@vueuse/core'
import type { EffectScope } from 'vue'
import { effectScope, getCurrentScope, inject, provide, watch } from 'vue'
import { effectScope, getCurrentInstance, getCurrentScope, inject, provide, watch } from 'vue'
import type { EdgeChange, FlowOptions, NodeChange, VueFlowStore } from '../types'
import { warn } from '../utils'
import { ErrorCode, VueFlowError, warn } from '../utils'
import { VueFlow } from '../context'
import { Storage } from '../utils/storage'
@@ -18,15 +18,21 @@ type Scope = (EffectScope & { vueFlowId: string }) | undefined
* If no store instance is found in context, a new store instance is created and registered in storage
*
* @public
* @param options - optional options to initialize the store instance
* @returns a vue flow store instance
* @param idOrOpts - id of the store instance or options to create a new store instance
*/
export function useVueFlow(options?: FlowOptions): VueFlowStore {
export function useVueFlow(id?: string): VueFlowStore
export function useVueFlow(options?: FlowOptions): VueFlowStore
export function useVueFlow(idOrOpts?: any): VueFlowStore {
const storage = Storage.getInstance()
const scope = getCurrentScope() as Scope
const id = options?.id
const isOptsObj = typeof idOrOpts === 'object'
const options = isOptsObj ? idOrOpts : undefined
const id = options?.id ?? idOrOpts
const vueFlowId = scope?.vueFlowId || id
let vueFlow: Injection
@@ -114,7 +120,7 @@ export function useVueFlow(options?: FlowOptions): VueFlowStore {
})
} else {
// If options were passed, overwrite state with the options' values
if (options) {
if (isOptsObj) {
vueFlow.setState(options)
}
}
@@ -126,8 +132,13 @@ export function useVueFlow(options?: FlowOptions): VueFlowStore {
scope.vueFlowId = vueFlow.id
}
if (options) {
warn('options are deprecated and will be removed in the next major version. Use props on the `<VueFlow>` component instead.')
if (isOptsObj) {
const instance = getCurrentInstance()
// ignore the warning if we are in a VueFlow component
if (instance?.type.name !== 'VueFlow') {
vueFlow.emits.error(new VueFlowError(ErrorCode.USEVUEFLOW_OPTIONS))
}
}
return vueFlow
@@ -309,7 +309,7 @@ export function useWatchProps(
;(storeRef.value as any) = nextValue
}
},
{ immediate: true, flush: 'pre' },
{ immediate: true },
)
})
}
@@ -56,18 +56,12 @@ const modelValue = useVModel(props, 'modelValue', emit)
const modelNodes = useVModel(props, 'nodes', emit)
const modelEdges = useVModel(props, 'edges', emit)
const { vueFlowRef, hooks, getNodeTypes, getEdgeTypes, ...rest } = useVueFlow(props)
const instance = useVueFlow(props)
// watch props and update store state
const dispose = useWatchProps({ modelValue, nodes: modelNodes, edges: modelEdges }, props, {
vueFlowRef,
hooks,
getNodeTypes,
getEdgeTypes,
...rest,
})
const dispose = useWatchProps({ modelValue, nodes: modelNodes, edges: modelEdges }, props, instance)
useHooks(emit, hooks)
useHooks(emit, instance.hooks)
useOnInitHandler()
@@ -83,13 +77,7 @@ onUnmounted(() => {
dispose()
})
defineExpose<VueFlowStore>({
vueFlowRef,
hooks,
getNodeTypes,
getEdgeTypes,
...rest,
})
defineExpose<VueFlowStore>(instance)
</script>
<script lang="ts">
@@ -100,7 +88,7 @@ export default {
</script>
<template>
<div ref="vueFlowRef" class="vue-flow">
<div :ref="instance.vueFlowRef" class="vue-flow">
<Viewport>
<EdgeRenderer />
+7
View File
@@ -14,6 +14,9 @@ export enum ErrorCode {
EDGE_SOURCE_TARGET_SAME = 'EDGE_SOURCE_TARGET_SAME',
EDGE_SOURCE_TARGET_MISSING = 'EDGE_SOURCE_TARGET_MISSING',
EDGE_ORPHANED = 'EDGE_ORPHANED',
// deprecation errors
USEVUEFLOW_OPTIONS = 'USEVUEFLOW_OPTIONS',
}
const messages = {
@@ -36,6 +39,10 @@ const messages = {
[ErrorCode.EDGE_ORPHANED]: (id: string) =>
`Edge was orphaned (suddenly missing source or target) and has been removed\nEdge: ${id}`,
[ErrorCode.EDGE_NOT_FOUND]: (id: string) => `Edge not found\nEdge: ${id}`,
// deprecation errors
[ErrorCode.USEVUEFLOW_OPTIONS]: () =>
`The options parameter is deprecated and will be removed in the next major version. Please use the id parameter instead`,
} as const
type ErrorArgs<T extends ErrorCode> = (typeof messages)[T] extends (...args: any[]) => string