json-diff-viewer-component 0.6.1 → 0.6.3
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 +42 -18
- package/package.json +2 -2
- package/src/lib/viewer.js +8 -6
package/README.md
CHANGED
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
|
-
-
|
|
21
|
+
- Nested JSON comparison
|
|
22
22
|
- Side-by-side synchronized scrolling
|
|
23
23
|
- Collapsible nodes (synced between panels)
|
|
24
|
-
- Diff indicators
|
|
24
|
+
- Diff indicators roll up to parent nodes
|
|
25
25
|
- Stats summary (added/removed/modified)
|
|
26
26
|
- Show only changed filter toggle
|
|
27
27
|
- Syntax highlighting
|
|
@@ -36,7 +36,7 @@ npm i json-diff-viewer-component
|
|
|
36
36
|
|
|
37
37
|
## Usage
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Import the package to register the `<json-diff-viewer>` custom element, then call `setData()` with both JSON values:
|
|
40
40
|
|
|
41
41
|
```js
|
|
42
42
|
import "json-diff-viewer-component";
|
|
@@ -45,8 +45,16 @@ const viewer = document.querySelector("json-diff-viewer");
|
|
|
45
45
|
viewer.setData(leftObj, rightObj);
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
For testing or extension, the class is also exported:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import { JsonDiffViewer } from "json-diff-viewer-component";
|
|
52
|
+
```
|
|
53
|
+
|
|
48
54
|
### HTML Attributes
|
|
49
55
|
|
|
56
|
+
Static JSON can be passed as attributes. Values must be valid JSON strings:
|
|
57
|
+
|
|
50
58
|
```html
|
|
51
59
|
<json-diff-viewer
|
|
52
60
|
left='{"name":"foo"}'
|
|
@@ -54,18 +62,28 @@ viewer.setData(leftObj, rightObj);
|
|
|
54
62
|
></json-diff-viewer>
|
|
55
63
|
```
|
|
56
64
|
|
|
65
|
+
- `JSON.parse` parses attribute values. Invalid JSON throws at parse time.
|
|
66
|
+
- Prefer `setData()` or property setters for dynamic or object data
|
|
67
|
+
|
|
57
68
|
### Properties
|
|
58
69
|
|
|
70
|
+
Set `left` and `right` as JavaScript values. Set both before the viewer draws a diff:
|
|
71
|
+
|
|
59
72
|
```js
|
|
60
73
|
viewer.left = { name: "foo" };
|
|
61
74
|
viewer.right = { name: "bar" };
|
|
75
|
+
|
|
76
|
+
viewer.left; // read current left value
|
|
77
|
+
viewer.right; // read current right value
|
|
62
78
|
```
|
|
63
79
|
|
|
64
|
-
###
|
|
80
|
+
### Built-in Controls
|
|
65
81
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
The component toolbar includes:
|
|
83
|
+
|
|
84
|
+
- **Show only changed**: filter toggle (default: **on**); hides unchanged nodes
|
|
85
|
+
- **Collapse all** / **Expand all**: bulk expand/collapse
|
|
86
|
+
- **Node toggles**: click any object/array line to expand/collapse (synced across both panels)
|
|
69
87
|
|
|
70
88
|
<details>
|
|
71
89
|
<summary>Framework Examples</summary>
|
|
@@ -131,7 +149,7 @@ watch(
|
|
|
131
149
|
|
|
132
150
|
## Styling
|
|
133
151
|
|
|
134
|
-
|
|
152
|
+
Override CSS custom properties (design tokens) on `json-diff-viewer`. Tokens live on `:host`; you set them from outside the shadow DOM.
|
|
135
153
|
|
|
136
154
|
### Design Tokens
|
|
137
155
|
|
|
@@ -170,21 +188,27 @@ Create your own theme by overriding these tokens. For example, a light theme:
|
|
|
170
188
|
|
|
171
189
|
```css
|
|
172
190
|
json-diff-viewer {
|
|
173
|
-
--
|
|
174
|
-
--
|
|
175
|
-
--
|
|
176
|
-
--
|
|
177
|
-
--
|
|
178
|
-
--
|
|
179
|
-
--
|
|
180
|
-
--
|
|
181
|
-
|
|
191
|
+
--add: #15803d;
|
|
192
|
+
--rem: #b91c1c;
|
|
193
|
+
--mod: #ca8a04;
|
|
194
|
+
--bg: #f4f4f4;
|
|
195
|
+
--bg2: #f9fafb;
|
|
196
|
+
--bdr: #d1d5db;
|
|
197
|
+
--txt: #030712;
|
|
198
|
+
--dim: #4b5563;
|
|
199
|
+
--slider: #d1d5db;
|
|
200
|
+
--key: #075985;
|
|
201
|
+
--str: #6d28d9;
|
|
202
|
+
--num: #047857;
|
|
203
|
+
--bool: #b45309;
|
|
204
|
+
--nul: #a21caf;
|
|
205
|
+
--br: #6b7280;
|
|
182
206
|
}
|
|
183
207
|
```
|
|
184
208
|
|
|
185
209
|
### Sizing
|
|
186
210
|
|
|
187
|
-
|
|
211
|
+
Set a height to get scrolling. Without one, the viewer grows to fit all content. Default border-radius is `12px`.
|
|
188
212
|
|
|
189
213
|
```css
|
|
190
214
|
json-diff-viewer {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-diff-viewer-component",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vanilla JS web component for side-by-side JSON diff visualization",
|
|
6
6
|
"bugs": "https://github.com/metaory/json-diff-viewer-component/issues",
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@fontsource/bungee": "^5.2.7",
|
|
33
|
-
"vite": "^
|
|
33
|
+
"vite": "^8.0.16"
|
|
34
34
|
}
|
|
35
35
|
}
|
package/src/lib/viewer.js
CHANGED
|
@@ -2,6 +2,8 @@ import { diff, TYPE } from "./diff.js";
|
|
|
2
2
|
import styles from "./styles.js";
|
|
3
3
|
|
|
4
4
|
const STAT_TYPES = ["added", "removed", "modified"];
|
|
5
|
+
const ENTITIES = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
6
|
+
const escapeHtml = (value) => String(value).replace(/[&<>"']/g, (char) => ENTITIES[char]);
|
|
5
7
|
|
|
6
8
|
const format = (val) => {
|
|
7
9
|
if (val === null) return ["null", "null"];
|
|
@@ -20,7 +22,7 @@ const filterChildren = (children, showOnlyChanged) =>
|
|
|
20
22
|
const isExpanded = (proxy, path) => proxy[path] !== false;
|
|
21
23
|
|
|
22
24
|
const buildKeyHtml = (key, root, hidden = false) =>
|
|
23
|
-
root ? "" : `<span class="key"${hidden ? ' style="visibility: hidden;"' : ""}>${key}</span><span class="colon"${hidden ? ' style="visibility: hidden;"' : ""}>:</span>`;
|
|
25
|
+
root ? "" : `<span class="key"${hidden ? ' style="visibility: hidden;"' : ""}>${escapeHtml(key)}</span><span class="colon"${hidden ? ' style="visibility: hidden;"' : ""}>:</span>`;
|
|
24
26
|
|
|
25
27
|
const buildRootClass = (root) => root ? " root" : "";
|
|
26
28
|
|
|
@@ -100,7 +102,7 @@ class JsonDiffViewer extends HTMLElement {
|
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
#compute() {
|
|
103
|
-
if (
|
|
105
|
+
if (this.#left == null || this.#right == null) return;
|
|
104
106
|
this.#tree = diff(this.#left, this.#right);
|
|
105
107
|
this.#stats = collectStats(this.#tree);
|
|
106
108
|
Object.keys(this.#exp).forEach((k) => {
|
|
@@ -182,18 +184,18 @@ class JsonDiffViewer extends HTMLElement {
|
|
|
182
184
|
const otherValue = side === 'left' ? node.right : node.left;
|
|
183
185
|
const [val, type] = format(otherValue);
|
|
184
186
|
const hiddenKey = buildKeyHtml(node.key, root, true);
|
|
185
|
-
return `<div class="node${rootClass}"><div class="line placeholder">${hiddenKey}<span class="val-${type}" style="visibility: hidden;">${val}</span></div></div>`;
|
|
187
|
+
return `<div class="node${rootClass}"><div class="line placeholder">${hiddenKey}<span class="val-${type}" style="visibility: hidden;">${escapeHtml(val)}</span></div></div>`;
|
|
186
188
|
}
|
|
187
189
|
|
|
188
190
|
if (value !== undefined && !node.isArray && !node.isObject) {
|
|
189
191
|
const [val, type] = format(value);
|
|
190
192
|
if (placeholder) {
|
|
191
|
-
return `<div class="node${rootClass}"><div class="line placeholder">${keyHtml}<span class="val-${type}"${hidden}>${val}</span></div></div>`;
|
|
193
|
+
return `<div class="node${rootClass}"><div class="line placeholder">${keyHtml}<span class="val-${type}"${hidden}>${escapeHtml(val)}</span></div></div>`;
|
|
192
194
|
}
|
|
193
195
|
const hasDiff = node.hasDiff && node.type !== TYPE.UNCHANGED;
|
|
194
196
|
const diffClass = hasDiff ? `diff-${node.type}` : "";
|
|
195
197
|
const nodeDiffClass = hasDiff ? ` ${diffClass}` : "";
|
|
196
|
-
return `<div class="node${rootClass}${nodeDiffClass}"><div class="line"><span class="tog"></span>${keyHtml}<span class="val-${type}">${val}</span></div></div>`;
|
|
198
|
+
return `<div class="node${rootClass}${nodeDiffClass}"><div class="line"><span class="tog"></span>${keyHtml}<span class="val-${type}">${escapeHtml(val)}</span></div></div>`;
|
|
197
199
|
}
|
|
198
200
|
|
|
199
201
|
const [open, close] = getBrackets(node.isArray);
|
|
@@ -219,7 +221,7 @@ class JsonDiffViewer extends HTMLElement {
|
|
|
219
221
|
const dot = hasChildDiff ? `<span class="dot dot-${dotType}"></span>` : "";
|
|
220
222
|
const nodeDiffClass = hasDiff && !hasChildDiff ? ` ${diffClass}` : "";
|
|
221
223
|
const toggle = expanded ? "▼" : "▶";
|
|
222
|
-
const dataPath = ` data-p="${currentPath}"`;
|
|
224
|
+
const dataPath = ` data-p="${escapeHtml(currentPath)}"`;
|
|
223
225
|
|
|
224
226
|
if (!expanded) {
|
|
225
227
|
return `<div class="node${rootClass}${nodeDiffClass}"><div class="line"${dataPath}><span class="tog">${toggle}</span>${dot}${keyHtml}<span class="br">${open}</span><span class="preview">${preview}</span><span class="br">${close}</span></div></div>`;
|