Skip to content

Commit e6b1846

Browse files
committed
feat: recreate diff viewer components and created utils from json diff kit
This commit includes major changes, viewer component is recreated based on previous model. This decision is made after performance considerations
1 parent aaa35c6 commit e6b1846

File tree

11 files changed

+648
-172
lines changed

11 files changed

+648
-172
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { SearchState } from "../types";
2+
3+
import { SearchIcon } from "../../SearchIcon";
4+
5+
type Props = {
6+
searchState: SearchState;
7+
handleSearch: (term: string) => void;
8+
navigateMatch: (direction: "next" | "prev") => void;
9+
hideSearch?: boolean;
10+
};
11+
12+
function SearchboxHolder({ searchState, handleSearch, navigateMatch, hideSearch }: Props) {
13+
if (hideSearch)
14+
return null;
15+
16+
return (
17+
<div>
18+
<div className="search-container">
19+
<div className="search-input-container">
20+
<span role="img" aria-label="search"><SearchIcon /></span>
21+
<input
22+
type="text"
23+
placeholder="Search in JSON..."
24+
value={searchState.term}
25+
onChange={e => handleSearch(e.target.value)}
26+
/>
27+
</div>
28+
{searchState.results.length > 0 && (
29+
<div className="search-results">
30+
<span>
31+
{searchState.currentIndex + 1}
32+
{" "}
33+
of
34+
{" "}
35+
{searchState.results.length}
36+
{" "}
37+
matches
38+
</span>
39+
<button onClick={() => navigateMatch("prev")}>Previous</button>
40+
<button onClick={() => navigateMatch("next")}>Next</button>
41+
</div>
42+
)}
43+
</div>
44+
</div>
45+
);
46+
}
47+
48+
export default SearchboxHolder;

src/components/DiffViewer/components/ViewerRow.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import type { DiffResult, InlineDiffOptions } from "json-diff-kit";
22
import type { ListChildComponentProps } from "react-window";
33

44
import { Viewer } from "json-diff-kit";
5+
import { useCallback } from "react";
56

6-
import type { DiffRowOrCollapsed } from "../types";
7+
import type { CollapsedLine, DiffRowOrCollapsed } from "../types";
78

89
import { DIFF_VIEWER_CLASS, isCollapsed } from "../utils/constants";
910

@@ -22,13 +23,19 @@ function ViewerRow({
2223
const originalLeftLine = data.leftDiff[index];
2324
const originalRightLine = data.rightDiff[index];
2425

26+
const handleExpand = useCallback((originalLeftLine: CollapsedLine) => {
27+
if (isCollapsed(originalLeftLine)) {
28+
onExpand(originalLeftLine.segmentIndex);
29+
}
30+
}, [onExpand, originalLeftLine]);
31+
2532
if (isCollapsed(originalLeftLine)) {
2633
return (
2734
<div className="collapsed-button" style={style}>
28-
<button onClick={() => onExpand(originalLeftLine.segmentIndex)} className="text-blue-500 underline">
35+
<button onClick={() => handleExpand(originalLeftLine)} className="text-blue-500 underline">
2936
Show Hidden Lines
3037
</button>
31-
<button onClick={() => onExpand(originalLeftLine.segmentIndex)} className="text-blue-500 underline">
38+
<button onClick={() => handleExpand(originalLeftLine)} className="text-blue-500 underline">
3239
Show Hidden Lines
3340
</button>
3441
</div>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import type { InlineDiffOptions } from "json-diff-kit";
2+
import type { Dispatch } from "react";
3+
import type { ListOnScrollProps } from "react-window";
4+
5+
import React, { useCallback, useEffect, useMemo } from "react";
6+
import { VariableSizeList as List } from "react-window";
7+
8+
import type { DiffRowOrCollapsed } from "../types";
9+
10+
import { useRowHeights } from "../hooks/useRowHeights";
11+
import { COLLAPSED_ROW_HEIGHT, getRowHeightFromCSS, isCollapsed } from "../utils/constants";
12+
import RowRenderer from "../utils/json-diff/row-renderer";
13+
14+
type VirtualDiffTableProps = {
15+
leftDiff: DiffRowOrCollapsed[];
16+
rightDiff: DiffRowOrCollapsed[];
17+
outerRef: React.RefObject<Node | null>;
18+
listRef: React.RefObject<List<any>>;
19+
height: number;
20+
inlineDiffOptions?: InlineDiffOptions;
21+
className?: string;
22+
style?: React.CSSProperties;
23+
setScrollTop: Dispatch<React.SetStateAction<number>>;
24+
onExpand: (segmentIndex: number) => void;
25+
};
26+
27+
const VirtualDiffTable: React.FC<VirtualDiffTableProps> = ({
28+
leftDiff,
29+
rightDiff,
30+
outerRef,
31+
listRef,
32+
height,
33+
inlineDiffOptions,
34+
className,
35+
setScrollTop,
36+
style,
37+
onExpand,
38+
}) => {
39+
// Virtual List Data
40+
const listData = useMemo(
41+
() => ({
42+
leftDiff,
43+
rightDiff,
44+
onExpand,
45+
inlineDiffOptions,
46+
}),
47+
[leftDiff, rightDiff, onExpand, inlineDiffOptions],
48+
);
49+
50+
const classes = [
51+
"json-diff-viewer",
52+
`json-diff-viewer-theme-custom`,
53+
className,
54+
]
55+
.join(" ");
56+
57+
// ROW HEIGHT CALCULATION
58+
const ROW_HEIGHT = useMemo(() => getRowHeightFromCSS(), []);
59+
const rowHeights = useRowHeights(leftDiff);
60+
const dynamicRowHeights = useCallback(
61+
(index: number) => {
62+
const leftLine = leftDiff[index];
63+
if (isCollapsed(leftLine))
64+
return COLLAPSED_ROW_HEIGHT;
65+
return (rowHeights[index] ?? 1) * ROW_HEIGHT;
66+
},
67+
[leftDiff, rowHeights],
68+
);
69+
70+
useEffect(() => {
71+
listRef.current?.resetAfterIndex(0, true);
72+
}, [rowHeights]);
73+
74+
return (
75+
<table
76+
className={classes}
77+
style={style}
78+
>
79+
<colgroup>
80+
<col style={{ width: "50px" }} />
81+
<col />
82+
<col style={{ width: "0px" }} />
83+
<col />
84+
</colgroup>
85+
<tbody>
86+
<List
87+
height={height}
88+
width="100%"
89+
outerRef={outerRef}
90+
ref={listRef}
91+
className="virtual-json-diff-list-container"
92+
itemCount={Math.max(leftDiff.length, rightDiff.length)}
93+
itemSize={dynamicRowHeights}
94+
overscanCount={28}
95+
itemData={listData}
96+
onScroll={({ scrollOffset }: ListOnScrollProps) => setScrollTop(scrollOffset)}
97+
>
98+
{RowRenderer}
99+
</List>
100+
</tbody>
101+
</table>
102+
);
103+
};
104+
105+
export default VirtualDiffTable;

0 commit comments

Comments
 (0)