feat: add useStore and useHooks composables that provide default store/hooks

This commit is contained in:
Braks
2021-10-20 22:39:54 +02:00
parent 61dc9dea33
commit b2b1fe822f
27 changed files with 174 additions and 128 deletions
+2
View File
@@ -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'
+8 -7
View File
@@ -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,
+25 -8
View File
@@ -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
}
+18
View File
@@ -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
}
+3 -3
View File
@@ -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 -4
View File
@@ -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])
+4 -2
View File
@@ -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),