@crashbytes/react-version-compare 1.0.0 → 1.0.2
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 +55 -7
- package/dist/cjs/index.js +308 -23
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +308 -23
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/styles.css +174 -0
- package/package.json +14 -4
package/README.md
CHANGED
|
@@ -5,11 +5,20 @@ A React component for comparing strings and arrays with precise word-level and i
|
|
|
5
5
|
[](https://badge.fury.io/js/react-version-compare)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
+
## Live Storybook Demo
|
|
9
|
+
|
|
10
|
+
You can explore and interact with all features of this component in the live Storybook:
|
|
11
|
+
|
|
12
|
+
👉 **[Live Storybook Demo](https://crashbytes.github.io/react-version-compare/)**
|
|
13
|
+
|
|
14
|
+
The Storybook provides interactive examples for all comparison scenarios. You can adjust the inputs and props using the controls panel to see how the component behaves with different data. This is the best way to preview, test, and understand the capabilities of `react-version-compare` without writing any code.
|
|
15
|
+
|
|
8
16
|
## Features
|
|
9
17
|
|
|
10
18
|
- 🎯 **Precise Highlighting**: Only highlights the actual differences, not entire lines
|
|
11
19
|
- 📝 **String Comparison**: Word-level diff for text content
|
|
12
20
|
- 📋 **Array Comparison**: Item-level diff for arrays of strings
|
|
21
|
+
- 📄 **Contentful Rich Text**: Compare Contentful documents with text or structure modes
|
|
13
22
|
- 🎨 **Clean Visual Design**: Clear red/green highlighting for changes
|
|
14
23
|
- 📱 **Responsive**: Works on desktop and mobile devices
|
|
15
24
|
- ⚡ **TypeScript Support**: Full TypeScript definitions included
|
|
@@ -18,11 +27,11 @@ A React component for comparing strings and arrays with precise word-level and i
|
|
|
18
27
|
## Installation
|
|
19
28
|
|
|
20
29
|
```bash
|
|
21
|
-
npm install react-version-compare
|
|
30
|
+
npm install @crashbytes/react-version-compare
|
|
22
31
|
```
|
|
23
32
|
|
|
24
33
|
```bash
|
|
25
|
-
yarn add react-version-compare
|
|
34
|
+
yarn add @crashbytes/react-version-compare
|
|
26
35
|
```
|
|
27
36
|
|
|
28
37
|
## Basic Usage
|
|
@@ -31,8 +40,8 @@ yarn add react-version-compare
|
|
|
31
40
|
|
|
32
41
|
```tsx
|
|
33
42
|
import React from 'react';
|
|
34
|
-
import Compare from 'react-version-compare';
|
|
35
|
-
import 'react-version-compare/dist/styles.css';
|
|
43
|
+
import Compare from '@crashbytes/react-version-compare';
|
|
44
|
+
import '@crashbytes/react-version-compare/dist/styles.css';
|
|
36
45
|
|
|
37
46
|
const App = () => {
|
|
38
47
|
const original = 'I am Captain Kirk, Captain of the USS Enterprise.';
|
|
@@ -70,16 +79,52 @@ const modifiedArray = [
|
|
|
70
79
|
/>
|
|
71
80
|
```
|
|
72
81
|
|
|
82
|
+
### Contentful Rich Text Comparison
|
|
83
|
+
|
|
84
|
+
The component now supports comparing Contentful Rich Text documents with two different modes:
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { Compare } from '@crashbytes/react-version-compare';
|
|
88
|
+
import { Document } from '@contentful/rich-text-types';
|
|
89
|
+
|
|
90
|
+
// Text mode - extracts plain text for comparison
|
|
91
|
+
<Compare
|
|
92
|
+
original={contentfulDoc1}
|
|
93
|
+
modified={contentfulDoc2}
|
|
94
|
+
compareMode="text"
|
|
95
|
+
viewMode="side-by-side"
|
|
96
|
+
/>
|
|
97
|
+
|
|
98
|
+
// Structure mode - compares document structure
|
|
99
|
+
<Compare
|
|
100
|
+
original={contentfulDoc1}
|
|
101
|
+
modified={contentfulDoc2}
|
|
102
|
+
compareMode="structure"
|
|
103
|
+
viewMode="side-by-side"
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Structure Mode** preserves the semantic meaning of the document by comparing:
|
|
108
|
+
- Headings (with levels)
|
|
109
|
+
- Paragraphs
|
|
110
|
+
- Lists and list items
|
|
111
|
+
- Block quotes
|
|
112
|
+
- And other rich text elements
|
|
113
|
+
|
|
114
|
+
**Text Mode** extracts plain text content and performs word-level comparison, similar to string comparison.
|
|
115
|
+
|
|
73
116
|
## API Reference
|
|
74
117
|
|
|
75
118
|
### Props
|
|
76
119
|
|
|
77
120
|
| Prop | Type | Default | Description |
|
|
78
121
|
|------|------|---------|-------------|
|
|
79
|
-
| `original` | `string \| string[]` | **required** | The original content |
|
|
80
|
-
| `modified` | `string \| string[]` | **required** | The modified content |
|
|
122
|
+
| `original` | `string \| string[] \| Document` | **required** | The original content |
|
|
123
|
+
| `modified` | `string \| string[] \| Document` | **required** | The modified content |
|
|
81
124
|
| `viewMode` | `'side-by-side' \| 'inline'` | `'side-by-side'` | How to display the comparison |
|
|
82
125
|
| `className` | `string` | `''` | Custom CSS class name |
|
|
126
|
+
| `caseSensitive` | `boolean` | `true` | Whether comparison is case sensitive |
|
|
127
|
+
| `compareMode` | `'text' \| 'structure'` | `'text'` | Comparison mode for Contentful documents |
|
|
83
128
|
|
|
84
129
|
## Examples
|
|
85
130
|
|
|
@@ -141,13 +186,16 @@ The component uses CSS classes that you can customize:
|
|
|
141
186
|
- **Content management**: Show edits in articles or posts
|
|
142
187
|
- **Data comparison**: Compare lists or arrays of items
|
|
143
188
|
- **Translation work**: Compare original and translated text
|
|
189
|
+
- **Contentful CMS**: Compare rich text content versions and track editorial changes
|
|
190
|
+
- **Documentation**: Track changes in structured content with semantic meaning
|
|
144
191
|
|
|
145
192
|
## How It Works
|
|
146
193
|
|
|
147
194
|
- **String comparison**: Uses word-level diffing to identify precise changes
|
|
148
195
|
- **Array comparison**: Compares items by position and content
|
|
196
|
+
- **Contentful comparison**: Extracts plain text or compares structural elements
|
|
149
197
|
- **Smart highlighting**: Only highlights actual differences, not entire lines
|
|
150
|
-
- **Type safety**: Ensures both inputs are the same type (
|
|
198
|
+
- **Type safety**: Ensures both inputs are the same type (strings, arrays, or Contentful documents)
|
|
151
199
|
|
|
152
200
|
## License
|
|
153
201
|
|
package/dist/cjs/index.js
CHANGED
|
@@ -2,15 +2,116 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
6
5
|
var diff = require('diff');
|
|
6
|
+
require('react');
|
|
7
|
+
var richTextTypes = require('@contentful/rich-text-types');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
const extractPlainText = document => {
|
|
11
|
+
const extractFromNode = node => {
|
|
12
|
+
if (node.nodeType === 'text') {
|
|
13
|
+
return node.value;
|
|
14
|
+
}
|
|
15
|
+
if ('content' in node && node.content) {
|
|
16
|
+
return node.content.map(child => extractFromNode(child)).join('');
|
|
17
|
+
}
|
|
18
|
+
return '';
|
|
19
|
+
};
|
|
20
|
+
return extractFromNode(document);
|
|
21
|
+
};
|
|
22
|
+
const extractStructuredContent = document => {
|
|
23
|
+
const result = [];
|
|
24
|
+
const extractFromNode = node => {
|
|
25
|
+
if (node.nodeType === 'text') {
|
|
26
|
+
// Skip standalone text nodes as they're usually part of a parent structure
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if ('content' in node && node.content) {
|
|
30
|
+
const textContent = node.content.map(child => child.nodeType === 'text' ? child.value : '').join('');
|
|
31
|
+
|
|
32
|
+
// Map node types to user-friendly names and extract heading levels
|
|
33
|
+
let displayType = node.nodeType;
|
|
34
|
+
let headingLevel;
|
|
35
|
+
switch (node.nodeType) {
|
|
36
|
+
case richTextTypes.BLOCKS.HEADING_1:
|
|
37
|
+
displayType = 'Heading';
|
|
38
|
+
headingLevel = 1;
|
|
39
|
+
break;
|
|
40
|
+
case richTextTypes.BLOCKS.HEADING_2:
|
|
41
|
+
displayType = 'Heading';
|
|
42
|
+
headingLevel = 2;
|
|
43
|
+
break;
|
|
44
|
+
case richTextTypes.BLOCKS.HEADING_3:
|
|
45
|
+
displayType = 'Heading';
|
|
46
|
+
headingLevel = 3;
|
|
47
|
+
break;
|
|
48
|
+
case richTextTypes.BLOCKS.HEADING_4:
|
|
49
|
+
displayType = 'Heading';
|
|
50
|
+
headingLevel = 4;
|
|
51
|
+
break;
|
|
52
|
+
case richTextTypes.BLOCKS.HEADING_5:
|
|
53
|
+
displayType = 'Heading';
|
|
54
|
+
headingLevel = 5;
|
|
55
|
+
break;
|
|
56
|
+
case richTextTypes.BLOCKS.HEADING_6:
|
|
57
|
+
displayType = 'Heading';
|
|
58
|
+
headingLevel = 6;
|
|
59
|
+
break;
|
|
60
|
+
case richTextTypes.BLOCKS.PARAGRAPH:
|
|
61
|
+
displayType = 'Text';
|
|
62
|
+
break;
|
|
63
|
+
case richTextTypes.BLOCKS.UL_LIST:
|
|
64
|
+
displayType = 'List';
|
|
65
|
+
break;
|
|
66
|
+
case richTextTypes.BLOCKS.OL_LIST:
|
|
67
|
+
displayType = 'Numbered List';
|
|
68
|
+
break;
|
|
69
|
+
case richTextTypes.BLOCKS.LIST_ITEM:
|
|
70
|
+
displayType = 'List Item';
|
|
71
|
+
break;
|
|
72
|
+
case richTextTypes.BLOCKS.QUOTE:
|
|
73
|
+
displayType = 'Quote';
|
|
74
|
+
break;
|
|
75
|
+
case richTextTypes.BLOCKS.TABLE:
|
|
76
|
+
displayType = 'Table';
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
displayType = node.nodeType.charAt(0).toUpperCase() + node.nodeType.slice(1);
|
|
80
|
+
}
|
|
81
|
+
if (textContent.trim()) {
|
|
82
|
+
result.push({
|
|
83
|
+
type: displayType,
|
|
84
|
+
content: textContent.trim(),
|
|
85
|
+
level: headingLevel
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Recursively process child nodes for nested structures like list items
|
|
90
|
+
node.content.forEach(child => {
|
|
91
|
+
if (child.nodeType !== 'text') {
|
|
92
|
+
extractFromNode(child);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
if (document.content) {
|
|
98
|
+
document.content.forEach(node => extractFromNode(node));
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
};
|
|
102
|
+
const isContentfulDocument = value => {
|
|
103
|
+
return value && typeof value === 'object' && value.nodeType === richTextTypes.BLOCKS.DOCUMENT && Array.isArray(value.content);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Types
|
|
7
107
|
|
|
8
108
|
const Compare = ({
|
|
9
109
|
original,
|
|
10
110
|
modified,
|
|
11
111
|
className = '',
|
|
12
112
|
viewMode = 'side-by-side',
|
|
13
|
-
caseSensitive = true
|
|
113
|
+
caseSensitive = true,
|
|
114
|
+
compareMode = 'text' // Default to text comparison
|
|
14
115
|
}) => {
|
|
15
116
|
// Handle string comparison
|
|
16
117
|
const renderStringDiff = (orig, mod) => {
|
|
@@ -21,21 +122,21 @@ const Compare = ({
|
|
|
21
122
|
const modifiedParts = [];
|
|
22
123
|
for (const part of diff$1) {
|
|
23
124
|
if (part.removed) {
|
|
24
|
-
originalParts.push(jsxRuntime.jsx("span", {
|
|
125
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
25
126
|
className: "diff-removed",
|
|
26
127
|
children: part.value
|
|
27
128
|
}, originalParts.length));
|
|
28
129
|
} else if (part.added) {
|
|
29
|
-
modifiedParts.push(jsxRuntime.jsx("span", {
|
|
130
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
30
131
|
className: "diff-added",
|
|
31
132
|
children: part.value
|
|
32
133
|
}, modifiedParts.length));
|
|
33
134
|
} else {
|
|
34
|
-
originalParts.push(jsxRuntime.jsx("span", {
|
|
135
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
35
136
|
className: "diff-unchanged",
|
|
36
137
|
children: part.value
|
|
37
138
|
}, originalParts.length));
|
|
38
|
-
modifiedParts.push(jsxRuntime.jsx("span", {
|
|
139
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
39
140
|
className: "diff-unchanged",
|
|
40
141
|
children: part.value
|
|
41
142
|
}, modifiedParts.length));
|
|
@@ -46,6 +147,7 @@ const Compare = ({
|
|
|
46
147
|
modifiedParts
|
|
47
148
|
};
|
|
48
149
|
};
|
|
150
|
+
|
|
49
151
|
// Handle array comparison
|
|
50
152
|
const renderArrayDiff = (orig, mod) => {
|
|
51
153
|
let origArr = orig;
|
|
@@ -60,25 +162,25 @@ const Compare = ({
|
|
|
60
162
|
for (const part of diff$1) {
|
|
61
163
|
if (part.removed) {
|
|
62
164
|
part.value.forEach((item, index) => {
|
|
63
|
-
originalParts.push(jsxRuntime.jsx("div", {
|
|
165
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
64
166
|
className: "diff-removed-line",
|
|
65
167
|
children: orig[origArr.indexOf(item, originalParts.length)] ?? item
|
|
66
168
|
}, `${originalParts.length}-${index}`));
|
|
67
169
|
});
|
|
68
170
|
} else if (part.added) {
|
|
69
171
|
part.value.forEach((item, index) => {
|
|
70
|
-
modifiedParts.push(jsxRuntime.jsx("div", {
|
|
172
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
71
173
|
className: "diff-added-line",
|
|
72
174
|
children: mod[modArr.indexOf(item, modifiedParts.length)] ?? item
|
|
73
175
|
}, `${modifiedParts.length}-${index}`));
|
|
74
176
|
});
|
|
75
177
|
} else {
|
|
76
178
|
part.value.forEach((item, index) => {
|
|
77
|
-
originalParts.push(jsxRuntime.jsx("div", {
|
|
179
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
78
180
|
className: "diff-unchanged-line",
|
|
79
181
|
children: orig[origArr.indexOf(item, originalParts.length)] ?? item
|
|
80
182
|
}, `${originalParts.length}-${index}`));
|
|
81
|
-
modifiedParts.push(jsxRuntime.jsx("div", {
|
|
183
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
82
184
|
className: "diff-unchanged-line",
|
|
83
185
|
children: mod[modArr.indexOf(item, modifiedParts.length)] ?? item
|
|
84
186
|
}, `${modifiedParts.length}-${index}`));
|
|
@@ -90,12 +192,186 @@ const Compare = ({
|
|
|
90
192
|
modifiedParts
|
|
91
193
|
};
|
|
92
194
|
};
|
|
195
|
+
|
|
196
|
+
// Handle Contentful document comparison
|
|
197
|
+
const renderContentfulDiff = (origDoc, modDoc) => {
|
|
198
|
+
if (compareMode === 'structure') {
|
|
199
|
+
// Compare structural elements
|
|
200
|
+
const origStructure = extractStructuredContent(origDoc);
|
|
201
|
+
const modStructure = extractStructuredContent(modDoc);
|
|
202
|
+
|
|
203
|
+
// Create a more sophisticated comparison that can handle changes within the same structure type
|
|
204
|
+
const maxLength = Math.max(origStructure.length, modStructure.length);
|
|
205
|
+
const originalParts = [];
|
|
206
|
+
const modifiedParts = [];
|
|
207
|
+
for (let i = 0; i < maxLength; i++) {
|
|
208
|
+
const origItem = origStructure[i];
|
|
209
|
+
const modItem = modStructure[i];
|
|
210
|
+
if (!origItem && modItem) {
|
|
211
|
+
// Added item
|
|
212
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
213
|
+
className: "diff-added-line",
|
|
214
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
215
|
+
className: "diff-structure-type",
|
|
216
|
+
children: modItem.type
|
|
217
|
+
}), modItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
218
|
+
className: "diff-structure-level",
|
|
219
|
+
children: [" H", modItem.level]
|
|
220
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
221
|
+
className: "diff-structure-content",
|
|
222
|
+
children: [": ", modItem.content]
|
|
223
|
+
})]
|
|
224
|
+
}, `added-${i}`));
|
|
225
|
+
} else if (origItem && !modItem) {
|
|
226
|
+
// Removed item
|
|
227
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
228
|
+
className: "diff-removed-line",
|
|
229
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
230
|
+
className: "diff-structure-type",
|
|
231
|
+
children: origItem.type
|
|
232
|
+
}), origItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
233
|
+
className: "diff-structure-level",
|
|
234
|
+
children: [" H", origItem.level]
|
|
235
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
236
|
+
className: "diff-structure-content",
|
|
237
|
+
children: [": ", origItem.content]
|
|
238
|
+
})]
|
|
239
|
+
}, `removed-${i}`));
|
|
240
|
+
} else if (origItem && modItem) {
|
|
241
|
+
// Compare items at the same position
|
|
242
|
+
const sameType = origItem.type === modItem.type && origItem.level === modItem.level;
|
|
243
|
+
if (sameType && origItem.content !== modItem.content) {
|
|
244
|
+
// Same structure type but different content - show word-level diff
|
|
245
|
+
const wordDiff = diff.diffWords(origItem.content, modItem.content, {
|
|
246
|
+
ignoreCase: !caseSensitive
|
|
247
|
+
});
|
|
248
|
+
const origContentParts = [];
|
|
249
|
+
const modContentParts = [];
|
|
250
|
+
for (const part of wordDiff) {
|
|
251
|
+
if (part.removed) {
|
|
252
|
+
origContentParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
253
|
+
className: "diff-removed",
|
|
254
|
+
children: part.value
|
|
255
|
+
}, origContentParts.length));
|
|
256
|
+
} else if (part.added) {
|
|
257
|
+
modContentParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
258
|
+
className: "diff-added",
|
|
259
|
+
children: part.value
|
|
260
|
+
}, modContentParts.length));
|
|
261
|
+
} else {
|
|
262
|
+
origContentParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
263
|
+
className: "diff-unchanged",
|
|
264
|
+
children: part.value
|
|
265
|
+
}, origContentParts.length));
|
|
266
|
+
modContentParts.push(/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
267
|
+
className: "diff-unchanged",
|
|
268
|
+
children: part.value
|
|
269
|
+
}, modContentParts.length));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
273
|
+
className: "diff-unchanged-line",
|
|
274
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
275
|
+
className: "diff-structure-type",
|
|
276
|
+
children: origItem.type
|
|
277
|
+
}), origItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
278
|
+
className: "diff-structure-level",
|
|
279
|
+
children: [" H", origItem.level]
|
|
280
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
281
|
+
className: "diff-structure-content",
|
|
282
|
+
children: [": ", origContentParts]
|
|
283
|
+
})]
|
|
284
|
+
}, `orig-${i}`));
|
|
285
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
286
|
+
className: "diff-unchanged-line",
|
|
287
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
288
|
+
className: "diff-structure-type",
|
|
289
|
+
children: modItem.type
|
|
290
|
+
}), modItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
291
|
+
className: "diff-structure-level",
|
|
292
|
+
children: [" H", modItem.level]
|
|
293
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
294
|
+
className: "diff-structure-content",
|
|
295
|
+
children: [": ", modContentParts]
|
|
296
|
+
})]
|
|
297
|
+
}, `mod-${i}`));
|
|
298
|
+
} else if (sameType && origItem.content === modItem.content) {
|
|
299
|
+
// Completely unchanged
|
|
300
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
301
|
+
className: "diff-unchanged-line",
|
|
302
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
303
|
+
className: "diff-structure-type",
|
|
304
|
+
children: origItem.type
|
|
305
|
+
}), origItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
306
|
+
className: "diff-structure-level",
|
|
307
|
+
children: [" H", origItem.level]
|
|
308
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
309
|
+
className: "diff-structure-content",
|
|
310
|
+
children: [": ", origItem.content]
|
|
311
|
+
})]
|
|
312
|
+
}, `unchanged-orig-${i}`));
|
|
313
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
314
|
+
className: "diff-unchanged-line",
|
|
315
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
316
|
+
className: "diff-structure-type",
|
|
317
|
+
children: modItem.type
|
|
318
|
+
}), modItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
319
|
+
className: "diff-structure-level",
|
|
320
|
+
children: [" H", modItem.level]
|
|
321
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
322
|
+
className: "diff-structure-content",
|
|
323
|
+
children: [": ", modItem.content]
|
|
324
|
+
})]
|
|
325
|
+
}, `unchanged-mod-${i}`));
|
|
326
|
+
} else {
|
|
327
|
+
// Different structure types - show as removed and added
|
|
328
|
+
originalParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
329
|
+
className: "diff-removed-line",
|
|
330
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
331
|
+
className: "diff-structure-type",
|
|
332
|
+
children: origItem.type
|
|
333
|
+
}), origItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
334
|
+
className: "diff-structure-level",
|
|
335
|
+
children: [" H", origItem.level]
|
|
336
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
337
|
+
className: "diff-structure-content",
|
|
338
|
+
children: [": ", origItem.content]
|
|
339
|
+
})]
|
|
340
|
+
}, `changed-orig-${i}`));
|
|
341
|
+
modifiedParts.push(/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
342
|
+
className: "diff-added-line",
|
|
343
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
344
|
+
className: "diff-structure-type",
|
|
345
|
+
children: modItem.type
|
|
346
|
+
}), modItem.level && /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
347
|
+
className: "diff-structure-level",
|
|
348
|
+
children: [" H", modItem.level]
|
|
349
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
350
|
+
className: "diff-structure-content",
|
|
351
|
+
children: [": ", modItem.content]
|
|
352
|
+
})]
|
|
353
|
+
}, `changed-mod-${i}`));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
originalParts,
|
|
359
|
+
modifiedParts
|
|
360
|
+
};
|
|
361
|
+
} else {
|
|
362
|
+
// Text-based comparison of Contentful documents
|
|
363
|
+
const origText = extractPlainText(origDoc);
|
|
364
|
+
const modText = extractPlainText(modDoc);
|
|
365
|
+
return renderStringDiff(origText, modText);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
93
368
|
const isStringComparison = typeof original === 'string' && typeof modified === 'string';
|
|
94
369
|
const isArrayComparison = Array.isArray(original) && Array.isArray(modified);
|
|
95
|
-
|
|
96
|
-
|
|
370
|
+
const isContentfulComparison = isContentfulDocument(original) && isContentfulDocument(modified);
|
|
371
|
+
if (!isStringComparison && !isArrayComparison && !isContentfulComparison) {
|
|
372
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
97
373
|
className: `compare-error ${className}`,
|
|
98
|
-
children: "Error: Both inputs must be either strings
|
|
374
|
+
children: "Error: Both inputs must be either strings, arrays of strings, or Contentful documents"
|
|
99
375
|
});
|
|
100
376
|
}
|
|
101
377
|
let originalParts, modifiedParts;
|
|
@@ -104,38 +380,47 @@ const Compare = ({
|
|
|
104
380
|
originalParts,
|
|
105
381
|
modifiedParts
|
|
106
382
|
} = renderStringDiff(original, modified));
|
|
107
|
-
} else {
|
|
383
|
+
} else if (isArrayComparison) {
|
|
108
384
|
({
|
|
109
385
|
originalParts,
|
|
110
386
|
modifiedParts
|
|
111
387
|
} = renderArrayDiff(original, modified));
|
|
388
|
+
} else if (isContentfulComparison) {
|
|
389
|
+
({
|
|
390
|
+
originalParts,
|
|
391
|
+
modifiedParts
|
|
392
|
+
} = renderContentfulDiff(original, modified));
|
|
393
|
+
} else {
|
|
394
|
+
// This should never happen due to the check above, but provide a fallback
|
|
395
|
+
originalParts = [];
|
|
396
|
+
modifiedParts = [];
|
|
112
397
|
}
|
|
113
398
|
if (viewMode === 'inline') {
|
|
114
|
-
return jsxRuntime.jsx("div", {
|
|
399
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
115
400
|
className: `compare-inline ${className}`,
|
|
116
|
-
children: jsxRuntime.jsxs("div", {
|
|
401
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
117
402
|
className: "compare-content",
|
|
118
403
|
children: [originalParts, modifiedParts]
|
|
119
404
|
})
|
|
120
405
|
});
|
|
121
406
|
}
|
|
122
|
-
return jsxRuntime.jsxs("div", {
|
|
407
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
123
408
|
className: `compare-side-by-side ${className}`,
|
|
124
|
-
children: [jsxRuntime.jsxs("div", {
|
|
409
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
125
410
|
className: "compare-panel",
|
|
126
|
-
children: [jsxRuntime.jsx("div", {
|
|
411
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
127
412
|
className: "compare-header original-header",
|
|
128
413
|
children: "Original"
|
|
129
|
-
}), jsxRuntime.jsx("div", {
|
|
414
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
130
415
|
className: "compare-content original-content",
|
|
131
416
|
children: originalParts
|
|
132
417
|
})]
|
|
133
|
-
}), jsxRuntime.jsxs("div", {
|
|
418
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
134
419
|
className: "compare-panel",
|
|
135
|
-
children: [jsxRuntime.jsx("div", {
|
|
420
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
136
421
|
className: "compare-header modified-header",
|
|
137
422
|
children: "Modified"
|
|
138
|
-
}), jsxRuntime.jsx("div", {
|
|
423
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
139
424
|
className: "compare-content modified-content",
|
|
140
425
|
children: modifiedParts
|
|
141
426
|
})]
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/components/Compare.tsx"],"sourcesContent":["import { diffWords, diffArrays } from 'diff';\nimport React from 'react';\n\n// Types\nexport interface CompareProps {\n original: string | string[];\n modified: string | string[];\n className?: string;\n viewMode?: 'side-by-side' | 'inline';\n caseSensitive?: boolean; // <-- Added\n}\n\nexport const Compare: React.FC<CompareProps> = ({\n original,\n modified,\n className = '',\n viewMode = 'side-by-side',\n caseSensitive = true, // <-- Default true\n}) => {\n // Handle string comparison\n const renderStringDiff = (orig: string, mod: string) => {\n const diff = diffWords(orig, mod, { ignoreCase: !caseSensitive });\n const originalParts: any[] = [];\n const modifiedParts: any[] = [];\n for (const part of diff) {\n if (part.removed) {\n originalParts.push(\n <span key={originalParts.length} className=\"diff-removed\">\n {part.value}\n </span>\n );\n } else if (part.added) {\n modifiedParts.push(\n <span key={modifiedParts.length} className=\"diff-added\">\n {part.value}\n </span>\n );\n } else {\n originalParts.push(\n <span key={originalParts.length} className=\"diff-unchanged\">\n {part.value}\n </span>\n );\n modifiedParts.push(\n <span key={modifiedParts.length} className=\"diff-unchanged\">\n {part.value}\n </span>\n );\n }\n }\n return { originalParts, modifiedParts };\n };\n\n // Handle array comparison\n const renderArrayDiff = (orig: string[], mod: string[]) => {\n let origArr = orig;\n let modArr = mod;\n if (!caseSensitive) {\n origArr = orig.map((s) => (typeof s === 'string' ? s.toLowerCase() : s));\n modArr = mod.map((s) => (typeof s === 'string' ? s.toLowerCase() : s));\n }\n const diff = diffArrays(origArr, modArr);\n const originalParts: any[] = [];\n const modifiedParts: any[] = [];\n for (const part of diff) {\n if (part.removed) {\n part.value.forEach((item: string, index: number) => {\n originalParts.push(\n <div key={`${originalParts.length}-${index}`} className=\"diff-removed-line\">\n {orig[origArr.indexOf(item, originalParts.length)] ?? item}\n </div>\n );\n });\n } else if (part.added) {\n part.value.forEach((item: string, index: number) => {\n modifiedParts.push(\n <div key={`${modifiedParts.length}-${index}`} className=\"diff-added-line\">\n {mod[modArr.indexOf(item, modifiedParts.length)] ?? item}\n </div>\n );\n });\n } else {\n part.value.forEach((item: string, index: number) => {\n originalParts.push(\n <div key={`${originalParts.length}-${index}`} className=\"diff-unchanged-line\">\n {orig[origArr.indexOf(item, originalParts.length)] ?? item}\n </div>\n );\n modifiedParts.push(\n <div key={`${modifiedParts.length}-${index}`} className=\"diff-unchanged-line\">\n {mod[modArr.indexOf(item, modifiedParts.length)] ?? item}\n </div>\n );\n });\n }\n }\n return { originalParts, modifiedParts };\n };\n\n const isStringComparison = typeof original === 'string' && typeof modified === 'string';\n const isArrayComparison = Array.isArray(original) && Array.isArray(modified);\n\n if (!isStringComparison && !isArrayComparison) {\n return (\n <div className={`compare-error ${className}`}>\n Error: Both inputs must be either strings or arrays of strings\n </div>\n );\n }\n\n let originalParts: any[], modifiedParts: any[];\n if (isStringComparison) {\n ({ originalParts, modifiedParts } = renderStringDiff(original as string, modified as string));\n } else {\n ({ originalParts, modifiedParts } = renderArrayDiff(original as string[], modified as string[]));\n }\n\n if (viewMode === 'inline') {\n return (\n <div className={`compare-inline ${className}`}>\n <div className=\"compare-content\">\n {originalParts}\n {modifiedParts}\n </div>\n </div>\n );\n }\n\n return (\n <div className={`compare-side-by-side ${className}`}>\n <div className=\"compare-panel\">\n <div className=\"compare-header original-header\">Original</div>\n <div className=\"compare-content original-content\">\n {originalParts}\n </div>\n </div>\n <div className=\"compare-panel\">\n <div className=\"compare-header modified-header\">Modified</div>\n <div className=\"compare-content modified-content\">\n {modifiedParts}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Compare;"],"names":["Compare","original","modified","className","viewMode","caseSensitive","renderStringDiff","orig","mod","diff","diffWords","ignoreCase","originalParts","modifiedParts","part","removed","push","_jsx","children","value","length","added","renderArrayDiff","origArr","modArr","map","s","toLowerCase","diffArrays","forEach","item","index","indexOf","isStringComparison","isArrayComparison","Array","isArray","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/components/Compare.tsx"],"sourcesContent":["import { diffWords, diffArrays } from 'diff';\nimport React from 'react';\nimport { Document, Block, Inline, Text, BLOCKS } from '@contentful/rich-text-types';\n\n// Utility functions for Contentful Rich Text\nconst extractPlainText = (document: Document): string => {\n const extractFromNode = (node: Block | Inline | Text): string => {\n if (node.nodeType === 'text') {\n return (node as Text).value;\n }\n \n if ('content' in node && node.content) {\n return node.content.map(child => extractFromNode(child)).join('');\n }\n \n return '';\n };\n \n return extractFromNode(document);\n};\n\nconst extractStructuredContent = (document: Document): Array<{ type: string; content: string; level?: number }> => {\n const result: Array<{ type: string; content: string; level?: number }> = [];\n \n const extractFromNode = (node: Block | Inline | Text): void => {\n if (node.nodeType === 'text') {\n // Skip standalone text nodes as they're usually part of a parent structure\n return;\n }\n \n if ('content' in node && node.content) {\n const textContent = node.content.map(child => \n child.nodeType === 'text' ? (child as Text).value : ''\n ).join('');\n \n // Map node types to user-friendly names and extract heading levels\n let displayType: string = node.nodeType;\n let headingLevel: number | undefined;\n \n switch (node.nodeType) {\n case BLOCKS.HEADING_1:\n displayType = 'Heading';\n headingLevel = 1;\n break;\n case BLOCKS.HEADING_2:\n displayType = 'Heading';\n headingLevel = 2;\n break;\n case BLOCKS.HEADING_3:\n displayType = 'Heading';\n headingLevel = 3;\n break;\n case BLOCKS.HEADING_4:\n displayType = 'Heading';\n headingLevel = 4;\n break;\n case BLOCKS.HEADING_5:\n displayType = 'Heading';\n headingLevel = 5;\n break;\n case BLOCKS.HEADING_6:\n displayType = 'Heading';\n headingLevel = 6;\n break;\n case BLOCKS.PARAGRAPH:\n displayType = 'Text';\n break;\n case BLOCKS.UL_LIST:\n displayType = 'List';\n break;\n case BLOCKS.OL_LIST:\n displayType = 'Numbered List';\n break;\n case BLOCKS.LIST_ITEM:\n displayType = 'List Item';\n break;\n case BLOCKS.QUOTE:\n displayType = 'Quote';\n break;\n case BLOCKS.TABLE:\n displayType = 'Table';\n break;\n default:\n displayType = node.nodeType.charAt(0).toUpperCase() + node.nodeType.slice(1);\n }\n \n if (textContent.trim()) {\n result.push({\n type: displayType,\n content: textContent.trim(),\n level: headingLevel\n });\n }\n \n // Recursively process child nodes for nested structures like list items\n node.content.forEach(child => {\n if (child.nodeType !== 'text') {\n extractFromNode(child);\n }\n });\n }\n };\n \n if (document.content) {\n document.content.forEach(node => extractFromNode(node));\n }\n \n return result;\n};\n\nconst isContentfulDocument = (value: any): value is Document => {\n return value && typeof value === 'object' && value.nodeType === BLOCKS.DOCUMENT && Array.isArray(value.content);\n};\n\n// Types\nexport interface CompareProps {\n original: string | string[] | Document;\n modified: string | string[] | Document;\n className?: string;\n viewMode?: 'side-by-side' | 'inline';\n caseSensitive?: boolean;\n compareMode?: 'text' | 'structure'; // New prop for Contentful documents\n}\n\nexport const Compare: React.FC<CompareProps> = ({\n original,\n modified,\n className = '',\n viewMode = 'side-by-side',\n caseSensitive = true,\n compareMode = 'text', // Default to text comparison\n}) => {\n // Handle string comparison\n const renderStringDiff = (orig: string, mod: string) => {\n const diff = diffWords(orig, mod, { ignoreCase: !caseSensitive });\n const originalParts: any[] = [];\n const modifiedParts: any[] = [];\n for (const part of diff) {\n if (part.removed) {\n originalParts.push(\n <span key={originalParts.length} className=\"diff-removed\">\n {part.value}\n </span>\n );\n } else if (part.added) {\n modifiedParts.push(\n <span key={modifiedParts.length} className=\"diff-added\">\n {part.value}\n </span>\n );\n } else {\n originalParts.push(\n <span key={originalParts.length} className=\"diff-unchanged\">\n {part.value}\n </span>\n );\n modifiedParts.push(\n <span key={modifiedParts.length} className=\"diff-unchanged\">\n {part.value}\n </span>\n );\n }\n }\n return { originalParts, modifiedParts };\n };\n\n // Handle array comparison\n const renderArrayDiff = (orig: string[], mod: string[]) => {\n let origArr = orig;\n let modArr = mod;\n if (!caseSensitive) {\n origArr = orig.map((s) => (typeof s === 'string' ? s.toLowerCase() : s));\n modArr = mod.map((s) => (typeof s === 'string' ? s.toLowerCase() : s));\n }\n const diff = diffArrays(origArr, modArr);\n const originalParts: any[] = [];\n const modifiedParts: any[] = [];\n for (const part of diff) {\n if (part.removed) {\n part.value.forEach((item: string, index: number) => {\n originalParts.push(\n <div key={`${originalParts.length}-${index}`} className=\"diff-removed-line\">\n {orig[origArr.indexOf(item, originalParts.length)] ?? item}\n </div>\n );\n });\n } else if (part.added) {\n part.value.forEach((item: string, index: number) => {\n modifiedParts.push(\n <div key={`${modifiedParts.length}-${index}`} className=\"diff-added-line\">\n {mod[modArr.indexOf(item, modifiedParts.length)] ?? item}\n </div>\n );\n });\n } else {\n part.value.forEach((item: string, index: number) => {\n originalParts.push(\n <div key={`${originalParts.length}-${index}`} className=\"diff-unchanged-line\">\n {orig[origArr.indexOf(item, originalParts.length)] ?? item}\n </div>\n );\n modifiedParts.push(\n <div key={`${modifiedParts.length}-${index}`} className=\"diff-unchanged-line\">\n {mod[modArr.indexOf(item, modifiedParts.length)] ?? item}\n </div>\n );\n });\n }\n }\n return { originalParts, modifiedParts };\n };\n\n // Handle Contentful document comparison\n const renderContentfulDiff = (origDoc: Document, modDoc: Document) => {\n if (compareMode === 'structure') {\n // Compare structural elements\n const origStructure = extractStructuredContent(origDoc);\n const modStructure = extractStructuredContent(modDoc);\n \n // Create a more sophisticated comparison that can handle changes within the same structure type\n const maxLength = Math.max(origStructure.length, modStructure.length);\n const originalParts: any[] = [];\n const modifiedParts: any[] = [];\n \n for (let i = 0; i < maxLength; i++) {\n const origItem = origStructure[i];\n const modItem = modStructure[i];\n \n if (!origItem && modItem) {\n // Added item\n modifiedParts.push(\n <div key={`added-${i}`} className=\"diff-added-line\">\n <span className=\"diff-structure-type\">{modItem.type}</span>\n {modItem.level && <span className=\"diff-structure-level\"> H{modItem.level}</span>}\n <span className=\"diff-structure-content\">: {modItem.content}</span>\n </div>\n );\n } else if (origItem && !modItem) {\n // Removed item\n originalParts.push(\n <div key={`removed-${i}`} className=\"diff-removed-line\">\n <span className=\"diff-structure-type\">{origItem.type}</span>\n {origItem.level && <span className=\"diff-structure-level\"> H{origItem.level}</span>}\n <span className=\"diff-structure-content\">: {origItem.content}</span>\n </div>\n );\n } else if (origItem && modItem) {\n // Compare items at the same position\n const sameType = origItem.type === modItem.type && origItem.level === modItem.level;\n \n if (sameType && origItem.content !== modItem.content) {\n // Same structure type but different content - show word-level diff\n const wordDiff = diffWords(origItem.content, modItem.content, { ignoreCase: !caseSensitive });\n \n const origContentParts: any[] = [];\n const modContentParts: any[] = [];\n \n for (const part of wordDiff) {\n if (part.removed) {\n origContentParts.push(\n <span key={origContentParts.length} className=\"diff-removed\">\n {part.value}\n </span>\n );\n } else if (part.added) {\n modContentParts.push(\n <span key={modContentParts.length} className=\"diff-added\">\n {part.value}\n </span>\n );\n } else {\n origContentParts.push(\n <span key={origContentParts.length} className=\"diff-unchanged\">\n {part.value}\n </span>\n );\n modContentParts.push(\n <span key={modContentParts.length} className=\"diff-unchanged\">\n {part.value}\n </span>\n );\n }\n }\n \n originalParts.push(\n <div key={`orig-${i}`} className=\"diff-unchanged-line\">\n <span className=\"diff-structure-type\">{origItem.type}</span>\n {origItem.level && <span className=\"diff-structure-level\"> H{origItem.level}</span>}\n <span className=\"diff-structure-content\">: {origContentParts}</span>\n </div>\n );\n modifiedParts.push(\n <div key={`mod-${i}`} className=\"diff-unchanged-line\">\n <span className=\"diff-structure-type\">{modItem.type}</span>\n {modItem.level && <span className=\"diff-structure-level\"> H{modItem.level}</span>}\n <span className=\"diff-structure-content\">: {modContentParts}</span>\n </div>\n );\n } else if (sameType && origItem.content === modItem.content) {\n // Completely unchanged\n originalParts.push(\n <div key={`unchanged-orig-${i}`} className=\"diff-unchanged-line\">\n <span className=\"diff-structure-type\">{origItem.type}</span>\n {origItem.level && <span className=\"diff-structure-level\"> H{origItem.level}</span>}\n <span className=\"diff-structure-content\">: {origItem.content}</span>\n </div>\n );\n modifiedParts.push(\n <div key={`unchanged-mod-${i}`} className=\"diff-unchanged-line\">\n <span className=\"diff-structure-type\">{modItem.type}</span>\n {modItem.level && <span className=\"diff-structure-level\"> H{modItem.level}</span>}\n <span className=\"diff-structure-content\">: {modItem.content}</span>\n </div>\n );\n } else {\n // Different structure types - show as removed and added\n originalParts.push(\n <div key={`changed-orig-${i}`} className=\"diff-removed-line\">\n <span className=\"diff-structure-type\">{origItem.type}</span>\n {origItem.level && <span className=\"diff-structure-level\"> H{origItem.level}</span>}\n <span className=\"diff-structure-content\">: {origItem.content}</span>\n </div>\n );\n modifiedParts.push(\n <div key={`changed-mod-${i}`} className=\"diff-added-line\">\n <span className=\"diff-structure-type\">{modItem.type}</span>\n {modItem.level && <span className=\"diff-structure-level\"> H{modItem.level}</span>}\n <span className=\"diff-structure-content\">: {modItem.content}</span>\n </div>\n );\n }\n }\n }\n \n return { originalParts, modifiedParts };\n } else {\n // Text-based comparison of Contentful documents\n const origText = extractPlainText(origDoc);\n const modText = extractPlainText(modDoc);\n return renderStringDiff(origText, modText);\n }\n };\n\n const isStringComparison = typeof original === 'string' && typeof modified === 'string';\n const isArrayComparison = Array.isArray(original) && Array.isArray(modified);\n const isContentfulComparison = isContentfulDocument(original) && isContentfulDocument(modified);\n\n if (!isStringComparison && !isArrayComparison && !isContentfulComparison) {\n return (\n <div className={`compare-error ${className}`}>\n Error: Both inputs must be either strings, arrays of strings, or Contentful documents\n </div>\n );\n }\n\n let originalParts: any[], modifiedParts: any[];\n if (isStringComparison) {\n ({ originalParts, modifiedParts } = renderStringDiff(original as string, modified as string));\n } else if (isArrayComparison) {\n ({ originalParts, modifiedParts } = renderArrayDiff(original as string[], modified as string[]));\n } else if (isContentfulComparison) {\n ({ originalParts, modifiedParts } = renderContentfulDiff(original as Document, modified as Document));\n } else {\n // This should never happen due to the check above, but provide a fallback\n originalParts = [];\n modifiedParts = [];\n }\n\n if (viewMode === 'inline') {\n return (\n <div className={`compare-inline ${className}`}>\n <div className=\"compare-content\">\n {originalParts}\n {modifiedParts}\n </div>\n </div>\n );\n }\n\n return (\n <div className={`compare-side-by-side ${className}`}>\n <div className=\"compare-panel\">\n <div className=\"compare-header original-header\">Original</div>\n <div className=\"compare-content original-content\">\n {originalParts}\n </div>\n </div>\n <div className=\"compare-panel\">\n <div className=\"compare-header modified-header\">Modified</div>\n <div className=\"compare-content modified-content\">\n {modifiedParts}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Compare;"],"names":["extractPlainText","document","extractFromNode","node","nodeType","value","content","map","child","join","extractStructuredContent","result","textContent","displayType","headingLevel","BLOCKS","HEADING_1","HEADING_2","HEADING_3","HEADING_4","HEADING_5","HEADING_6","PARAGRAPH","UL_LIST","OL_LIST","LIST_ITEM","QUOTE","TABLE","charAt","toUpperCase","slice","trim","push","type","level","forEach","isContentfulDocument","DOCUMENT","Array","isArray","Compare","original","modified","className","viewMode","caseSensitive","compareMode","renderStringDiff","orig","mod","diff","diffWords","ignoreCase","originalParts","modifiedParts","part","removed","_jsx","children","length","added","renderArrayDiff","origArr","modArr","s","toLowerCase","diffArrays","item","index","indexOf","renderContentfulDiff","origDoc","modDoc","origStructure","modStructure","maxLength","Math","max","i","origItem","modItem","_jsxs","sameType","wordDiff","origContentParts","modContentParts","origText","modText","isStringComparison","isArrayComparison","isContentfulComparison"],"mappings":"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"}
|