feat(handle): Add onClick handler
* for touch enabled connections
This commit is contained in:
@@ -4,7 +4,7 @@ import { Position } from '../../types'
|
||||
import { NodeId } from '../../context'
|
||||
import type { HandleProps } from '../../types/handle'
|
||||
|
||||
const { id, hooks } = useVueFlow()
|
||||
const { id, hooks, connectionStartHandle } = useVueFlow()
|
||||
const props = withDefaults(defineProps<HandleProps>(), {
|
||||
type: 'source',
|
||||
position: 'top' as Position,
|
||||
@@ -13,11 +13,12 @@ const props = withDefaults(defineProps<HandleProps>(), {
|
||||
|
||||
const nodeId = inject(NodeId, '')
|
||||
|
||||
const handler = useHandle()
|
||||
const { onMouseDown, onClick } = useHandle()
|
||||
const onMouseDownHandler = (event: MouseEvent) =>
|
||||
handler(event, props.id, nodeId, props.type === 'target', props.isValidConnection, undefined, (connection) =>
|
||||
onMouseDown(event, props.id ?? null, nodeId, props.type === 'target', props.isValidConnection, undefined, (connection) =>
|
||||
hooks.value.connect.trigger(connection),
|
||||
)
|
||||
const onClickHandler = (event: MouseEvent) => onClick(event, props.id ?? null, nodeId, props.type, props.isValidConnection)
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
@@ -38,9 +39,14 @@ export default {
|
||||
source: props.type !== 'target',
|
||||
target: props.type === 'target',
|
||||
connectable: props.connectable,
|
||||
connecting:
|
||||
connectionStartHandle?.nodeId === nodeId &&
|
||||
connectionStartHandle?.handleId === props.id &&
|
||||
connectionStartHandle?.type === props.type,
|
||||
},
|
||||
]"
|
||||
@mousedown="onMouseDownHandler"
|
||||
@click="onClickHandler"
|
||||
>
|
||||
<slot :node-id="nodeId" v-bind="props"></slot>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@ export const checkElementBelowIsValid = (
|
||||
connectionMode: ConnectionMode,
|
||||
isTarget: boolean,
|
||||
nodeId: string,
|
||||
handleId: string,
|
||||
handleId: string | null,
|
||||
isValidConnection: ValidConnectionFunc,
|
||||
doc: Document,
|
||||
) => {
|
||||
@@ -67,10 +67,10 @@ const resetRecentHandle = (hoveredHandle: Element): void => {
|
||||
hoveredHandle?.classList.remove('vue-flow__handle-connecting')
|
||||
}
|
||||
|
||||
export default (store: FlowStore = useVueFlow().store) =>
|
||||
(
|
||||
export default (store: FlowStore = useVueFlow().store) => {
|
||||
const onMouseDown = (
|
||||
event: MouseEvent,
|
||||
handleId: string,
|
||||
handleId: string | null,
|
||||
nodeId: string,
|
||||
isTarget: boolean,
|
||||
isValidConnection?: ValidConnectionFunc,
|
||||
@@ -173,3 +173,49 @@ export default (store: FlowStore = useVueFlow().store) =>
|
||||
doc.addEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject)
|
||||
doc.addEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject)
|
||||
}
|
||||
|
||||
const onClick = (
|
||||
event: MouseEvent,
|
||||
handleId: string | null,
|
||||
nodeId: string,
|
||||
handleType: HandleType,
|
||||
isValidConnection?: ValidConnectionFunc,
|
||||
) => {
|
||||
if (!store.connectOnClick) return
|
||||
if (!store.connectionStartHandle) {
|
||||
store.hooks.connectStart.trigger({ event, nodeId, handleId, handleType })
|
||||
store.setState({ connectionStartHandle: { nodeId, type: handleType, handleId } })
|
||||
} else {
|
||||
let validConnectFunc: ValidConnectionFunc = isValidConnection ?? (() => true)
|
||||
const node = store.getNode(nodeId)
|
||||
|
||||
if (node && (typeof node.connectable === 'undefined' ? store.nodesConnectable : node.connectable) === false) return
|
||||
if (!isValidConnection) {
|
||||
if (node) validConnectFunc = (handleType !== 'target' ? node.isValidTargetPos : node.isValidSourcePos) ?? (() => true)
|
||||
}
|
||||
const doc = getHostForElement(event.target as HTMLElement)
|
||||
const { connection, isValid } = checkElementBelowIsValid(
|
||||
event as MouseEvent,
|
||||
store.connectionMode,
|
||||
store.connectionStartHandle.type === 'target',
|
||||
store.connectionStartHandle.nodeId,
|
||||
store.connectionStartHandle.handleId || null,
|
||||
validConnectFunc,
|
||||
doc,
|
||||
)
|
||||
|
||||
store.hooks.connectStop.trigger(event)
|
||||
|
||||
if (isValid) store.hooks.connect.trigger(connection)
|
||||
|
||||
store.hooks.connectEnd.trigger(event)
|
||||
|
||||
store.setState({ connectionStartHandle: null })
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
onMouseDown,
|
||||
onClick,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export type OnConnectStartParams = {
|
||||
/** Source node id */
|
||||
nodeId?: string
|
||||
/** Source handle id */
|
||||
handleId?: string
|
||||
handleId: string | null
|
||||
/** Source handle type */
|
||||
handleType?: HandleType
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { CSSProperties, ToRefs } from 'vue'
|
||||
import { GraphEdge, Edge, DefaultEdgeOptions } from "./edge";
|
||||
import { GraphEdge, Edge, DefaultEdgeOptions } from './edge'
|
||||
import { GraphNode, CoordinateExtent, Node } from './node'
|
||||
import { ConnectionLineType, ConnectionMode } from './connection'
|
||||
import { KeyCode, PanOnScrollMode, UseZoomPanHelper } from './zoom'
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ export interface HandleProps {
|
||||
/** Unique id of handle element */
|
||||
id?: string
|
||||
/** Handle type (source / target) {@link HandleType} */
|
||||
type?: string
|
||||
type?: HandleType
|
||||
/** Handle position (top, bottom, left, right) {@link Position} */
|
||||
position?: Position
|
||||
/** A valid connection func {@link ValidConnectionFunc} */
|
||||
|
||||
@@ -72,8 +72,3 @@ export interface NodeProps<T = any> {
|
||||
children?: Node<T>[]
|
||||
dragHandle?: string
|
||||
}
|
||||
|
||||
export type NodeBounds = XYPosition & {
|
||||
width: number | null
|
||||
height: number | null
|
||||
}
|
||||
|
||||
+2
-2
@@ -31,8 +31,8 @@ export const getHandlePosition = (position: Position, rect: Rect, handle?: Handl
|
||||
}
|
||||
}
|
||||
|
||||
export const getHandle = (bounds?: HandleElement[], handleId?: string): HandleElement | undefined => {
|
||||
if (!bounds) return undefined
|
||||
export const getHandle = (bounds: HandleElement[] = [], handleId: string | null): HandleElement | undefined => {
|
||||
if (!bounds.length) return undefined
|
||||
|
||||
// there is no handleId when there are no multiple handles/ handles with ids
|
||||
// so we just pick the first one
|
||||
|
||||
Reference in New Issue
Block a user