@haklex/rich-diff 0.0.65 → 0.0.67
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/README.md +52 -12
- package/dist/RichDiff.d.ts +5 -5
- package/dist/RichDiff.d.ts.map +1 -1
- package/dist/compute-diff.d.ts +1 -1
- package/dist/compute-diff.d.ts.map +1 -1
- package/dist/index.mjs +41 -51
- package/package.json +14 -9
package/README.md
CHANGED
|
@@ -1,31 +1,71 @@
|
|
|
1
1
|
# @haklex/rich-diff
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Diff viewer for comparing two Lexical editor states side-by-side.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @haklex/rich-diff
|
|
8
|
+
pnpm add @haklex/rich-diff
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Peer Dependencies
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export type { DiffHunk, DiffOpType } from './compute-diff'
|
|
18
|
-
```
|
|
13
|
+
| Package | Version |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `react` | `>=19` |
|
|
16
|
+
| `react-dom` | `>=19` |
|
|
19
17
|
|
|
20
|
-
##
|
|
18
|
+
## Usage
|
|
21
19
|
|
|
22
20
|
```tsx
|
|
23
21
|
import { RichDiff } from '@haklex/rich-diff'
|
|
24
22
|
import '@haklex/rich-diff/style.css'
|
|
25
23
|
|
|
26
|
-
<RichDiff
|
|
24
|
+
<RichDiff before={previousEditorState} after={currentEditorState} />
|
|
27
25
|
```
|
|
28
26
|
|
|
27
|
+
### Programmatic Diff
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { computeDiff } from '@haklex/rich-diff'
|
|
31
|
+
|
|
32
|
+
const hunks = computeDiff(beforeState, afterState)
|
|
33
|
+
// hunks: DiffHunk[] with op type (add, remove, equal) and content
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Exports
|
|
37
|
+
|
|
38
|
+
### Components
|
|
39
|
+
|
|
40
|
+
| Export | Description |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `RichDiff` | Side-by-side diff viewer component |
|
|
43
|
+
|
|
44
|
+
### Functions
|
|
45
|
+
|
|
46
|
+
| Export | Description |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `computeDiff(before, after)` | Compute diff hunks between two editor states |
|
|
49
|
+
|
|
50
|
+
### Types
|
|
51
|
+
|
|
52
|
+
| Export | Description |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `RichDiffProps` | Props for `RichDiff` |
|
|
55
|
+
| `DiffHunk` | A single diff hunk with operation type and content |
|
|
56
|
+
| `DiffOpType` | Diff operation type (`'add'` / `'remove'` / `'equal'`) |
|
|
57
|
+
|
|
58
|
+
### Sub-path Exports
|
|
59
|
+
|
|
60
|
+
| Import Path | Description |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| `@haklex/rich-diff` | All components, functions, and types |
|
|
63
|
+
| `@haklex/rich-diff/style.css` | Compiled diff viewer stylesheet |
|
|
64
|
+
|
|
65
|
+
## Part of Haklex
|
|
66
|
+
|
|
67
|
+
This package is part of the [Haklex](../../README.md) rich editor ecosystem.
|
|
68
|
+
|
|
29
69
|
## License
|
|
30
70
|
|
|
31
71
|
MIT
|
package/dist/RichDiff.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { RichRendererProps } from '@haklex/rich-static-renderer';
|
|
2
2
|
import { SerializedEditorState } from 'lexical';
|
|
3
3
|
export interface RichDiffProps {
|
|
4
|
-
|
|
4
|
+
className?: string;
|
|
5
|
+
extraNodes?: RichRendererProps['extraNodes'];
|
|
5
6
|
newValue: SerializedEditorState;
|
|
6
|
-
|
|
7
|
-
theme?: RichRendererProps['theme'];
|
|
7
|
+
oldValue: SerializedEditorState;
|
|
8
8
|
rendererConfig?: RichRendererProps['rendererConfig'];
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
theme?: RichRendererProps['theme'];
|
|
10
|
+
variant?: RichRendererProps['variant'];
|
|
11
11
|
}
|
|
12
12
|
export declare function RichDiff({ oldValue, newValue, variant, theme, rendererConfig, extraNodes, className, }: RichDiffProps): import("react/jsx-runtime").JSX.Element;
|
|
13
13
|
//# sourceMappingURL=RichDiff.d.ts.map
|
package/dist/RichDiff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichDiff.d.ts","sourceRoot":"","sources":["../src/RichDiff.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,
|
|
1
|
+
{"version":3,"file":"RichDiff.d.ts","sourceRoot":"","sources":["../src/RichDiff.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,qBAAqB,EAAyB,MAAM,SAAS,CAAC;AAO5E,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,QAAQ,EAAE,qBAAqB,CAAC;IAChC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,cAAc,CAAC,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;CACxC;AA2ED,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,QAAQ,EACR,OAAmB,EACnB,KAAe,EACf,cAAc,EACd,UAAU,EACV,SAAS,GACV,EAAE,aAAa,2CAiDf"}
|
package/dist/compute-diff.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SerializedEditorState, SerializedLexicalNode } from 'lexical';
|
|
2
2
|
export type DiffOpType = 'equal' | 'insert' | 'delete';
|
|
3
3
|
export interface DiffHunk {
|
|
4
|
-
type: DiffOpType;
|
|
5
4
|
nodes: SerializedLexicalNode[];
|
|
5
|
+
type: DiffOpType;
|
|
6
6
|
}
|
|
7
7
|
export declare function computeDiff(oldState: SerializedEditorState, newState: SerializedEditorState): DiffHunk[];
|
|
8
8
|
//# sourceMappingURL=compute-diff.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute-diff.d.ts","sourceRoot":"","sources":["../src/compute-diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"compute-diff.d.ts","sourceRoot":"","sources":["../src/compute-diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE5E,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,IAAI,EAAE,UAAU,CAAC;CAClB;AAgfD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,qBAAqB,GAC9B,QAAQ,EAAE,CA6CZ"}
|
package/dist/index.mjs
CHANGED
|
@@ -100,7 +100,7 @@ function diffMiddleChars(oldChars, newChars) {
|
|
|
100
100
|
}
|
|
101
101
|
const dp = Array.from(
|
|
102
102
|
{ length: m + 1 },
|
|
103
|
-
() =>
|
|
103
|
+
() => Array.from({ length: n + 1 }).fill(0)
|
|
104
104
|
);
|
|
105
105
|
for (let i2 = 1; i2 <= m; i2++) {
|
|
106
106
|
for (let j2 = 1; j2 <= n; j2++) {
|
|
@@ -229,7 +229,7 @@ function alignNodes(oldNodes, newNodes) {
|
|
|
229
229
|
const n = newNodes.length;
|
|
230
230
|
const dp = Array.from(
|
|
231
231
|
{ length: m + 1 },
|
|
232
|
-
() =>
|
|
232
|
+
() => Array.from({ length: n + 1 }).fill(0)
|
|
233
233
|
);
|
|
234
234
|
for (let i2 = 1; i2 <= m; i2++) {
|
|
235
235
|
for (let j2 = 1; j2 <= n; j2++) {
|
|
@@ -287,18 +287,21 @@ function diffChildrenInline(oldChildren, newChildren) {
|
|
|
287
287
|
let changed = false;
|
|
288
288
|
for (const op of ops) {
|
|
289
289
|
switch (op.kind) {
|
|
290
|
-
case "equal":
|
|
290
|
+
case "equal": {
|
|
291
291
|
nextOldChildren.push(op.node);
|
|
292
292
|
nextNewChildren.push(op.node);
|
|
293
293
|
break;
|
|
294
|
-
|
|
294
|
+
}
|
|
295
|
+
case "delete": {
|
|
295
296
|
changed = true;
|
|
296
297
|
nextOldChildren.push(decorateSubtree(op.node, "delete"));
|
|
297
298
|
break;
|
|
298
|
-
|
|
299
|
+
}
|
|
300
|
+
case "insert": {
|
|
299
301
|
changed = true;
|
|
300
302
|
nextNewChildren.push(decorateSubtree(op.node, "insert"));
|
|
301
303
|
break;
|
|
304
|
+
}
|
|
302
305
|
case "modify": {
|
|
303
306
|
changed = true;
|
|
304
307
|
if (isTextNode(op.oldNode) && isTextNode(op.newNode)) {
|
|
@@ -367,7 +370,7 @@ function computeDiff(oldState, newState) {
|
|
|
367
370
|
}
|
|
368
371
|
break;
|
|
369
372
|
}
|
|
370
|
-
case "modify":
|
|
373
|
+
case "modify": {
|
|
371
374
|
{
|
|
372
375
|
const inline = diffModifiedNode(op.oldNode, op.newNode);
|
|
373
376
|
hunks.push(
|
|
@@ -376,18 +379,21 @@ function computeDiff(oldState, newState) {
|
|
|
376
379
|
);
|
|
377
380
|
}
|
|
378
381
|
break;
|
|
379
|
-
|
|
382
|
+
}
|
|
383
|
+
case "delete": {
|
|
380
384
|
hunks.push({
|
|
381
385
|
type: "delete",
|
|
382
386
|
nodes: [decorateSubtree(op.node, "delete")]
|
|
383
387
|
});
|
|
384
388
|
break;
|
|
385
|
-
|
|
389
|
+
}
|
|
390
|
+
case "insert": {
|
|
386
391
|
hunks.push({
|
|
387
392
|
type: "insert",
|
|
388
393
|
nodes: [decorateSubtree(op.node, "insert")]
|
|
389
394
|
});
|
|
390
395
|
break;
|
|
396
|
+
}
|
|
391
397
|
}
|
|
392
398
|
}
|
|
393
399
|
return hunks;
|
|
@@ -442,11 +448,11 @@ function HunkRenderer({
|
|
|
442
448
|
return /* @__PURE__ */ jsx(
|
|
443
449
|
RichRenderer,
|
|
444
450
|
{
|
|
445
|
-
|
|
446
|
-
variant,
|
|
447
|
-
theme,
|
|
451
|
+
extraNodes,
|
|
448
452
|
rendererConfig,
|
|
449
|
-
|
|
453
|
+
theme,
|
|
454
|
+
value: doc,
|
|
455
|
+
variant
|
|
450
456
|
}
|
|
451
457
|
);
|
|
452
458
|
}
|
|
@@ -459,48 +465,32 @@ function RichDiff({
|
|
|
459
465
|
extraNodes,
|
|
460
466
|
className
|
|
461
467
|
}) {
|
|
462
|
-
const hunks = useMemo(
|
|
463
|
-
() => computeDiff(oldValue, newValue),
|
|
464
|
-
[oldValue, newValue]
|
|
465
|
-
);
|
|
468
|
+
const hunks = useMemo(() => computeDiff(oldValue, newValue), [oldValue, newValue]);
|
|
466
469
|
const rows = useMemo(() => buildRows(hunks), [hunks]);
|
|
467
470
|
const rendererProps = { variant, theme, rendererConfig, extraNodes };
|
|
468
471
|
const variantClass = getVariantClass(variant);
|
|
469
|
-
return /* @__PURE__ */ jsx(PortalThemeProvider, { className: variantClass, theme, children: /* @__PURE__ */ jsx(ColorSchemeProvider, { colorScheme: theme, children: /* @__PURE__ */ jsx(
|
|
470
|
-
"div",
|
|
471
|
-
|
|
472
|
-
className:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
/* @__PURE__ */ jsx(
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
),
|
|
493
|
-
/* @__PURE__ */ jsx(
|
|
494
|
-
"div",
|
|
495
|
-
{
|
|
496
|
-
className: `${cell} ${row$1.right ? row$1.right.type === "insert" ? insert : "" : empty}`.trim(),
|
|
497
|
-
children: row$1.right && /* @__PURE__ */ jsx(HunkRenderer, { hunk: row$1.right, ...rendererProps })
|
|
498
|
-
}
|
|
499
|
-
)
|
|
500
|
-
] }, i)) })
|
|
501
|
-
] })
|
|
502
|
-
}
|
|
503
|
-
) }) });
|
|
472
|
+
return /* @__PURE__ */ jsx(PortalThemeProvider, { className: variantClass, theme, children: /* @__PURE__ */ jsx(ColorSchemeProvider, { colorScheme: theme, children: /* @__PURE__ */ jsx("div", { className: variantClass, style: { width: "100%", maxWidth: "100%" }, children: /* @__PURE__ */ jsxs("div", { className: `${root} ${className ?? ""}`.trim(), children: [
|
|
473
|
+
/* @__PURE__ */ jsxs("div", { className: header, children: [
|
|
474
|
+
/* @__PURE__ */ jsx("div", { className: `${headerCell} ${headerOld}`, children: "Old" }),
|
|
475
|
+
/* @__PURE__ */ jsx("div", { className: headerCell, children: "New" })
|
|
476
|
+
] }),
|
|
477
|
+
/* @__PURE__ */ jsx("div", { className: body, children: rows.map((row$1, i) => /* @__PURE__ */ jsxs("div", { className: row, children: [
|
|
478
|
+
/* @__PURE__ */ jsx(
|
|
479
|
+
"div",
|
|
480
|
+
{
|
|
481
|
+
className: `${cell} ${cellOld} ${row$1.left ? row$1.left.type === "delete" ? delete_ : "" : empty}`.trim(),
|
|
482
|
+
children: row$1.left && /* @__PURE__ */ jsx(HunkRenderer, { hunk: row$1.left, ...rendererProps })
|
|
483
|
+
}
|
|
484
|
+
),
|
|
485
|
+
/* @__PURE__ */ jsx(
|
|
486
|
+
"div",
|
|
487
|
+
{
|
|
488
|
+
className: `${cell} ${row$1.right ? row$1.right.type === "insert" ? insert : "" : empty}`.trim(),
|
|
489
|
+
children: row$1.right && /* @__PURE__ */ jsx(HunkRenderer, { hunk: row$1.right, ...rendererProps })
|
|
490
|
+
}
|
|
491
|
+
)
|
|
492
|
+
] }, i)) })
|
|
493
|
+
] }) }) }) });
|
|
504
494
|
}
|
|
505
495
|
export {
|
|
506
496
|
RichDiff,
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-diff",
|
|
3
|
-
"
|
|
4
|
-
"version": "0.0.65",
|
|
3
|
+
"version": "0.0.67",
|
|
5
4
|
"description": "Rich diff editor",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Innei/haklex.git",
|
|
8
|
+
"directory": "packages/rich-diff"
|
|
9
|
+
},
|
|
6
10
|
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
7
12
|
"exports": {
|
|
8
13
|
".": {
|
|
9
14
|
"import": "./dist/index.mjs",
|
|
@@ -15,14 +20,10 @@
|
|
|
15
20
|
"files": [
|
|
16
21
|
"dist"
|
|
17
22
|
],
|
|
18
|
-
"peerDependencies": {
|
|
19
|
-
"react": ">=19",
|
|
20
|
-
"react-dom": ">=19"
|
|
21
|
-
},
|
|
22
23
|
"dependencies": {
|
|
23
|
-
"@haklex/rich-
|
|
24
|
-
"@haklex/rich-
|
|
25
|
-
"@haklex/rich-
|
|
24
|
+
"@haklex/rich-static-renderer": "0.0.67",
|
|
25
|
+
"@haklex/rich-style-token": "0.0.67",
|
|
26
|
+
"@haklex/rich-editor": "0.0.67"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@types/react": "^19.2.14",
|
|
@@ -36,6 +37,10 @@
|
|
|
36
37
|
"vite": "^7.3.1",
|
|
37
38
|
"vite-plugin-dts": "^4.5.4"
|
|
38
39
|
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=19",
|
|
42
|
+
"react-dom": ">=19"
|
|
43
|
+
},
|
|
39
44
|
"publishConfig": {
|
|
40
45
|
"access": "public"
|
|
41
46
|
},
|