update: Add injection keys

This commit is contained in:
Braks
2021-10-19 19:23:30 +02:00
parent 1853c21353
commit a895853b64
19 changed files with 113 additions and 133 deletions

View File

@@ -2,50 +2,26 @@ import { ElementId, Elements, Position } from '../../src'
const nodeWidth = 80
const nodeGapWidth = nodeWidth * 2
const nodeStyle = { width: nodeWidth + 'px', fontSize: '11px', color: 'white' }
const nodeStyle = { width: `${nodeWidth}px`, fontSize: '11px', color: 'white' }
const sourceTargetPositions = [
{ source: Position.Bottom, target: Position.Top },
{ source: Position.Right, target: Position.Left }
{ source: Position.Right, target: Position.Left },
]
const nodeColors = [
['#1e9e99', '#4cb3ac', '#6ec9c0', '#8ddfd4'],
['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8']
['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8'],
]
const edgeTypes = ['default', 'step', 'smoothstep', 'straight']
const offsets = [
{
x: 0,
y: -nodeGapWidth
y: -nodeGapWidth,
},
{
x: nodeGapWidth,
y: -nodeGapWidth
y: -nodeGapWidth,
},
{
x: nodeGapWidth,
y: 0
},
{
x: nodeGapWidth,
y: nodeGapWidth
},
{
x: 0,
y: nodeGapWidth
},
{
x: -nodeGapWidth,
y: nodeGapWidth
},
{
x: -nodeGapWidth,
y: 0
},
{
x: -nodeGapWidth,
y: -nodeGapWidth
}
]
let id = 0
@@ -66,7 +42,7 @@ export function getElements(): Elements {
const style = { ...nodeStyle, background: nodeColors[sourceTargetIndex][edgeTypeIndex] }
const sourcePosition = {
x: offsetIndex * nodeWidth * 4,
y: edgeTypeIndex * 300 + sourceTargetIndex * edgeTypes.length * 300
y: edgeTypeIndex * 300 + sourceTargetIndex * edgeTypes.length * 300,
}
const sourceId = getNodeId()
const sourceData = { label: `Source ${sourceId}` }
@@ -76,14 +52,14 @@ export function getElements(): Elements {
data: sourceData,
position: sourcePosition,
sourcePosition: currSourceTargetPos.source,
targetPosition: currSourceTargetPos.target
targetPosition: currSourceTargetPos.target,
}
const targetId = getNodeId()
const targetData = { label: `Target ${targetId}` }
const targetPosition = {
x: sourcePosition.x + currOffset.x,
y: sourcePosition.y + currOffset.y
y: sourcePosition.y + currOffset.y,
}
const targetNode = {
id: targetId,
@@ -91,7 +67,7 @@ export function getElements(): Elements {
data: targetData,
position: targetPosition,
sourcePosition: currSourceTargetPos.source,
targetPosition: currSourceTargetPos.target
targetPosition: currSourceTargetPos.target,
}
initialElements.push(sourceNode)

View File

@@ -1,8 +1,8 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { ConnectionLineType, CustomConnectionLine, HandleElement, Node, Position, RevueFlowStore } from '~/types'
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import { ConnectionLineType, CustomConnectionLine, HandleElement, Node, Position } from '~/types'
import { getBezierPath, getSmoothStepPath } from '~/components/Edges/utils'
import { Hooks, Store } from '~/context/symbols'
interface ConnectionLineProps {
sourceNode: Node
@@ -16,8 +16,8 @@ const props = withDefaults(defineProps<ConnectionLineProps>(), {
connectionLineStyle: () => ({}),
})
const hooks = inject<RevueFlowHooks>('hooks')!
const store = inject<RevueFlowStore>('store')!
const hooks = inject(Hooks)!
const store = inject(Store)!
const sourceHandle =
store.connectionHandleId && store.connectionHandleType

View File

@@ -1,10 +1,10 @@
<script lang="ts" setup>
import EdgeAnchor from './EdgeAnchor.vue'
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import { getEdgePositions, getHandle, getSourceTargetNodes, isEdgeVisible } from '~/container/EdgeRenderer/utils'
import { isEdge } from '~/utils/graph'
import { ConnectionMode, Dimensions, Edge, EdgeType, Elements, Position, RevueFlowStore, Transform } from '~/types'
import { ConnectionMode, Dimensions, Edge, EdgeType, Elements, Position, Transform } from '~/types'
import { onMouseDown } from '~/components/Handle/utils'
import { Hooks, Store } from '~/context/symbols'
interface EdgeProps {
type: EdgeType
@@ -25,8 +25,8 @@ const props = withDefaults(defineProps<EdgeProps>(), {
onlyRenderVisibleElements: false,
})
const store = inject<RevueFlowStore>('store')!
const hooks = inject<RevueFlowHooks>('hooks')!
const store = inject(Store)!
const hooks = inject(Hooks)!
hooks.connect.on((connection) => {
hooks.edgeUpdate.trigger({ edge: props.edge, connection })

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { ElementId, Position, RevueFlowStore } from '~/types'
import { ElementId, Position } from '~/types'
import { onMouseDown, ValidConnectionFunc } from '~/components/Handle/utils'
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import { Hooks, Store } from '~/context/symbols'
interface HandleProps {
id?: string
@@ -18,8 +18,8 @@ const props = withDefaults(defineProps<HandleProps>(), {
connectable: true,
})
const store = inject<RevueFlowStore>('store')!
const hooks = inject<RevueFlowHooks>('hooks')!
const store = inject(Store)!
const hooks = inject(Hooks)!
const nodeId = inject<ElementId>('NodeIdContext')!
const onMouseDownHandler = (event: MouseEvent) =>

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { DraggableEventListener } from '@braks/revue-draggable'
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import { Node, NodeDimensionUpdate, NodeType, RevueFlowStore } from '~/types'
import { Node, NodeDimensionUpdate, NodeType } from '~/types'
import { Hooks, Store } from '~/context/symbols'
interface NodeProps {
node: Node
@@ -21,8 +21,8 @@ const props = withDefaults(defineProps<NodeProps>(), {
selectNodesOnDrag: true,
})
const store = inject<RevueFlowStore>('store')!
const hooks = inject<RevueFlowHooks>('hooks')!
const store = inject(Store)!
const hooks = inject(Hooks)!
provide('NodeIdContext', props.node.id)
const nodeElement = templateRef<HTMLDivElement>('node-element', null)

View File

@@ -1,8 +1,8 @@
<script lang="ts" setup>
import { DraggableEventListener } from '@braks/revue-draggable'
import { Node, RevueFlowStore } from '~/types'
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import { Node } from '~/types'
import { isNode } from '~/utils/graph'
import { Hooks, Store } from '~/context/symbols'
interface NodesSelectionProps {
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void
@@ -13,8 +13,8 @@ interface NodesSelectionProps {
const props = defineProps<NodesSelectionProps>()
const store = inject<RevueFlowStore>('store')!
const hooks = inject<RevueFlowHooks>('hooks')!
const store = inject(Store)!
const hooks = inject(Hooks)!
const selectedNodes = computed(() =>
store.selectedElements

View File

@@ -1,9 +1,9 @@
<script lang="ts" setup>
import SelectionRect from './SelectionRect.vue'
import { RevueFlowStore } from '~/types'
import { getMousePosition } from '~/components/UserSelection/utils'
import { Store } from '~/context/symbols'
const store = inject<RevueFlowStore>('store')!
const store = inject(Store)!
const el = templateRef('user-selection', null)
const onMouseDown = (event: MouseEvent) => {

View File

@@ -12,10 +12,10 @@ import {
Transform,
TranslateExtent,
} from '~/types'
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import { clamp } from '~/utils'
import useKeyPress from '~/hooks/useKeyPress'
// import { onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils/graph'
import { Hooks } from '~/context/symbols'
import { onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils/graph'
const viewChanged = (prevTransform: FlowTransform, eventTransform: ZoomTransform): boolean =>
prevTransform.x !== eventTransform.x || prevTransform.y !== eventTransform.y || prevTransform.zoom !== eventTransform.k
@@ -73,7 +73,7 @@ export default function (
panOnScrollMode = PanOnScrollMode.Free,
paneMoveable = true,
} = options
const hooks = inject<RevueFlowHooks>('hooks')!
const hooks = inject(Hooks)!
const prevTransform = ref<FlowTransform>({ x: 0, y: 0, zoom: 0 })
const clampedX = clamp(defaultPosition[0], translateExtent[0][0], translateExtent[1][0])

View File

@@ -4,15 +4,8 @@ import { getSourceTargetNodes } from './utils'
import MarkerDefinitions from './MarkerDefinitions.vue'
import Edge from '~/components/Edges/Edge.vue'
import ConnectionLine from '~/components/ConnectionLine/ConnectionLine.vue'
import {
ConnectionLineType,
ConnectionMode,
CustomConnectionLine,
Dimensions,
EdgeType,
RevueFlowStore,
Transform,
} from '~/types'
import { ConnectionLineType, ConnectionMode, CustomConnectionLine, Dimensions, EdgeType, Transform } from '~/types'
import { Store } from '~/context/symbols'
interface EdgeRendererProps {
edgeTypes: Record<string, EdgeType>
@@ -36,7 +29,7 @@ const props = withDefaults(defineProps<EdgeRendererProps>(), {
connectionLineType: ConnectionLineType.Bezier,
})
const store = inject<RevueFlowStore>('store')!
const store = inject(Store)!
const sourceNode = computed(() => store.nodes.find((n) => n.id === store.connectionNodeId))
const connectionLineVisible = computed(

View File

@@ -11,7 +11,6 @@ import {
ConnectionMode,
Elements,
PanOnScrollMode,
RevueFlowStore,
NodeType,
EdgeType,
CustomConnectionLine,
@@ -19,13 +18,14 @@ import {
TranslateExtent,
NodeExtent,
} from '~/types'
import { RevueFlowHooks, useRevueFlow } from '~/hooks/RevueFlowHooks'
import configureStore from '~/store/configure-store'
import { initialState } from '~/store'
import { DefaultNode, InputNode, OutputNode } from '~/components/Nodes'
import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge } from '~/components/Edges'
import { createEdgeTypes } from '~/container/EdgeRenderer/utils'
import { createNodeTypes } from '~/container/NodeRenderer/utils'
import { useHooks } from '~/hooks/RevueFlowHooks'
import { Hooks, Store } from '~/context/symbols'
export interface FlowProps {
elements: Elements
@@ -101,7 +101,7 @@ const props = withDefaults(defineProps<FlowProps>(), {
paneMoveable: true,
edgeUpdaterRadius: 10,
})
const emit = defineEmits(Object.keys(useRevueFlow()))
const emit = defineEmits(Object.keys(useHooks()))
const defaultNodeTypes: Record<string, NodeType> = {
input: InputNode as NodeType,
@@ -116,13 +116,13 @@ const defaultEdgeTypes: Record<string, EdgeType> = {
smoothstep: SmoothStepEdge as EdgeType,
}
let store = inject<RevueFlowStore>('store')!
let store = inject(Store)!
if (!store) {
store = configureStore({
...initialState,
...props,
})()
provide<RevueFlowStore>('store', store)
provide(Store, store)
}
const init = () => {
@@ -138,8 +138,8 @@ onBeforeUnmount(() => store?.$dispose())
onUpdated(() => init())
init()
const hooks = useRevueFlow().bind(emit)
provide<RevueFlowHooks>('hooks', hooks)
const hooks = useHooks().bind(emit)
provide(Hooks, hooks)
const nodeTypes = createNodeTypes({ ...defaultNodeTypes, ...props.nodeTypes })
const edgeTypes = createEdgeTypes({ ...defaultEdgeTypes, ...props.edgeTypes })

View File

@@ -1,7 +1,8 @@
<script lang="ts" setup>
import Node from '~/components/Nodes/Node.vue'
import { NodeType, Node as TNode, Transform, Dimensions, RevueFlowStore } from '~/types'
import { NodeType, Node as TNode, Transform, Dimensions } from '~/types'
import { getNodesInside } from '~/utils/graph'
import { Store } from '~/context/symbols'
interface NodeRendererProps {
nodeTypes: Record<string, NodeType>
@@ -14,7 +15,7 @@ const props = withDefaults(defineProps<NodeRendererProps>(), {
dimensions: () => ({ width: 0, height: 0 }),
})
const store = inject<RevueFlowStore>('store')!
const store = inject(Store)!
const getNodes = computed(() =>
store.onlyRenderVisibleElements

View File

@@ -1,10 +1,10 @@
<script lang="ts" setup>
import { RevueFlowHooks } from '~/hooks/RevueFlowHooks'
import useKeyPress from '~/hooks/useKeyPress'
import { KeyCode, RevueFlowStore } from '~/types'
import { KeyCode } from '~/types'
import useGlobalKeyHandler from '~/hooks/useGlobalKeyHandler'
import NodesSelection from '~/components/NodesSelection/NodesSelection.vue'
import UserSelection from '~/components/UserSelection/UserSelection.vue'
import { Hooks, Store } from '~/context/symbols'
interface SelectionPaneProps {
selectionKeyCode?: KeyCode
@@ -16,8 +16,8 @@ const props = withDefaults(defineProps<SelectionPaneProps>(), {
deleteKeyCode: 'Backspace',
multiSelectionKeyCode: 'Meta',
})
const store = inject<RevueFlowStore>('store')!
const hooks = inject<RevueFlowHooks>('hooks')!
const store = inject(Store)!
const hooks = inject(Hooks)!
const keyPressed = useKeyPress(props.selectionKeyCode)
const onClick = (event: MouseEvent) => {

View File

@@ -1,8 +1,9 @@
<script lang="ts" setup>
import { KeyCode, PanOnScrollMode, RevueFlowStore } from '~/types'
import { KeyCode, PanOnScrollMode } from '~/types'
import useZoom from '~/composables/useZoom'
import useResizeHandler from '~/hooks/useResizeHandler'
import useZoomPanHelper from '~/hooks/useZoomPanHelper'
import { Store } from '~/context/symbols'
interface ZoomPaneProps {
selectionKeyCode?: KeyCode
@@ -31,7 +32,7 @@ const props = withDefaults(defineProps<ZoomPaneProps>(), {
panOnScrollMode: PanOnScrollMode.Free,
paneMoveable: true,
})
const store = inject<RevueFlowStore>('store')!
const store = inject(Store)!
const zoomPaneEl = templateRef<HTMLDivElement>('zoom-pane', null)
const { transform, d3Selection, d3Zoom } = useZoom(zoomPaneEl, props, (initD3ZoomPayload) => store.initD3Zoom(initD3ZoomPayload))

5
src/context/symbols.ts Normal file
View File

@@ -0,0 +1,5 @@
import { InjectionKey } from 'vue'
import { FlowHooks, FlowStore } from '~/types'
export const Store: InjectionKey<FlowStore> = Symbol('store')
export const Hooks: InjectionKey<FlowHooks> = Symbol('hooks')

View File

@@ -1,51 +1,8 @@
// global hooks
import { EventHook } from '@vueuse/core'
import { Connection, Edge, Elements, FlowTransform, Node, OnConnectStartParams, OnLoadParams } from '../types'
import { Connection, Edge, Elements, FlowHooks, FlowTransform, Node, OnConnectStartParams, OnLoadParams } from '~/types'
export interface RevueFlowHooks {
elementClick: EventHook<{ event: MouseEvent; element: Node | Edge }>
elementsRemove: EventHook<Elements>
nodeDoubleClick: EventHook<{ event: MouseEvent; node: Node }>
nodeClick: EventHook<{ event: MouseEvent; node: Node }>
nodeMouseEnter: EventHook<{ event: MouseEvent; node: Node }>
nodeMouseMove: EventHook<{ event: MouseEvent; node: Node }>
nodeMouseLeave: EventHook<{ event: MouseEvent; node: Node }>
nodeContextMenu: EventHook<{ event: MouseEvent; node: Node }>
nodeDragStart: EventHook<{ event: MouseEvent; node: Node }>
nodeDrag: EventHook<{ event: MouseEvent; node: Node }>
nodeDragStop: EventHook<{ event: MouseEvent; node: Node }>
connect: EventHook<Connection>
connectStart: EventHook<{
event: MouseEvent
params: OnConnectStartParams
}>
connectStop: EventHook<MouseEvent>
connectEnd: EventHook<MouseEvent>
load: EventHook<OnLoadParams>
move: EventHook<FlowTransform | undefined>
moveStart: EventHook<FlowTransform | undefined>
moveEnd: EventHook<FlowTransform | undefined>
selectionChange: EventHook<Elements | null>
selectionDragStart: EventHook<{ event: MouseEvent; nodes: Node[] }>
selectionDrag: EventHook<{ event: MouseEvent; nodes: Node[] }>
selectionDragStop: EventHook<{ event: MouseEvent; nodes: Node[] }>
selectionContextMenu: EventHook<{ event: MouseEvent; nodes: Node[] }>
paneScroll: EventHook<WheelEvent | undefined>
paneClick: EventHook<MouseEvent>
paneContextMenu: EventHook<MouseEvent>
edgeUpdate: EventHook<{ edge: Edge; connection: Connection }>
edgeContextMenu: EventHook<{ event: MouseEvent; edge: Edge }>
edgeMouseEnter: EventHook<{ event: MouseEvent; edge: Edge }>
edgeMouseMove: EventHook<{ event: MouseEvent; edge: Edge }>
edgeMouseLeave: EventHook<{ event: MouseEvent; edge: Edge }>
edgeDoubleClick: EventHook<{ event: MouseEvent; edge: Edge }>
edgeClick: EventHook<{ event: MouseEvent; edge: Edge }>
edgeUpdateStart: EventHook<{ event: MouseEvent; edge: Edge }>
edgeUpdateEnd: EventHook<{ event: MouseEvent; edge: Edge }>
}
export const useRevueFlow = (): RevueFlowHooks & { bind: (emit: (event: string, ...args: any[]) => void) => RevueFlowHooks } => {
const eventHooks: RevueFlowHooks = {
export const useHooks = (): FlowHooks & { bind: (emit: (event: string, ...args: any[]) => void) => FlowHooks } => {
const eventHooks: FlowHooks = {
elementClick: createEventHook<{ event: MouseEvent; element: Node | Edge }>(),
elementsRemove: createEventHook<Elements>(),
nodeDoubleClick: createEventHook<{ event: MouseEvent; node: Node }>(),

View File

@@ -1,6 +1,7 @@
import useKeyPress from './useKeyPress'
import { isNode, getConnectedEdges } from '~/utils/graph'
import { Elements, KeyCode, ElementId, FlowElement, RevueFlowStore } from '~/types'
import { Elements, KeyCode, ElementId, FlowElement } from '~/types'
import { Store } from '~/context/symbols'
interface HookParams {
deleteKeyCode: KeyCode
@@ -9,7 +10,7 @@ interface HookParams {
}
export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove = () => {} }: HookParams): void => {
const store = inject<RevueFlowStore>('store')!
const store = inject(Store)!
useKeyPress(deleteKeyCode, (keyPressed) => {
if (keyPressed && store.selectedElements) {

45
src/types/hooks.ts Normal file
View File

@@ -0,0 +1,45 @@
// global hooks
import { EventHook } from '@vueuse/core'
import { Connection, Edge, Elements, FlowTransform, Node, OnConnectStartParams, OnLoadParams } from '../types'
export interface FlowHooks {
elementClick: EventHook<{ event: MouseEvent; element: Node | Edge }>
elementsRemove: EventHook<Elements>
nodeDoubleClick: EventHook<{ event: MouseEvent; node: Node }>
nodeClick: EventHook<{ event: MouseEvent; node: Node }>
nodeMouseEnter: EventHook<{ event: MouseEvent; node: Node }>
nodeMouseMove: EventHook<{ event: MouseEvent; node: Node }>
nodeMouseLeave: EventHook<{ event: MouseEvent; node: Node }>
nodeContextMenu: EventHook<{ event: MouseEvent; node: Node }>
nodeDragStart: EventHook<{ event: MouseEvent; node: Node }>
nodeDrag: EventHook<{ event: MouseEvent; node: Node }>
nodeDragStop: EventHook<{ event: MouseEvent; node: Node }>
connect: EventHook<Connection>
connectStart: EventHook<{
event: MouseEvent
params: OnConnectStartParams
}>
connectStop: EventHook<MouseEvent>
connectEnd: EventHook<MouseEvent>
load: EventHook<OnLoadParams>
move: EventHook<FlowTransform | undefined>
moveStart: EventHook<FlowTransform | undefined>
moveEnd: EventHook<FlowTransform | undefined>
selectionChange: EventHook<Elements | null>
selectionDragStart: EventHook<{ event: MouseEvent; nodes: Node[] }>
selectionDrag: EventHook<{ event: MouseEvent; nodes: Node[] }>
selectionDragStop: EventHook<{ event: MouseEvent; nodes: Node[] }>
selectionContextMenu: EventHook<{ event: MouseEvent; nodes: Node[] }>
paneScroll: EventHook<WheelEvent | undefined>
paneClick: EventHook<MouseEvent>
paneContextMenu: EventHook<MouseEvent>
edgeUpdate: EventHook<{ edge: Edge; connection: Connection }>
edgeContextMenu: EventHook<{ event: MouseEvent; edge: Edge }>
edgeMouseEnter: EventHook<{ event: MouseEvent; edge: Edge }>
edgeMouseMove: EventHook<{ event: MouseEvent; edge: Edge }>
edgeMouseLeave: EventHook<{ event: MouseEvent; edge: Edge }>
edgeDoubleClick: EventHook<{ event: MouseEvent; edge: Edge }>
edgeClick: EventHook<{ event: MouseEvent; edge: Edge }>
edgeUpdateStart: EventHook<{ event: MouseEvent; edge: Edge }>
edgeUpdateEnd: EventHook<{ event: MouseEvent; edge: Edge }>
}

View File

@@ -6,3 +6,4 @@ export * from './handle'
export * from './node'
export * from './panel'
export * from './store'
export * from './hooks'

View File

@@ -7,7 +7,7 @@ import { Node, NodeExtent, TranslateExtent } from './node'
import { RevueFlowActions } from './actions'
import { D3Selection, D3Zoom, D3ZoomHandler } from '~/types/panel'
export interface RevueFlowState {
export interface FlowState {
dimensions: Dimensions
transform: Transform
nodes: Node[]
@@ -51,4 +51,4 @@ export interface RevueFlowState {
onConnectEnd?: OnConnectEndFunc
}
export type RevueFlowStore = Store<string, RevueFlowState, any, RevueFlowActions>
export type FlowStore = Store<string, FlowState, any, RevueFlowActions>