Repository navigation
Expand file tree
/
Copy pathObjectNode.tsx
More file actions
81 lines (73 loc) · 2.65 KB
/
Copy pathObjectNode.tsx
File metadata and controls
81 lines (73 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import React from "react";
import type { CustomNodeProps } from ".";
import { NODE_DIMENSIONS } from "../../../../../constants/graph";
import type { NodeData } from "../../../../../types/graph";
import { TextRenderer } from "./TextRenderer";
import * as Styled from "./styles";
type RowProps = {
row: NodeData["text"][number];
x: number;
y: number;
index: number;
};
const Row = ({ row, x, y, index }: RowProps) => {
const rowPosition = index * NODE_DIMENSIONS.ROW_HEIGHT;
const getRowText = () => {
if (row.type === "object") return `{${row.childrenCount ?? 0} keys}`;
if (row.type === "array") return `[${row.childrenCount ?? 0} items]`;
return row.value;
};
return (
<Styled.StyledRow
$value={row.value}
data-key={`${row.key}: ${row.value}`}
data-x={x}
data-y={y + rowPosition}
>
<Styled.StyledKey $type="object">{row.key}: </Styled.StyledKey>
<TextRenderer>{getRowText()}</TextRenderer>
</Styled.StyledRow>
);
};
const Node = ({ node, x, y }: CustomNodeProps) => (
<Styled.StyledForeignObject
data-id={`node-${node.id}`}
width={node.width}
height={node.height}
x={0}
y={0}
$isObject
>
<div style={{ position: "relative", width: "100%", height: "100%" }}>
{(() => {
const firstRow = node.text?.[0];
const firstPrimitiveValue = typeof firstRow?.value === "string" || typeof firstRow?.value === "number" ? String(firstRow?.value) : undefined;
const shouldShowLabel = Boolean(node.name && node.name !== firstPrimitiveValue);
return shouldShowLabel ? (
<div style={{ position: "absolute", top: 2, left: 6, fontSize: 10, fontWeight: 700, pointerEvents: "none" }}>
{node.name}
</div>
) : null;
})()}
<div style={{ paddingTop: (() => {
const firstRow = node.text?.[0];
const firstPrimitiveValue = typeof firstRow?.value === "string" || typeof firstRow?.value === "number" ? String(firstRow?.value) : undefined;
const shouldShowLabel = Boolean(node.name && node.name !== firstPrimitiveValue);
return shouldShowLabel ? 16 : 0;
})() }}>
{node.text.map((row, index) => (
<Row key={`${node.id}-${index}`} row={row} x={x} y={y} index={index} />
))}
</div>
</div>
</Styled.StyledForeignObject>
);
function propsAreEqual(prev: CustomNodeProps, next: CustomNodeProps) {
return (
JSON.stringify(prev.node.text) === JSON.stringify(next.node.text) &&
prev.node.width === next.node.width &&
prev.node.name === next.node.name &&
prev.node.color === next.node.color
);
}
export const ObjectNode = React.memo(Node, propsAreEqual);