181 lines
5.9 KiB
TypeScript
181 lines
5.9 KiB
TypeScript
import { Component, computed, defineComponent, ref } from 'vue';
|
|
|
|
import store from '../../store';
|
|
import { Edge, EdgeProps, Position, WrapEdgeProps } from '../../types';
|
|
import { onMouseDown } from '../Handle/handler';
|
|
import { EdgeAnchor } from './EdgeAnchor';
|
|
|
|
export default (EdgeComponent: any): Component<EdgeProps> => {
|
|
return defineComponent({
|
|
components: { EdgeComponent },
|
|
props: WrapEdgeProps,
|
|
setup(props) {
|
|
const pinia = store();
|
|
const updating = ref<boolean>(false);
|
|
const inactive = !props.elementsSelectable && !props.onClick;
|
|
const edgeClasses = computed(() => [
|
|
'react-flow__edge',
|
|
`react-flow__edge-${props.type}`,
|
|
{ selected: props.selected, animated: props.animated, inactive, updating: updating.value }
|
|
]);
|
|
|
|
const edgeElement = computed<Edge>(() => {
|
|
const el: Edge = {
|
|
id: props.id || '',
|
|
source: props.source || '',
|
|
target: props.target || '',
|
|
type: props.type
|
|
};
|
|
|
|
if (props.sourceHandleId) {
|
|
el.sourceHandle = props.sourceHandleId;
|
|
}
|
|
|
|
if (props.targetHandleId) {
|
|
el.targetHandle = props.targetHandleId;
|
|
}
|
|
|
|
if (typeof props.data !== 'undefined') {
|
|
el.data = props.data;
|
|
}
|
|
|
|
return el;
|
|
});
|
|
|
|
const onEdgeClick = (event: MouseEvent) => {
|
|
if (props.elementsSelectable) {
|
|
pinia.unsetNodesSelection();
|
|
pinia.addSelectedElements(edgeElement.value as any);
|
|
}
|
|
|
|
if (props.onClick) props.onClick?.(event, edgeElement.value);
|
|
};
|
|
|
|
const onEdgeContextMenu = (event: MouseEvent) => {
|
|
if (typeof props.onContextMenu === 'function') props.onContextMenu?.(event, edgeElement.value);
|
|
};
|
|
|
|
const onEdgeMouseEnter = (event: MouseEvent) => {
|
|
if (typeof props.onMouseEnter === 'function') props.onMouseEnter?.(event, edgeElement.value);
|
|
};
|
|
|
|
const onEdgeMouseMove = (event: MouseEvent) => {
|
|
if (typeof props.onMouseMove === 'function') props.onMouseMove?.(event, edgeElement.value);
|
|
};
|
|
|
|
const onEdgeMouseLeave = (event: MouseEvent) => {
|
|
if (typeof props.onMouseLeave === 'function') props.onMouseLeave?.(event, edgeElement.value);
|
|
};
|
|
|
|
const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
|
|
const nodeId = isSourceHandle ? props.target : props.source;
|
|
const handleId = isSourceHandle ? props.targetHandleId : props.sourceHandleId;
|
|
const isValidConnection = () => true;
|
|
const isTarget = isSourceHandle;
|
|
|
|
props.onEdgeUpdateStart?.(event, edgeElement.value);
|
|
|
|
const _onEdgeUpdate = props.onEdgeUpdateEnd
|
|
? (evt: MouseEvent) => {
|
|
if (props.onEdgeUpdateEnd) props.onEdgeUpdateEnd(evt, edgeElement.value);
|
|
}
|
|
: undefined;
|
|
|
|
onMouseDown(
|
|
event,
|
|
handleId,
|
|
nodeId || '',
|
|
pinia.setConnectionNodeId,
|
|
pinia.setConnectionPosition,
|
|
props.onConnectEdge as any,
|
|
isTarget,
|
|
isValidConnection,
|
|
pinia.connectionMode,
|
|
isSourceHandle ? 'target' : 'source',
|
|
_onEdgeUpdate
|
|
);
|
|
};
|
|
|
|
const onEdgeUpdaterSourceMouseDown = (event: MouseEvent) => {
|
|
handleEdgeUpdater(event, true);
|
|
};
|
|
|
|
const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => {
|
|
handleEdgeUpdater(event, false);
|
|
};
|
|
|
|
const onEdgeUpdaterMouseEnter = () => (updating.value = true);
|
|
const onEdgeUpdaterMouseOut = () => (updating.value = false);
|
|
|
|
if (props.isHidden) {
|
|
return null;
|
|
}
|
|
|
|
return () => (
|
|
<g
|
|
class={edgeClasses.value}
|
|
onClick={onEdgeClick}
|
|
onContextmenu={onEdgeContextMenu}
|
|
onMouseenter={onEdgeMouseEnter}
|
|
onMousemove={onEdgeMouseMove}
|
|
onMouseleave={onEdgeMouseLeave}
|
|
>
|
|
<EdgeComponent
|
|
id={props.id}
|
|
source={props.source}
|
|
target={props.target}
|
|
selected={props.selected}
|
|
animated={props.animated}
|
|
label={props.label}
|
|
labelStyle={props.labelStyle}
|
|
labelShowBg={props.labelShowBg}
|
|
labelBgStyle={props.labelBgStyle}
|
|
labelBgPadding={props.labelBgPadding}
|
|
labelBgBorderRadius={props.labelBgBorderRadius}
|
|
data={props.data}
|
|
style={props.style}
|
|
arrowHeadType={props.arrowHeadType}
|
|
sourceX={props.sourceX}
|
|
sourceY={props.sourceY}
|
|
targetX={props.targetX}
|
|
targetY={props.targetY}
|
|
sourcePosition={props.sourcePosition}
|
|
targetPosition={props.targetPosition}
|
|
markerEndId={props.markerEndId}
|
|
sourceHandleId={props.sourceHandleId}
|
|
targetHandleId={props.targetHandleId}
|
|
/>
|
|
{props.handleEdgeUpdate && (
|
|
<g
|
|
onMousedown={onEdgeUpdaterSourceMouseDown}
|
|
onMouseenter={onEdgeUpdaterMouseEnter}
|
|
onMouseout={onEdgeUpdaterMouseOut}
|
|
>
|
|
<EdgeAnchor
|
|
position={props.sourcePosition as Position}
|
|
centerX={props.sourceX as number}
|
|
centerY={props.sourceY as number}
|
|
radius={props.edgeUpdaterRadius}
|
|
/>
|
|
</g>
|
|
)}
|
|
{props.handleEdgeUpdate && (
|
|
<g
|
|
onMousedown={onEdgeUpdaterTargetMouseDown}
|
|
onMouseenter={onEdgeUpdaterMouseEnter}
|
|
onMouseout={onEdgeUpdaterMouseOut}
|
|
>
|
|
<EdgeAnchor
|
|
position={props.sourcePosition as Position}
|
|
centerX={props.sourceX as number}
|
|
centerY={props.sourceY as number}
|
|
radius={props.edgeUpdaterRadius}
|
|
/>
|
|
</g>
|
|
)}
|
|
</g>
|
|
);
|
|
}
|
|
});
|
|
};
|