/* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { ComponentType, memo } from 'react'; import { NodeOrigin, getNodePositionWithOrigin } from '@xyflow/system'; import { shallow } from 'zustand/shallow'; import { useStore } from '../../hooks/useStore'; import { MiniMapNode } from './MiniMapNode'; import type { ReactFlowState } from '../../types'; import type { MiniMapNodes as MiniMapNodesProps, GetMiniMapNodeAttribute, MiniMapNodeProps } from './types'; declare const window: any; const selector = (s: ReactFlowState) => s.nodeOrigin; const selectorNodeIds = (s: ReactFlowState) => s.nodes.map((node) => node.id); const getAttrFunction = (func: any): GetMiniMapNodeAttribute => (func instanceof Function ? func : () => func); function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth, // We need to rename the prop to be `CapitalCase` so that JSX will render it as // a component properly. nodeComponent: NodeComponent = MiniMapNode, onClick, }: MiniMapNodesProps) { const nodeIds = useStore(selectorNodeIds, shallow); const nodeOrigin = useStore(selector); const nodeColorFunc = getAttrFunction(nodeColor); const nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor); const nodeClassNameFunc = getAttrFunction(nodeClassName); const shapeRendering = typeof window === 'undefined' || !!window.chrome ? 'crispEdges' : 'geometricPrecision'; return ( <> {nodeIds.map((nodeId) => ( // The split of responsibilities between MiniMapNodes and // NodeComponentWrapper may appear weird. However, it’s designed to // minimize the cost of updates when individual nodes change. // // For more details, see a similar commit in `NodeRenderer/index.tsx`. ))} ); } const NodeComponentWrapper = memo(function NodeComponentWrapper({ id, nodeOrigin, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick, }: { id: string; nodeOrigin: NodeOrigin; nodeColorFunc: GetMiniMapNodeAttribute; nodeStrokeColorFunc: GetMiniMapNodeAttribute; nodeClassNameFunc: GetMiniMapNodeAttribute; nodeBorderRadius: number; nodeStrokeWidth?: number; NodeComponent: ComponentType; onClick: MiniMapNodesProps['onClick']; shapeRendering: string; }) { const { node, x, y } = useStore((s) => { const node = s.nodeLookup.get(id); const { x, y } = getNodePositionWithOrigin(node, node?.origin || nodeOrigin).positionAbsolute; return { node, x, y, }; }, shallow); if (!node || node.hidden || !(node.computed?.width || node.width) || !(node.computed?.height || node.height)) { return null; } return ( ); }); export default memo(MiniMapNodes);