collect-system/packages/ui/src/components/mindmap/MindMap.tsx

90 lines
2.5 KiB
TypeScript
Executable File

import { useCallback, useState, useRef, useEffect } from 'react';
import {
ReactFlow,
Controls,
Background,
useReactFlow,
Panel,
ReactFlowProvider,
NodeOrigin,
ConnectionLineType,
useStoreApi,
InternalNode,
} from '@xyflow/react';
import MindMapNode from './MindMapNode';
import useMindMapStore, { RFState } from './store';
import { shallow, useShallow } from 'zustand/shallow';
import MindMapEdge from './MindMapEdge';
import '@xyflow/react/dist/style.css';
import { useFlowKeyboardControls } from './hooks/useFlowKeyboardControl';
const selector = (state: RFState) => ({
nodes: state.nodes,
edges: state.edges,
onNodesChange: state.onNodesChange,
onEdgesChange: state.onEdgesChange,
addChildNode: state.addChildNode,
addSiblingNode: state.addSiblingNode,
selectedNodeId: state.selectedNodeId,
setSelectedNodeIdId: state.setSelectedNodeId,
undo: state.undo,
redo: state.redo,
canUndo: state.canUndo,
canRedo: state.canRedo
});
const nodeOrigin: NodeOrigin = [0.5, 0.5];
// 节点类型定义
const nodeTypes = {
mindmap: MindMapNode,
};
const edgeTypes = {
mindmap: MindMapEdge,
};
const connectionLineStyle = {
stroke: '#999',
strokeWidth: 2,
radius: 20 // Add corner radius for orthogonal lines
};
const defaultEdgeOptions = {
style: connectionLineStyle,
type: 'mindmap',
animated: false
};
export function Flow() {
const { nodes, edges, onNodesChange, undo, redo, setSelectedNodeIdId, onEdgesChange, addChildNode, addSiblingNode, selectedNodeId } = useMindMapStore(
useShallow(selector)
);
useFlowKeyboardControls()
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
nodeOrigin={nodeOrigin}
connectionLineStyle={connectionLineStyle}
defaultEdgeOptions={defaultEdgeOptions}
connectionLineType={ConnectionLineType.SmoothStep}
fitView
panOnDrag={[2]}
minZoom={0.2}
maxZoom={4}
nodesConnectable={false}
>
<Background />
<Controls />
<Panel position="top-left">React Flow Mind Map</Panel>
</ReactFlow>
);
}
export function MindMap() {
return <ReactFlowProvider>
<Flow></Flow>
</ReactFlowProvider>
}