feat(edges): add interactionWidth option #1580 #1114

This commit is contained in:
moklick
2022-09-07 17:43:36 +02:00
parent 7a96817114
commit 51e957e5db
10 changed files with 62 additions and 61 deletions
+5 -3
View File
@@ -81,9 +81,10 @@ const edges: Edge[] = [
markerEnd: { markerEnd: {
type: MarkerType.ArrowClosed, type: MarkerType.ArrowClosed,
}, },
options: { pathOptions: {
offset: 30, offset: 30,
}, },
interactionWidth: 0,
}, },
{ {
id: 'e3-4', id: 'e3-4',
@@ -93,9 +94,10 @@ const edges: Edge[] = [
markerEnd: { markerEnd: {
type: MarkerType.ArrowClosed, type: MarkerType.ArrowClosed,
}, },
options: { pathOptions: {
borderRadius: 2, borderRadius: 2,
}, },
interactionWidth: 0,
}, },
{ {
@@ -121,7 +123,7 @@ const edges: Edge[] = [
const defaultEdgeOptions = { const defaultEdgeOptions = {
style: { style: {
strokeWidth: 2, strokeWidth: 1,
}, },
}; };
+14 -14
View File
@@ -14,20 +14,8 @@ const BaseEdge = ({
style, style,
markerEnd, markerEnd,
markerStart, markerStart,
interactionWidth = 15,
}: BaseEdgeProps) => { }: BaseEdgeProps) => {
const text = label ? (
<EdgeText
x={centerX}
y={centerY}
label={label}
labelStyle={labelStyle}
labelShowBg={labelShowBg}
labelBgStyle={labelBgStyle}
labelBgPadding={labelBgPadding}
labelBgBorderRadius={labelBgBorderRadius}
/>
) : null;
return ( return (
<> <>
<path <path
@@ -38,7 +26,19 @@ const BaseEdge = ({
markerEnd={markerEnd} markerEnd={markerEnd}
markerStart={markerStart} markerStart={markerStart}
/> />
{text} {interactionWidth && <path d={path} fill="none" strokeWidth={interactionWidth} />}
{label ? (
<EdgeText
x={centerX}
y={centerY}
label={label}
labelStyle={labelStyle}
labelShowBg={labelShowBg}
labelBgStyle={labelBgStyle}
labelBgPadding={labelBgPadding}
labelBgBorderRadius={labelBgBorderRadius}
/>
) : null}
</> </>
); );
}; };
@@ -143,7 +143,8 @@ const BezierEdge = memo(
style, style,
markerEnd, markerEnd,
markerStart, markerStart,
options, pathOptions,
interactionWidth,
}: BezierEdgeProps) => { }: BezierEdgeProps) => {
const params = { const params = {
sourceX, sourceX,
@@ -152,7 +153,7 @@ const BezierEdge = memo(
targetX, targetX,
targetY, targetY,
targetPosition, targetPosition,
curvature: options?.curvature, curvature: pathOptions?.curvature,
}; };
const path = getBezierPath(params); const path = getBezierPath(params);
const [centerX, centerY] = getBezierCenter(params); const [centerX, centerY] = getBezierCenter(params);
@@ -171,6 +172,7 @@ const BezierEdge = memo(
style={style} style={style}
markerEnd={markerEnd} markerEnd={markerEnd}
markerStart={markerStart} markerStart={markerStart}
interactionWidth={interactionWidth}
/> />
); );
} }
@@ -117,6 +117,7 @@ const SimpleBezierEdge = memo(
style, style,
markerEnd, markerEnd,
markerStart, markerStart,
interactionWidth,
}: EdgeProps) => { }: EdgeProps) => {
const params = { const params = {
sourceX, sourceX,
@@ -143,6 +144,7 @@ const SimpleBezierEdge = memo(
style={style} style={style}
markerEnd={markerEnd} markerEnd={markerEnd}
markerStart={markerStart} markerStart={markerStart}
interactionWidth={interactionWidth}
/> />
); );
} }
@@ -202,7 +202,8 @@ const SmoothStepEdge = memo(
targetPosition = Position.Top, targetPosition = Position.Top,
markerEnd, markerEnd,
markerStart, markerStart,
options, pathOptions,
interactionWidth,
}: SmoothStepEdgeProps) => { }: SmoothStepEdgeProps) => {
const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
@@ -213,8 +214,8 @@ const SmoothStepEdge = memo(
targetX, targetX,
targetY, targetY,
targetPosition, targetPosition,
borderRadius: options?.borderRadius, borderRadius: pathOptions?.borderRadius,
offset: options?.offset, offset: pathOptions?.offset,
}); });
return ( return (
@@ -231,6 +232,7 @@ const SmoothStepEdge = memo(
style={style} style={style}
markerEnd={markerEnd} markerEnd={markerEnd}
markerStart={markerStart} markerStart={markerStart}
interactionWidth={interactionWidth}
/> />
); );
} }
@@ -1,9 +1,14 @@
import { memo } from 'react'; import { memo, useMemo } from 'react';
import { EdgeSmoothStepProps } from '../../types'; import { SmoothStepEdgeProps } from '../../types';
import SmoothStepEdge from './SmoothStepEdge'; import SmoothStepEdge from './SmoothStepEdge';
const StepEdge = memo((props: EdgeSmoothStepProps) => <SmoothStepEdge {...props} borderRadius={0} />); const StepEdge = memo((props: SmoothStepEdgeProps) => (
<SmoothStepEdge
{...props}
pathOptions={useMemo(() => ({ borderRadius: 0, offset: props.pathOptions?.offset }), [props.pathOptions?.offset])}
/>
));
StepEdge.displayName = 'StepEdge'; StepEdge.displayName = 'StepEdge';
@@ -18,17 +18,17 @@ const StraightEdge = memo(
style, style,
markerEnd, markerEnd,
markerStart, markerStart,
interactionWidth,
}: EdgeProps) => { }: EdgeProps) => {
const yOffset = Math.abs(targetY - sourceY) / 2; const yOffset = Math.abs(targetY - sourceY) / 2;
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
const xOffset = Math.abs(targetX - sourceX) / 2; const xOffset = Math.abs(targetX - sourceX) / 2;
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset; const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
const path = `M ${sourceX},${sourceY}L ${targetX},${targetY}`;
return ( return (
<BaseEdge <BaseEdge
path={path} path={`M ${sourceX},${sourceY}L ${targetX},${targetY}`}
centerX={centerX} centerX={centerX}
centerY={centerY} centerY={centerY}
label={label} label={label}
@@ -40,6 +40,7 @@ const StraightEdge = memo(
style={style} style={style}
markerEnd={markerEnd} markerEnd={markerEnd}
markerStart={markerStart} markerStart={markerStart}
interactionWidth={interactionWidth}
/> />
); );
} }
@@ -52,7 +52,8 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
rfId, rfId,
ariaLabel, ariaLabel,
disableKeyboardA11y, disableKeyboardA11y,
options, pathOptions,
interactionWidth,
}: WrapEdgeProps): JSX.Element | null => { }: WrapEdgeProps): JSX.Element | null => {
const edgeRef = useRef<SVGGElement>(null); const edgeRef = useRef<SVGGElement>(null);
const [updateHover, setUpdateHover] = useState<boolean>(false); const [updateHover, setUpdateHover] = useState<boolean>(false);
@@ -190,7 +191,8 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
targetHandleId={targetHandleId} targetHandleId={targetHandleId}
markerStart={markerStartUrl} markerStart={markerStartUrl}
markerEnd={markerEndUrl} markerEnd={markerEndUrl}
options={options} pathOptions={pathOptions}
interactionWidth={interactionWidth}
/> />
)} )}
@@ -182,7 +182,8 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
rfId={props.rfId} rfId={props.rfId}
ariaLabel={edge.ariaLabel} ariaLabel={edge.ariaLabel}
disableKeyboardA11y={props.disableKeyboardA11y} disableKeyboardA11y={props.disableKeyboardA11y}
options={'options' in edge ? edge.options : undefined} pathOptions={'pathOptions' in edge ? edge.pathOptions : undefined}
interactionWidth={edge.interactionWidth}
/> />
); );
})} })}
+15 -31
View File
@@ -32,25 +32,26 @@ type DefaultEdge<T = any> = {
markerEnd?: EdgeMarkerType; markerEnd?: EdgeMarkerType;
zIndex?: number; zIndex?: number;
ariaLabel?: string; ariaLabel?: string;
interactionWidth?: number;
}; };
export type SmoothStepEdgeOptions = { export type SmoothStepPathOptions = {
offset?: number; offset?: number;
borderRadius?: number; borderRadius?: number;
}; };
type SmoothStepEdgeType<T> = DefaultEdge<T> & { type SmoothStepEdgeType<T> = DefaultEdge<T> & {
type: 'smoothstep'; type: 'smoothstep';
options?: SmoothStepEdgeOptions; pathOptions?: SmoothStepPathOptions;
}; };
export type BezierEdgeOptions = { export type BezierPathOptions = {
curvature?: number; curvature?: number;
}; };
type BezierEdgeType<T> = DefaultEdge<T> & { type BezierEdgeType<T> = DefaultEdge<T> & {
type: 'default'; type: 'default';
options?: BezierEdgeOptions; pathOptions?: BezierPathOptions;
}; };
export type Edge<T = any> = DefaultEdge<T> | SmoothStepEdgeType<T> | BezierEdgeType<T>; export type Edge<T = any> = DefaultEdge<T> | SmoothStepEdgeType<T> | BezierEdgeType<T>;
@@ -61,7 +62,7 @@ export type DefaultEdgeOptions = Omit<
>; >;
// props that get passed to a custom edge // props that get passed to a custom edge
export interface EdgeProps<T = any> { export type EdgeProps<T = any> = {
id: string; id: string;
source: string; source: string;
target: string; target: string;
@@ -85,8 +86,9 @@ export interface EdgeProps<T = any> {
targetHandleId?: string | null; targetHandleId?: string | null;
markerStart?: string; markerStart?: string;
markerEnd?: string; markerEnd?: string;
options?: BezierEdgeOptions | SmoothStepEdgeOptions; pathOptions?: BezierPathOptions | SmoothStepPathOptions;
} interactionWidth?: number;
};
export type BaseEdgeProps = Pick< export type BaseEdgeProps = Pick<
EdgeProps, EdgeProps,
@@ -99,6 +101,7 @@ export type BaseEdgeProps = Pick<
| 'style' | 'style'
| 'markerStart' | 'markerStart'
| 'markerEnd' | 'markerEnd'
| 'interactionWidth'
> & { > & {
centerX: number; centerX: number;
centerY: number; centerY: number;
@@ -107,24 +110,9 @@ export type BaseEdgeProps = Pick<
export type EdgeMouseHandler = (event: React.MouseEvent, edge: Edge) => void; export type EdgeMouseHandler = (event: React.MouseEvent, edge: Edge) => void;
export interface WrapEdgeProps<T = any> { export type WrapEdgeProps<T = any> = Omit<Edge<T>, 'sourceHandle' | 'targetHandle'> & {
id: string;
className?: string;
type: string;
data?: T;
onClick?: EdgeMouseHandler; onClick?: EdgeMouseHandler;
onEdgeDoubleClick?: EdgeMouseHandler; onEdgeDoubleClick?: EdgeMouseHandler;
selected: boolean;
animated?: boolean;
label?: string | ReactNode;
labelStyle?: CSSProperties;
labelShowBg?: boolean;
labelBgStyle?: CSSProperties;
labelBgPadding?: [number, number];
labelBgBorderRadius?: number;
style?: CSSProperties;
source: string;
target: string;
sourceHandleId?: string | null; sourceHandleId?: string | null;
targetHandleId?: string | null; targetHandleId?: string | null;
sourceX: number; sourceX: number;
@@ -134,7 +122,6 @@ export interface WrapEdgeProps<T = any> {
sourcePosition: Position; sourcePosition: Position;
targetPosition: Position; targetPosition: Position;
elementsSelectable?: boolean; elementsSelectable?: boolean;
hidden?: boolean;
onEdgeUpdate?: OnEdgeUpdateFunc; onEdgeUpdate?: OnEdgeUpdateFunc;
onContextMenu?: EdgeMouseHandler; onContextMenu?: EdgeMouseHandler;
onMouseEnter?: EdgeMouseHandler; onMouseEnter?: EdgeMouseHandler;
@@ -143,20 +130,17 @@ export interface WrapEdgeProps<T = any> {
edgeUpdaterRadius?: number; edgeUpdaterRadius?: number;
onEdgeUpdateStart?: (event: React.MouseEvent, edge: Edge, handleType: HandleType) => void; onEdgeUpdateStart?: (event: React.MouseEvent, edge: Edge, handleType: HandleType) => void;
onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge, handleType: HandleType) => void; onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge, handleType: HandleType) => void;
markerStart?: EdgeMarkerType;
markerEnd?: EdgeMarkerType;
rfId?: string; rfId?: string;
ariaLabel?: string | null;
disableKeyboardA11y: boolean; disableKeyboardA11y: boolean;
options?: SmoothStepEdgeOptions | BezierEdgeOptions; pathOptions?: BezierPathOptions | SmoothStepPathOptions;
} };
export interface SmoothStepEdgeProps<T = any> extends EdgeProps<T> { export interface SmoothStepEdgeProps<T = any> extends EdgeProps<T> {
options?: SmoothStepEdgeOptions; pathOptions?: SmoothStepPathOptions;
} }
export interface BezierEdgeProps<T = any> extends EdgeProps<T> { export interface BezierEdgeProps<T = any> extends EdgeProps<T> {
options?: BezierEdgeOptions; pathOptions?: BezierPathOptions;
} }
export interface EdgeTextProps extends HTMLAttributes<SVGElement> { export interface EdgeTextProps extends HTMLAttributes<SVGElement> {
x: number; x: number;