react-diff-viewer-continued 4.2.0 → 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/.claude/settings.local.json +2 -1
- package/.github/workflows/pages.yml +36 -0
- package/.github/workflows/publish.yml +2 -10
- package/.github/workflows/release.yml +2 -2
- package/CHANGELOG.md +41 -0
- package/README.md +5 -3
- package/lib/cjs/src/compute-lines.d.ts +4 -4
- package/lib/cjs/src/compute-lines.js +18 -23
- package/lib/cjs/src/index.d.ts +16 -6
- package/lib/cjs/src/index.js +113 -96
- package/lib/cjs/src/styles.d.ts +38 -32
- package/lib/cjs/src/styles.js +88 -62
- package/lib/cjs/src/workerBundle.d.ts +1 -1
- package/lib/cjs/src/workerBundle.js +1 -1
- package/lib/esm/src/compute-lines.js +18 -23
- package/lib/esm/src/index.js +100 -78
- package/lib/esm/src/styles.js +89 -63
- package/lib/esm/src/workerBundle.js +1 -1
- package/package.json +19 -16
- package/pnpm-workspace.yaml +7 -0
- package/tsconfig.json +3 -4
- package/publish-examples.sh +0 -10
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Deploy GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
deploy:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: pnpm/action-setup@v4
|
|
18
|
+
with:
|
|
19
|
+
version: latest
|
|
20
|
+
|
|
21
|
+
- uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: 'lts/*'
|
|
24
|
+
cache: 'pnpm'
|
|
25
|
+
|
|
26
|
+
- run: pnpm install
|
|
27
|
+
|
|
28
|
+
- name: Configure git
|
|
29
|
+
run: |
|
|
30
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
31
|
+
git config --global user.name "github-actions[bot]"
|
|
32
|
+
|
|
33
|
+
- name: Deploy examples to GitHub Pages
|
|
34
|
+
run: pnpm publish:examples
|
|
35
|
+
env:
|
|
36
|
+
GITHUB_REPO_URL: https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
|
|
@@ -33,16 +33,8 @@ jobs:
|
|
|
33
33
|
- run: pnpm install
|
|
34
34
|
- run: pnpm build
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
- run: npm install -g npm@latest
|
|
38
|
-
|
|
39
|
-
- name: Publish to npm
|
|
40
|
-
run: pnpm publish --access public --provenance --no-git-checks
|
|
41
|
-
env:
|
|
42
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
43
|
-
|
|
44
|
-
# Create GitHub release with changelog notes
|
|
45
|
-
- name: Create GitHub release
|
|
36
|
+
- name: Publish and create GitHub release
|
|
46
37
|
run: pnpm just-release
|
|
47
38
|
env:
|
|
48
39
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.3.0 (2026-07-10)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- export default light and dark theme variables
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- do not do extra publish step, just release publishes
|
|
12
|
+
- make exports immutable
|
|
13
|
+
- freeze dark theme variables and add export-existence tests
|
|
14
|
+
- add GitHub Pages deployment workflow and Vite base path
|
|
15
|
+
- isolate diff table from host table CSS (daisyui/bootstrap)
|
|
16
|
+
- bump js-yaml to ^4.2.0 (CVE-2026-53550)
|
|
17
|
+
- clear remaining audit advisories in dev toolchain
|
|
18
|
+
|
|
19
|
+
### Documentation
|
|
20
|
+
|
|
21
|
+
- add overscan, disableWorker, and loading overlay to README
|
|
22
|
+
|
|
23
|
+
### Chores
|
|
24
|
+
|
|
25
|
+
- make pnpm canonical (drop npm lockfile, approve builds)
|
|
26
|
+
|
|
27
|
+
## 4.2.2 (2026-04-23)
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
- strict typescript types, and visible loader
|
|
32
|
+
|
|
33
|
+
## 4.2.1 (2026-04-23)
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
- make overscan configurable
|
|
38
|
+
- handle ' HTML entity in diff view to prevent "undefined" suffix
|
|
39
|
+
- mousedown and mouseup
|
|
40
|
+
- do not show content while scrolling fast outside the overscan area
|
|
41
|
+
- update dependencies
|
|
42
|
+
- clean up old package-lock.json
|
|
43
|
+
|
|
3
44
|
## 4.2.0 (2026-03-10)
|
|
4
45
|
|
|
5
46
|
### Features
|
package/README.md
CHANGED
|
@@ -92,8 +92,9 @@ class Diff extends PureComponent {
|
|
|
92
92
|
| linesOffset | `number` | `0` | Number to start count code lines from. |
|
|
93
93
|
| summary | `string \| ReactElement` | `undefined` | Text or element to display in the summary bar (e.g., filename). |
|
|
94
94
|
| hideSummary | `boolean` | `false` | Hide the summary bar (expand/collapse button, change count, summary text). |
|
|
95
|
-
| infiniteLoading | `{ pageSize: number, containerHeight: string }` | `undefined` | Enable virtualization for large diffs. When enabled, only visible rows are rendered. `containerHeight` sets the scrollable container height (e.g., `'500px'` or `'80vh'`).
|
|
96
|
-
| loadingElement | `() => ReactElement` | `undefined` | Function that returns an element to display while the diff is being computed. Useful with `infiniteLoading` for large files.
|
|
95
|
+
| infiniteLoading | `{ pageSize: number, containerHeight: string, overscan?: number }` | `undefined` | Enable virtualization for large diffs. When enabled, only visible rows are rendered. `containerHeight` sets the scrollable container height (e.g., `'500px'` or `'80vh'`). `overscan` controls how many extra rows to render above and below the viewport (default `20`). |
|
|
96
|
+
| loadingElement | `() => ReactElement` | `undefined` | Function that returns an element to display while the diff is being computed or when content is hidden during fast scrolling. Useful with `infiniteLoading` for large files. |
|
|
97
|
+
| disableWorker | `boolean` | `false` | Disable the Web Worker used for diff computation, falling back to synchronous computation on the main thread. Useful when the worker bundle fails to load in certain bundler configurations. |
|
|
97
98
|
| nonce | `string` | `''` | Nonce to use for inline styles (for CSP). |
|
|
98
99
|
|
|
99
100
|
## Instance Methods
|
|
@@ -114,7 +115,8 @@ Enable virtualization to only render visible rows:
|
|
|
114
115
|
newValue={largeNewFile}
|
|
115
116
|
infiniteLoading={{
|
|
116
117
|
pageSize: 20,
|
|
117
|
-
containerHeight: '80vh'
|
|
118
|
+
containerHeight: '80vh',
|
|
119
|
+
overscan: 20,
|
|
118
120
|
}}
|
|
119
121
|
loadingElement={() => (
|
|
120
122
|
<div style={{ padding: '20px', textAlign: 'center' }}>
|
|
@@ -23,8 +23,8 @@ export interface DiffInformation {
|
|
|
23
23
|
rawValue?: string;
|
|
24
24
|
}
|
|
25
25
|
export interface LineInformation {
|
|
26
|
-
left
|
|
27
|
-
right
|
|
26
|
+
left: DiffInformation;
|
|
27
|
+
right: DiffInformation;
|
|
28
28
|
}
|
|
29
29
|
export interface ComputedLineInformation {
|
|
30
30
|
lineInformation: LineInformation[];
|
|
@@ -37,7 +37,7 @@ export interface ComputedDiffInformation {
|
|
|
37
37
|
export interface JsDiffChangeObject {
|
|
38
38
|
added?: boolean;
|
|
39
39
|
removed?: boolean;
|
|
40
|
-
value
|
|
40
|
+
value: string;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* Computes word diff information in the line.
|
|
@@ -64,5 +64,5 @@ declare const computeDiff: (oldValue: string | Record<string, unknown>, newValue
|
|
|
64
64
|
* @param showLines lines that are always shown, regardless of diff
|
|
65
65
|
*/
|
|
66
66
|
declare const computeLineInformation: (oldString: string | Record<string, unknown>, newString: string | Record<string, unknown>, disableWordDiff?: boolean, lineCompareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[]), linesOffset?: number, showLines?: string[], deferWordDiff?: boolean) => ComputedLineInformation;
|
|
67
|
-
declare const computeLineInformationWorker: (oldString: string | Record<string, unknown>, newString: string | Record<string, unknown>, disableWordDiff?: boolean, lineCompareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[]), linesOffset?: number, showLines?: string[], deferWordDiff?: boolean) => Promise<ComputedLineInformation>;
|
|
67
|
+
declare const computeLineInformationWorker: (oldString: string | Record<string, unknown>, newString: string | Record<string, unknown>, disableWordDiff?: boolean, lineCompareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[]), linesOffset?: number, showLines?: string[], deferWordDiff?: boolean, disableWorker?: boolean) => Promise<ComputedLineInformation>;
|
|
68
68
|
export { computeLineInformation, computeLineInformationWorker, computeDiff };
|
|
@@ -305,24 +305,17 @@ const computeDiff = (oldValue, newValue, compareMethod = DiffMethod.CHARS) => {
|
|
|
305
305
|
right: [],
|
|
306
306
|
};
|
|
307
307
|
diffArray.forEach(({ added, removed, value }) => {
|
|
308
|
-
const diffInformation = {};
|
|
309
308
|
if (added) {
|
|
310
|
-
|
|
311
|
-
diffInformation.value = value;
|
|
312
|
-
computedDiff.right.push(diffInformation);
|
|
309
|
+
computedDiff.right.push({ type: DiffType.ADDED, value });
|
|
313
310
|
}
|
|
314
|
-
if (removed) {
|
|
315
|
-
|
|
316
|
-
diffInformation.value = value;
|
|
317
|
-
computedDiff.left.push(diffInformation);
|
|
311
|
+
else if (removed) {
|
|
312
|
+
computedDiff.left.push({ type: DiffType.REMOVED, value });
|
|
318
313
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
computedDiff.
|
|
323
|
-
computedDiff.left.push(diffInformation);
|
|
314
|
+
else {
|
|
315
|
+
const info = { type: DiffType.DEFAULT, value };
|
|
316
|
+
computedDiff.right.push(info);
|
|
317
|
+
computedDiff.left.push(info);
|
|
324
318
|
}
|
|
325
|
-
return diffInformation;
|
|
326
319
|
});
|
|
327
320
|
return computedDiff;
|
|
328
321
|
};
|
|
@@ -477,7 +470,7 @@ const computeLineInformation = (oldString, newString, disableWordDiff = false, l
|
|
|
477
470
|
}
|
|
478
471
|
return { right, left };
|
|
479
472
|
})
|
|
480
|
-
.filter(
|
|
473
|
+
.filter((x) => x != null);
|
|
481
474
|
};
|
|
482
475
|
diffArray.forEach(({ added, removed, value }, index) => {
|
|
483
476
|
lineInformation = [
|
|
@@ -502,20 +495,21 @@ const computeLineInformation = (oldString, newString, disableWordDiff = false, l
|
|
|
502
495
|
* @param showLines lines that are always shown, regardless of diff
|
|
503
496
|
* @returns Promise<ComputedLineInformation> - Resolves with line-by-line diff data from the worker.
|
|
504
497
|
*/
|
|
505
|
-
// Import the bundled worker code (generated by scripts/build-worker.js)
|
|
506
|
-
import { WORKER_CODE } from './workerBundle.js';
|
|
507
498
|
// Cached Blob URL for the worker - created once and reused
|
|
508
499
|
let workerBlobUrl = null;
|
|
509
500
|
let workerAvailable = null;
|
|
510
|
-
//
|
|
511
|
-
const getWorkerBlobUrl = () => {
|
|
501
|
+
// Lazily import and create a Blob URL from the bundled worker code
|
|
502
|
+
const getWorkerBlobUrl = async () => {
|
|
512
503
|
if (workerBlobUrl !== null)
|
|
513
504
|
return workerBlobUrl;
|
|
505
|
+
if (workerAvailable === false)
|
|
506
|
+
return null;
|
|
514
507
|
if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined') {
|
|
515
508
|
workerAvailable = false;
|
|
516
509
|
return null;
|
|
517
510
|
}
|
|
518
511
|
try {
|
|
512
|
+
const { WORKER_CODE } = await import('./workerBundle.js');
|
|
519
513
|
const blob = new Blob([WORKER_CODE], { type: 'application/javascript' });
|
|
520
514
|
workerBlobUrl = URL.createObjectURL(blob);
|
|
521
515
|
workerAvailable = true;
|
|
@@ -526,9 +520,12 @@ const getWorkerBlobUrl = () => {
|
|
|
526
520
|
}
|
|
527
521
|
return workerBlobUrl;
|
|
528
522
|
};
|
|
529
|
-
const computeLineInformationWorker = (oldString, newString, disableWordDiff = false, lineCompareMethod = DiffMethod.CHARS, linesOffset = 0, showLines = [], deferWordDiff = false) => {
|
|
523
|
+
const computeLineInformationWorker = async (oldString, newString, disableWordDiff = false, lineCompareMethod = DiffMethod.CHARS, linesOffset = 0, showLines = [], deferWordDiff = false, disableWorker = false) => {
|
|
530
524
|
const fallback = () => computeLineInformation(oldString, newString, disableWordDiff, lineCompareMethod, linesOffset, showLines, deferWordDiff);
|
|
531
|
-
|
|
525
|
+
if (disableWorker) {
|
|
526
|
+
return Promise.resolve(fallback());
|
|
527
|
+
}
|
|
528
|
+
const blobUrl = await getWorkerBlobUrl();
|
|
532
529
|
if (!blobUrl) {
|
|
533
530
|
return Promise.resolve(fallback());
|
|
534
531
|
}
|
|
@@ -538,7 +535,6 @@ const computeLineInformationWorker = (oldString, newString, disableWordDiff = fa
|
|
|
538
535
|
worker = new Worker(blobUrl);
|
|
539
536
|
}
|
|
540
537
|
catch (_a) {
|
|
541
|
-
// Worker instantiation failed - fall back to synchronous computation
|
|
542
538
|
workerAvailable = false;
|
|
543
539
|
resolve(fallback());
|
|
544
540
|
return;
|
|
@@ -548,7 +544,6 @@ const computeLineInformationWorker = (oldString, newString, disableWordDiff = fa
|
|
|
548
544
|
worker.terminate();
|
|
549
545
|
};
|
|
550
546
|
worker.onerror = () => {
|
|
551
|
-
// Worker error - fall back and mark as unavailable for future calls
|
|
552
547
|
workerAvailable = false;
|
|
553
548
|
worker.terminate();
|
|
554
549
|
resolve(fallback());
|
package/lib/cjs/src/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ReactElement, RefObject } from "react";
|
|
|
3
3
|
import type { Change } from "diff";
|
|
4
4
|
import { type Block } from "./compute-hidden-blocks.js";
|
|
5
5
|
import { type DiffInformation, DiffMethod, DiffType, type LineInformation } from "./compute-lines.js";
|
|
6
|
-
import { type ReactDiffViewerStyles, type ReactDiffViewerStylesOverride } from "./styles.js";
|
|
6
|
+
import { type ReactDiffViewerStyles, type ReactDiffViewerStylesOverride, type ReactDiffViewerStylesVariables } from "./styles.js";
|
|
7
7
|
export declare enum LineNumberPrefix {
|
|
8
8
|
LEFT = "L",
|
|
9
9
|
RIGHT = "R"
|
|
@@ -11,6 +11,7 @@ export declare enum LineNumberPrefix {
|
|
|
11
11
|
export interface InfiniteLoadingProps {
|
|
12
12
|
pageSize: number;
|
|
13
13
|
containerHeight: string;
|
|
14
|
+
overscan?: number;
|
|
14
15
|
}
|
|
15
16
|
export interface ComputedDiffResult {
|
|
16
17
|
lineInformation: LineInformation[];
|
|
@@ -39,8 +40,8 @@ export interface ReactDiffViewerProps {
|
|
|
39
40
|
type: DiffType;
|
|
40
41
|
prefix: LineNumberPrefix;
|
|
41
42
|
value: string | DiffInformation[];
|
|
42
|
-
additionalLineNumber
|
|
43
|
-
additionalPrefix
|
|
43
|
+
additionalLineNumber?: number;
|
|
44
|
+
additionalPrefix?: LineNumberPrefix;
|
|
44
45
|
styles: ReactDiffViewerStyles;
|
|
45
46
|
}) => ReactElement;
|
|
46
47
|
highlightLines?: string[];
|
|
@@ -69,17 +70,23 @@ export interface ReactDiffViewerProps {
|
|
|
69
70
|
* Show debug overlay with virtualization info (for development)
|
|
70
71
|
*/
|
|
71
72
|
showDebugInfo?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Disable Web Worker for diff computation, using synchronous fallback instead.
|
|
75
|
+
* Useful when the worker bundle fails to load in certain bundler configurations.
|
|
76
|
+
*/
|
|
77
|
+
disableWorker?: boolean;
|
|
72
78
|
}
|
|
73
79
|
export interface ReactDiffViewerState {
|
|
74
|
-
expandedBlocks
|
|
80
|
+
expandedBlocks: number[];
|
|
75
81
|
noSelect?: "left" | "right";
|
|
76
|
-
scrollableContainerRef: RefObject<HTMLDivElement>;
|
|
82
|
+
scrollableContainerRef: RefObject<HTMLDivElement | null>;
|
|
77
83
|
computedDiffResult: Record<string, ComputedDiffResult>;
|
|
78
84
|
isLoading: boolean;
|
|
79
85
|
visibleStartRow: number;
|
|
80
86
|
contentColumnWidth: number | null;
|
|
81
87
|
charWidth: number | null;
|
|
82
88
|
cumulativeOffsets: number[] | null;
|
|
89
|
+
isScrolling: boolean;
|
|
83
90
|
}
|
|
84
91
|
declare class DiffViewer extends React.Component<ReactDiffViewerProps, ReactDiffViewerState> {
|
|
85
92
|
private styles;
|
|
@@ -88,6 +95,8 @@ declare class DiffViewer extends React.Component<ReactDiffViewerProps, ReactDiff
|
|
|
88
95
|
private charMeasureRef;
|
|
89
96
|
private stickyHeaderRef;
|
|
90
97
|
private resizeObserver;
|
|
98
|
+
private scrollDebounceTimer;
|
|
99
|
+
private lastRenderedRange;
|
|
91
100
|
static defaultProps: ReactDiffViewerProps;
|
|
92
101
|
constructor(props: ReactDiffViewerProps);
|
|
93
102
|
/**
|
|
@@ -249,4 +258,5 @@ declare class DiffViewer extends React.Component<ReactDiffViewerProps, ReactDiff
|
|
|
249
258
|
export default DiffViewer;
|
|
250
259
|
export { DiffMethod };
|
|
251
260
|
export { default as computeStyles } from "./styles.js";
|
|
252
|
-
export
|
|
261
|
+
export { defaultLightThemeVariables, defaultDarkThemeVariables, } from "./styles.js";
|
|
262
|
+
export type { ReactDiffViewerStylesOverride, ReactDiffViewerStyles, ReactDiffViewerStylesVariables };
|