選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.tsx 2.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { useCallback, useEffect, useState } from 'react';
  2. import ReactFlow, {
  3. Background,
  4. Controls,
  5. Edge,
  6. Node,
  7. NodeMouseHandler,
  8. OnConnect,
  9. OnEdgesChange,
  10. OnNodesChange,
  11. addEdge,
  12. applyEdgeChanges,
  13. applyNodeChanges,
  14. } from 'reactflow';
  15. import 'reactflow/dist/style.css';
  16. import { NodeContextMenu, useHandleNodeContextMenu } from './context-menu';
  17. import FlowDrawer from '../flow-drawer';
  18. import { useHandleDrop, useShowDrawer } from '../hooks';
  19. import { initialEdges, initialNodes } from '../mock';
  20. import { getLayoutedElements } from '../utils';
  21. import { TextUpdaterNode } from './node';
  22. const nodeTypes = { textUpdater: TextUpdaterNode };
  23. interface IProps {
  24. sideWidth: number;
  25. }
  26. function FlowCanvas({ sideWidth }: IProps) {
  27. const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(
  28. initialNodes,
  29. initialEdges,
  30. 'LR',
  31. );
  32. const [nodes, setNodes] = useState<Node[]>(layoutedNodes);
  33. const [edges, setEdges] = useState<Edge[]>(layoutedEdges);
  34. const { ref, menu, onNodeContextMenu, onPaneClick } =
  35. useHandleNodeContextMenu(sideWidth);
  36. const { drawerVisible, hideDrawer, showDrawer } = useShowDrawer();
  37. const onNodesChange: OnNodesChange = useCallback(
  38. (changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
  39. [],
  40. );
  41. const onEdgesChange: OnEdgesChange = useCallback(
  42. (changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
  43. [],
  44. );
  45. const onConnect: OnConnect = useCallback(
  46. (params) => setEdges((eds) => addEdge(params, eds)),
  47. [],
  48. );
  49. const onNodeClick: NodeMouseHandler = useCallback(() => {
  50. showDrawer();
  51. }, [showDrawer]);
  52. const { onDrop, onDragOver, setReactFlowInstance } = useHandleDrop(setNodes);
  53. useEffect(() => {
  54. console.info('nodes:', nodes);
  55. console.info('edges:', edges);
  56. }, [nodes, edges]);
  57. return (
  58. <div style={{ height: '100%', width: '100%' }}>
  59. <ReactFlow
  60. ref={ref}
  61. nodes={nodes}
  62. onNodesChange={onNodesChange}
  63. onNodeContextMenu={onNodeContextMenu}
  64. edges={edges}
  65. onEdgesChange={onEdgesChange}
  66. fitView
  67. onConnect={onConnect}
  68. nodeTypes={nodeTypes}
  69. onPaneClick={onPaneClick}
  70. onDrop={onDrop}
  71. onDragOver={onDragOver}
  72. onNodeClick={onNodeClick}
  73. onInit={setReactFlowInstance}
  74. >
  75. <Background />
  76. <Controls />
  77. {Object.keys(menu).length > 0 && (
  78. <NodeContextMenu onClick={onPaneClick} {...(menu as any)} />
  79. )}
  80. </ReactFlow>
  81. <FlowDrawer visible={drawerVisible} hideModal={hideDrawer}></FlowDrawer>
  82. </div>
  83. );
  84. }
  85. export default FlowCanvas;