Skip to content

Commit 6b10fdb

Browse files
committed
- Split defintion and registration
- Fix stories
1 parent da9509f commit 6b10fdb

File tree

5 files changed

+203
-186
lines changed

5 files changed

+203
-186
lines changed

Diff for: README.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
[![edit-in-WebComponents.dev](https://webcomponents.dev/assets/ext/edit_in_wcd.svg)](https://webcomponents.dev/edit/VXr2i1M8U1s4He9bOdII)
12
[![edit-in-webcomponents.dev](https://webcomponents.dev/assets/ext/edit_in_wcd.svg)](https://webcomponents.dev/edit/VXr2i1M8U1s4He9bOdII)
3+
24
# `<json-element>`
35

46
# Credits
@@ -8,3 +10,5 @@ Inspired by [svelte-json-tree](https://github.com/tanhauhau/svelte-json-tree)
810
Challenged by [@passle\_](https://twitter.com/passle_) "Can you do it with 0 dependencies?!" 💪
911

1012
> Created with [webcomponents.dev](https://webcomponents.dev)
13+
14+
> Created with [WebComponents.dev](https://webcomponents.dev)

Diff for: src/JSONElement.js

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
export default class JSONElement extends HTMLElement {
2+
constructor() {
3+
super();
4+
const shadow = this.attachShadow({ mode: "open" });
5+
this.value = {};
6+
}
7+
8+
connectedCallback() {
9+
this.render();
10+
}
11+
12+
render() {
13+
this.shadowRoot.innerHTML = `
14+
<style>
15+
${JSONElement.styles}
16+
</style>
17+
${this.renderNode(undefined, this.value)}`;
18+
}
19+
20+
//
21+
// Main Renders
22+
//
23+
24+
renderNode(key, obj) {
25+
const type = JSONElement.objType(obj);
26+
switch (type) {
27+
case "Object":
28+
case "Array":
29+
return this.renderParent(type, key, obj);
30+
default:
31+
return this.renderKeyValue(key, this.renderValue(type, obj));
32+
}
33+
}
34+
35+
renderValue(type, value) {
36+
switch (type) {
37+
case "Boolean":
38+
return `${value ? "true" : "false"}`;
39+
case "String":
40+
return `"${value}"`;
41+
case "Number":
42+
return `${value}`;
43+
case "Date":
44+
return `${value.toISOString()}`;
45+
case "Null":
46+
return "null";
47+
case "Undefined":
48+
return "undefined";
49+
case "Function":
50+
case "Symbol":
51+
return `${value.toString()}`;
52+
default:
53+
return `###unsupported yet###`;
54+
}
55+
}
56+
57+
renderParent(type, key, value) {
58+
const summary = `<summary>${this.renderSummaryObject(
59+
type,
60+
key,
61+
value
62+
)}</summary>`;
63+
64+
let details = "";
65+
const keys = Reflect.ownKeys(value);
66+
keys.forEach((key) => {
67+
details += this.renderNode(key, value[key]);
68+
});
69+
70+
return `<details>${summary}<div>${details}</div></details>`;
71+
}
72+
73+
renderKeyValue(key, value) {
74+
return `<div>${this.renderSpanKey(key)}${this.renderSpanValue(
75+
value
76+
)}</div>`;
77+
}
78+
79+
renderSpanKey(key) {
80+
return key ? `<span class="key">${key}: </span>` : "";
81+
}
82+
83+
renderSpanValue(value) {
84+
return value ? `<span class="value">${value}</span>` : "";
85+
}
86+
87+
renderSpanLessImportant(value) {
88+
return value ? `<span class="less">${value}</span>` : "";
89+
}
90+
91+
//
92+
// Summary renders
93+
//
94+
95+
renderSummaryObject(type, key, value) {
96+
const frontkey = this.renderSpanKey(key);
97+
98+
let openSummary = "";
99+
let closeSummary = "";
100+
101+
switch (type) {
102+
case "Object":
103+
openSummary = "Object: {";
104+
closeSummary = "}";
105+
break;
106+
case "Array":
107+
openSummary = "Array: [";
108+
closeSummary = "]";
109+
break;
110+
}
111+
112+
const keys = Reflect.ownKeys(value);
113+
114+
const content = keys.reduce((accu, key, index) => {
115+
if (index > 5) return accu;
116+
if (index == 5) return accu + ` ${this.renderSpanLessImportant("...")}`;
117+
// less than 5 items show in summary
118+
const child = value[key];
119+
return (
120+
accu + ` ${this.renderSpanKey(key)}${this.renderSummaryValue(child)}`
121+
);
122+
}, "");
123+
124+
return `${frontkey}${openSummary} ${content} ${closeSummary}`;
125+
}
126+
127+
renderSummaryValue(value) {
128+
const type = JSONElement.objType(value);
129+
switch (type) {
130+
case "Object":
131+
return this.renderSpanLessImportant("{...}");
132+
case "Array":
133+
return this.renderSpanLessImportant("[...]");
134+
default:
135+
return this.renderSpanValue(this.renderValue(type, value));
136+
}
137+
}
138+
139+
//
140+
// Tools
141+
//
142+
143+
static objType(obj) {
144+
const type = Object.prototype.toString.call(obj).slice(8, -1);
145+
if (type === "Object") {
146+
if (typeof obj[Symbol.iterator] === "function") {
147+
return "Iterable";
148+
}
149+
return obj.constructor.name;
150+
}
151+
152+
return type;
153+
}
154+
155+
//
156+
// Styles
157+
//
158+
159+
static get styles() {
160+
return `
161+
:host {
162+
font-family: monospace;
163+
}
164+
165+
details > div {
166+
padding-left: 15px;
167+
}
168+
169+
.key {
170+
color: purple;
171+
}
172+
173+
.value {
174+
color: green;
175+
}
176+
177+
.less {
178+
color: grey;
179+
}
180+
181+
`;
182+
}
183+
}

Diff for: src/index.js

+2-179
Original file line numberDiff line numberDiff line change
@@ -1,179 +1,2 @@
1-
export default class JSONElement extends HTMLElement {
2-
constructor() {
3-
super();
4-
const shadow = this.attachShadow({ mode: "open" });
5-
this.value = {};
6-
}
7-
8-
static get styles() {
9-
return `
10-
:host {
11-
font-family: monospace;
12-
}
13-
14-
details > div {
15-
padding-left: 15px;
16-
}
17-
18-
.key {
19-
color: purple;
20-
}
21-
22-
.value {
23-
color: green;
24-
}
25-
26-
.less {
27-
color: grey;
28-
}
29-
30-
`;
31-
}
32-
33-
connectedCallback() {
34-
this.render();
35-
}
36-
37-
render() {
38-
this.shadowRoot.innerHTML = `
39-
<style>
40-
${JSONElement.styles}
41-
</style>
42-
${this.renderNode(undefined, this.value)}`;
43-
}
44-
45-
//
46-
// Main Renders
47-
//
48-
49-
renderNode(key, obj) {
50-
const type = JSONElement.objType(obj);
51-
switch (type) {
52-
case "Object":
53-
case "Array":
54-
return this.renderParent(type, key, obj);
55-
default:
56-
return this.renderKeyValue(key, this.renderValue(type, obj));
57-
}
58-
}
59-
60-
renderValue(type, value) {
61-
switch (type) {
62-
case "Boolean":
63-
return `${value ? "true" : "false"}`;
64-
case "String":
65-
return `"${value}"`;
66-
case "Number":
67-
return `${value}`;
68-
case "Date":
69-
return `${value.toISOString()}`;
70-
case "Null":
71-
return "null";
72-
case "Undefined":
73-
return "undefined";
74-
case "Function":
75-
case "Symbol":
76-
return `${value.toString()}`;
77-
default:
78-
return `###unsupported yet###`;
79-
}
80-
}
81-
82-
renderParent(type, key, value) {
83-
const summary = `<summary>${this.renderSummaryObject(
84-
type,
85-
key,
86-
value
87-
)}</summary>`;
88-
89-
let details = "";
90-
const keys = Reflect.ownKeys(value);
91-
keys.forEach(key => {
92-
details += this.renderNode(key, value[key]);
93-
});
94-
95-
return `<details>${summary}<div>${details}</div></details>`;
96-
}
97-
98-
renderKeyValue(key, value) {
99-
return `<div>${this.renderSpanKey(key)}${this.renderSpanValue(
100-
value
101-
)}</div>`;
102-
}
103-
104-
renderSpanKey(key) {
105-
return key ? `<span class="key">${key}: </span>` : "";
106-
}
107-
108-
renderSpanValue(value) {
109-
return value ? `<span class="value">${value}</span>` : "";
110-
}
111-
112-
renderSpanLessImportant(value) {
113-
return value ? `<span class="less">${value}</span>` : "";
114-
}
115-
116-
//
117-
// Summary renders
118-
//
119-
120-
renderSummaryObject(type, key, value) {
121-
const frontkey = this.renderSpanKey(key);
122-
123-
let openSummary = "";
124-
let closeSummary = "";
125-
126-
switch (type) {
127-
case "Object":
128-
openSummary = "Object: {";
129-
closeSummary = "}";
130-
break;
131-
case "Array":
132-
openSummary = "Array: [";
133-
closeSummary = "]";
134-
break;
135-
}
136-
137-
const keys = Reflect.ownKeys(value);
138-
139-
const content = keys.reduce((accu, key, index) => {
140-
if (index > 5) return accu;
141-
if (index == 5) return accu + ` ${this.renderSpanLessImportant("...")}`;
142-
// less than 5 items show in summary
143-
const child = value[key];
144-
return (
145-
accu + ` ${this.renderSpanKey(key)}${this.renderSummaryValue(child)}`
146-
);
147-
}, "");
148-
149-
return `${frontkey}${openSummary} ${content} ${closeSummary}`;
150-
}
151-
152-
renderSummaryValue(value) {
153-
const type = JSONElement.objType(value);
154-
switch (type) {
155-
case "Object":
156-
return this.renderSpanLessImportant("{...}");
157-
case "Array":
158-
return this.renderSpanLessImportant("[...]");
159-
default:
160-
return this.renderSpanValue(this.renderValue(type, value));
161-
}
162-
}
163-
164-
//
165-
// Tools
166-
//
167-
168-
static objType(obj) {
169-
const type = Object.prototype.toString.call(obj).slice(8, -1);
170-
if (type === "Object") {
171-
if (typeof obj[Symbol.iterator] === "function") {
172-
return "Iterable";
173-
}
174-
return obj.constructor.name;
175-
}
176-
177-
return type;
178-
}
179-
}
1+
import JSONElement from "./JSONElement";
2+
export default JSONElement;

0 commit comments

Comments
 (0)