Skip to content

Commit 2d71e87

Browse files
committed
handle addition and deletion space allocation
1 parent 2e1889d commit 2d71e87

4 files changed

Lines changed: 45 additions & 17 deletions

File tree

package-lock.json

Lines changed: 2 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-diff-viewer-component",
3-
"version": "0.3.0",
3+
"version": "0.4.0",
44
"type": "module",
55
"description": "Vanilla JS web component for side-by-side JSON diff visualization",
66
"keywords": [

src/lib/styles.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export default `
1616
.node.root { padding-left: 0; }
1717
.line { display: flex; align-items: flex-start; gap: 0.5rem; padding: 2px 4px; border-radius: 4px; cursor: pointer; transition: background .15s; }
1818
.line:hover { background: rgba(0,0,0,.03); }
19+
.line.placeholder { cursor: default; pointer-events: none; }
20+
.line.placeholder:hover { background: transparent; }
1921
.tog { width: 1rem; flex-shrink: 0; color: var(--br); user-select: none; }
2022
.tog:hover { color: var(--txt); }
2123
.key { color: var(--key); }

src/lib/viewer.js

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,38 @@ class JsonDiffViewer extends HTMLElement {
129129
this.#bind();
130130
}
131131

132+
#placeholder(node, side, path, root = true) {
133+
const currentPath = path ? `${path}.${node.key}` : String(node.key);
134+
const value = node[side];
135+
const keyHtml = root ? "" : `<span class="key" style="visibility: hidden;">${node.key}</span><span class="colon" style="visibility: hidden;">:</span>`;
136+
const rootClass = root ? " root" : "";
137+
138+
if (!node.isArray && !node.isObject) {
139+
if (value === undefined) {
140+
return `<div class="node${rootClass}"><div class="line placeholder"><span class="tog"></span>${keyHtml}</div></div>`;
141+
}
142+
const [val, type] = format(value);
143+
return `<div class="node${rootClass}"><div class="line placeholder"><span class="tog"></span>${keyHtml}<span class="val-${type}" style="visibility: hidden;">${val}</span></div></div>`;
144+
}
145+
146+
const [open, close] = node.isArray ? ["[", "]"] : ["{", "}"];
147+
const children = node.children || [];
148+
const isExpanded = this.#proxy[currentPath] !== false;
149+
const filteredChildren = this.#showOnlyChanged
150+
? children.filter((c) => c.hasDiff)
151+
: children;
152+
const childrenHtml = isExpanded
153+
? filteredChildren.map((c) => this.#placeholder(c, side, currentPath, false)).join("")
154+
: "";
155+
const preview = `${filteredChildren.length}`;
156+
157+
if (!isExpanded) {
158+
return `<div class="node${rootClass}"><div class="line placeholder"><span class="tog">▶</span>${keyHtml}<span class="br" style="visibility: hidden;">${open}</span><span class="preview" style="visibility: hidden;">${preview}</span><span class="br" style="visibility: hidden;">${close}</span></div></div>`;
159+
}
160+
161+
return `<div class="node${rootClass}"><div class="line placeholder"><span class="tog">▼</span>${keyHtml}<span class="br" style="visibility: hidden;">${open}</span></div>${childrenHtml}<div class="line placeholder"><span class="tog"></span><span class="br" style="visibility: hidden;">${close}</span></div></div>`;
162+
}
163+
132164
#node(node, side, path, root = true) {
133165
const currentPath = path ? `${path}.${node.key}` : String(node.key);
134166
const value = node[side];
@@ -143,6 +175,13 @@ class JsonDiffViewer extends HTMLElement {
143175
const rootClass = root ? " root" : "";
144176
const nodeDiffClass = hasDiff && !hasChildDiff ? ` ${diffClass}` : "";
145177

178+
if (value === undefined) {
179+
if (node.children?.length) {
180+
return this.#placeholder(node, side, path, root);
181+
}
182+
return `<div class="node${rootClass}"><div class="line placeholder"><span class="tog"></span>${root ? "" : `<span class="key" style="visibility: hidden;">${node.key}</span><span class="colon" style="visibility: hidden;">:</span>`}</div></div>`;
183+
}
184+
146185
if (!node.isArray && !node.isObject) {
147186
const [val, type] = format(value);
148187
return `<div class="node${rootClass}${nodeDiffClass}"><div class="line"><span class="tog"></span>${dot}${keyHtml}<span class="val-${type}">${val}</span></div></div>`;
@@ -153,10 +192,7 @@ class JsonDiffViewer extends HTMLElement {
153192
const filteredChildren = this.#showOnlyChanged
154193
? node.children?.filter((c) => c.hasDiff) || []
155194
: node.children || [];
156-
const childrenHtml =
157-
filteredChildren
158-
.map((c) => this.#node(c, side, currentPath, false))
159-
.join("") || "";
195+
const childrenHtml = filteredChildren.map((c) => this.#node(c, side, currentPath, false)).join("");
160196
const preview = `${filteredChildren.length}`;
161197

162198
if (!isExpanded) {

0 commit comments

Comments
 (0)