@bochenw/react-diff-viewer-continued 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +521 -0
- package/lib/cjs/src/comment-row.d.ts +33 -0
- package/lib/cjs/src/comment-row.js +58 -0
- package/lib/cjs/src/compute-hidden-blocks.d.ts +13 -0
- package/lib/cjs/src/compute-hidden-blocks.js +36 -0
- package/lib/cjs/src/compute-lines.d.ts +68 -0
- package/lib/cjs/src/compute-lines.js +559 -0
- package/lib/cjs/src/computeWorker.d.ts +1 -0
- package/lib/cjs/src/computeWorker.js +10 -0
- package/lib/cjs/src/diff-row.d.ts +40 -0
- package/lib/cjs/src/diff-row.js +136 -0
- package/lib/cjs/src/expand.d.ts +1 -0
- package/lib/cjs/src/expand.js +4 -0
- package/lib/cjs/src/fold.d.ts +1 -0
- package/lib/cjs/src/fold.js +4 -0
- package/lib/cjs/src/index.d.ts +236 -0
- package/lib/cjs/src/index.js +783 -0
- package/lib/cjs/src/line-number-prefix.d.ts +4 -0
- package/lib/cjs/src/line-number-prefix.js +5 -0
- package/lib/cjs/src/render-word-diff.d.ts +22 -0
- package/lib/cjs/src/render-word-diff.js +212 -0
- package/lib/cjs/src/skipped-line-indicator.d.ts +29 -0
- package/lib/cjs/src/skipped-line-indicator.js +29 -0
- package/lib/cjs/src/styles.d.ts +102 -0
- package/lib/cjs/src/styles.js +430 -0
- package/lib/cjs/src/workerBundle.d.ts +5 -0
- package/lib/cjs/src/workerBundle.js +7 -0
- package/lib/esm/src/comment-row.js +58 -0
- package/lib/esm/src/compute-hidden-blocks.js +36 -0
- package/lib/esm/src/compute-lines.js +559 -0
- package/lib/esm/src/computeWorker.js +10 -0
- package/lib/esm/src/diff-row.js +136 -0
- package/lib/esm/src/expand.js +4 -0
- package/lib/esm/src/fold.js +4 -0
- package/lib/esm/src/index.js +780 -0
- package/lib/esm/src/line-number-prefix.js +5 -0
- package/lib/esm/src/render-word-diff.js +211 -0
- package/lib/esm/src/skipped-line-indicator.js +29 -0
- package/lib/esm/src/styles.js +431 -0
- package/lib/esm/src/workerBundle.js +7 -0
- package/package.json +90 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ReactElement, RefObject } from "react";
|
|
3
|
+
import type { Change } from "diff";
|
|
4
|
+
import { type DiffInformation, DiffMethod, DiffType } from "./compute-lines.js";
|
|
5
|
+
import { LineNumberPrefix } from "./line-number-prefix.js";
|
|
6
|
+
import type { ReactDiffViewerStyles } from "./styles.js";
|
|
7
|
+
export interface DiffRowProps {
|
|
8
|
+
leftLineNumber: number | undefined;
|
|
9
|
+
leftType: DiffType;
|
|
10
|
+
leftValue: string | DiffInformation[];
|
|
11
|
+
rightLineNumber: number | undefined;
|
|
12
|
+
rightType: DiffType;
|
|
13
|
+
rightValue: string | DiffInformation[];
|
|
14
|
+
highlightLeft: boolean;
|
|
15
|
+
highlightRight: boolean;
|
|
16
|
+
splitView: boolean;
|
|
17
|
+
hideLineNumbers: boolean;
|
|
18
|
+
styles: ReactDiffViewerStyles;
|
|
19
|
+
onLineNumberClick?: (lineId: string, event: React.MouseEvent<HTMLTableCellElement>) => void;
|
|
20
|
+
renderContent?: (source: string) => ReactElement;
|
|
21
|
+
renderGutter?: (data: {
|
|
22
|
+
lineNumber: number;
|
|
23
|
+
type: DiffType;
|
|
24
|
+
prefix: LineNumberPrefix;
|
|
25
|
+
value: string | DiffInformation[];
|
|
26
|
+
additionalLineNumber: number;
|
|
27
|
+
additionalPrefix: LineNumberPrefix;
|
|
28
|
+
styles: ReactDiffViewerStyles;
|
|
29
|
+
}) => ReactElement;
|
|
30
|
+
compareMethod: DiffMethod | ((oldStr: string, newStr: string) => Change[]);
|
|
31
|
+
contentColumnRef?: RefObject<HTMLTableCellElement | null>;
|
|
32
|
+
hasCumulativeOffsets: boolean;
|
|
33
|
+
index: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Memoized component that renders a single diff row (split or inline view).
|
|
37
|
+
* Only re-renders when the line data, highlight state, or display config changes.
|
|
38
|
+
* Function props (callbacks, renderers) are excluded from the equality check.
|
|
39
|
+
*/
|
|
40
|
+
export declare const DiffRow: React.NamedExoticComponent<DiffRowProps>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import cn from "classnames";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { DiffType, } from "./compute-lines.js";
|
|
5
|
+
import { LineNumberPrefix } from "./line-number-prefix.js";
|
|
6
|
+
import { renderWordDiff } from "./render-word-diff.js";
|
|
7
|
+
/**
|
|
8
|
+
* Custom equality function for React.memo — compares only data props, skips functions.
|
|
9
|
+
*/
|
|
10
|
+
function diffRowPropsAreEqual(prev, next) {
|
|
11
|
+
return (prev.leftLineNumber === next.leftLineNumber &&
|
|
12
|
+
prev.leftType === next.leftType &&
|
|
13
|
+
prev.leftValue === next.leftValue &&
|
|
14
|
+
prev.rightLineNumber === next.rightLineNumber &&
|
|
15
|
+
prev.rightType === next.rightType &&
|
|
16
|
+
prev.rightValue === next.rightValue &&
|
|
17
|
+
prev.highlightLeft === next.highlightLeft &&
|
|
18
|
+
prev.highlightRight === next.highlightRight &&
|
|
19
|
+
prev.splitView === next.splitView &&
|
|
20
|
+
prev.hideLineNumbers === next.hideLineNumbers &&
|
|
21
|
+
prev.styles === next.styles &&
|
|
22
|
+
prev.contentColumnRef === next.contentColumnRef &&
|
|
23
|
+
prev.hasCumulativeOffsets === next.hasCumulativeOffsets);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Renders a single line (one side of split view, or one line in inline view).
|
|
27
|
+
* This produces the <td> cells for gutter, marker, and content.
|
|
28
|
+
*/
|
|
29
|
+
function renderLine(lineNumber, type, prefix, value, highlightLine, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, contentColumnRef, hasCumulativeOffsets, additionalLineNumber, additionalPrefix) {
|
|
30
|
+
const lineNumberTemplate = `${prefix}-${lineNumber}`;
|
|
31
|
+
const additionalLineNumberTemplate = `${additionalPrefix}-${additionalLineNumber}`;
|
|
32
|
+
const added = type === DiffType.ADDED;
|
|
33
|
+
const removed = type === DiffType.REMOVED;
|
|
34
|
+
const changed = type === DiffType.CHANGED;
|
|
35
|
+
let content;
|
|
36
|
+
const hasWordDiff = Array.isArray(value);
|
|
37
|
+
if (hasWordDiff) {
|
|
38
|
+
content = renderWordDiff(value, styles, compareMethod, renderContent);
|
|
39
|
+
}
|
|
40
|
+
else if (renderContent) {
|
|
41
|
+
content = renderContent(value);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
content = value;
|
|
45
|
+
}
|
|
46
|
+
let ElementType = "div";
|
|
47
|
+
if (added && !hasWordDiff) {
|
|
48
|
+
ElementType = "ins";
|
|
49
|
+
}
|
|
50
|
+
else if (removed && !hasWordDiff) {
|
|
51
|
+
ElementType = "del";
|
|
52
|
+
}
|
|
53
|
+
const handleLineNumberClick = lineNumber && onLineNumberClick
|
|
54
|
+
? (e) => onLineNumberClick(lineNumberTemplate, e)
|
|
55
|
+
: undefined;
|
|
56
|
+
const handleAdditionalLineNumberClick = additionalLineNumber && onLineNumberClick
|
|
57
|
+
? (e) => onLineNumberClick(additionalLineNumberTemplate, e)
|
|
58
|
+
: undefined;
|
|
59
|
+
// Determine if this content cell should get the measurement ref
|
|
60
|
+
const shouldSetRef = prefix === LineNumberPrefix.LEFT && !hasCumulativeOffsets;
|
|
61
|
+
return (_jsxs(_Fragment, { children: [!hideLineNumbers && (_jsx("td", { onClick: handleLineNumberClick, className: cn(styles.gutter, {
|
|
62
|
+
[styles.emptyGutter]: !lineNumber,
|
|
63
|
+
[styles.diffAdded]: added,
|
|
64
|
+
[styles.diffRemoved]: removed,
|
|
65
|
+
[styles.diffChanged]: changed,
|
|
66
|
+
[styles.highlightedGutter]: highlightLine,
|
|
67
|
+
}), children: _jsx("pre", { className: styles.lineNumber, children: lineNumber }) })), !splitView && !hideLineNumbers && (_jsx("td", { onClick: handleAdditionalLineNumberClick, className: cn(styles.gutter, {
|
|
68
|
+
[styles.emptyGutter]: !additionalLineNumber,
|
|
69
|
+
[styles.diffAdded]: added,
|
|
70
|
+
[styles.diffRemoved]: removed,
|
|
71
|
+
[styles.diffChanged]: changed,
|
|
72
|
+
[styles.highlightedGutter]: highlightLine,
|
|
73
|
+
}), children: _jsx("pre", { className: styles.lineNumber, children: additionalLineNumber }) })), renderGutter
|
|
74
|
+
? renderGutter({
|
|
75
|
+
lineNumber,
|
|
76
|
+
type,
|
|
77
|
+
prefix,
|
|
78
|
+
value,
|
|
79
|
+
additionalLineNumber,
|
|
80
|
+
additionalPrefix,
|
|
81
|
+
styles,
|
|
82
|
+
})
|
|
83
|
+
: null, _jsx("td", { className: cn(styles.marker, {
|
|
84
|
+
[styles.emptyLine]: !content,
|
|
85
|
+
[styles.diffAdded]: added,
|
|
86
|
+
[styles.diffRemoved]: removed,
|
|
87
|
+
[styles.diffChanged]: changed,
|
|
88
|
+
[styles.highlightedLine]: highlightLine,
|
|
89
|
+
}), children: _jsxs("pre", { children: [added && "+", removed && "-"] }) }), _jsx("td", { ref: shouldSetRef ? contentColumnRef : undefined, className: cn(styles.content, {
|
|
90
|
+
[styles.emptyLine]: !content,
|
|
91
|
+
[styles.diffAdded]: added,
|
|
92
|
+
[styles.diffRemoved]: removed,
|
|
93
|
+
[styles.diffChanged]: changed,
|
|
94
|
+
[styles.highlightedLine]: highlightLine,
|
|
95
|
+
left: prefix === LineNumberPrefix.LEFT,
|
|
96
|
+
right: prefix === LineNumberPrefix.RIGHT,
|
|
97
|
+
}), onMouseDown: () => {
|
|
98
|
+
const elements = document.getElementsByClassName(prefix === LineNumberPrefix.LEFT ? "right" : "left");
|
|
99
|
+
for (let i = 0; i < elements.length; i++) {
|
|
100
|
+
const element = elements.item(i);
|
|
101
|
+
element.classList.add(styles.noSelect);
|
|
102
|
+
}
|
|
103
|
+
}, title: added && !hasWordDiff
|
|
104
|
+
? "Added line"
|
|
105
|
+
: removed && !hasWordDiff
|
|
106
|
+
? "Removed line"
|
|
107
|
+
: undefined, children: _jsx(ElementType, { className: styles.contentText, children: content }) })] }));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Memoized component that renders a single diff row (split or inline view).
|
|
111
|
+
* Only re-renders when the line data, highlight state, or display config changes.
|
|
112
|
+
* Function props (callbacks, renderers) are excluded from the equality check.
|
|
113
|
+
*/
|
|
114
|
+
export const DiffRow = React.memo(function DiffRow(props) {
|
|
115
|
+
const { leftLineNumber, leftType, leftValue, rightLineNumber, rightType, rightValue, highlightLeft, highlightRight, splitView, hideLineNumbers, styles, onLineNumberClick, renderContent, renderGutter, compareMethod, contentColumnRef, hasCumulativeOffsets, index, } = props;
|
|
116
|
+
if (splitView) {
|
|
117
|
+
// Split view: one <tr> with left and right cells
|
|
118
|
+
return (_jsxs("tr", { className: styles.line, children: [renderLine(leftLineNumber, leftType, LineNumberPrefix.LEFT, leftValue, highlightLeft, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, contentColumnRef, hasCumulativeOffsets), renderLine(rightLineNumber, rightType, LineNumberPrefix.RIGHT, rightValue, highlightRight, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter)] }, index));
|
|
119
|
+
}
|
|
120
|
+
// Inline view
|
|
121
|
+
if (leftType === DiffType.REMOVED && rightType === DiffType.ADDED) {
|
|
122
|
+
// Changed line: render two <tr> rows (removed then added)
|
|
123
|
+
return (_jsxs(React.Fragment, { children: [_jsx("tr", { className: styles.line, children: renderLine(leftLineNumber, leftType, LineNumberPrefix.LEFT, leftValue, highlightLeft, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, contentColumnRef, hasCumulativeOffsets, null) }), _jsx("tr", { className: styles.line, children: renderLine(null, rightType, LineNumberPrefix.RIGHT, rightValue, highlightRight, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, undefined, undefined, rightLineNumber, LineNumberPrefix.RIGHT) })] }, index));
|
|
124
|
+
}
|
|
125
|
+
let content;
|
|
126
|
+
if (leftType === DiffType.REMOVED) {
|
|
127
|
+
content = renderLine(leftLineNumber, leftType, LineNumberPrefix.LEFT, leftValue, highlightLeft, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, contentColumnRef, hasCumulativeOffsets, null);
|
|
128
|
+
}
|
|
129
|
+
if (leftType === DiffType.DEFAULT) {
|
|
130
|
+
content = renderLine(leftLineNumber, leftType, LineNumberPrefix.LEFT, leftValue, highlightLeft, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, contentColumnRef, hasCumulativeOffsets, rightLineNumber, LineNumberPrefix.RIGHT);
|
|
131
|
+
}
|
|
132
|
+
if (rightType === DiffType.ADDED) {
|
|
133
|
+
content = renderLine(null, rightType, LineNumberPrefix.RIGHT, rightValue, highlightRight, styles, splitView, hideLineNumbers, compareMethod, onLineNumberClick, renderContent, renderGutter, undefined, undefined, rightLineNumber);
|
|
134
|
+
}
|
|
135
|
+
return (_jsx("tr", { className: styles.line, children: content }, index));
|
|
136
|
+
}, diffRowPropsAreEqual);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Expand(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function Expand() {
|
|
3
|
+
return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", width: "16", height: "16", children: [_jsx("title", { children: "expand" }), _jsx("path", { d: "m8.177.677 2.896 2.896a.25.25 0 0 1-.177.427H8.75v1.25a.75.75 0 0 1-1.5 0V4H5.104a.25.25 0 0 1-.177-.427L7.823.677a.25.25 0 0 1 .354 0ZM7.25 10.75a.75.75 0 0 1 1.5 0V12h2.146a.25.25 0 0 1 .177.427l-2.896 2.896a.25.25 0 0 1-.354 0l-2.896-2.896A.25.25 0 0 1 5.104 12H7.25v-1.25Zm-5-2a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 6 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 12 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z" })] }));
|
|
4
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Fold(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function Fold() {
|
|
3
|
+
return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", width: "16", height: "16", children: [_jsx("title", { children: "fold" }), _jsx("path", { d: "M10.896 2H8.75V.75a.75.75 0 0 0-1.5 0V2H5.104a.25.25 0 0 0-.177.427l2.896 2.896a.25.25 0 0 0 .354 0l2.896-2.896A.25.25 0 0 0 10.896 2ZM8.75 15.25a.75.75 0 0 1-1.5 0V14H5.104a.25.25 0 0 1-.177-.427l2.896-2.896a.25.25 0 0 1 .354 0l2.896 2.896a.25.25 0 0 1-.177.427H8.75v1.25Zm-6.5-6.5a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 6 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 12 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z" })] }));
|
|
4
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ReactElement, RefObject } from "react";
|
|
3
|
+
import type { Change } from "diff";
|
|
4
|
+
import { type Block } from "./compute-hidden-blocks.js";
|
|
5
|
+
import { type DiffInformation, DiffMethod, DiffType, type LineInformation } from "./compute-lines.js";
|
|
6
|
+
import { type ReactDiffViewerStyles, type ReactDiffViewerStylesOverride } from "./styles.js";
|
|
7
|
+
import { LineNumberPrefix } from "./line-number-prefix.js";
|
|
8
|
+
import { type CommentRenderData } from "./comment-row.js";
|
|
9
|
+
export { LineNumberPrefix } from "./line-number-prefix.js";
|
|
10
|
+
export interface InfiniteLoadingProps {
|
|
11
|
+
pageSize: number;
|
|
12
|
+
containerHeight: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ComputedDiffResult {
|
|
15
|
+
lineInformation: LineInformation[];
|
|
16
|
+
lineBlocks: Record<number, number>;
|
|
17
|
+
blocks: Block[];
|
|
18
|
+
}
|
|
19
|
+
export interface ReactDiffViewerProps {
|
|
20
|
+
oldValue: string | Record<string, unknown>;
|
|
21
|
+
newValue: string | Record<string, unknown>;
|
|
22
|
+
splitView?: boolean;
|
|
23
|
+
linesOffset?: number;
|
|
24
|
+
disableWordDiff?: boolean;
|
|
25
|
+
compareMethod?: DiffMethod | ((oldStr: string, newStr: string) => Change[]);
|
|
26
|
+
extraLinesSurroundingDiff?: number;
|
|
27
|
+
hideLineNumbers?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Show the lines indicated here. Specified as L20 or R18 for respectively line 20 on the left or line 18 on the right.
|
|
30
|
+
*/
|
|
31
|
+
alwaysShowLines?: string[];
|
|
32
|
+
showDiffOnly?: boolean;
|
|
33
|
+
renderContent?: (source: string) => ReactElement;
|
|
34
|
+
codeFoldMessageRenderer?: (totalFoldedLines: number, leftStartLineNumber: number, rightStartLineNumber: number) => ReactElement;
|
|
35
|
+
onLineNumberClick?: (lineId: string, event: React.MouseEvent<HTMLTableCellElement>) => void;
|
|
36
|
+
renderGutter?: (data: {
|
|
37
|
+
lineNumber: number;
|
|
38
|
+
type: DiffType;
|
|
39
|
+
prefix: LineNumberPrefix;
|
|
40
|
+
value: string | DiffInformation[];
|
|
41
|
+
additionalLineNumber: number;
|
|
42
|
+
additionalPrefix: LineNumberPrefix;
|
|
43
|
+
styles: ReactDiffViewerStyles;
|
|
44
|
+
}) => ReactElement;
|
|
45
|
+
highlightLines?: string[];
|
|
46
|
+
styles?: ReactDiffViewerStylesOverride;
|
|
47
|
+
useDarkTheme?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Used to describe the thing being diffed
|
|
50
|
+
*/
|
|
51
|
+
summary?: string | ReactElement;
|
|
52
|
+
leftTitle?: string | ReactElement;
|
|
53
|
+
rightTitle?: string | ReactElement;
|
|
54
|
+
nonce?: string;
|
|
55
|
+
/**
|
|
56
|
+
* to enable infiniteLoading for better performance
|
|
57
|
+
*/
|
|
58
|
+
infiniteLoading?: InfiniteLoadingProps;
|
|
59
|
+
/**
|
|
60
|
+
* to display loading element when diff is being computed
|
|
61
|
+
*/
|
|
62
|
+
loadingElement?: () => ReactElement;
|
|
63
|
+
/**
|
|
64
|
+
* Hide the summary bar (expand/collapse button, change count, filename)
|
|
65
|
+
*/
|
|
66
|
+
hideSummary?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Show debug overlay with virtualization info (for development)
|
|
69
|
+
*/
|
|
70
|
+
showDebugInfo?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Array of line IDs that have comments to display.
|
|
73
|
+
* Uses the same format as highlightLines: "L-{num}" or "R-{num}".
|
|
74
|
+
* The library renders a comment <tr> below each line in this set,
|
|
75
|
+
* invoking renderComment to get the content.
|
|
76
|
+
*/
|
|
77
|
+
commentLineIds?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* Render prop called for each line ID in commentLineIds.
|
|
80
|
+
* Returns the consumer's comment UI to display in the comment row.
|
|
81
|
+
* The returned ReactElement is placed inside a <td> spanning the full table width.
|
|
82
|
+
*/
|
|
83
|
+
renderComment?: (data: CommentRenderData) => ReactElement | null;
|
|
84
|
+
/**
|
|
85
|
+
* Estimated height (px) for comment rows before they are measured.
|
|
86
|
+
* Affects virtualization scroll accuracy. Defaults to 100.
|
|
87
|
+
*/
|
|
88
|
+
estimatedCommentRowHeight?: number;
|
|
89
|
+
}
|
|
90
|
+
export interface ReactDiffViewerState {
|
|
91
|
+
expandedBlocks?: number[];
|
|
92
|
+
noSelect?: "left" | "right";
|
|
93
|
+
scrollableContainerRef: RefObject<HTMLDivElement>;
|
|
94
|
+
computedDiffResult: Record<string, ComputedDiffResult>;
|
|
95
|
+
isLoading: boolean;
|
|
96
|
+
visibleStartRow: number;
|
|
97
|
+
contentColumnWidth: number | null;
|
|
98
|
+
charWidth: number | null;
|
|
99
|
+
cumulativeOffsets: number[] | null;
|
|
100
|
+
}
|
|
101
|
+
declare class DiffViewer extends React.Component<ReactDiffViewerProps, ReactDiffViewerState> {
|
|
102
|
+
private styles;
|
|
103
|
+
private wordDiffCache;
|
|
104
|
+
private contentColumnRef;
|
|
105
|
+
private charMeasureRef;
|
|
106
|
+
private stickyHeaderRef;
|
|
107
|
+
private resizeObserver;
|
|
108
|
+
private commentRowObserver;
|
|
109
|
+
private commentRowHeights;
|
|
110
|
+
private commentRowElements;
|
|
111
|
+
private commentRowRefCache;
|
|
112
|
+
private pendingOffsetRecalc;
|
|
113
|
+
private static readonly ESTIMATED_COMMENT_ROW_HEIGHT;
|
|
114
|
+
/**
|
|
115
|
+
* Shallow comparison for string arrays — avoids unnecessary work when
|
|
116
|
+
* the consumer creates a new array reference with identical contents.
|
|
117
|
+
*/
|
|
118
|
+
private static shallowArrayEqual;
|
|
119
|
+
static defaultProps: ReactDiffViewerProps;
|
|
120
|
+
constructor(props: ReactDiffViewerProps);
|
|
121
|
+
/**
|
|
122
|
+
* Memoized conversion of commentLineIds array to Set for O(1) lookups.
|
|
123
|
+
*/
|
|
124
|
+
private getCommentLineIdsSet;
|
|
125
|
+
/**
|
|
126
|
+
* Memoized conversion of highlightLines array to Set for O(1) lookups.
|
|
127
|
+
*/
|
|
128
|
+
private getHighlightLinesSet;
|
|
129
|
+
/**
|
|
130
|
+
* Creates a ref callback for a CommentRow's <tr> element.
|
|
131
|
+
* When mounted, observes it for height changes via ResizeObserver.
|
|
132
|
+
* Callbacks are cached per lineId to avoid creating new closures on every render.
|
|
133
|
+
*/
|
|
134
|
+
private getCommentRowRef;
|
|
135
|
+
/**
|
|
136
|
+
* Debounced offset recalculation — batches multiple ResizeObserver callbacks
|
|
137
|
+
* into a single requestAnimationFrame.
|
|
138
|
+
*/
|
|
139
|
+
private scheduleOffsetRecalc;
|
|
140
|
+
/**
|
|
141
|
+
* Initializes the ResizeObserver for measuring comment row heights.
|
|
142
|
+
*/
|
|
143
|
+
private initCommentRowObserver;
|
|
144
|
+
/**
|
|
145
|
+
* Computes word diff on-demand for a line, with caching.
|
|
146
|
+
* This is used when word diff was deferred during initial computation.
|
|
147
|
+
*/
|
|
148
|
+
private getWordDiffValues;
|
|
149
|
+
/**
|
|
150
|
+
* Resets code block expand to the initial stage. Will be exposed to the parent component via
|
|
151
|
+
* refs.
|
|
152
|
+
*/
|
|
153
|
+
resetCodeBlocks: () => boolean;
|
|
154
|
+
/**
|
|
155
|
+
* Pushes the target expanded code block to the state. During the re-render,
|
|
156
|
+
* this value is used to expand/fold unmodified code.
|
|
157
|
+
*/
|
|
158
|
+
private onBlockExpand;
|
|
159
|
+
/**
|
|
160
|
+
* Gets the height of the sticky header, if present.
|
|
161
|
+
*/
|
|
162
|
+
private getStickyHeaderHeight;
|
|
163
|
+
/**
|
|
164
|
+
* Measures the width of a single character in the monospace font.
|
|
165
|
+
* Falls back to 7.2px if measurement fails.
|
|
166
|
+
*/
|
|
167
|
+
private measureCharWidth;
|
|
168
|
+
/**
|
|
169
|
+
* Measures the available width for content in a content column.
|
|
170
|
+
* Falls back to estimating from container width if direct measurement fails.
|
|
171
|
+
*/
|
|
172
|
+
private measureContentColumnWidth;
|
|
173
|
+
/**
|
|
174
|
+
* Gets the text length from a value that may be a string or DiffInformation array.
|
|
175
|
+
*/
|
|
176
|
+
private getTextLength;
|
|
177
|
+
/**
|
|
178
|
+
* Builds cumulative vertical offsets for each line based on character count and column width.
|
|
179
|
+
* This allows accurate scroll position calculations with variable row heights.
|
|
180
|
+
*/
|
|
181
|
+
private buildCumulativeOffsets;
|
|
182
|
+
/**
|
|
183
|
+
* Binary search to find the line index at a given scroll offset.
|
|
184
|
+
*/
|
|
185
|
+
private findLineAtOffset;
|
|
186
|
+
/**
|
|
187
|
+
* Recalculates cumulative offsets based on current measurements.
|
|
188
|
+
* Called on resize and when blocks are expanded/collapsed.
|
|
189
|
+
*/
|
|
190
|
+
private recalculateOffsets;
|
|
191
|
+
/**
|
|
192
|
+
* Computes final styles for the diff viewer. It combines the default styles with the user
|
|
193
|
+
* supplied overrides. The computed styles are cached with performance in mind.
|
|
194
|
+
*
|
|
195
|
+
* @param styles User supplied style overrides.
|
|
196
|
+
*/
|
|
197
|
+
private computeStyles;
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
* Generates a unique cache key based on the current props used in diff computation.
|
|
201
|
+
*
|
|
202
|
+
* This key is used to memoize results and avoid recomputation for the same inputs.
|
|
203
|
+
* @returns A stringified JSON key representing the current diff settings and input values.
|
|
204
|
+
*
|
|
205
|
+
*/
|
|
206
|
+
private getMemoisedKey;
|
|
207
|
+
/**
|
|
208
|
+
* Computes and memoizes the diff result between `oldValue` and `newValue`.
|
|
209
|
+
*
|
|
210
|
+
* If a memoized result exists for the current input configuration, it uses that.
|
|
211
|
+
* Otherwise, it runs the diff logic in a Web Worker to avoid blocking the UI.
|
|
212
|
+
* It also computes hidden line blocks for collapsing unchanged sections,
|
|
213
|
+
* and stores the result in the local component state.
|
|
214
|
+
*/
|
|
215
|
+
private memoisedCompute;
|
|
216
|
+
private static readonly ESTIMATED_ROW_HEIGHT;
|
|
217
|
+
/**
|
|
218
|
+
* Handles scroll events on the scrollable container.
|
|
219
|
+
*
|
|
220
|
+
* Updates the visible start row for virtualization.
|
|
221
|
+
*/
|
|
222
|
+
private onScroll;
|
|
223
|
+
/**
|
|
224
|
+
* Generates the entire diff view with virtualization support.
|
|
225
|
+
*/
|
|
226
|
+
private renderDiff;
|
|
227
|
+
componentDidUpdate(prevProps: ReactDiffViewerProps): void;
|
|
228
|
+
componentDidMount(): void;
|
|
229
|
+
componentWillUnmount(): void;
|
|
230
|
+
render: () => ReactElement;
|
|
231
|
+
}
|
|
232
|
+
export default DiffViewer;
|
|
233
|
+
export { DiffMethod };
|
|
234
|
+
export { default as computeStyles } from "./styles.js";
|
|
235
|
+
export type { ReactDiffViewerStylesOverride, ReactDiffViewerStyles };
|
|
236
|
+
export type { CommentRenderData } from "./comment-row.js";
|