Files
vue-flow/src/components/Edges/wrapEdge.tsx
2021-07-09 19:30:47 +02:00

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>
);
}
});
};