json-renderers 1.17.3 → 1.18.4
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/docs/dist/min.js +1352 -1577
- package/docs/dist/v17/min.js +560 -1088
- package/docs/dist/v18/min.js +1352 -0
- package/docs/index.html +91 -2
- package/docs/subDoc/advanceDoc.html +1140 -0
- package/docs/subDoc/index.html +244 -0
- package/docs/subDoc/simpleDoc.html +476 -0
- package/package.json +3 -2
- package/src/index.js +2 -2
- package/src/v17/getSpec.js +1 -1
- package/src/v17/guard.js +1 -1
- package/src/v17/index.js +3 -0
- package/src/v18/buildSpec/index.js +25 -0
- package/src/v18/common/deriveColumnsFromData.js +20 -0
- package/src/v18/index.js +33 -0
- package/src/v18/meta.js +6 -0
- package/src/v18/registerGlobal.js +16 -0
- package/src/v18/renderToDom/index.js +47 -0
- /package/src/v17/{spec.json → configSpec.json} +0 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>json-renderers - Simple Guide</title>
|
|
8
|
+
<meta name="description"
|
|
9
|
+
content="A simple guide to KeshavSoft json-renderers: the house-building story, 3-tier architecture, and minimal table mounting example.">
|
|
10
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
11
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
12
|
+
<link
|
|
13
|
+
href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&family=Inter:wght@300;400;500;600;700;800&display=swap"
|
|
14
|
+
rel="stylesheet">
|
|
15
|
+
<style>
|
|
16
|
+
:root {
|
|
17
|
+
--bg: #f8fafc;
|
|
18
|
+
--surface: #ffffff;
|
|
19
|
+
--ink: #1e293b;
|
|
20
|
+
--muted: #64748b;
|
|
21
|
+
--line: #e2e8f0;
|
|
22
|
+
--brand: #2563eb;
|
|
23
|
+
--brand-soft: #eff6ff;
|
|
24
|
+
--brand-dark: #1d4ed8;
|
|
25
|
+
--shadow: 0 4px 20px -2px rgba(15, 23, 42, 0.06);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
* {
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
body {
|
|
33
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
34
|
+
background: var(--bg);
|
|
35
|
+
color: var(--ink);
|
|
36
|
+
line-height: 1.65;
|
|
37
|
+
margin: 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Topbar Navigation */
|
|
42
|
+
.topbar {
|
|
43
|
+
position: sticky;
|
|
44
|
+
top: 0;
|
|
45
|
+
z-index: 50;
|
|
46
|
+
background: rgba(255, 255, 255, 0.95);
|
|
47
|
+
backdrop-filter: blur(12px);
|
|
48
|
+
border-bottom: 1px solid var(--line);
|
|
49
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.topbar-inner {
|
|
53
|
+
max-width: 950px;
|
|
54
|
+
margin: 0 auto;
|
|
55
|
+
padding: 12px 20px;
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: space-between;
|
|
59
|
+
gap: 16px;
|
|
60
|
+
flex-wrap: wrap;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.brand {
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
gap: 10px;
|
|
67
|
+
text-decoration: none;
|
|
68
|
+
color: var(--ink);
|
|
69
|
+
font-weight: 700;
|
|
70
|
+
font-size: 16px;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.brand:hover {
|
|
74
|
+
text-decoration: none;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.logo {
|
|
78
|
+
display: grid;
|
|
79
|
+
place-items: center;
|
|
80
|
+
background: linear-gradient(135deg, #10b981, #059669);
|
|
81
|
+
color: white;
|
|
82
|
+
border-radius: 9px;
|
|
83
|
+
width: 32px;
|
|
84
|
+
height: 32px;
|
|
85
|
+
font-weight: 800;
|
|
86
|
+
font-size: 14px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.nav-links {
|
|
90
|
+
display: flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: 8px;
|
|
93
|
+
flex-wrap: wrap;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.nav-links a {
|
|
97
|
+
color: var(--muted);
|
|
98
|
+
text-decoration: none;
|
|
99
|
+
font-size: 13px;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
padding: 6px 12px;
|
|
102
|
+
border-radius: 8px;
|
|
103
|
+
transition: all 0.15s ease;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.nav-links a:hover {
|
|
107
|
+
color: var(--ink);
|
|
108
|
+
background: #f1f5f9;
|
|
109
|
+
text-decoration: none;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.nav-links a.active {
|
|
113
|
+
color: #065f46;
|
|
114
|
+
background: #d1fae5;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.nav-links a.btn-cta {
|
|
118
|
+
background: #3b82f6;
|
|
119
|
+
color: #ffffff;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.nav-links a.btn-cta:hover {
|
|
123
|
+
background: #2563eb;
|
|
124
|
+
color: #ffffff;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Main Container */
|
|
128
|
+
.content-wrap {
|
|
129
|
+
max-width: 900px;
|
|
130
|
+
margin: 32px auto 60px;
|
|
131
|
+
padding: 0 20px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Breadcrumbs */
|
|
135
|
+
.breadcrumbs {
|
|
136
|
+
display: flex;
|
|
137
|
+
align-items: center;
|
|
138
|
+
gap: 6px;
|
|
139
|
+
font-size: 12px;
|
|
140
|
+
color: var(--muted);
|
|
141
|
+
margin-bottom: 20px;
|
|
142
|
+
font-family: 'Fira Code', monospace;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.breadcrumbs a {
|
|
146
|
+
color: var(--muted);
|
|
147
|
+
text-decoration: none;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.breadcrumbs a:hover {
|
|
151
|
+
color: var(--brand);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* Main Card */
|
|
155
|
+
.article-card {
|
|
156
|
+
background: var(--surface);
|
|
157
|
+
border: 1px solid var(--line);
|
|
158
|
+
border-radius: 18px;
|
|
159
|
+
padding: clamp(24px, 4vw, 42px);
|
|
160
|
+
box-shadow: var(--shadow);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.badge-pill {
|
|
164
|
+
display: inline-flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
gap: 6px;
|
|
167
|
+
padding: 4px 12px;
|
|
168
|
+
border-radius: 9999px;
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
font-weight: 600;
|
|
171
|
+
font-family: 'Fira Code', monospace;
|
|
172
|
+
background: #ecfdf5;
|
|
173
|
+
color: #065f46;
|
|
174
|
+
border: 1px solid #a7f3d0;
|
|
175
|
+
margin-bottom: 12px;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
h1 {
|
|
179
|
+
color: #0f172a;
|
|
180
|
+
font-size: clamp(28px, 4vw, 36px);
|
|
181
|
+
letter-spacing: -0.03em;
|
|
182
|
+
margin: 8px 0 16px;
|
|
183
|
+
line-height: 1.2;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
h2 {
|
|
187
|
+
color: #1e3a8a;
|
|
188
|
+
font-size: clamp(20px, 3vw, 24px);
|
|
189
|
+
letter-spacing: -0.02em;
|
|
190
|
+
margin: 32px 0 14px;
|
|
191
|
+
padding-top: 12px;
|
|
192
|
+
border-top: 1px solid #f1f5f9;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.lead {
|
|
196
|
+
font-size: 16px;
|
|
197
|
+
color: #334155;
|
|
198
|
+
line-height: 1.7;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.story {
|
|
202
|
+
background: #f0f7ff;
|
|
203
|
+
border: 1px solid #bfdbfe;
|
|
204
|
+
padding: 20px 22px;
|
|
205
|
+
border-radius: 14px;
|
|
206
|
+
margin: 20px 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.story p {
|
|
210
|
+
margin: 10px 0;
|
|
211
|
+
color: #1e293b;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.story p:first-child {
|
|
215
|
+
margin-top: 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.story p:last-child {
|
|
219
|
+
margin-bottom: 0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
ol {
|
|
223
|
+
padding-left: 20px;
|
|
224
|
+
margin: 16px 0;
|
|
225
|
+
color: #334155;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
ol li {
|
|
229
|
+
margin-bottom: 8px;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
code,
|
|
233
|
+
pre {
|
|
234
|
+
font-family: 'Fira Code', monospace;
|
|
235
|
+
background: #f1f5f9;
|
|
236
|
+
color: #0f172a;
|
|
237
|
+
border-radius: 6px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
code {
|
|
241
|
+
padding: 2px 6px;
|
|
242
|
+
font-size: 13.5px;
|
|
243
|
+
border: 1px solid #e2e8f0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.code-container {
|
|
247
|
+
position: relative;
|
|
248
|
+
margin: 18px 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
pre {
|
|
252
|
+
padding: 16px 18px;
|
|
253
|
+
border-radius: 12px;
|
|
254
|
+
white-space: pre-wrap;
|
|
255
|
+
overflow-x: auto;
|
|
256
|
+
font-size: 13.5px;
|
|
257
|
+
line-height: 1.6;
|
|
258
|
+
border: 1px solid #cbd5e1;
|
|
259
|
+
background: #0f172a;
|
|
260
|
+
color: #e2e8f0;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.copy-btn {
|
|
264
|
+
position: absolute;
|
|
265
|
+
top: 10px;
|
|
266
|
+
right: 10px;
|
|
267
|
+
background: rgba(255, 255, 255, 0.15);
|
|
268
|
+
color: #f8fafc;
|
|
269
|
+
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
270
|
+
border-radius: 6px;
|
|
271
|
+
padding: 4px 10px;
|
|
272
|
+
font-size: 11px;
|
|
273
|
+
font-family: 'Fira Code', monospace;
|
|
274
|
+
cursor: pointer;
|
|
275
|
+
transition: background 0.15s ease;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.copy-btn:hover {
|
|
279
|
+
background: rgba(255, 255, 255, 0.3);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.inline-code {
|
|
283
|
+
font-family: 'Fira Code', monospace;
|
|
284
|
+
background: #f1f5f9;
|
|
285
|
+
color: #1d4ed8;
|
|
286
|
+
padding: 2px 6px;
|
|
287
|
+
border-radius: 4px;
|
|
288
|
+
font-size: 13px;
|
|
289
|
+
border: 1px solid #e2e8f0;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.callout-box {
|
|
293
|
+
background: #f8fafc;
|
|
294
|
+
border: 1px solid var(--line);
|
|
295
|
+
border-radius: 14px;
|
|
296
|
+
padding: 18px 20px;
|
|
297
|
+
margin-top: 28px;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* Next Steps Navigation Box */
|
|
301
|
+
.next-nav {
|
|
302
|
+
display: grid;
|
|
303
|
+
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
304
|
+
gap: 14px;
|
|
305
|
+
margin-top: 36px;
|
|
306
|
+
padding-top: 24px;
|
|
307
|
+
border-top: 1px solid var(--line);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.next-card {
|
|
311
|
+
display: block;
|
|
312
|
+
padding: 16px;
|
|
313
|
+
border-radius: 12px;
|
|
314
|
+
border: 1px solid var(--line);
|
|
315
|
+
background: #ffffff;
|
|
316
|
+
text-decoration: none;
|
|
317
|
+
color: inherit;
|
|
318
|
+
transition: all 0.2s ease;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.next-card:hover {
|
|
322
|
+
border-color: #3b82f6;
|
|
323
|
+
transform: translateY(-2px);
|
|
324
|
+
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.08);
|
|
325
|
+
text-decoration: none;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.next-card-subtitle {
|
|
329
|
+
font-size: 11px;
|
|
330
|
+
text-transform: uppercase;
|
|
331
|
+
font-family: 'Fira Code', monospace;
|
|
332
|
+
color: var(--muted);
|
|
333
|
+
margin-bottom: 4px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.next-card-title {
|
|
337
|
+
font-size: 14px;
|
|
338
|
+
font-weight: 700;
|
|
339
|
+
color: #1e293b;
|
|
340
|
+
display: flex;
|
|
341
|
+
align-items: center;
|
|
342
|
+
justify-content: space-between;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
a {
|
|
346
|
+
color: var(--brand);
|
|
347
|
+
text-decoration: none;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
a:hover {
|
|
351
|
+
text-decoration: underline;
|
|
352
|
+
}
|
|
353
|
+
</style>
|
|
354
|
+
</head>
|
|
355
|
+
|
|
356
|
+
<body>
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
<div class="content-wrap">
|
|
360
|
+
|
|
361
|
+
<!-- Breadcrumb trail -->
|
|
362
|
+
<div class="breadcrumbs">
|
|
363
|
+
<a href="../index.html">Home</a>
|
|
364
|
+
<span>/</span>
|
|
365
|
+
<a href="index.html">subDoc</a>
|
|
366
|
+
<span>/</span>
|
|
367
|
+
<span style="color:#059669; font-weight:600;">simpleDoc.html</span>
|
|
368
|
+
</div>
|
|
369
|
+
|
|
370
|
+
<!-- Article Card -->
|
|
371
|
+
<article class="article-card">
|
|
372
|
+
<div class="badge-pill">
|
|
373
|
+
<span>🌱</span> Quick Conceptual Guide • 3 min read
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
<h1>json-renderers</h1>
|
|
377
|
+
<p><b>Render JSON-driven UI into the browser:</b></p>
|
|
378
|
+
<p class="lead"><strong>json-renderers</strong> is the browser runtime layer in the KeshavSoft declarative UI
|
|
379
|
+
ecosystem. It accepts render configuration, obtains a JSON description of the requested component, asks
|
|
380
|
+
<span class="inline-code">@keshavsoft/json-to-tag</span> to create DOM nodes, and mounts the result in the
|
|
381
|
+
requested browser container.
|
|
382
|
+
</p>
|
|
383
|
+
<p>It is an orchestration layer rather than the specification compiler itself. The component structure is
|
|
384
|
+
prepared upstream by <span class="inline-code">json-renderers-build</span>; actual element construction is
|
|
385
|
+
delegated to <span class="inline-code">@keshavsoft/json-to-tag</span>.</p>
|
|
386
|
+
|
|
387
|
+
<h2>Simple House-Building Story</h2>
|
|
388
|
+
<div class="story">
|
|
389
|
+
<p><b>1. json-renderers-build — The Architect:</b> prepares a JSON blueprint.</p>
|
|
390
|
+
<p><b>2. json-to-tag — The Construction Worker:</b> reads the blueprint and creates real HTML elements.</p>
|
|
391
|
+
<p><b>3. json-renderers — The Site Manager:</b> puts those elements in the correct place on the webpage.</p>
|
|
392
|
+
</div>
|
|
393
|
+
|
|
394
|
+
<h2>Example: Show a Student Table</h2>
|
|
395
|
+
<ol>
|
|
396
|
+
<li>Send student data and column names.</li>
|
|
397
|
+
<li><code>json-renderers-build</code> prepares the table specification.</li>
|
|
398
|
+
<li><code>json-to-tag</code> creates the HTML table elements.</li>
|
|
399
|
+
<li><code>json-renderers</code> mounts the table inside the target container.</li>
|
|
400
|
+
</ol>
|
|
401
|
+
|
|
402
|
+
<div class="code-container">
|
|
403
|
+
<button class="copy-btn" id="copyBtn">Copy</button>
|
|
404
|
+
<pre id="codeSnippet"><div id="students"></div>
|
|
405
|
+
<script type="module">
|
|
406
|
+
import render from "json-renderers";
|
|
407
|
+
render({
|
|
408
|
+
type: "table",
|
|
409
|
+
targetHtmlId: "students",
|
|
410
|
+
data: [{ name: "Ravi", city: "Kakinada" }],
|
|
411
|
+
columns: ["Name", "City"]
|
|
412
|
+
});
|
|
413
|
+
</script></pre>
|
|
414
|
+
</div>
|
|
415
|
+
|
|
416
|
+
<h2>Remember</h2>
|
|
417
|
+
<div class="callout-box">
|
|
418
|
+
<p style="margin:0; font-size:15px;"><b>Build prepares the blueprint → json-to-tag creates the DOM →
|
|
419
|
+
json-renderers mounts it on the page.</b></p>
|
|
420
|
+
</div>
|
|
421
|
+
|
|
422
|
+
<p style="margin-top:24px; font-size:14px; color:#64748b;">
|
|
423
|
+
Official repository: <a href="https://github.com/keshavsoft/json-renderers" target="_blank"
|
|
424
|
+
rel="noopener noreferrer">github.com/keshavsoft/json-renderers</a>
|
|
425
|
+
</p>
|
|
426
|
+
|
|
427
|
+
<!-- Next Steps & Connected Navigation -->
|
|
428
|
+
<div class="next-nav">
|
|
429
|
+
<a href="advanceDoc.html" class="next-card">
|
|
430
|
+
<div class="next-card-subtitle">Next Track • In-Depth</div>
|
|
431
|
+
<div class="next-card-title">
|
|
432
|
+
<span>Read Advanced Guide</span>
|
|
433
|
+
<span>→</span>
|
|
434
|
+
</div>
|
|
435
|
+
</a>
|
|
436
|
+
|
|
437
|
+
<a href="index.html" class="next-card">
|
|
438
|
+
<div class="next-card-subtitle">Hub • Overview</div>
|
|
439
|
+
<div class="next-card-title">
|
|
440
|
+
<span>Back to SubDoc Hub</span>
|
|
441
|
+
<span>→</span>
|
|
442
|
+
</div>
|
|
443
|
+
</a>
|
|
444
|
+
|
|
445
|
+
<a href="../index.html" class="next-card">
|
|
446
|
+
<div class="next-card-subtitle">Sandbox • Live DOM</div>
|
|
447
|
+
<div class="next-card-title">
|
|
448
|
+
<span>Try Live Workbench</span>
|
|
449
|
+
<span>→</span>
|
|
450
|
+
</div>
|
|
451
|
+
</a>
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
</article>
|
|
455
|
+
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
<script>
|
|
459
|
+
const copyBtn = document.getElementById('copyBtn');
|
|
460
|
+
if (copyBtn) {
|
|
461
|
+
copyBtn.addEventListener('click', async () => {
|
|
462
|
+
const code = document.getElementById('codeSnippet')?.textContent || '';
|
|
463
|
+
try {
|
|
464
|
+
await navigator.clipboard.writeText(code);
|
|
465
|
+
copyBtn.textContent = 'Copied!';
|
|
466
|
+
setTimeout(() => { copyBtn.textContent = 'Copy'; }, 1500);
|
|
467
|
+
} catch (e) {
|
|
468
|
+
copyBtn.textContent = 'Done';
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
</script>
|
|
473
|
+
|
|
474
|
+
</body>
|
|
475
|
+
|
|
476
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-renderers",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.4",
|
|
4
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",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@keshavsoft/json-to-tag": "^1.9.3",
|
|
44
|
-
"json-renderers-build": "^1.
|
|
44
|
+
"json-renderers-build": "^1.23.9",
|
|
45
|
+
"json-renderers-guard": "^1.5.2"
|
|
45
46
|
}
|
|
46
47
|
}
|
package/src/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export { default } from "./
|
|
1
|
+
export * from "./v18/index.js";
|
|
2
|
+
export { default } from "./v18/index.js";
|
package/src/v17/getSpec.js
CHANGED
package/src/v17/guard.js
CHANGED
package/src/v17/index.js
CHANGED
|
@@ -7,6 +7,9 @@ import renderToDom from "./renderToDom/index.js";
|
|
|
7
7
|
// Main orchestrator: coordinates validation, spec building, and DOM rendering
|
|
8
8
|
const render = (options = {}) => {
|
|
9
9
|
const config = validateConfig(options);
|
|
10
|
+
const showLog = config?.showLog;
|
|
11
|
+
|
|
12
|
+
if (showLog) console.log("first : ", config?.columns, config?.data, config?.appendPosition);
|
|
10
13
|
|
|
11
14
|
const spec = buildSpec({
|
|
12
15
|
inColumns: config.columns,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import jsonRenderBuild from "json-renderers-build";
|
|
2
|
+
|
|
3
|
+
// --- Story of Spec Build ---
|
|
4
|
+
const startFunc = ({
|
|
5
|
+
inColumns,
|
|
6
|
+
inType = "table",
|
|
7
|
+
inData,
|
|
8
|
+
inShowLog = false
|
|
9
|
+
} = {}) => {
|
|
10
|
+
const localData = inData ?? [];
|
|
11
|
+
const localColumns = inColumns;
|
|
12
|
+
const localType = inType;
|
|
13
|
+
const localShowLog = inShowLog;
|
|
14
|
+
|
|
15
|
+
const specAsJsonToDom = jsonRenderBuild({
|
|
16
|
+
type: localType,
|
|
17
|
+
data: localData,
|
|
18
|
+
columns: localColumns,
|
|
19
|
+
showLog: localShowLog
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return specAsJsonToDom;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
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/v18/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import registerGlobal from "./registerGlobal.js";
|
|
2
|
+
|
|
3
|
+
import guardFunc from "json-renderers-guard";
|
|
4
|
+
|
|
5
|
+
import buildSpec from "./buildSpec/index.js";
|
|
6
|
+
import renderToDom from "./renderToDom/index.js";
|
|
7
|
+
|
|
8
|
+
// Main orchestrator: coordinates validation, spec building, and DOM rendering
|
|
9
|
+
const render = (config = {}) => {
|
|
10
|
+
guardFunc(config);
|
|
11
|
+
const showLog = config?.showLog;
|
|
12
|
+
|
|
13
|
+
if (showLog) console.log("first : ", config?.columns, config?.data, config?.appendPosition);
|
|
14
|
+
|
|
15
|
+
const spec = buildSpec({
|
|
16
|
+
inColumns: config.columns,
|
|
17
|
+
inData: config.data,
|
|
18
|
+
inType: config.type,
|
|
19
|
+
inShowLog: config.showLog
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return renderToDom({
|
|
23
|
+
inSpec: spec,
|
|
24
|
+
inTargetHtmlId: config.targetHtmlId,
|
|
25
|
+
inAppendPosition: config.appendPosition,
|
|
26
|
+
inShowLog: config.showLog
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
registerGlobal(render);
|
|
31
|
+
|
|
32
|
+
export { render };
|
|
33
|
+
export default render;
|
package/src/v18/meta.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import meta from "./meta.js";
|
|
2
|
+
|
|
3
|
+
export const registerGlobal = (inDefinition) => {
|
|
4
|
+
const localDefinition = inDefinition;
|
|
5
|
+
|
|
6
|
+
if (typeof globalThis === "undefined" || !localDefinition) return;
|
|
7
|
+
|
|
8
|
+
globalThis.ks ??= {};
|
|
9
|
+
|
|
10
|
+
globalThis.ks.jsonRenderers = {
|
|
11
|
+
meta,
|
|
12
|
+
render: localDefinition
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default registerGlobal;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import jsonToTag from "@keshavsoft/json-to-tag";
|
|
2
|
+
|
|
3
|
+
// --- Story of DOM Rendering and Mounting ---
|
|
4
|
+
const renderToDom = ({
|
|
5
|
+
inSpec,
|
|
6
|
+
inTargetHtmlId,
|
|
7
|
+
inAppendPosition,
|
|
8
|
+
inShowLog = false
|
|
9
|
+
} = {}) => {
|
|
10
|
+
const localSpec = inSpec;
|
|
11
|
+
const localTargetHtmlId = inTargetHtmlId;
|
|
12
|
+
const localAppendPosition = inAppendPosition;
|
|
13
|
+
const localShowLog = inShowLog;
|
|
14
|
+
|
|
15
|
+
const content = jsonToTag(localSpec);
|
|
16
|
+
|
|
17
|
+
if (localShowLog) console.log("renderToDom 1 (content):", content);
|
|
18
|
+
|
|
19
|
+
const container = document.getElementById(localTargetHtmlId);
|
|
20
|
+
if (!container) return null;
|
|
21
|
+
|
|
22
|
+
const isCollection = Array.isArray(content) ||
|
|
23
|
+
content instanceof NodeList ||
|
|
24
|
+
content instanceof HTMLCollection;
|
|
25
|
+
|
|
26
|
+
if (isCollection) {
|
|
27
|
+
if (localAppendPosition === "prepend") {
|
|
28
|
+
container.prepend(...content);
|
|
29
|
+
} else {
|
|
30
|
+
container.append(...content);
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
if (localAppendPosition === "prepend") {
|
|
34
|
+
container.prepend(content);
|
|
35
|
+
} else {
|
|
36
|
+
container.innerHTML = "";
|
|
37
|
+
container.append(content);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (localShowLog) console.log("renderToDom 2 (mounted):", container);
|
|
42
|
+
|
|
43
|
+
return container;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { renderToDom };
|
|
47
|
+
export default renderToDom;
|
|
File without changes
|