Skip to content

Commit 6d0e474

Browse files
committed
updated demo to accept file, url and text input
1 parent e857b43 commit 6d0e474

File tree

3 files changed

+339
-33
lines changed

3 files changed

+339
-33
lines changed

index.html

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,55 @@
11
<!DOCTYPE html>
22
<html lang="en">
3+
34
<head>
45
<meta charset="UTF-8">
56
<meta name="viewport" content="width=device-width, initial-scale=1.0">
67
<link rel="icon" type="image/svg+xml" href="/logo.svg">
78
<title>JSON Diff Viewer</title>
89
</head>
10+
911
<body>
1012
<div id="app">
11-
<h1>JSON Diff Viewer
12-
<div class="header-controls">
13-
<button id="theme-toggle">Light</button>
14-
<a href="https://github.com/metaory/json-diff-viewer-component" target="_blank" rel="noopener noreferrer"><img src="/github.svg" alt="GitHub" class="github-logo"></a>
13+
<header>
14+
<h1>JSON Diff Viewer
15+
<div class="header-controls">
16+
<a id="docs-link" href="https://github.com/metaory/json-diff-viewer-component#usage" target="_blank"
17+
rel="noopener noreferrer">Library</a>
18+
<button id="load-toggle">Load Data</button>
19+
<button id="theme-toggle">Light</button>
20+
<a href="https://github.com/metaory/json-diff-viewer-component" target="_blank" rel="noopener noreferrer"><img
21+
src="/github.svg" alt="GitHub" class="github-logo"></a>
22+
</div>
23+
</h1>
24+
<p class="tagline">Framework Agnostic Web Component</p>
25+
</header>
26+
<section id="input-panel" class="collapsed" data-mode="file">
27+
<nav class="input-tabs">
28+
<button class="tab active" data-mode="file">File</button>
29+
<button class="tab" data-mode="paste">Paste</button>
30+
<button class="tab" data-mode="url">URL</button>
31+
</nav>
32+
<div class="input-grid">
33+
<div class="input-col">
34+
<label>Left</label>
35+
<input type="file" accept=".json" data-side="left" hidden>
36+
<button type="button" class="file-btn" data-side="left">Choose file...</button>
37+
<textarea placeholder="Paste JSON..." data-side="left"></textarea>
38+
<input type="url" placeholder="https://..." data-side="left">
39+
</div>
40+
<div class="input-col">
41+
<label>Right</label>
42+
<input type="file" accept=".json" data-side="right" hidden>
43+
<button type="button" class="file-btn" data-side="right">Choose file...</button>
44+
<textarea placeholder="Paste JSON..." data-side="right"></textarea>
45+
<input type="url" placeholder="https://..." data-side="right">
46+
</div>
1547
</div>
16-
</h1>
48+
<button id="compare-btn">Compare</button>
49+
</section>
1750
<json-diff-viewer></json-diff-viewer>
1851
</div>
1952
<script type="module" src="/src/main.js"></script>
2053
</body>
21-
</html>
54+
55+
</html>

src/main.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import "./style.css";
44

55
const viewer = document.querySelector("json-diff-viewer");
66
const toggle = document.querySelector("#theme-toggle");
7+
const loadToggle = document.querySelector("#load-toggle");
8+
const panel = document.querySelector("#input-panel");
9+
const tabs = document.querySelectorAll(".tab");
10+
const compareBtn = document.querySelector("#compare-btn");
711

812
const themes = {
913
dark: {
@@ -41,7 +45,84 @@ toggle.addEventListener("click", () => {
4145
applyTheme(toggleTheme(getTheme()));
4246
});
4347

48+
const uncheckFilter = () => {
49+
const checkbox = viewer.shadowRoot?.querySelector('[data-action="filter"]');
50+
if (!checkbox?.checked) return;
51+
checkbox.checked = false;
52+
checkbox.dispatchEvent(new Event("change"));
53+
};
54+
4455
Promise.all([
4556
fetch(`${import.meta.env.BASE_URL}data/a1.json`).then((r) => r.json()),
4657
fetch(`${import.meta.env.BASE_URL}data/a2.json`).then((r) => r.json()),
47-
]).then(([left, right]) => viewer.setData(left, right));
58+
]).then(([left, right]) => {
59+
viewer.setData(left, right);
60+
uncheckFilter();
61+
});
62+
63+
loadToggle.addEventListener("click", () => {
64+
panel.classList.toggle("collapsed");
65+
loadToggle.classList.toggle("active", !panel.classList.contains("collapsed"));
66+
});
67+
68+
for (const tab of tabs) {
69+
tab.addEventListener("click", () => {
70+
for (const t of tabs) t.classList.remove("active");
71+
tab.classList.add("active");
72+
panel.dataset.mode = tab.dataset.mode;
73+
});
74+
}
75+
76+
for (const btn of panel.querySelectorAll(".file-btn")) {
77+
const input = panel.querySelector(`input[type="file"][data-side="${btn.dataset.side}"]`);
78+
btn.addEventListener("click", () => input.click());
79+
input.addEventListener("change", () => {
80+
const name = input.files[0]?.name;
81+
btn.textContent = name || "Choose file...";
82+
btn.classList.toggle("has-file", !!name);
83+
});
84+
}
85+
86+
const readFile = (file) =>
87+
new Promise((resolve) => {
88+
const reader = new FileReader();
89+
reader.onload = (e) => resolve(JSON.parse(e.target.result));
90+
reader.readAsText(file);
91+
});
92+
93+
const getInput = (side, mode) => {
94+
const types = { file: 'input[type="file"]', paste: "textarea", url: 'input[type="url"]' };
95+
return panel.querySelector(`${types[mode]}[data-side="${side}"]`);
96+
};
97+
98+
const loaders = {
99+
file: () => {
100+
const left = getInput("left", "file").files[0];
101+
const right = getInput("right", "file").files[0];
102+
if (!left || !right) return;
103+
return Promise.all([readFile(left), readFile(right)]);
104+
},
105+
paste: () => {
106+
const left = getInput("left", "paste").value;
107+
const right = getInput("right", "paste").value;
108+
if (!left || !right) return;
109+
return Promise.resolve([JSON.parse(left), JSON.parse(right)]);
110+
},
111+
url: () => {
112+
const left = getInput("left", "url").value;
113+
const right = getInput("right", "url").value;
114+
if (!left || !right) return;
115+
return Promise.all([
116+
fetch(left).then((r) => r.json()),
117+
fetch(right).then((r) => r.json()),
118+
]);
119+
},
120+
};
121+
122+
compareBtn.addEventListener("click", async () => {
123+
const result = await loaders[panel.dataset.mode]?.();
124+
if (!result) return;
125+
viewer.setData(result[0], result[1]);
126+
panel.classList.add("collapsed");
127+
loadToggle.classList.remove("active");
128+
});

0 commit comments

Comments
 (0)