boolean
-
-type Result = {
- elementBelow: Element | null
- isValid: boolean
- connection: Connection
- isHoveringHandle: boolean
-}
-
-// checks if element below mouse is a handle and returns connection in form of an object { source: 123, target: 312 }
-function checkElementBelowIsValid(
- event: MouseEvent,
- connectionMode: ConnectionMode,
- isTarget: boolean,
- nodeId: ElementId,
- 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
-
- const result: Result = {
- elementBelow,
- isValid: false,
- connection: { source: null, target: null, sourceHandle: null, targetHandle: null },
- isHoveringHandle: false,
- }
-
- if (elementBelow && (elementBelowIsTarget || elementBelowIsSource)) {
- result.isHoveringHandle = true
-
- // in strict mode we don't allow target to target or source to source connections
- const isValid =
- connectionMode === ConnectionMode.Strict ? (isTarget && elementBelowIsSource) || (!isTarget && elementBelowIsTarget) : true
-
- if (isValid) {
- const elementBelowNodeId = elementBelow.getAttribute('data-nodeid')
- const elementBelowHandleId = elementBelow.getAttribute('data-handleid')
- const connection: Connection = isTarget
- ? {
- source: elementBelowNodeId,
- sourceHandle: elementBelowHandleId,
- target: nodeId,
- targetHandle: handleId,
- }
- : {
- source: nodeId,
- sourceHandle: handleId,
- target: elementBelowNodeId,
- targetHandle: elementBelowHandleId,
- }
-
- result.connection = connection
- result.isValid = isValidConnection(connection)
- }
- }
-
- return result
-}
-
-function resetRecentHandle(hoveredHandle: Element): void {
- hoveredHandle?.classList.remove('revue-flow__handle-valid')
- hoveredHandle?.classList.remove('revue-flow__handle-connecting')
-}
-
-export function onMouseDown(
- event: MouseEvent,
- store: FlowStore,
- hooks: {
- connectStart: FlowHooks['connectStart']
- connectStop: FlowHooks['connectStop']
- connectEnd: FlowHooks['connectEnd']
- connect: FlowHooks['connect']
- edgeUpdateEnd: FlowHooks['edgeUpdateEnd']
- },
- handleId: ElementId,
- nodeId: ElementId,
- isTarget: boolean,
- isValidConnection: ValidConnectionFunc = () => {
- return true
- },
- elementEdgeUpdaterType?: HandleType,
-): void {
- const revueFlowNode = (event.target as Element).closest('.revue-flow')
- // when revue-flow is used inside a shadow root we can't use document
- const doc = getHostForElement(event.target as HTMLElement)
-
- if (!doc) {
- return
- }
-
- const elementBelow = doc.elementFromPoint(event.clientX, event.clientY)
- const elementBelowIsTarget = elementBelow?.classList.contains('target')
- const elementBelowIsSource = elementBelow?.classList.contains('source')
-
- if (!revueFlowNode || (!elementBelowIsTarget && !elementBelowIsSource && !elementEdgeUpdaterType)) {
- return
- }
-
- const handleType = elementEdgeUpdaterType || (elementBelowIsTarget ? 'target' : 'source')
- const containerBounds = revueFlowNode.getBoundingClientRect()
- let recentHoveredHandle: Element
-
- store.connectionPosition.x = event.clientX - containerBounds.left
- store.connectionPosition.y = event.clientY - containerBounds.top
-
- store.setConnectionNodeId({
- connectionNodeId: nodeId,
- connectionHandleId: handleId,
- connectionHandleType: handleType,
- })
- hooks.connectStart.trigger({ event, params: { nodeId, handleId, handleType } })
-
- function onMouseMove(event: MouseEvent) {
- store.connectionPosition.x = event.clientX - containerBounds.left
- store.connectionPosition.y = event.clientY - containerBounds.top
-
- const { connection, elementBelow, isValid, isHoveringHandle } = checkElementBelowIsValid(
- event,
- store.connectionMode,
- isTarget,
- nodeId,
- handleId,
- isValidConnection,
- doc,
- )
-
- if (!isHoveringHandle) {
- return resetRecentHandle(recentHoveredHandle)
- }
-
- const isOwnHandle = connection.source === connection.target
-
- if (!isOwnHandle && elementBelow) {
- recentHoveredHandle = elementBelow
- elementBelow.classList.add('revue-flow__handle-connecting')
- elementBelow.classList.toggle('revue-flow__handle-valid', isValid)
- }
- }
-
- function onMouseUp(event: MouseEvent) {
- const { connection, isValid } = checkElementBelowIsValid(
- event,
- store.connectionMode,
- isTarget,
- nodeId,
- handleId,
- isValidConnection,
- doc,
- )
-
- hooks.connectStop.trigger(event)
-
- if (isValid) {
- hooks.connect.trigger(connection)
- }
-
- hooks.connectEnd.trigger(event)
-
- if (elementEdgeUpdaterType) {
- hooks.edgeUpdateEnd.trigger({ event } as any)
- }
-
- resetRecentHandle(recentHoveredHandle)
- store.setConnectionNodeId({ connectionNodeId: undefined, connectionHandleId: undefined, connectionHandleType: undefined })
- store.connectionPosition = { x: NaN, y: NaN }
-
- doc.removeEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject)
- doc.removeEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject)
- }
-
- doc.addEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject)
- doc.addEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject)
-}
diff --git a/src/components/Nodes/Node.vue b/src/components/Nodes/Node.vue
index 65d64ad5..5e24c7a6 100644
--- a/src/components/Nodes/Node.vue
+++ b/src/components/Nodes/Node.vue
@@ -95,7 +95,6 @@ const onDragStop: DraggableEventListener = ({ event }) => {
if (props.selectable && !props.selectNodesOnDrag && !props.selected) {
store.addSelectedElements([n])
}
-
hooks.nodeClick.trigger({ event, node: n })
return
@@ -163,8 +162,7 @@ onMounted(() => {
@contextmenu="onContextMenuHandler"
@click="onSelectNodeHandler"
>
-
+ >
+
+
diff --git a/src/composables/index.ts b/src/composables/index.ts
index 03170c98..fbb01f9b 100644
--- a/src/composables/index.ts
+++ b/src/composables/index.ts
@@ -1,7 +1,6 @@
-export { default as useGlobalKeyHandler } from './useGlobalKeyHandler'
+export { default as useHandle } from './useHandle'
export { default as useHooks } from './useHooks'
export { default as useKeyPress } from './useKeyPress'
-export { default as useResizeHandler } from './useResizeHandler'
export { default as useUpdateNodeInternals } from './useUpdateNodeInternals'
export { default as useZoom } from './useZoom'
export { default as useZoomPanHelper } from './useZoomPanHelper'
diff --git a/src/composables/useGlobalKeyHandler.ts b/src/composables/useGlobalKeyHandler.ts
deleted file mode 100644
index ebd23dc1..00000000
--- a/src/composables/useGlobalKeyHandler.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import useKeyPress from './useKeyPress'
-import { isNode, getConnectedEdges } from '~/utils/graph'
-import { Elements, KeyCode, ElementId, FlowElement } from '~/types'
-import { Store } from '~/context'
-
-interface HookParams {
- deleteKeyCode: KeyCode
- multiSelectionKeyCode: KeyCode
- onElementsRemove?: (elements: Elements) => void
-}
-
-export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove = () => {} }: HookParams): void => {
- const store = inject(Store)!
-
- useKeyPress(deleteKeyCode, (keyPressed) => {
- if (keyPressed && store.selectedElements) {
- const selectedNodes = store.selectedElements.filter(isNode)
- const connectedEdges = getConnectedEdges(selectedNodes, store.edges)
- const elementsToRemove = [...store.selectedElements, ...connectedEdges].reduce(
- (res, item) => res.set(item.id, item),
- new Map