Files
xyflow/packages/react/src/components/Edges/EdgeText.tsx
T

77 lines
1.9 KiB
TypeScript

import { memo, useState, useEffect, useRef } from 'react';
import cc from 'classcat';
import type { Rect } from '@xyflow/system';
import type { EdgeTextProps } from '../../types';
function EdgeTextComponent({
x,
y,
label,
labelStyle = {},
labelShowBg = true,
labelBgStyle = {},
labelBgPadding = [2, 4],
labelBgBorderRadius = 2,
children,
className,
...rest
}: EdgeTextProps) {
const [edgeTextBbox, setEdgeTextBbox] = useState<Rect>({ x: 1, y: 0, width: 0, height: 0 });
const edgeTextClasses = cc(['react-flow__edge-textwrapper', className]);
const edgeTextRef = useRef<SVGTextElement | null>(null);
useEffect(() => {
if (edgeTextRef.current) {
const textBbox = edgeTextRef.current.getBBox();
setEdgeTextBbox({
x: textBbox.x,
y: textBbox.y,
width: textBbox.width,
height: textBbox.height,
});
}
}, [label]);
if (typeof label === 'undefined' || !label) {
return null;
}
return (
<g
transform={`translate(${x - edgeTextBbox.width / 2} ${y - edgeTextBbox.height / 2})`}
className={edgeTextClasses}
visibility={edgeTextBbox.width ? 'visible' : 'hidden'}
{...rest}
>
{labelShowBg && (
<rect
width={edgeTextBbox.width + 2 * labelBgPadding[0]}
x={-labelBgPadding[0]}
y={-labelBgPadding[1]}
height={edgeTextBbox.height + 2 * labelBgPadding[1]}
className="react-flow__edge-textbg"
style={labelBgStyle}
rx={labelBgBorderRadius}
ry={labelBgBorderRadius}
/>
)}
<text
className="react-flow__edge-text"
y={edgeTextBbox.height / 2}
dy="0.3em"
ref={edgeTextRef}
style={labelStyle}
>
{label}
</text>
{children}
</g>
);
}
EdgeTextComponent.displayName = 'EdgeText';
export const EdgeText = memo(EdgeTextComponent);