90 lines
2.5 KiB
TypeScript
Executable File
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>
|
|
} |