Skip to content

Commit a79008d

Browse files
authored
chore/COMPASS-9493 export typed diagram hook (#80)
* chore/COMPASS-9493 export typed diagram hook * map state internally * fix tests
1 parent 59ff4b4 commit a79008d

File tree

12 files changed

+327
-194
lines changed

12 files changed

+327
-194
lines changed

src/components/canvas/canvas.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,19 @@ import {
88
useEdgesState,
99
useNodesState,
1010
} from '@xyflow/react';
11-
import { MouseEvent, useCallback, useEffect } from 'react';
11+
import { MouseEvent, useCallback, useEffect, useMemo } from 'react';
1212

1313
import { MiniMap } from '@/components/controls/mini-map';
1414
import { Controls } from '@/components/controls/controls';
1515
import { DiagramProps } from '@/types';
1616
import { Node } from '@/components/node/node';
17-
import { useCanvas } from '@/components/canvas/use-canvas';
1817
import { InternalEdge, InternalNode } from '@/types/internal';
1918
import { FloatingEdge } from '@/components/edge/floating-edge';
2019
import { SelfReferencingEdge } from '@/components/edge/self-referencing-edge';
2120
import { MarkerList } from '@/components/markers/marker-list';
2221
import { ConnectionLine } from '@/components/line/connection-line';
23-
import { convertToExternalNode, convertToExternalNodes } from '@/utilities/convert-nodes';
24-
import { convertToExternalEdge, convertToExternalEdges } from '@/utilities/convert-edges';
22+
import { convertToExternalNode, convertToExternalNodes, convertToInternalNodes } from '@/utilities/convert-nodes';
23+
import { convertToExternalEdge, convertToExternalEdges, convertToInternalEdges } from '@/utilities/convert-edges';
2524

2625
const MAX_ZOOM = 3;
2726
const MIN_ZOOM = 0.1;
@@ -60,7 +59,8 @@ export const Canvas = ({
6059
onSelectionChange,
6160
...rest
6261
}: DiagramProps) => {
63-
const { initialNodes, initialEdges } = useCanvas(externalNodes, externalEdges);
62+
const initialNodes = useMemo(() => convertToInternalNodes(externalNodes), [externalNodes]);
63+
const initialEdges = useMemo(() => convertToInternalEdges(externalEdges), [externalEdges]);
6464

6565
const [nodes, setNodes, onNodesChange] = useNodesState<InternalNode>(initialNodes);
6666
const [edges, setEdges, onEdgesChange] = useEdgesState<InternalEdge>(initialEdges);

src/components/canvas/use-canvas.test.tsx

Lines changed: 0 additions & 133 deletions
This file was deleted.

src/components/canvas/use-canvas.tsx

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/components/controls/controls.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import Icon from '@leafygreen-ui/icon';
2-
import { ControlButton, Controls as ReactFlowControls, useReactFlow, useViewport } from '@xyflow/react';
2+
import { ControlButton, Controls as ReactFlowControls, useViewport } from '@xyflow/react';
33
import { palette } from '@leafygreen-ui/palette';
44
import { fontFamilies, spacing } from '@leafygreen-ui/tokens';
55
import styled from '@emotion/styled';
66

7+
import { useDiagram } from '@/hooks/use-diagram';
8+
79
const zoomTransitionOption = { duration: 500 };
810

911
const ControlsWrapper = styled(ReactFlowControls)`
@@ -43,7 +45,7 @@ interface DiagramControlsProps {
4345
}
4446

4547
export const Controls = ({ title }: DiagramControlsProps) => {
46-
const { zoomIn, zoomOut, fitView } = useReactFlow();
48+
const { zoomIn, zoomOut, fitView } = useDiagram();
4749
const { zoom } = useViewport();
4850

4951
return (

src/hooks/use-diagram.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useReactFlow } from '@xyflow/react';
2+
3+
import { convertToExternalNode, convertToInternalNodes } from '@/utilities/convert-nodes';
4+
import { InternalEdge, InternalNode } from '@/types/internal';
5+
import { NodeProps, EdgeProps } from '@/types';
6+
import { convertToExternalEdge, convertToInternalEdges } from '@/utilities/convert-edges';
7+
8+
export type DiagramInstance = ReturnType<typeof useDiagram>;
9+
export function useDiagram() {
10+
const diagram = useReactFlow<InternalNode, InternalEdge>();
11+
12+
return {
13+
...diagram,
14+
getNode: (id: string) => {
15+
const node = diagram.getNode(id);
16+
if (node) {
17+
return convertToExternalNode(node);
18+
}
19+
},
20+
getNodes: () => {
21+
const nodes = diagram.getNodes();
22+
return nodes.map(convertToExternalNode);
23+
},
24+
addNodes: (payload: NodeProps[]) => {
25+
const data = convertToInternalNodes(payload);
26+
diagram.addNodes(data);
27+
},
28+
setNodes: (payload: NodeProps[]) => {
29+
const data = convertToInternalNodes(payload);
30+
diagram.setNodes(data);
31+
},
32+
getEdge: (id: string) => {
33+
const edge = diagram.getEdge(id);
34+
if (edge) {
35+
return convertToExternalEdge(edge);
36+
}
37+
},
38+
getEdges: () => {
39+
const edges = diagram.getEdges();
40+
return edges.map(convertToExternalEdge);
41+
},
42+
addEdges: (payload: EdgeProps[]) => {
43+
const data = convertToInternalEdges(payload);
44+
diagram.addEdges(data);
45+
},
46+
setEdges: (payload: EdgeProps[]) => {
47+
const data = convertToInternalEdges(payload);
48+
diagram.setEdges(data);
49+
},
50+
};
51+
}

src/index.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
export * from '@/components/diagram';
22
export * from '@/utilities/apply-layout';
3-
export { convertToExternalEdge as mapEdgeToDiagramEdge } from '@/utilities/convert-edges';
4-
export { convertToExternalNode as mapNodeToDiagramNode } from '@/utilities/convert-nodes';
53
export * from '@/utilities/add-nodes-within-bounds';
4+
export * from '@/utilities/get-nodes-bounds';
65
export * from '@/types';
7-
export {
8-
ReactFlowProvider as DiagramProvider,
9-
useReactFlow as useDiagram,
10-
useOnSelectionChange,
11-
getNodesBounds,
12-
getViewportForBounds,
13-
type ReactFlowInstance as DiagramInstance,
14-
} from '@xyflow/react';
6+
export { useDiagram, type DiagramInstance } from '@/hooks/use-diagram';
7+
export { ReactFlowProvider as DiagramProvider, useOnSelectionChange, getViewportForBounds } from '@xyflow/react';

src/types/internal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ export type InternalNode = ReactFlowNode<NodeData>;
1515
export interface InternalEdge extends Omit<EdgeProps, 'markerStart' | 'markerEnd'> {
1616
markerStart: 'start-one' | 'start-oneOrMany' | 'start-many';
1717
markerEnd: 'end-one' | 'end-oneOrMany' | 'end-many';
18+
type: 'selfReferencingEdge' | 'floatingEdge';
1819
}

0 commit comments

Comments
 (0)