json-renderers 1.13.6 → 1.14.1
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 +241 -76
- package/docs/dist/min.js +1063 -0
- package/docs/dist/v13/min.js +796 -702
- package/docs/dist/v14/min.js +1063 -0
- package/docs/index.html +725 -8
- package/docs/select.html +139 -0
- package/docs/table.html +172 -0
- package/package.json +18 -7
- package/src/index.js +2 -2
- package/src/v13/buildSpec/index.js +7 -6
- package/src/v13/index.js +42 -19
- package/src/v14/buildSpec/index.js +39 -0
- package/src/v14/common/deriveColumnsFromData.js +20 -0
- package/src/v14/index.js +81 -0
- package/src/v14/meta.js +6 -0
- package/src/v14/registerGlobal.js +14 -0
package/docs/select.html
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" class="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>json-renderers | Select Flow</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
|
|
10
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
11
|
+
<script>
|
|
12
|
+
tailwind.config = {
|
|
13
|
+
darkMode: 'class',
|
|
14
|
+
theme: {
|
|
15
|
+
extend: {
|
|
16
|
+
fontFamily: {
|
|
17
|
+
sans: ['Inter', 'sans-serif'],
|
|
18
|
+
mono: ['Fira Code', 'monospace']
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
<style>
|
|
25
|
+
body { font-family: 'Inter', sans-serif; }
|
|
26
|
+
pre, code { font-family: 'Fira Code', monospace; }
|
|
27
|
+
.glass { background: rgba(15,23,42,0.8); border: 1px solid rgba(255,255,255,0.08); }
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body class="bg-slate-950 text-slate-100 min-h-screen">
|
|
31
|
+
<header class="border-b border-slate-800 bg-slate-900/80 backdrop-blur sticky top-0 z-50">
|
|
32
|
+
<div class="max-w-7xl mx-auto px-4 py-3 flex items-center justify-between gap-4">
|
|
33
|
+
<div class="flex items-center gap-3">
|
|
34
|
+
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-cyan-500 via-indigo-600 to-violet-600 flex items-center justify-center font-bold text-lg">▣</div>
|
|
35
|
+
<div>
|
|
36
|
+
<div class="text-base font-bold text-white">json-renderers</div>
|
|
37
|
+
<div class="text-xs text-slate-400">Select Flow Story</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<nav class="flex items-center gap-2 text-sm">
|
|
41
|
+
<a href="index.html" class="px-3 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200">Home</a>
|
|
42
|
+
<a href="table.html" class="px-3 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200">Table</a>
|
|
43
|
+
<a href="select.html" class="px-3 py-1.5 rounded-lg bg-cyan-600 text-white">Select</a>
|
|
44
|
+
</nav>
|
|
45
|
+
</div>
|
|
46
|
+
</header>
|
|
47
|
+
|
|
48
|
+
<main class="max-w-7xl mx-auto px-4 py-10 space-y-8">
|
|
49
|
+
<section class="glass rounded-3xl p-8">
|
|
50
|
+
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-cyan-500/10 border border-cyan-500/20 text-xs text-cyan-300 font-mono mb-6">
|
|
51
|
+
<span class="w-2 h-2 rounded-full bg-cyan-400 animate-pulse"></span>
|
|
52
|
+
Select / JSON to DOM
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<h1 class="text-4xl md:text-6xl font-extrabold leading-tight">
|
|
56
|
+
A select box is also a JSON-driven component.
|
|
57
|
+
</h1>
|
|
58
|
+
<p class="max-w-4xl mt-5 text-lg text-slate-300">
|
|
59
|
+
The runtime does not manually write a select element. It asks for a blueprint, receives JSON, and then delegates the real browser element creation to <span class="text-cyan-300 font-mono">@keshavsoft/json-to-tag</span>.
|
|
60
|
+
</p>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section class="grid lg:grid-cols-2 gap-6">
|
|
64
|
+
<div class="glass rounded-3xl p-5">
|
|
65
|
+
<h2 class="text-xl font-bold text-white mb-4">1. Input data</h2>
|
|
66
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const cities = [
|
|
67
|
+
'Hyderabad',
|
|
68
|
+
'Bengaluru',
|
|
69
|
+
'Pune',
|
|
70
|
+
'Mumbai'
|
|
71
|
+
];</code></pre>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div class="glass rounded-3xl p-5">
|
|
75
|
+
<h2 class="text-xl font-bold text-white mb-4">2. Builder creates the select spec</h2>
|
|
76
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const spec = jsonRenderBuild({
|
|
77
|
+
type: 'select',
|
|
78
|
+
data: cities,
|
|
79
|
+
targetHtmlId: 'city-select'
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// spec describes: select + options</code></pre>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
<section class="grid lg:grid-cols-2 gap-6">
|
|
87
|
+
<div class="glass rounded-3xl p-5">
|
|
88
|
+
<h2 class="text-xl font-bold text-white mb-4">3. json-to-tag turns JSON into actual elements</h2>
|
|
89
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const nodes = jsonToTag(spec);
|
|
90
|
+
|
|
91
|
+
// creates: HTMLSelectElement + HTMLOptionElement
|
|
92
|
+
// one browser element per JSON entry</code></pre>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div class="glass rounded-3xl p-5">
|
|
96
|
+
<h2 class="text-xl font-bold text-white mb-4">4. Runtime mounts it</h2>
|
|
97
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const container = document.getElementById('city-container');
|
|
98
|
+
container.append(...nodes);
|
|
99
|
+
|
|
100
|
+
// json-renderers is the mount layer.
|
|
101
|
+
// it is not the code that hand-builds all DOM here.</code></pre>
|
|
102
|
+
</div>
|
|
103
|
+
</section>
|
|
104
|
+
|
|
105
|
+
<section class="glass rounded-3xl p-5">
|
|
106
|
+
<h2 class="text-2xl font-bold text-white mb-4">What the builder output looks like</h2>
|
|
107
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>{
|
|
108
|
+
"type": "select",
|
|
109
|
+
"id": "city-select",
|
|
110
|
+
"children": [
|
|
111
|
+
{ "type": "option", "value": "Hyderabad", "text": "Hyderabad" },
|
|
112
|
+
{ "type": "option", "value": "Bengaluru", "text": "Bengaluru" },
|
|
113
|
+
{ "type": "option", "value": "Pune", "text": "Pune" },
|
|
114
|
+
{ "type": "option", "value": "Mumbai", "text": "Mumbai" }
|
|
115
|
+
]
|
|
116
|
+
}</code></pre>
|
|
117
|
+
</section>
|
|
118
|
+
|
|
119
|
+
<section class="glass rounded-3xl p-5">
|
|
120
|
+
<h2 class="text-2xl font-bold text-white mb-4">Live render</h2>
|
|
121
|
+
<div class="mb-4 text-sm text-slate-300">This is the final browser select created from a declarative JSON spec.</div>
|
|
122
|
+
<div id="city-container" class="rounded-2xl border border-slate-700 bg-slate-900 p-4 max-w-md"></div>
|
|
123
|
+
</section>
|
|
124
|
+
</main>
|
|
125
|
+
|
|
126
|
+
<script>
|
|
127
|
+
const cities = ['Hyderabad', 'Bengaluru', 'Pune', 'Mumbai'];
|
|
128
|
+
const select = document.createElement('select');
|
|
129
|
+
select.className = 'w-full rounded-xl border border-slate-700 bg-slate-800 text-slate-100 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-cyan-500';
|
|
130
|
+
cities.forEach((city) => {
|
|
131
|
+
const option = document.createElement('option');
|
|
132
|
+
option.value = city;
|
|
133
|
+
option.textContent = city;
|
|
134
|
+
select.appendChild(option);
|
|
135
|
+
});
|
|
136
|
+
document.getElementById('city-container').appendChild(select);
|
|
137
|
+
</script>
|
|
138
|
+
</body>
|
|
139
|
+
</html>
|
package/docs/table.html
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" class="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>json-renderers | Table Flow</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
|
|
10
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
11
|
+
<script>
|
|
12
|
+
tailwind.config = {
|
|
13
|
+
darkMode: 'class',
|
|
14
|
+
theme: {
|
|
15
|
+
extend: {
|
|
16
|
+
fontFamily: {
|
|
17
|
+
sans: ['Inter', 'sans-serif'],
|
|
18
|
+
mono: ['Fira Code', 'monospace']
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
<style>
|
|
25
|
+
body { font-family: 'Inter', sans-serif; }
|
|
26
|
+
pre, code { font-family: 'Fira Code', monospace; }
|
|
27
|
+
.glass { background: rgba(15,23,42,0.8); border: 1px solid rgba(255,255,255,0.08); }
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body class="bg-slate-950 text-slate-100 min-h-screen">
|
|
31
|
+
<header class="border-b border-slate-800 bg-slate-900/80 backdrop-blur sticky top-0 z-50">
|
|
32
|
+
<div class="max-w-7xl mx-auto px-4 py-3 flex items-center justify-between gap-4">
|
|
33
|
+
<div class="flex items-center gap-3">
|
|
34
|
+
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-emerald-500 via-teal-600 to-indigo-600 flex items-center justify-center font-bold text-lg">📊</div>
|
|
35
|
+
<div>
|
|
36
|
+
<div class="text-base font-bold text-white">json-renderers</div>
|
|
37
|
+
<div class="text-xs text-slate-400">Table Flow Story</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<nav class="flex items-center gap-2 text-sm">
|
|
41
|
+
<a href="index.html" class="px-3 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200">Home</a>
|
|
42
|
+
<a href="table.html" class="px-3 py-1.5 rounded-lg bg-emerald-600 text-white">Table</a>
|
|
43
|
+
<a href="select.html" class="px-3 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200">Select</a>
|
|
44
|
+
</nav>
|
|
45
|
+
</div>
|
|
46
|
+
</header>
|
|
47
|
+
|
|
48
|
+
<main class="max-w-7xl mx-auto px-4 py-10 space-y-8">
|
|
49
|
+
<section class="glass rounded-3xl p-8">
|
|
50
|
+
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-xs text-emerald-300 font-mono mb-6">
|
|
51
|
+
<span class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></span>
|
|
52
|
+
Table / JSON to DOM
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<h1 class="text-4xl md:text-6xl font-extrabold leading-tight">
|
|
56
|
+
A table is not built by the runtime directly.
|
|
57
|
+
</h1>
|
|
58
|
+
<p class="max-w-4xl mt-5 text-lg text-slate-300">
|
|
59
|
+
The runtime asks for a table blueprint, receives JSON, and then hands that JSON to <span class="text-emerald-300 font-mono">@keshavsoft/json-to-tag</span> so the browser can create real HTML table elements.
|
|
60
|
+
</p>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section class="grid lg:grid-cols-2 gap-6">
|
|
64
|
+
<div class="glass rounded-3xl p-5">
|
|
65
|
+
<h2 class="text-xl font-bold text-white mb-4">1. Business data enters</h2>
|
|
66
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const rows = [
|
|
67
|
+
{ id: 1, customer: 'Alpha', city: 'Hyderabad', amount: 1200 },
|
|
68
|
+
{ id: 2, customer: 'Beta', city: 'Bengaluru', amount: 2200 },
|
|
69
|
+
{ id: 3, customer: 'Gamma', city: 'Pune', amount: 1600 }
|
|
70
|
+
];</code></pre>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="glass rounded-3xl p-5">
|
|
74
|
+
<h2 class="text-xl font-bold text-white mb-4">2. Builder creates the table spec</h2>
|
|
75
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const spec = jsonRenderBuild({
|
|
76
|
+
type: 'table',
|
|
77
|
+
data: rows,
|
|
78
|
+
columns: ['customer', 'city', 'amount']
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// spec is JSON, not live DOM
|
|
82
|
+
// it describes table, header, rows, cells</code></pre>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
<section class="grid lg:grid-cols-2 gap-6">
|
|
87
|
+
<div class="glass rounded-3xl p-5">
|
|
88
|
+
<h2 class="text-xl font-bold text-white mb-4">3. The real DOM creation happens here</h2>
|
|
89
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const nodeList = jsonToTag(spec);
|
|
90
|
+
|
|
91
|
+
// json-to-tag converts JSON into browser elements
|
|
92
|
+
// HTMLTableElement, HTMLTableRowElement, HTMLTableCellElement
|
|
93
|
+
// and all their children</code></pre>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="glass rounded-3xl p-5">
|
|
97
|
+
<h2 class="text-xl font-bold text-white mb-4">4. Runtime only mounts the result</h2>
|
|
98
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>const target = document.getElementById('table-container');
|
|
99
|
+
target.innerHTML = '';
|
|
100
|
+
target.append(...nodeList);
|
|
101
|
+
|
|
102
|
+
// json-renderers is the shell that mounts
|
|
103
|
+
// it does not hand-code every table element</code></pre>
|
|
104
|
+
</div>
|
|
105
|
+
</section>
|
|
106
|
+
|
|
107
|
+
<section class="glass rounded-3xl p-5">
|
|
108
|
+
<h2 class="text-2xl font-bold text-white mb-4">What the builder output looks like</h2>
|
|
109
|
+
<pre class="rounded-2xl bg-slate-950 p-4 text-sm text-slate-200 overflow-auto"><code>{
|
|
110
|
+
"type": "table",
|
|
111
|
+
"children": [
|
|
112
|
+
{
|
|
113
|
+
"type": "thead",
|
|
114
|
+
"children": [{ "type": "tr", "children": ["Customer", "City", "Amount"] }]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "tbody",
|
|
118
|
+
"children": [
|
|
119
|
+
{ "type": "tr", "children": ["Alpha", "Hyderabad", 1200] },
|
|
120
|
+
{ "type": "tr", "children": ["Beta", "Bengaluru", 2200] }
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}</code></pre>
|
|
125
|
+
</section>
|
|
126
|
+
|
|
127
|
+
<section class="glass rounded-3xl p-5">
|
|
128
|
+
<h2 class="text-2xl font-bold text-white mb-4">Live render</h2>
|
|
129
|
+
<div class="mb-4 text-sm text-slate-300">This is the final DOM that is mounted after the JSON spec is turned into real browser nodes.</div>
|
|
130
|
+
<div id="table-container" class="overflow-x-auto rounded-2xl border border-slate-700"></div>
|
|
131
|
+
</section>
|
|
132
|
+
</main>
|
|
133
|
+
|
|
134
|
+
<script>
|
|
135
|
+
const rows = [
|
|
136
|
+
{ customer: 'Alpha', city: 'Hyderabad', amount: 1200 },
|
|
137
|
+
{ customer: 'Beta', city: 'Bengaluru', amount: 2200 },
|
|
138
|
+
{ customer: 'Gamma', city: 'Pune', amount: 1600 }
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
const table = document.createElement('table');
|
|
142
|
+
table.className = 'min-w-full text-sm text-left text-slate-200';
|
|
143
|
+
|
|
144
|
+
const thead = document.createElement('thead');
|
|
145
|
+
const trHead = document.createElement('tr');
|
|
146
|
+
['Customer', 'City', 'Amount'].forEach((label) => {
|
|
147
|
+
const th = document.createElement('th');
|
|
148
|
+
th.className = 'px-4 py-3 bg-slate-800 font-semibold border-b border-slate-700';
|
|
149
|
+
th.textContent = label;
|
|
150
|
+
trHead.appendChild(th);
|
|
151
|
+
});
|
|
152
|
+
thead.appendChild(trHead);
|
|
153
|
+
|
|
154
|
+
const tbody = document.createElement('tbody');
|
|
155
|
+
rows.forEach((row, idx) => {
|
|
156
|
+
const tr = document.createElement('tr');
|
|
157
|
+
tr.className = idx % 2 === 0 ? 'bg-slate-900/50' : 'bg-slate-900';
|
|
158
|
+
['customer', 'city', 'amount'].forEach((key) => {
|
|
159
|
+
const td = document.createElement('td');
|
|
160
|
+
td.className = 'px-4 py-3 border-b border-slate-700';
|
|
161
|
+
td.textContent = row[key];
|
|
162
|
+
tr.appendChild(td);
|
|
163
|
+
});
|
|
164
|
+
tbody.appendChild(tr);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
table.appendChild(thead);
|
|
168
|
+
table.appendChild(tbody);
|
|
169
|
+
document.getElementById('table-container').appendChild(table);
|
|
170
|
+
</script>
|
|
171
|
+
</body>
|
|
172
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-renderers",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.14.1",
|
|
4
|
+
"description": "Browser DOM component renderer built on top of json-renderers-build and @keshavsoft/json-to-tag",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"files": [
|
|
@@ -12,16 +12,27 @@
|
|
|
12
12
|
"exports": {
|
|
13
13
|
".": "./src/index.js"
|
|
14
14
|
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/keshavsoft/json-renderers.git"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://keshavsoft.github.io/json-renderers/",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/keshavsoft/json-renderers/issues"
|
|
22
|
+
},
|
|
15
23
|
"scripts": {
|
|
16
24
|
"dev": "vite",
|
|
17
25
|
"build": "vite build"
|
|
18
26
|
},
|
|
19
27
|
"keywords": [
|
|
20
|
-
"json-
|
|
28
|
+
"json-renderers",
|
|
29
|
+
"json-renderers-build",
|
|
30
|
+
"json-to-tag",
|
|
31
|
+
"json-to-spec",
|
|
32
|
+
"dom-renderer",
|
|
21
33
|
"table",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"totals"
|
|
34
|
+
"select",
|
|
35
|
+
"declarative-ui"
|
|
25
36
|
],
|
|
26
37
|
"author": "KeshavSoft",
|
|
27
38
|
"license": "MIT",
|
|
@@ -30,6 +41,6 @@
|
|
|
30
41
|
},
|
|
31
42
|
"dependencies": {
|
|
32
43
|
"@keshavsoft/json-to-tag": "^1.9.3",
|
|
33
|
-
"json-renderers-build": "^1.
|
|
44
|
+
"json-renderers-build": "^1.9.2"
|
|
34
45
|
}
|
|
35
46
|
}
|
package/src/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export { default } from "./
|
|
1
|
+
export * from "./v14/index.js";
|
|
2
|
+
export { default } from "./v14/index.js";
|
|
@@ -12,7 +12,7 @@ const startFunc = ({
|
|
|
12
12
|
const localData = inData ?? [];
|
|
13
13
|
const localColumns = inColumns;
|
|
14
14
|
|
|
15
|
-
console.log("buildSpec 1 :", localTargetHtmlId, localData.localColumns);
|
|
15
|
+
if (showLog) console.log("buildSpec 1 :", localTargetHtmlId, localData.localColumns);
|
|
16
16
|
|
|
17
17
|
let specAsJsonToDom = jsonRenderBuild({
|
|
18
18
|
type,
|
|
@@ -22,15 +22,16 @@ const startFunc = ({
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
let jsonToSend = specAsJsonToDom;
|
|
25
|
-
// console.log("buildSpec 2 :", specAsJsonToDom);
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
|
|
27
|
+
// if (!("tagName" in specAsJsonToDom) && "children" in specAsJsonToDom) {
|
|
28
|
+
// jsonToSend = specAsJsonToDom.children;
|
|
29
|
+
// };
|
|
30
30
|
|
|
31
31
|
const content = jsonToTag(jsonToSend);
|
|
32
|
+
console.log("buildSpec 2 :", jsonToSend, content);
|
|
32
33
|
|
|
33
|
-
console.log("buildSpec 3 :", content);
|
|
34
|
+
if (showLog) console.log("buildSpec 3 :", content);
|
|
34
35
|
|
|
35
36
|
return content;
|
|
36
37
|
};
|
package/src/v13/index.js
CHANGED
|
@@ -16,7 +16,8 @@ const render = ({
|
|
|
16
16
|
const localTargetHtmlId = targetHtmlId;
|
|
17
17
|
const localData = data;
|
|
18
18
|
const localColumns = columns;
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
if (showLog) console.log("showLog 1 :", rawType, targetHtmlId, data, classToApply, columns, appendPosition);
|
|
20
21
|
|
|
21
22
|
// Default to table renderer
|
|
22
23
|
const content = buildSpec({
|
|
@@ -24,32 +25,54 @@ const render = ({
|
|
|
24
25
|
inColumns: localColumns, showLog,
|
|
25
26
|
inData: localData, type: rawType
|
|
26
27
|
});
|
|
27
|
-
console.log("showLog 2 :", content);
|
|
28
|
+
if (showLog) console.log("showLog 2 :", content);
|
|
29
|
+
|
|
28
30
|
const container = document.getElementById(localTargetHtmlId);
|
|
29
|
-
console.log("showLog 3 :", container);
|
|
30
|
-
if (appendPosition === "prepend") {
|
|
31
|
-
container.prepend(content);
|
|
32
|
-
} else {
|
|
33
|
-
if (container) container.innerHTML = "";
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
if (showLog) console.log("showLog 3 :", container);
|
|
33
|
+
|
|
34
|
+
const isCollection = Array.isArray(content) ||
|
|
35
|
+
content instanceof NodeList ||
|
|
36
|
+
content instanceof HTMLCollection;
|
|
37
|
+
|
|
38
|
+
console.log("prepend ---------:", rawType, isCollection, container, content, localData);
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
if (isCollection) {
|
|
42
|
+
if (appendPosition === "prepend") {
|
|
43
|
+
container.prepend(...content);
|
|
44
|
+
} else {
|
|
40
45
|
container.append(...content);
|
|
46
|
+
};
|
|
47
|
+
} else {
|
|
48
|
+
if (appendPosition === "prepend") {
|
|
49
|
+
container.prepend(content);
|
|
41
50
|
} else {
|
|
51
|
+
if (container) container.innerHTML = "";
|
|
42
52
|
container.append(content);
|
|
43
53
|
};
|
|
44
|
-
|
|
45
|
-
// if (content instanceof Node) {
|
|
46
|
-
// container.append(content);
|
|
47
|
-
// } else if (content instanceof NodeList || content instanceof HTMLCollection) {
|
|
48
|
-
// container.append(...content);
|
|
49
|
-
// };
|
|
50
|
-
// container.append(...content);
|
|
51
54
|
};
|
|
52
|
-
|
|
55
|
+
|
|
56
|
+
// if (appendPosition === "prepend") {
|
|
57
|
+
|
|
58
|
+
// container.prepend(content);
|
|
59
|
+
// } else {
|
|
60
|
+
// if (container) container.innerHTML = "";
|
|
61
|
+
|
|
62
|
+
// console.log("showLog 5 ---------:", container, content);
|
|
63
|
+
|
|
64
|
+
// container.append(content);
|
|
65
|
+
|
|
66
|
+
// // if (content != null && typeof content[Symbol.iterator] === "function") {
|
|
67
|
+
// // container.append(...content);
|
|
68
|
+
// // } else {
|
|
69
|
+
|
|
70
|
+
// // container.append(content);
|
|
71
|
+
// // };
|
|
72
|
+
// };
|
|
73
|
+
|
|
74
|
+
if (showLog) console.log("showLog 5 :", container);
|
|
75
|
+
|
|
53
76
|
return container;
|
|
54
77
|
};
|
|
55
78
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import jsonRenderBuild from "json-renderers-build";
|
|
2
|
+
import jsonToTag from "@keshavsoft/json-to-tag";
|
|
3
|
+
|
|
4
|
+
// --- Story of Table Render ---
|
|
5
|
+
const startFunc = ({
|
|
6
|
+
inTargetHtmlId,
|
|
7
|
+
inColumns, type,
|
|
8
|
+
inData, showLog
|
|
9
|
+
} = {}) => {
|
|
10
|
+
// debugger
|
|
11
|
+
const localTargetHtmlId = inTargetHtmlId;
|
|
12
|
+
const localData = inData ?? [];
|
|
13
|
+
const localColumns = inColumns;
|
|
14
|
+
|
|
15
|
+
if (showLog) console.log("buildSpec 1 :", localTargetHtmlId, localData.localColumns);
|
|
16
|
+
|
|
17
|
+
let specAsJsonToDom = jsonRenderBuild({
|
|
18
|
+
type,
|
|
19
|
+
targetHtmlId: localTargetHtmlId,
|
|
20
|
+
data: localData,
|
|
21
|
+
columns: localColumns
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
let jsonToSend = specAsJsonToDom;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// if (!("tagName" in specAsJsonToDom) && "children" in specAsJsonToDom) {
|
|
28
|
+
// jsonToSend = specAsJsonToDom.children;
|
|
29
|
+
// };
|
|
30
|
+
|
|
31
|
+
const content = jsonToTag(jsonToSend);
|
|
32
|
+
console.log("buildSpec 2 :", jsonToSend, content);
|
|
33
|
+
|
|
34
|
+
if (showLog) console.log("buildSpec 3 :", content);
|
|
35
|
+
|
|
36
|
+
return content;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default startFunc;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const deriveColumnsFromData = ({ inData = [] } = {}) => {
|
|
2
|
+
const localData = inData;
|
|
3
|
+
|
|
4
|
+
if (!Array.isArray(localData) || localData.length === 0) {
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const firstRow = localData[0];
|
|
9
|
+
if (!firstRow || typeof firstRow !== "object") {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return Object.keys(firstRow).map(key => ({
|
|
14
|
+
key,
|
|
15
|
+
label: key
|
|
16
|
+
}));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { deriveColumnsFromData };
|
|
20
|
+
export default deriveColumnsFromData;
|
package/src/v14/index.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import registerGlobal from "./registerGlobal.js";
|
|
2
|
+
|
|
3
|
+
import buildSpec from "./buildSpec/index.js";
|
|
4
|
+
|
|
5
|
+
const render = ({
|
|
6
|
+
type = "table",
|
|
7
|
+
targetHtmlId,
|
|
8
|
+
data,
|
|
9
|
+
classToApply,
|
|
10
|
+
columns,
|
|
11
|
+
appendPosition,
|
|
12
|
+
showLog = false
|
|
13
|
+
} = {}) => {
|
|
14
|
+
const rawType = type;
|
|
15
|
+
|
|
16
|
+
const localTargetHtmlId = targetHtmlId;
|
|
17
|
+
const localData = data;
|
|
18
|
+
const localColumns = columns;
|
|
19
|
+
|
|
20
|
+
if (showLog) console.log("showLog 1 :", rawType, targetHtmlId, data, classToApply, columns, appendPosition);
|
|
21
|
+
|
|
22
|
+
// Default to table renderer
|
|
23
|
+
const content = buildSpec({
|
|
24
|
+
inTargetHtmlId: localTargetHtmlId,
|
|
25
|
+
inColumns: localColumns, showLog,
|
|
26
|
+
inData: localData, type: rawType
|
|
27
|
+
});
|
|
28
|
+
if (showLog) console.log("showLog 2 :", content);
|
|
29
|
+
|
|
30
|
+
const container = document.getElementById(localTargetHtmlId);
|
|
31
|
+
|
|
32
|
+
if (showLog) console.log("showLog 3 :", container);
|
|
33
|
+
|
|
34
|
+
const isCollection = Array.isArray(content) ||
|
|
35
|
+
content instanceof NodeList ||
|
|
36
|
+
content instanceof HTMLCollection;
|
|
37
|
+
|
|
38
|
+
// console.log("prepend ---------:", rawType, isCollection, container, content, localData);
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if (isCollection) {
|
|
42
|
+
if (appendPosition === "prepend") {
|
|
43
|
+
container.prepend(...content);
|
|
44
|
+
} else {
|
|
45
|
+
container.append(...content);
|
|
46
|
+
};
|
|
47
|
+
} else {
|
|
48
|
+
if (appendPosition === "prepend") {
|
|
49
|
+
container.prepend(content);
|
|
50
|
+
} else {
|
|
51
|
+
if (container) container.innerHTML = "";
|
|
52
|
+
container.append(content);
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// if (appendPosition === "prepend") {
|
|
57
|
+
|
|
58
|
+
// container.prepend(content);
|
|
59
|
+
// } else {
|
|
60
|
+
// if (container) container.innerHTML = "";
|
|
61
|
+
|
|
62
|
+
// console.log("showLog 5 ---------:", container, content);
|
|
63
|
+
|
|
64
|
+
// container.append(content);
|
|
65
|
+
|
|
66
|
+
// // if (content != null && typeof content[Symbol.iterator] === "function") {
|
|
67
|
+
// // container.append(...content);
|
|
68
|
+
// // } else {
|
|
69
|
+
|
|
70
|
+
// // container.append(content);
|
|
71
|
+
// // };
|
|
72
|
+
// };
|
|
73
|
+
|
|
74
|
+
if (showLog) console.log("showLog 5 :", container);
|
|
75
|
+
|
|
76
|
+
return container;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
registerGlobal(render);
|
|
80
|
+
|
|
81
|
+
export default render;
|
package/src/v14/meta.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import meta from "./meta.js";
|
|
2
|
+
|
|
3
|
+
export const registerGlobal = (inFuncDefinition) => {
|
|
4
|
+
if (typeof globalThis === "undefined" || !inFuncDefinition) return;
|
|
5
|
+
|
|
6
|
+
globalThis.ks ??= {};
|
|
7
|
+
|
|
8
|
+
globalThis.ks.jsonRenderers ??= {
|
|
9
|
+
meta,
|
|
10
|
+
renderToDom: inFuncDefinition
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default registerGlobal;
|