@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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +521 -0
  3. package/lib/cjs/src/comment-row.d.ts +33 -0
  4. package/lib/cjs/src/comment-row.js +58 -0
  5. package/lib/cjs/src/compute-hidden-blocks.d.ts +13 -0
  6. package/lib/cjs/src/compute-hidden-blocks.js +36 -0
  7. package/lib/cjs/src/compute-lines.d.ts +68 -0
  8. package/lib/cjs/src/compute-lines.js +559 -0
  9. package/lib/cjs/src/computeWorker.d.ts +1 -0
  10. package/lib/cjs/src/computeWorker.js +10 -0
  11. package/lib/cjs/src/diff-row.d.ts +40 -0
  12. package/lib/cjs/src/diff-row.js +136 -0
  13. package/lib/cjs/src/expand.d.ts +1 -0
  14. package/lib/cjs/src/expand.js +4 -0
  15. package/lib/cjs/src/fold.d.ts +1 -0
  16. package/lib/cjs/src/fold.js +4 -0
  17. package/lib/cjs/src/index.d.ts +236 -0
  18. package/lib/cjs/src/index.js +783 -0
  19. package/lib/cjs/src/line-number-prefix.d.ts +4 -0
  20. package/lib/cjs/src/line-number-prefix.js +5 -0
  21. package/lib/cjs/src/render-word-diff.d.ts +22 -0
  22. package/lib/cjs/src/render-word-diff.js +212 -0
  23. package/lib/cjs/src/skipped-line-indicator.d.ts +29 -0
  24. package/lib/cjs/src/skipped-line-indicator.js +29 -0
  25. package/lib/cjs/src/styles.d.ts +102 -0
  26. package/lib/cjs/src/styles.js +430 -0
  27. package/lib/cjs/src/workerBundle.d.ts +5 -0
  28. package/lib/cjs/src/workerBundle.js +7 -0
  29. package/lib/esm/src/comment-row.js +58 -0
  30. package/lib/esm/src/compute-hidden-blocks.js +36 -0
  31. package/lib/esm/src/compute-lines.js +559 -0
  32. package/lib/esm/src/computeWorker.js +10 -0
  33. package/lib/esm/src/diff-row.js +136 -0
  34. package/lib/esm/src/expand.js +4 -0
  35. package/lib/esm/src/fold.js +4 -0
  36. package/lib/esm/src/index.js +780 -0
  37. package/lib/esm/src/line-number-prefix.js +5 -0
  38. package/lib/esm/src/render-word-diff.js +211 -0
  39. package/lib/esm/src/skipped-line-indicator.js +29 -0
  40. package/lib/esm/src/styles.js +431 -0
  41. package/lib/esm/src/workerBundle.js +7 -0
  42. package/package.json +90 -0
@@ -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,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,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
+ }