import { memo, ReactNode } from 'react'; import { shallow } from 'zustand/shallow'; import cc from 'classcat'; import { errorMessages } from '@xyflow/system'; import { useStore } from '../../hooks/useStore'; import useVisibleEdges from '../../hooks/useVisibleEdges'; import MarkerDefinitions from './MarkerDefinitions'; import { GraphViewProps } from '../GraphView'; import type { EdgeTypesWrapped, ReactFlowState } from '../../types'; type EdgeRendererProps = Pick< GraphViewProps, | 'onEdgeClick' | 'onEdgeDoubleClick' | 'defaultMarkerColor' | 'onlyRenderVisibleElements' | 'onEdgeUpdate' | 'onEdgeContextMenu' | 'onEdgeMouseEnter' | 'onEdgeMouseMove' | 'onEdgeMouseLeave' | 'onEdgeUpdateStart' | 'onEdgeUpdateEnd' | 'edgeUpdaterRadius' | 'noPanClassName' | 'elevateEdgesOnSelect' | 'rfId' | 'disableKeyboardA11y' > & { edgeTypes: EdgeTypesWrapped; elevateEdgesOnSelect: boolean; children: ReactNode; }; const selector = (s: ReactFlowState) => ({ width: s.width, height: s.height, edgesFocusable: s.edgesFocusable, edgesUpdatable: s.edgesUpdatable, elementsSelectable: s.elementsSelectable, connectionMode: s.connectionMode, onError: s.onError, }); const EdgeRenderer = ({ defaultMarkerColor, onlyRenderVisibleElements, elevateEdgesOnSelect, rfId, edgeTypes, noPanClassName, onEdgeUpdate, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, edgeUpdaterRadius, onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, children, }: EdgeRendererProps) => { const { edgesFocusable, edgesUpdatable, elementsSelectable, onError } = useStore(selector, shallow); const edgeTree = useVisibleEdges(onlyRenderVisibleElements, elevateEdgesOnSelect); return ( <> {edgeTree.map(({ level, edges, isMaxLevel }) => ( {isMaxLevel && } {edges.map((edge) => { let edgeType = edge.type || 'default'; if (!edgeTypes[edgeType]) { onError?.('011', errorMessages['error011'](edgeType)); edgeType = 'default'; } const EdgeComponent = edgeTypes[edgeType]; const isFocusable = !!(edge.focusable || (edgesFocusable && typeof edge.focusable === 'undefined')); const isUpdatable = typeof onEdgeUpdate !== 'undefined' && (edge.updatable || (edgesUpdatable && typeof edge.updatable === 'undefined')); const isSelectable = !!( edge.selectable || (elementsSelectable && typeof edge.selectable === 'undefined') ); return ( ); })} ))} {children} ); }; EdgeRenderer.displayName = 'EdgeRenderer'; export default memo(EdgeRenderer);