feat(core): add viewport helper to state

This commit is contained in:
braks
2024-02-05 07:51:12 +01:00
committed by Braks
parent fbadf9427f
commit c855dfe454
6 changed files with 39 additions and 19 deletions
@@ -4,12 +4,33 @@ import { useVueFlow } from './useVueFlow'
export function useOnInitHandler() { export function useOnInitHandler() {
const vfInstance = useVueFlow() const vfInstance = useVueFlow()
watch(vfInstance.viewportInitialized, (isInitialized) => { watch(
if (isInitialized) { () => vfInstance.viewportHelper.value.viewportInitialized,
setTimeout(() => { (isInitialized) => {
vfInstance.emits.init(vfInstance) if (isInitialized) {
vfInstance.emits.paneReady(vfInstance) setTimeout(() => {
}, 1) // todo: call these when *nodes* are initialized instead of the viewport
} // currently doesn't work quite right because the viewport dimensions are not yet available when the nodes are initialized
}) if (!vfInstance.fitViewOnInitDone.value && vfInstance.fitViewOnInit.value) {
vfInstance.fitView()
}
vfInstance.fitViewOnInitDone.value = true
// Here, we are making all nodes visible once we have the dimensions.
if (!document.querySelector('#vue-flow__initialized-styles')) {
const style = document.createElement('style')
style.id = 'vue-flow__initialized-styles'
document.head.appendChild(style)
const css = `.vue-flow__node { visibility: visible !important; }`
style.appendChild(document.createTextNode(css))
}
vfInstance.emits.init(vfInstance)
vfInstance.emits.paneReady(vfInstance)
}, 1)
}
},
)
} }
+3 -3
View File
@@ -3,7 +3,7 @@ import { computed } from 'vue'
import type { ComputedGetters, D3Selection, GraphNode, Project, State, ViewportFunctions } from '../types' import type { ComputedGetters, D3Selection, GraphNode, Project, State, ViewportFunctions } from '../types'
import { clampPosition, getRectOfNodes, getTransformForBounds, pointToRendererPoint, rendererPointToPoint, warn } from '../utils' import { clampPosition, getRectOfNodes, getTransformForBounds, pointToRendererPoint, rendererPointToPoint, warn } from '../utils'
interface ExtendedViewport extends ViewportFunctions { export interface ViewportHelper extends ViewportFunctions {
viewportInitialized: boolean viewportInitialized: boolean
screenToFlowCoordinate: Project screenToFlowCoordinate: Project
flowToScreenCoordinate: Project flowToScreenCoordinate: Project
@@ -17,7 +17,7 @@ function noop() {
return Promise.resolve(false) return Promise.resolve(false)
} }
const initialViewportHelper: ExtendedViewport = { const initialViewportHelper: ViewportHelper = {
zoomIn: noop, zoomIn: noop,
zoomOut: noop, zoomOut: noop,
zoomTo: noop, zoomTo: noop,
@@ -72,7 +72,7 @@ export function useViewport(state: State, getters: ComputedGetters) {
}) })
} }
return computed<ExtendedViewport>(() => { return computed<ViewportHelper>(() => {
const isInitialized = state.d3Zoom && state.d3Selection && state.dimensions.width && state.dimensions.height const isInitialized = state.d3Zoom && state.d3Selection && state.dimensions.width && state.dimensions.height
if (!isInitialized) { if (!isInitialized) {
+1
View File
@@ -939,6 +939,7 @@ export function useActions(
toObject, toObject,
fromObject, fromObject,
updateNodeInternals, updateNodeInternals,
viewportHelper,
$reset, $reset,
$destroy: () => {}, $destroy: () => {},
} }
-2
View File
@@ -51,8 +51,6 @@ function defaultState(): State {
d3Selection: null, d3Selection: null,
d3ZoomHandler: null, d3ZoomHandler: null,
viewportInitialized: false,
minZoom: 0.5, minZoom: 0.5,
maxZoom: 2, maxZoom: 2,
+3 -2
View File
@@ -1,5 +1,6 @@
import type { CSSProperties, ComputedRef, ToRefs } from 'vue' import type { CSSProperties, ComputedRef, ToRefs } from 'vue'
import type { KeyFilter } from '@vueuse/core' import type { KeyFilter } from '@vueuse/core'
import type { ViewportHelper } from '../composables'
import type { import type {
Dimensions, Dimensions,
ElementData, ElementData,
@@ -57,8 +58,6 @@ export interface State extends Omit<FlowOptions, 'id' | 'modelValue'> {
readonly d3Selection: D3Selection | null readonly d3Selection: D3Selection | null
readonly d3ZoomHandler: D3ZoomHandler | null readonly d3ZoomHandler: D3ZoomHandler | null
viewportInitialized: boolean
/** use setMinZoom action to change minZoom */ /** use setMinZoom action to change minZoom */
minZoom: number minZoom: number
/** use setMaxZoom action to change maxZoom */ /** use setMaxZoom action to change maxZoom */
@@ -291,6 +290,8 @@ export interface Actions extends ViewportFunctions {
getConnectedEdges: (nodesOrId: Node[] | string) => GraphEdge[] getConnectedEdges: (nodesOrId: Node[] | string) => GraphEdge[]
/** pan the viewport; return indicates if a transform has happened or not */ /** pan the viewport; return indicates if a transform has happened or not */
panBy: (delta: XYPosition) => boolean panBy: (delta: XYPosition) => boolean
/** viewport helper instance */
viewportHelper: ComputedRef<ViewportHelper>
/** reset state to defaults */ /** reset state to defaults */
$reset: () => void $reset: () => void
+3 -4
View File
@@ -8,20 +8,19 @@ import { VueFlow } from '@vue-flow/core'
import type { FlowProps } from '@vue-flow/core' import type { FlowProps } from '@vue-flow/core'
function mountVueFlow(props?: FlowProps, attrs?: Record<string, any>, slots?: Record<string, any>) { function mountVueFlow(props?: FlowProps, attrs?: Record<string, any>, slots?: Record<string, any>) {
cy.mount(VueFlow as any, { cy.mount(VueFlow, {
props: { props: {
id: 'test', id: 'test',
fitViewOnInit: true, fitViewOnInit: true,
...props, ...props,
} as FlowProps, } as FlowProps,
attrs: { attrs: {
key: 'flowy',
style: { style: {
height: '100vh', height: '100vh',
width: '100vw', width: '100vw',
}, } as CSSStyleDeclaration,
...attrs, ...attrs,
} as Record<string, any>, },
slots, slots,
}) })
} }