react-diff-viewer-continued 3.3.1 → 4.0.1
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/.github/workflows/release.yml +1 -0
- package/CHANGELOG.md +24 -2
- package/lib/src/compute-hidden-blocks.d.ts +1 -1
- package/lib/src/compute-lines.js +1 -1
- package/lib/src/expand.d.ts +1 -0
- package/lib/src/expand.js +8 -0
- package/lib/src/fold.d.ts +1 -0
- package/lib/src/fold.js +8 -0
- package/lib/src/index.d.ts +9 -2
- package/lib/src/index.js +111 -31
- package/lib/src/styles.d.ts +6 -0
- package/lib/src/styles.js +67 -10
- package/package.json +1 -1
- package/release.config.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [4.0.1](https://github.com/aeolun/react-diff-viewer-continued/compare/v4.0.0...v4.0.1) (2023-11-01)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* publish files on 4.x ([650c249](https://github.com/aeolun/react-diff-viewer-continued/commit/650c249c5bf1d8b27d780b65555df5ae0f5d9e2b))
|
|
7
|
+
|
|
8
|
+
# [4.0.0](https://github.com/aeolun/react-diff-viewer-continued/compare/v3.3.0...v4.0.0) (2023-10-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* do not trim trailing newlines (fixes [#27](https://github.com/aeolun/react-diff-viewer-continued/issues/27)) ([ee4d53f](https://github.com/aeolun/react-diff-viewer-continued/commit/ee4d53f8e2ba3e374b51bffef3a00d3fe6206d02))
|
|
14
|
+
* use semantic elements for diff elements (fixes [#23](https://github.com/aeolun/react-diff-viewer-continued/issues/23)) ([a6222c7](https://github.com/aeolun/react-diff-viewer-continued/commit/a6222c7af151e7dc29046c8eac916271866b4899))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
* feat!: diff/flexbox based layout, text selectable per side (fixes #15) ([9f6c4d5](https://github.com/aeolun/react-diff-viewer-continued/commit/9f6c4d59e84ecb44761c39e172ffab6a689d5779)), closes [#15](https://github.com/aeolun/react-diff-viewer-continued/issues/15)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* add summary element and fold expansion/folding (fixes [#22](https://github.com/aeolun/react-diff-viewer-continued/issues/22), [#21](https://github.com/aeolun/react-diff-viewer-continued/issues/21)) ([e47cbe1](https://github.com/aeolun/react-diff-viewer-continued/commit/e47cbe1286a2143b0f8078a683e96edea0ed967b))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### BREAKING CHANGES
|
|
26
|
+
|
|
27
|
+
* This completely modifies the way react-diff-viewer-continued is rendered. The overall
|
|
28
|
+
layout should be more or less the same, but with the new layout probably come new bugs.
|
|
7
29
|
|
|
8
30
|
# [3.3.0](https://github.com/aeolun/react-diff-viewer-continued/compare/v3.2.6...v3.3.0) (2023-10-17)
|
|
9
31
|
|
package/lib/src/compute-lines.js
CHANGED
|
@@ -112,7 +112,7 @@ const computeLineInformation = (oldString, newString, disableWordDiff = false, l
|
|
|
112
112
|
let diffArray = [];
|
|
113
113
|
// Use diffLines for strings, and diffJson for objects...
|
|
114
114
|
if (typeof oldString === 'string' && typeof newString === 'string') {
|
|
115
|
-
diffArray = diff.diffLines(oldString
|
|
115
|
+
diffArray = diff.diffLines(oldString, newString, {
|
|
116
116
|
newlineIsToken: false,
|
|
117
117
|
ignoreWhitespace: false,
|
|
118
118
|
ignoreCase: false,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Expand(): JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Expand = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
function Expand() {
|
|
6
|
+
return (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", width: "16", height: "16", children: (0, jsx_runtime_1.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" }) });
|
|
7
|
+
}
|
|
8
|
+
exports.Expand = Expand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Fold(): JSX.Element;
|
package/lib/src/fold.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Fold = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
function Fold() {
|
|
6
|
+
return (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", width: "16", height: "16", children: (0, jsx_runtime_1.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" }) });
|
|
7
|
+
}
|
|
8
|
+
exports.Fold = Fold;
|
package/lib/src/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
2
3
|
import { DiffInformation, DiffMethod, DiffType, LineInformation } from './compute-lines';
|
|
3
4
|
import { ReactDiffViewerStyles, ReactDiffViewerStylesOverride } from './styles';
|
|
4
|
-
import { ReactElement } from "react";
|
|
5
5
|
export declare enum LineNumberPrefix {
|
|
6
6
|
LEFT = "L",
|
|
7
7
|
RIGHT = "R"
|
|
@@ -35,6 +35,10 @@ export interface ReactDiffViewerProps {
|
|
|
35
35
|
highlightLines?: string[];
|
|
36
36
|
styles?: ReactDiffViewerStylesOverride;
|
|
37
37
|
useDarkTheme?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Used to describe the thing being diffed
|
|
40
|
+
*/
|
|
41
|
+
summary?: string | ReactElement;
|
|
38
42
|
leftTitle?: string | ReactElement;
|
|
39
43
|
rightTitle?: string | ReactElement;
|
|
40
44
|
nonce?: string;
|
|
@@ -108,7 +112,10 @@ declare class DiffViewer extends React.Component<ReactDiffViewerProps, ReactDiff
|
|
|
108
112
|
* @param obj.right Life diff information for the removed section of the inline view.
|
|
109
113
|
* @param index React key for the lines.
|
|
110
114
|
*/
|
|
111
|
-
renderInlineView: ({ left, right }: LineInformation, index: number) =>
|
|
115
|
+
renderInlineView: ({ left, right }: LineInformation, index: number) => {
|
|
116
|
+
left: ReactElement[];
|
|
117
|
+
right: ReactElement[];
|
|
118
|
+
};
|
|
112
119
|
/**
|
|
113
120
|
* Returns a function with clicked block number in the closure.
|
|
114
121
|
*
|
package/lib/src/index.js
CHANGED
|
@@ -34,6 +34,8 @@ const compute_lines_1 = require("./compute-lines");
|
|
|
34
34
|
Object.defineProperty(exports, "DiffMethod", { enumerable: true, get: function () { return compute_lines_1.DiffMethod; } });
|
|
35
35
|
const styles_1 = __importDefault(require("./styles"));
|
|
36
36
|
const compute_hidden_blocks_1 = require("./compute-hidden-blocks");
|
|
37
|
+
const expand_1 = require("./expand");
|
|
38
|
+
const fold_1 = require("./fold");
|
|
37
39
|
const m = require('memoize-one');
|
|
38
40
|
const memoize = m.default || m;
|
|
39
41
|
var LineNumberPrefix;
|
|
@@ -95,10 +97,14 @@ class DiffViewer extends React.Component {
|
|
|
95
97
|
*/
|
|
96
98
|
this.renderWordDiff = (diffArray, renderer) => {
|
|
97
99
|
return diffArray.map((wordDiff, i) => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
const content = renderer ? renderer(wordDiff.value) : wordDiff.value;
|
|
101
|
+
return wordDiff.type === compute_lines_1.DiffType.ADDED ?
|
|
102
|
+
(0, jsx_runtime_1.jsx)("ins", { className: (0, classnames_1.default)(this.styles.wordDiff, {
|
|
103
|
+
[this.styles.wordAdded]: wordDiff.type === compute_lines_1.DiffType.ADDED,
|
|
104
|
+
}), children: content }, i)
|
|
105
|
+
: wordDiff.type === compute_lines_1.DiffType.REMOVED ? (0, jsx_runtime_1.jsx)("del", { className: (0, classnames_1.default)(this.styles.wordDiff, {
|
|
106
|
+
[this.styles.wordRemoved]: wordDiff.type === compute_lines_1.DiffType.REMOVED,
|
|
107
|
+
}), children: content }, i) : (0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)(this.styles.wordDiff), children: content }, i);
|
|
102
108
|
});
|
|
103
109
|
};
|
|
104
110
|
/**
|
|
@@ -123,7 +129,8 @@ class DiffViewer extends React.Component {
|
|
|
123
129
|
const removed = type === compute_lines_1.DiffType.REMOVED;
|
|
124
130
|
const changed = type === compute_lines_1.DiffType.CHANGED;
|
|
125
131
|
let content;
|
|
126
|
-
|
|
132
|
+
const hasWordDiff = Array.isArray(value);
|
|
133
|
+
if (hasWordDiff) {
|
|
127
134
|
content = this.renderWordDiff(value, this.props.renderContent);
|
|
128
135
|
}
|
|
129
136
|
else if (this.props.renderContent) {
|
|
@@ -132,13 +139,20 @@ class DiffViewer extends React.Component {
|
|
|
132
139
|
else {
|
|
133
140
|
content = value;
|
|
134
141
|
}
|
|
135
|
-
|
|
142
|
+
let ElementType = 'div';
|
|
143
|
+
if (added && !hasWordDiff) {
|
|
144
|
+
ElementType = 'ins';
|
|
145
|
+
}
|
|
146
|
+
else if (removed && !hasWordDiff) {
|
|
147
|
+
ElementType = 'del';
|
|
148
|
+
}
|
|
149
|
+
return ((0, jsx_runtime_1.jsxs)(ElementType, { className: this.styles.line, role: 'row', title: added && !hasWordDiff ? "Added line" : removed && !hasWordDiff ? "Removed line" : undefined, children: [!this.props.hideLineNumbers && ((0, jsx_runtime_1.jsx)("div", { onClick: lineNumber && this.onLineNumberClickProxy(lineNumberTemplate), className: (0, classnames_1.default)(this.styles.gutter, {
|
|
136
150
|
[this.styles.emptyGutter]: !lineNumber,
|
|
137
151
|
[this.styles.diffAdded]: added,
|
|
138
152
|
[this.styles.diffRemoved]: removed,
|
|
139
153
|
[this.styles.diffChanged]: changed,
|
|
140
154
|
[this.styles.highlightedGutter]: highlightLine,
|
|
141
|
-
}), children: (0, jsx_runtime_1.jsx)("pre", { className: this.styles.lineNumber, children: lineNumber }) })), !this.props.splitView && !this.props.hideLineNumbers && ((0, jsx_runtime_1.jsx)("
|
|
155
|
+
}), children: (0, jsx_runtime_1.jsx)("pre", { className: this.styles.lineNumber, children: lineNumber }) })), !this.props.splitView && !this.props.hideLineNumbers && ((0, jsx_runtime_1.jsx)("div", { onClick: additionalLineNumber &&
|
|
142
156
|
this.onLineNumberClickProxy(additionalLineNumberTemplate), className: (0, classnames_1.default)(this.styles.gutter, {
|
|
143
157
|
[this.styles.emptyGutter]: !additionalLineNumber,
|
|
144
158
|
[this.styles.diffAdded]: added,
|
|
@@ -155,13 +169,13 @@ class DiffViewer extends React.Component {
|
|
|
155
169
|
additionalPrefix,
|
|
156
170
|
styles: this.styles,
|
|
157
171
|
})
|
|
158
|
-
: null, (0, jsx_runtime_1.jsx)("
|
|
172
|
+
: null, (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(this.styles.marker, {
|
|
159
173
|
[this.styles.emptyLine]: !content,
|
|
160
174
|
[this.styles.diffAdded]: added,
|
|
161
175
|
[this.styles.diffRemoved]: removed,
|
|
162
176
|
[this.styles.diffChanged]: changed,
|
|
163
177
|
[this.styles.highlightedLine]: highlightLine,
|
|
164
|
-
}), children: (0, jsx_runtime_1.jsxs)("pre", { children: [added && '+', removed && '-'] }) }), (0, jsx_runtime_1.jsx)("
|
|
178
|
+
}), children: (0, jsx_runtime_1.jsxs)("pre", { children: [added && '+', removed && '-'] }) }), (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(this.styles.lineContent, {
|
|
165
179
|
[this.styles.emptyLine]: !content,
|
|
166
180
|
[this.styles.diffAdded]: added,
|
|
167
181
|
[this.styles.diffRemoved]: removed,
|
|
@@ -178,7 +192,14 @@ class DiffViewer extends React.Component {
|
|
|
178
192
|
* @param index React key for the lines.
|
|
179
193
|
*/
|
|
180
194
|
this.renderSplitView = ({ left, right }, index) => {
|
|
181
|
-
return
|
|
195
|
+
return {
|
|
196
|
+
left: [
|
|
197
|
+
this.renderLine(left.lineNumber, left.type, LineNumberPrefix.LEFT, left.value)
|
|
198
|
+
],
|
|
199
|
+
right: [
|
|
200
|
+
this.renderLine(right.lineNumber, right.type, LineNumberPrefix.RIGHT, right.value)
|
|
201
|
+
]
|
|
202
|
+
};
|
|
182
203
|
};
|
|
183
204
|
/**
|
|
184
205
|
* Generates lines for inline view.
|
|
@@ -191,18 +212,42 @@ class DiffViewer extends React.Component {
|
|
|
191
212
|
this.renderInlineView = ({ left, right }, index) => {
|
|
192
213
|
let content;
|
|
193
214
|
if (left.type === compute_lines_1.DiffType.REMOVED && right.type === compute_lines_1.DiffType.ADDED) {
|
|
194
|
-
return
|
|
215
|
+
return {
|
|
216
|
+
left: [
|
|
217
|
+
this.renderLine(left.lineNumber, left.type, LineNumberPrefix.LEFT, left.value, null),
|
|
218
|
+
this.renderLine(null, right.type, LineNumberPrefix.RIGHT, right.value, right.lineNumber)
|
|
219
|
+
],
|
|
220
|
+
right: []
|
|
221
|
+
};
|
|
195
222
|
}
|
|
196
223
|
if (left.type === compute_lines_1.DiffType.REMOVED) {
|
|
197
|
-
|
|
224
|
+
return {
|
|
225
|
+
left: [
|
|
226
|
+
this.renderLine(left.lineNumber, left.type, LineNumberPrefix.LEFT, left.value, null)
|
|
227
|
+
],
|
|
228
|
+
right: []
|
|
229
|
+
};
|
|
198
230
|
}
|
|
199
231
|
if (left.type === compute_lines_1.DiffType.DEFAULT) {
|
|
200
|
-
|
|
232
|
+
return {
|
|
233
|
+
left: [
|
|
234
|
+
this.renderLine(left.lineNumber, left.type, LineNumberPrefix.LEFT, left.value, right.lineNumber, LineNumberPrefix.RIGHT)
|
|
235
|
+
],
|
|
236
|
+
right: []
|
|
237
|
+
};
|
|
201
238
|
}
|
|
202
239
|
if (right.type === compute_lines_1.DiffType.ADDED) {
|
|
203
|
-
|
|
240
|
+
return {
|
|
241
|
+
left: [
|
|
242
|
+
this.renderLine(null, right.type, LineNumberPrefix.RIGHT, right.value, right.lineNumber)
|
|
243
|
+
],
|
|
244
|
+
right: []
|
|
245
|
+
};
|
|
204
246
|
}
|
|
205
|
-
return
|
|
247
|
+
return {
|
|
248
|
+
left: [],
|
|
249
|
+
right: []
|
|
250
|
+
};
|
|
206
251
|
};
|
|
207
252
|
/**
|
|
208
253
|
* Returns a function with clicked block number in the closure.
|
|
@@ -222,11 +267,14 @@ class DiffViewer extends React.Component {
|
|
|
222
267
|
this.renderSkippedLineIndicator = (num, blockNumber, leftBlockLineNumber, rightBlockLineNumber) => {
|
|
223
268
|
const { hideLineNumbers, splitView } = this.props;
|
|
224
269
|
const message = this.props.codeFoldMessageRenderer ? (this.props.codeFoldMessageRenderer(num, leftBlockLineNumber, rightBlockLineNumber)) : ((0, jsx_runtime_1.jsxs)("pre", { className: this.styles.codeFoldContent, children: ["Expand ", num, " lines ..."] }));
|
|
225
|
-
const content = ((0, jsx_runtime_1.jsx)("
|
|
270
|
+
const content = ((0, jsx_runtime_1.jsx)("div", { className: this.styles.codeFoldContentContainer, children: (0, jsx_runtime_1.jsx)("a", { onClick: this.onBlockClickProxy(blockNumber), tabIndex: 0, children: message }) }));
|
|
226
271
|
const isUnifiedViewWithoutLineNumbers = !splitView && !hideLineNumbers;
|
|
227
|
-
return
|
|
228
|
-
|
|
229
|
-
|
|
272
|
+
return {
|
|
273
|
+
left: [(0, jsx_runtime_1.jsxs)("div", { className: this.styles.codeFold, children: [!hideLineNumbers && (0, jsx_runtime_1.jsx)("div", { className: this.styles.codeFoldGutter }), this.props.renderGutter ? ((0, jsx_runtime_1.jsx)("div", { className: this.styles.codeFoldGutter })) : null, (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)({
|
|
274
|
+
[this.styles.codeFoldGutter]: isUnifiedViewWithoutLineNumbers,
|
|
275
|
+
}) }), isUnifiedViewWithoutLineNumbers ? ((0, jsx_runtime_1.jsx)(React.Fragment, { children: content })) : ((0, jsx_runtime_1.jsx)(React.Fragment, { children: content }))] }, this.props.splitView ? `${leftBlockLineNumber}` : `${leftBlockLineNumber}-${rightBlockLineNumber}`)],
|
|
276
|
+
right: this.props.splitView ? [(0, jsx_runtime_1.jsx)("div", { className: this.styles.codeFold }, `${rightBlockLineNumber}`)] : []
|
|
277
|
+
};
|
|
230
278
|
};
|
|
231
279
|
/**
|
|
232
280
|
* Generates the entire diff view.
|
|
@@ -238,24 +286,30 @@ class DiffViewer extends React.Component {
|
|
|
238
286
|
? 0
|
|
239
287
|
: Math.round(this.props.extraLinesSurroundingDiff);
|
|
240
288
|
const { lineBlocks, blocks } = (0, compute_hidden_blocks_1.computeHiddenBlocks)(lineInformation, diffLines, extraLines);
|
|
241
|
-
|
|
289
|
+
const leftLines = [];
|
|
290
|
+
const rightLines = [];
|
|
291
|
+
lineInformation.forEach((line, lineIndex) => {
|
|
242
292
|
if (this.props.showDiffOnly) {
|
|
243
293
|
const blockIndex = lineBlocks[lineIndex];
|
|
244
294
|
if (blockIndex !== undefined) {
|
|
245
295
|
const lastLineOfBlock = blocks[blockIndex].endLine === lineIndex;
|
|
246
296
|
if (!this.state.expandedBlocks.includes(blockIndex) && lastLineOfBlock) {
|
|
247
|
-
|
|
297
|
+
const { left, right } = this.renderSkippedLineIndicator(blocks[blockIndex].lines, blockIndex, line.left.lineNumber, line.right.lineNumber);
|
|
298
|
+
leftLines.push(...left);
|
|
299
|
+
rightLines.push(...right);
|
|
248
300
|
}
|
|
249
301
|
else if (!this.state.expandedBlocks.includes(blockIndex)) {
|
|
250
302
|
return null;
|
|
251
303
|
}
|
|
252
304
|
}
|
|
253
305
|
}
|
|
254
|
-
const
|
|
306
|
+
const { left, right } = splitView
|
|
255
307
|
? this.renderSplitView(line, lineIndex)
|
|
256
308
|
: this.renderInlineView(line, lineIndex);
|
|
257
|
-
|
|
309
|
+
leftLines.push(...left);
|
|
310
|
+
rightLines.push(...right);
|
|
258
311
|
});
|
|
312
|
+
return { leftLines, rightLines, lineInformation, blocks };
|
|
259
313
|
};
|
|
260
314
|
this.render = () => {
|
|
261
315
|
const { oldValue, newValue, useDarkTheme, leftTitle, rightTitle, splitView, hideLineNumbers, nonce, } = this.props;
|
|
@@ -266,14 +320,40 @@ class DiffViewer extends React.Component {
|
|
|
266
320
|
}
|
|
267
321
|
this.styles = this.computeStyles(this.props.styles, useDarkTheme, nonce);
|
|
268
322
|
const nodes = this.renderDiff();
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
323
|
+
let deletions = 0, additions = 0;
|
|
324
|
+
nodes.lineInformation.forEach((l) => {
|
|
325
|
+
if (l.left.type === compute_lines_1.DiffType.ADDED) {
|
|
326
|
+
additions++;
|
|
327
|
+
}
|
|
328
|
+
if (l.right.type === compute_lines_1.DiffType.ADDED) {
|
|
329
|
+
additions++;
|
|
330
|
+
}
|
|
331
|
+
if (l.left.type === compute_lines_1.DiffType.REMOVED) {
|
|
332
|
+
deletions++;
|
|
333
|
+
}
|
|
334
|
+
if (l.right.type === compute_lines_1.DiffType.REMOVED) {
|
|
335
|
+
deletions++;
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
const totalChanges = deletions + additions;
|
|
339
|
+
const percentageAddition = Math.round((additions / totalChanges) * 100);
|
|
340
|
+
const blocks = [];
|
|
341
|
+
for (let i = 0; i < 5; i++) {
|
|
342
|
+
if (percentageAddition > i * 20) {
|
|
343
|
+
blocks.push((0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)(this.styles.block, this.styles.blockAddition) }, i));
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
blocks.push((0, jsx_runtime_1.jsx)("span", { className: (0, classnames_1.default)(this.styles.block, this.styles.blockDeletion) }, i));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const allExpanded = this.state.expandedBlocks.length === nodes.blocks.length;
|
|
350
|
+
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: this.styles.summary, role: 'banner', children: [(0, jsx_runtime_1.jsx)("a", { style: { cursor: 'pointer' }, onClick: () => {
|
|
351
|
+
this.setState({
|
|
352
|
+
expandedBlocks: allExpanded ? [] : nodes.blocks.map(b => b.index)
|
|
353
|
+
});
|
|
354
|
+
}, children: allExpanded ? (0, jsx_runtime_1.jsx)(fold_1.Fold, {}) : (0, jsx_runtime_1.jsx)(expand_1.Expand, {}) }), " ", totalChanges, " ", (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: '1px' }, children: blocks }), " ", this.props.summary ? (0, jsx_runtime_1.jsx)("span", { children: this.props.summary }) : null] }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(this.styles.diffContainer, {
|
|
355
|
+
[this.styles.splitView]: splitView,
|
|
356
|
+
}), children: [(0, jsx_runtime_1.jsxs)("div", { className: this.styles.column, role: 'table', title: `Diff information for ${leftTitle}`, children: [leftTitle ? (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(this.styles.titleBlock, this.styles.column), role: 'columnheader', children: (0, jsx_runtime_1.jsx)("pre", { className: this.styles.contentText, children: leftTitle }) }) : null, nodes.leftLines] }), nodes.rightLines.length > 0 ? (0, jsx_runtime_1.jsxs)("div", { className: this.styles.column, role: 'table', title: `Diff information for ${rightTitle}`, children: [rightTitle ? (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(this.styles.titleBlock, this.styles.column), role: 'columnheader', children: (0, jsx_runtime_1.jsx)("pre", { className: this.styles.contentText, children: rightTitle }) }) : null, nodes.rightLines] }) : null] })] }));
|
|
277
357
|
};
|
|
278
358
|
this.state = {
|
|
279
359
|
expandedBlocks: [],
|
package/lib/src/styles.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface ReactDiffViewerStyles {
|
|
|
7
7
|
line?: string;
|
|
8
8
|
highlightedGutter?: string;
|
|
9
9
|
contentText?: string;
|
|
10
|
+
lineContent?: string;
|
|
10
11
|
gutter?: string;
|
|
11
12
|
highlightedLine?: string;
|
|
12
13
|
lineNumber?: string;
|
|
@@ -15,11 +16,14 @@ export interface ReactDiffViewerStyles {
|
|
|
15
16
|
wordAdded?: string;
|
|
16
17
|
wordRemoved?: string;
|
|
17
18
|
codeFoldGutter?: string;
|
|
19
|
+
summary?: string;
|
|
20
|
+
codeFoldContentContainer?: string;
|
|
18
21
|
emptyGutter?: string;
|
|
19
22
|
emptyLine?: string;
|
|
20
23
|
codeFold?: string;
|
|
21
24
|
titleBlock?: string;
|
|
22
25
|
content?: string;
|
|
26
|
+
column?: string;
|
|
23
27
|
splitView?: string;
|
|
24
28
|
[key: string]: string | undefined;
|
|
25
29
|
}
|
|
@@ -71,9 +75,11 @@ export interface ReactDiffViewerStylesOverride {
|
|
|
71
75
|
wordAdded?: CSSInterpolation;
|
|
72
76
|
wordRemoved?: CSSInterpolation;
|
|
73
77
|
codeFoldGutter?: CSSInterpolation;
|
|
78
|
+
codeFoldContentContainer?: CSSInterpolation;
|
|
74
79
|
codeFold?: CSSInterpolation;
|
|
75
80
|
emptyLine?: CSSInterpolation;
|
|
76
81
|
content?: CSSInterpolation;
|
|
82
|
+
column?: CSSInterpolation;
|
|
77
83
|
titleBlock?: CSSInterpolation;
|
|
78
84
|
splitView?: CSSInterpolation;
|
|
79
85
|
}
|
package/lib/src/styles.js
CHANGED
|
@@ -70,7 +70,7 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
70
70
|
removedGutterColor: '#8c8c8c',
|
|
71
71
|
codeFoldContentColor: '#656a8b',
|
|
72
72
|
diffViewerTitleBackground: '#2f323e',
|
|
73
|
-
diffViewerTitleColor: '#
|
|
73
|
+
diffViewerTitleColor: '#757a9b',
|
|
74
74
|
diffViewerTitleBorderColor: '#353846',
|
|
75
75
|
}, (overrideVariables.dark || {})),
|
|
76
76
|
};
|
|
@@ -79,27 +79,39 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
79
79
|
const content = css({
|
|
80
80
|
width: '100%',
|
|
81
81
|
label: 'content',
|
|
82
|
+
flex: 1
|
|
82
83
|
});
|
|
83
84
|
const splitView = css({
|
|
84
|
-
[`.${content}`]: {
|
|
85
|
-
width: '50%',
|
|
86
|
-
},
|
|
87
85
|
label: 'split-view',
|
|
88
86
|
});
|
|
87
|
+
const summary = css({
|
|
88
|
+
background: variables.diffViewerTitleBackground,
|
|
89
|
+
color: variables.diffViewerTitleColor,
|
|
90
|
+
padding: '0.5em 1em',
|
|
91
|
+
display: 'flex',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
gap: '0.5em',
|
|
94
|
+
fontFamily: "monospace",
|
|
95
|
+
fill: variables.diffViewerTitleColor,
|
|
96
|
+
});
|
|
89
97
|
const diffContainer = css({
|
|
90
98
|
width: '100%',
|
|
99
|
+
minWidth: '1000px',
|
|
100
|
+
overflowX: 'auto',
|
|
91
101
|
background: variables.diffViewerBackground,
|
|
92
102
|
pre: {
|
|
93
103
|
margin: 0,
|
|
94
104
|
whiteSpace: 'pre-wrap',
|
|
95
|
-
lineHeight: '
|
|
105
|
+
lineHeight: '1.6em',
|
|
106
|
+
width: 'fit-content'
|
|
96
107
|
},
|
|
97
108
|
label: 'diff-container',
|
|
98
109
|
borderCollapse: 'collapse',
|
|
110
|
+
display: 'flex'
|
|
99
111
|
});
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
112
|
+
const lineContent = css({
|
|
113
|
+
overflow: 'hidden',
|
|
114
|
+
width: '100%'
|
|
103
115
|
});
|
|
104
116
|
const contentText = css({
|
|
105
117
|
color: variables.diffViewerColor,
|
|
@@ -107,7 +119,10 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
107
119
|
});
|
|
108
120
|
const titleBlock = css({
|
|
109
121
|
background: variables.diffViewerTitleBackground,
|
|
110
|
-
padding:
|
|
122
|
+
padding: '0.5em',
|
|
123
|
+
lineHeight: '1.4em',
|
|
124
|
+
height: "2.4em",
|
|
125
|
+
overflow: 'hidden',
|
|
111
126
|
borderBottom: `1px solid ${variables.diffViewerTitleBorderColor}`,
|
|
112
127
|
label: 'title-block',
|
|
113
128
|
':last-child': {
|
|
@@ -159,20 +174,48 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
159
174
|
});
|
|
160
175
|
const wordAdded = css({
|
|
161
176
|
background: variables.wordAddedBackground,
|
|
177
|
+
textDecoration: 'none',
|
|
162
178
|
label: 'word-added',
|
|
163
179
|
});
|
|
164
180
|
const wordRemoved = css({
|
|
165
181
|
background: variables.wordRemovedBackground,
|
|
182
|
+
textDecoration: 'none',
|
|
166
183
|
label: 'word-removed',
|
|
167
184
|
});
|
|
168
185
|
const codeFoldGutter = css({
|
|
169
186
|
backgroundColor: variables.codeFoldGutterBackground,
|
|
170
187
|
label: 'code-fold-gutter',
|
|
188
|
+
minWidth: '50px'
|
|
189
|
+
});
|
|
190
|
+
const codeFoldContentContainer = css({
|
|
191
|
+
padding: '8px 16px'
|
|
192
|
+
});
|
|
193
|
+
const codeFoldContent = css({
|
|
194
|
+
color: variables.codeFoldContentColor,
|
|
195
|
+
label: 'code-fold-content',
|
|
196
|
+
});
|
|
197
|
+
const block = css({
|
|
198
|
+
display: 'block',
|
|
199
|
+
width: '10px',
|
|
200
|
+
height: '10px',
|
|
201
|
+
backgroundColor: '#ddd',
|
|
202
|
+
borderWidth: '1px',
|
|
203
|
+
borderStyle: 'solid',
|
|
204
|
+
borderColor: variables.diffViewerTitleBorderColor
|
|
205
|
+
});
|
|
206
|
+
const blockAddition = css({
|
|
207
|
+
backgroundColor: variables.wordAddedBackground
|
|
208
|
+
});
|
|
209
|
+
const blockDeletion = css({
|
|
210
|
+
backgroundColor: variables.wordRemovedBackground
|
|
171
211
|
});
|
|
172
212
|
const codeFold = css({
|
|
173
213
|
backgroundColor: variables.codeFoldBackground,
|
|
174
214
|
height: 40,
|
|
175
215
|
fontSize: 14,
|
|
216
|
+
display: 'flex',
|
|
217
|
+
alignItems: 'center',
|
|
218
|
+
userSelect: 'none',
|
|
176
219
|
fontWeight: 700,
|
|
177
220
|
label: 'code-fold',
|
|
178
221
|
a: {
|
|
@@ -186,9 +229,10 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
186
229
|
const emptyLine = css({
|
|
187
230
|
backgroundColor: variables.emptyLineBackground,
|
|
188
231
|
label: 'empty-line',
|
|
232
|
+
flex: 1,
|
|
189
233
|
});
|
|
190
234
|
const marker = css({
|
|
191
|
-
width:
|
|
235
|
+
width: 28,
|
|
192
236
|
paddingLeft: 10,
|
|
193
237
|
paddingRight: 10,
|
|
194
238
|
userSelect: 'none',
|
|
@@ -255,6 +299,12 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
255
299
|
const line = css({
|
|
256
300
|
verticalAlign: 'baseline',
|
|
257
301
|
label: 'line',
|
|
302
|
+
height: '1.6em',
|
|
303
|
+
display: 'flex',
|
|
304
|
+
textDecoration: 'none'
|
|
305
|
+
});
|
|
306
|
+
const column = css({
|
|
307
|
+
flex: 1
|
|
258
308
|
});
|
|
259
309
|
const defaultStyles = {
|
|
260
310
|
diffContainer,
|
|
@@ -267,16 +317,23 @@ exports.default = (styleOverride, useDarkTheme = false, nonce = '') => {
|
|
|
267
317
|
highlightedLine,
|
|
268
318
|
gutter,
|
|
269
319
|
line,
|
|
320
|
+
lineContent,
|
|
270
321
|
wordDiff,
|
|
271
322
|
wordAdded,
|
|
323
|
+
summary,
|
|
324
|
+
block,
|
|
325
|
+
blockAddition,
|
|
326
|
+
blockDeletion,
|
|
272
327
|
wordRemoved,
|
|
273
328
|
codeFoldGutter,
|
|
329
|
+
codeFoldContentContainer,
|
|
274
330
|
codeFold,
|
|
275
331
|
emptyGutter,
|
|
276
332
|
emptyLine,
|
|
277
333
|
lineNumber,
|
|
278
334
|
contentText,
|
|
279
335
|
content,
|
|
336
|
+
column,
|
|
280
337
|
codeFoldContent,
|
|
281
338
|
titleBlock,
|
|
282
339
|
};
|
package/package.json
CHANGED