feat: add useStore and useHooks composables that provide default store/hooks
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
export { default as useHandle } from './useHandle'
|
||||
export { default as useHooks } from './useHooks'
|
||||
export * from './useHooks'
|
||||
export { default as useKeyPress } from './useKeyPress'
|
||||
export { default as useUpdateNodeInternals } from './useUpdateNodeInternals'
|
||||
export { default as useZoom } from './useZoom'
|
||||
export { default as useZoomPanHelper } from './useZoomPanHelper'
|
||||
export { default as useStore } from './useStore'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { getHostForElement } from '~/utils'
|
||||
import { Hooks, Store } from '~/context'
|
||||
import { Connection, ConnectionMode, ElementId, HandleType, ValidConnectionFunc } from '~/types'
|
||||
import useStore from '~/composables/useStore'
|
||||
import useHooks from '~/composables/useHooks'
|
||||
|
||||
type Result = {
|
||||
elementBelow: Element | null
|
||||
@@ -10,7 +11,7 @@ type Result = {
|
||||
}
|
||||
|
||||
// checks if element below mouse is a handle and returns connection in form of an object { source: 123, target: 312 }
|
||||
export function checkElementBelowIsValid(
|
||||
export const checkElementBelowIsValid = (
|
||||
event: MouseEvent,
|
||||
connectionMode: ConnectionMode,
|
||||
isTarget: boolean,
|
||||
@@ -18,7 +19,7 @@ export function checkElementBelowIsValid(
|
||||
handleId: ElementId | null,
|
||||
isValidConnection: ValidConnectionFunc,
|
||||
doc: Document,
|
||||
) {
|
||||
) => {
|
||||
const elementBelow = doc.elementFromPoint(event.clientX, event.clientY)
|
||||
const elementBelowIsTarget = elementBelow?.classList.contains('target') || false
|
||||
const elementBelowIsSource = elementBelow?.classList.contains('source') || false
|
||||
@@ -62,14 +63,14 @@ export function checkElementBelowIsValid(
|
||||
return result
|
||||
}
|
||||
|
||||
function resetRecentHandle(hoveredHandle: Element): void {
|
||||
const resetRecentHandle = (hoveredHandle: Element): void => {
|
||||
hoveredHandle?.classList.remove('revue-flow__handle-valid')
|
||||
hoveredHandle?.classList.remove('revue-flow__handle-connecting')
|
||||
}
|
||||
|
||||
export default function () {
|
||||
const store = inject(Store)!
|
||||
const hooks = inject(Hooks)!
|
||||
export default () => {
|
||||
const store = useStore()
|
||||
const hooks = useHooks()
|
||||
|
||||
return (
|
||||
event: MouseEvent,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// global hooks
|
||||
import { Connection, Edge, Elements, FlowHooks, FlowTransform, Node, OnConnectStartParams, OnLoadParams } from '~/types'
|
||||
import { Connection, Edge, Elements, EmitFunc, FlowHooks, FlowTransform, Node, OnConnectStartParams, OnLoadParams } from '~/types'
|
||||
import { Hooks } from '~/context'
|
||||
|
||||
export default (): FlowHooks & { bind: (emit: (event: string, ...args: any[]) => void) => FlowHooks } => {
|
||||
const eventHooks: FlowHooks = {
|
||||
// flow event hooks
|
||||
const hooks = (): FlowHooks => {
|
||||
return {
|
||||
elementClick: createEventHook<{ event: MouseEvent; element: Node | Edge }>(),
|
||||
elementsRemove: createEventHook<Elements>(),
|
||||
nodeDoubleClick: createEventHook<{ event: MouseEvent; node: Node }>(),
|
||||
@@ -43,11 +44,13 @@ export default (): FlowHooks & { bind: (emit: (event: string, ...args: any[]) =>
|
||||
edgeUpdateStart: createEventHook<{ event: MouseEvent; edge: Edge }>(),
|
||||
edgeUpdateEnd: createEventHook<{ event: MouseEvent; edge: Edge }>(),
|
||||
}
|
||||
|
||||
const bind = (emit: (event: string, args: any) => void) => {
|
||||
}
|
||||
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: any) => {
|
||||
emit(key, data)
|
||||
value.on((data: unknown) => {
|
||||
emit(key as keyof FlowHooks, data)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,3 +62,17 @@ export default (): FlowHooks & { bind: (emit: (event: string, ...args: any[]) =>
|
||||
bind,
|
||||
}
|
||||
}
|
||||
|
||||
export default (emit?: EmitFunc) => {
|
||||
let hooks = inject(Hooks)!
|
||||
if (!hooks) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
return hooks
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { FlowOptions } from '~/types'
|
||||
import useFlowStore from '~/store/useFlowStore'
|
||||
import { initialState } from '~/store'
|
||||
import { Store } from '~/context'
|
||||
|
||||
export default (options?: Partial<FlowOptions>) => {
|
||||
let store = inject(Store)!
|
||||
if (!store) {
|
||||
console.warn('store context not found; creating default store')
|
||||
store = useFlowStore({
|
||||
...initialState(),
|
||||
...options,
|
||||
})()
|
||||
provide(Store, store)
|
||||
}
|
||||
|
||||
return store
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ElementId, UpdateNodeInternals } from '~/types'
|
||||
import { Store } from '~/context'
|
||||
import useStore from '~/composables/useStore'
|
||||
|
||||
export default function (): UpdateNodeInternals {
|
||||
const store = inject(Store)!
|
||||
export default (): UpdateNodeInternals => {
|
||||
const store = useStore()
|
||||
|
||||
return (id: ElementId) => {
|
||||
const nodeElement: HTMLDivElement | null = document.querySelector(`.revue-flow__node[data-id="${id}"]`)
|
||||
|
||||
@@ -5,7 +5,8 @@ import { get } from '@vueuse/core'
|
||||
import { FlowTransform, PanOnScrollMode, Transform, UseZoom, UseZoomOptions } from '~/types'
|
||||
import { clamp } from '~/utils'
|
||||
import useKeyPress from '~/composables/useKeyPress'
|
||||
import { Hooks, Store } from '~/context'
|
||||
import useHooks from '~/composables/useHooks'
|
||||
import useStore from '~/composables/useStore'
|
||||
|
||||
const viewChanged = (prevTransform: FlowTransform, eventTransform: ZoomTransform): boolean =>
|
||||
prevTransform.x !== eventTransform.x || prevTransform.y !== eventTransform.y || prevTransform.zoom !== eventTransform.k
|
||||
@@ -16,7 +17,7 @@ const eventToFlowTransform = (eventTransform: ZoomTransform): FlowTransform => (
|
||||
zoom: eventTransform.k,
|
||||
})
|
||||
|
||||
export default function (el: Ref<HTMLDivElement>, options: UseZoomOptions): UseZoom {
|
||||
export default (el: Ref<HTMLDivElement>, options: UseZoomOptions): UseZoom => {
|
||||
const {
|
||||
selectionKeyCode = 'Shift',
|
||||
zoomActivationKeyCode = 'Meta',
|
||||
@@ -30,8 +31,8 @@ export default function (el: Ref<HTMLDivElement>, options: UseZoomOptions): UseZ
|
||||
panOnScrollMode = PanOnScrollMode.Free,
|
||||
paneMoveable = true,
|
||||
} = options
|
||||
const hooks = inject(Hooks)!
|
||||
const store = inject(Store)!
|
||||
const hooks = useHooks()
|
||||
const store = useStore()
|
||||
const prevTransform = ref<FlowTransform>({ x: 0, y: 0, zoom: 0 })
|
||||
|
||||
const clampedX = clamp(defaultPosition[0], store.translateExtent[0][0], store.translateExtent[1][0])
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { zoomIdentity } from 'd3-zoom'
|
||||
import { getRectOfNodes, pointToRendererPoint, getTransformForBounds } from '~/utils/graph'
|
||||
import { FitViewParams, FlowTransform, Rect, UseZoomPanHelper, XYPosition } from '~/types'
|
||||
import { Store } from '~/context'
|
||||
import useStore from '~/composables/useStore'
|
||||
|
||||
const DEFAULT_PADDING = 0.1
|
||||
|
||||
export default function (store = inject(Store)!): UseZoomPanHelper {
|
||||
export default (): UseZoomPanHelper => {
|
||||
const store = useStore()
|
||||
|
||||
return {
|
||||
zoomIn: () => store.d3Selection && store.d3Zoom?.scaleBy(store.d3Selection, 1.2),
|
||||
zoomOut: () => store.d3Selection && store.d3Zoom?.scaleBy(store.d3Selection, 1 / 1.2),
|
||||
|
||||
Reference in New Issue
Block a user