json-renderers 1.14.1 → 1.16.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.
@@ -0,0 +1,964 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>About Select | How to Create HTML Select Dropdowns with CDN & window.ks</title>
7
+ <meta name="description" content="Beginner-friendly documentation on how to build and mount HTML select dropdowns from JSON using json-renderers via CDN import and window.ks." />
8
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
+ <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" />
11
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
12
+ <script src="https://cdn.tailwindcss.com"></script>
13
+ <script>
14
+ tailwind.config = {
15
+ theme: {
16
+ extend: {
17
+ colors: {
18
+ brand: {
19
+ 50: '#f0fdfa',
20
+ 100: '#ccfbf1',
21
+ 500: '#14b8a6',
22
+ 600: '#0d9488',
23
+ 700: '#0f766e',
24
+ 800: '#115e59',
25
+ 900: '#134e4a'
26
+ }
27
+ },
28
+ fontFamily: {
29
+ sans: ['Inter', 'sans-serif'],
30
+ mono: ['Fira Code', 'monospace']
31
+ }
32
+ }
33
+ }
34
+ };
35
+ </script>
36
+ <style>
37
+ body {
38
+ font-family: 'Inter', sans-serif;
39
+ background-color: #ffffff;
40
+ color: #1e293b;
41
+ }
42
+ pre, code {
43
+ font-family: 'Fira Code', monospace;
44
+ }
45
+ .custom-scrollbar::-webkit-scrollbar {
46
+ width: 6px;
47
+ height: 6px;
48
+ }
49
+ .custom-scrollbar::-webkit-scrollbar-track {
50
+ background: #f1f5f9;
51
+ }
52
+ .custom-scrollbar::-webkit-scrollbar-thumb {
53
+ background: #cbd5e1;
54
+ border-radius: 4px;
55
+ }
56
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover {
57
+ background: #94a3b8;
58
+ }
59
+ .step-badge {
60
+ width: 2.25rem;
61
+ height: 2.25rem;
62
+ border-radius: 9999px;
63
+ display: inline-flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ font-weight: 700;
67
+ font-size: 0.875rem;
68
+ }
69
+ /* Style bootstrap select inside our container */
70
+ #live-select-output select {
71
+ display: block;
72
+ width: 100%;
73
+ padding: 0.65rem 2.25rem 0.65rem 1rem;
74
+ font-size: 0.95rem;
75
+ font-weight: 500;
76
+ line-height: 1.5;
77
+ color: #0f172a;
78
+ background-color: #ffffff;
79
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%230f172a' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
80
+ background-repeat: no-repeat;
81
+ background-position: right 0.85rem center;
82
+ background-size: 16px 12px;
83
+ border: 1.5px solid #cbd5e1;
84
+ border-radius: 0.75rem;
85
+ transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
86
+ outline: none;
87
+ }
88
+ #live-select-output select:focus {
89
+ border-color: #0284c7;
90
+ box-shadow: 0 0 0 3px rgba(2, 132, 199, 0.15);
91
+ }
92
+ </style>
93
+ </head>
94
+ <body class="bg-white text-slate-800 min-h-screen antialiased flex flex-col font-sans selection:bg-cyan-500 selection:text-white">
95
+
96
+ <!-- Top Sticky Navigation Bar -->
97
+ <header class="border-b border-slate-200 bg-white/95 backdrop-blur sticky top-0 z-50 shadow-sm">
98
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 py-3.5 flex items-center justify-between gap-4">
99
+ <div class="flex items-center gap-3">
100
+ <a href="index.html" class="w-10 h-10 rounded-xl bg-gradient-to-br from-cyan-500 via-teal-600 to-indigo-600 flex items-center justify-center font-bold text-white shadow-md text-lg hover:scale-105 transition">
101
+ ▣
102
+ </a>
103
+ <div>
104
+ <div class="flex items-center gap-2">
105
+ <a href="index.html" class="text-base font-bold text-slate-900 tracking-tight hover:text-cyan-600 transition">json-renderers</a>
106
+ <span class="px-2 py-0.5 text-xs bg-cyan-100 text-cyan-800 rounded-full border border-cyan-200 font-mono font-medium">Documentation</span>
107
+ </div>
108
+ <p class="text-xs text-slate-500">About Select: CDN &amp; window.ks Complete Guide</p>
109
+ </div>
110
+ </div>
111
+
112
+ <nav class="flex items-center gap-2 text-sm">
113
+ <a href="index.html" class="px-3 py-1.5 rounded-lg bg-slate-100 hover:bg-slate-200 text-slate-700 font-medium transition">Home</a>
114
+ <a href="aboutSelect.html" class="px-3 py-1.5 rounded-lg bg-cyan-600 text-white font-semibold shadow-sm transition">About Select</a>
115
+ <a href="table/index.html" class="px-3 py-1.5 rounded-lg bg-slate-100 hover:bg-slate-200 text-slate-700 font-medium transition">About Table</a>
116
+ <a href="select.html" class="px-3 py-1.5 rounded-lg bg-slate-100 hover:bg-slate-200 text-slate-700 font-medium transition">Select Flow</a>
117
+ <a href="table.html" class="px-3 py-1.5 rounded-lg bg-slate-100 hover:bg-slate-200 text-slate-700 font-medium transition">Table Flow</a>
118
+ <a href="https://github.com/keshavsoft/json-renderers" target="_blank" rel="noopener noreferrer" class="px-3 py-1.5 rounded-lg bg-slate-100 hover:bg-slate-200 text-slate-700 border border-slate-200 font-medium transition hidden sm:inline-flex items-center gap-1.5">
119
+ <svg class="w-4 h-4 fill-current text-slate-700" viewBox="0 0 24 24"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
120
+ <span>GitHub</span>
121
+ </a>
122
+ </nav>
123
+ </div>
124
+ </header>
125
+
126
+ <main class="flex-1 max-w-7xl w-full mx-auto p-4 sm:p-6 lg:p-8 space-y-12">
127
+
128
+ <!-- Hero Section -->
129
+ <section class="bg-gradient-to-br from-slate-50 via-cyan-50/40 to-indigo-50/40 rounded-3xl p-6 sm:p-10 border border-slate-200 shadow-sm relative overflow-hidden">
130
+ <div class="relative z-10 space-y-5">
131
+ <div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-cyan-100 border border-cyan-200 text-xs text-cyan-800 font-mono font-medium">
132
+ <span class="w-2 h-2 rounded-full bg-cyan-600 animate-pulse"></span>
133
+ Beginner's Guide &bull; Light Theme &bull; Zero Build Steps
134
+ </div>
135
+
136
+ <h1 class="text-3xl sm:text-5xl font-extrabold text-slate-900 tracking-tight leading-tight">
137
+ How to Create HTML Select Dropdowns <br class="hidden sm:inline" />
138
+ <span class="text-transparent bg-clip-text bg-gradient-to-r from-cyan-600 via-teal-600 to-indigo-600">Using CDN &amp; window.ks</span>
139
+ </h1>
140
+
141
+ <p class="max-w-4xl text-slate-600 text-base sm:text-lg leading-relaxed">
142
+ Need to render a dynamic <code class="text-cyan-700 bg-cyan-50 px-1.5 py-0.5 rounded border border-cyan-200 font-mono text-sm">&lt;select&gt;</code> element from an array of strings or records in JSON?
143
+ This tutorial shows you how to populate and mount a fully functional dropdown in the browser DOM in just a few lines of code—without hand-crafting <code class="text-cyan-700 bg-cyan-50 px-1.5 py-0.5 rounded border border-cyan-200 font-mono text-sm">&lt;option&gt;</code> loops or string concatenation.
144
+ </p>
145
+
146
+ <!-- Quick Jump Links -->
147
+ <div class="flex flex-wrap gap-3 pt-2">
148
+ <a href="#mental-model" class="px-4 py-2 rounded-xl bg-white hover:bg-slate-50 text-slate-700 text-xs sm:text-sm font-semibold transition border border-slate-300 shadow-sm flex items-center gap-1.5">
149
+ <span>💡</span> How It Works
150
+ </a>
151
+ <a href="#method-cdn" class="px-4 py-2 rounded-xl bg-cyan-600 hover:bg-cyan-700 text-white text-xs sm:text-sm font-semibold transition flex items-center gap-1.5 shadow-sm shadow-cyan-600/30">
152
+ <span>⚡</span> Method 1: byCdn (Direct Import)
153
+ </a>
154
+ <a href="#method-ks" class="px-4 py-2 rounded-xl bg-indigo-600 hover:bg-indigo-700 text-white text-xs sm:text-sm font-semibold transition flex items-center gap-1.5 shadow-sm shadow-indigo-600/30">
155
+ <span>🌐</span> Method 2: byKs (window.ks)
156
+ </a>
157
+ <a href="#comparison" class="px-4 py-2 rounded-xl bg-white hover:bg-slate-50 text-slate-700 text-xs sm:text-sm font-semibold transition border border-slate-300 shadow-sm flex items-center gap-1.5">
158
+ <span>⚖️</span> Comparison
159
+ </a>
160
+ <a href="#interactive-playground" class="px-4 py-2 rounded-xl bg-teal-600 hover:bg-teal-700 text-white text-xs sm:text-sm font-semibold transition flex items-center gap-1.5 shadow-sm">
161
+ <span>🎮</span> Live Interactive Demo
162
+ </a>
163
+ </div>
164
+ </div>
165
+ </section>
166
+
167
+ <!-- Mental Model: 4 Simple Steps -->
168
+ <section id="mental-model" class="space-y-6">
169
+ <div class="border-b border-slate-200 pb-4">
170
+ <span class="text-xs uppercase font-mono tracking-wider text-cyan-600 font-semibold">Architecture</span>
171
+ <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight mt-1">What Happens When You Render a Select Dropdown?</h2>
172
+ <p class="text-slate-500 text-sm mt-1">The 4-stage pipeline that turns your JSON items into browser DOM elements.</p>
173
+ </div>
174
+
175
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
176
+ <!-- Stage 1 -->
177
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm flex flex-col justify-between hover:border-cyan-400 transition">
178
+ <div>
179
+ <div class="flex items-center justify-between mb-3">
180
+ <span class="step-badge bg-cyan-100 text-cyan-700 border border-cyan-200">1</span>
181
+ <span class="text-xs font-mono text-slate-500">JSON Input</span>
182
+ </div>
183
+ <h3 class="font-bold text-slate-900 mb-2">Input JSON Array</h3>
184
+ <p class="text-xs text-slate-600 leading-relaxed mb-3">
185
+ An array of string values or records from your API or <code class="text-slate-800 font-mono text-[11px]">data.json</code>:
186
+ </p>
187
+ <pre class="bg-slate-900 p-2.5 rounded-lg text-[11px] text-cyan-300 font-mono overflow-x-auto"><code>[
188
+ "State Bank of India",
189
+ "HDFC Bank",
190
+ "ICICI Bank"
191
+ ]</code></pre>
192
+ </div>
193
+ <div class="text-[11px] font-mono text-cyan-700 font-semibold mt-3 pt-3 border-t border-slate-100">Step 1: Raw Data &rarr;</div>
194
+ </div>
195
+
196
+ <!-- Stage 2 -->
197
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm flex flex-col justify-between hover:border-teal-400 transition">
198
+ <div>
199
+ <div class="flex items-center justify-between mb-3">
200
+ <span class="step-badge bg-teal-100 text-teal-700 border border-teal-200">2</span>
201
+ <span class="text-xs font-mono text-slate-500">Orchestrator</span>
202
+ </div>
203
+ <h3 class="font-bold text-slate-900 mb-2">json-renderers Call</h3>
204
+ <p class="text-xs text-slate-600 leading-relaxed mb-3">
205
+ You execute the renderer passing <code class="text-teal-700 font-mono text-[11px]">type: "select"</code> and your target DOM ID:
206
+ </p>
207
+ <pre class="bg-slate-900 p-2.5 rounded-lg text-[11px] text-teal-300 font-mono overflow-x-auto"><code>render({
208
+ type: "select",
209
+ data: data.LedgerName,
210
+ targetHtmlId: "container"
211
+ });</code></pre>
212
+ </div>
213
+ <div class="text-[11px] font-mono text-teal-700 font-semibold mt-3 pt-3 border-t border-slate-100">Step 2: Builder Call &rarr;</div>
214
+ </div>
215
+
216
+ <!-- Stage 3 -->
217
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm flex flex-col justify-between hover:border-indigo-400 transition">
218
+ <div>
219
+ <div class="flex items-center justify-between mb-3">
220
+ <span class="step-badge bg-indigo-100 text-indigo-700 border border-indigo-200">3</span>
221
+ <span class="text-xs font-mono text-slate-500">DOM Engine</span>
222
+ </div>
223
+ <h3 class="font-bold text-slate-900 mb-2">json-to-tag Creation</h3>
224
+ <p class="text-xs text-slate-600 leading-relaxed mb-3">
225
+ <code class="text-indigo-700 font-mono text-[11px]">@keshavsoft/json-to-tag</code> converts the specification into true browser elements:
226
+ </p>
227
+ <div class="text-[11px] font-mono bg-slate-900 p-2.5 rounded-lg text-indigo-200 leading-relaxed">
228
+ &lt;select class="form-select"&gt;<br/>
229
+ &nbsp;&nbsp;&lt;option&gt;State Bank...&lt;/option&gt;<br/>
230
+ &nbsp;&nbsp;&lt;option&gt;HDFC Bank&lt;/option&gt;<br/>
231
+ &lt;/select&gt;
232
+ </div>
233
+ </div>
234
+ <div class="text-[11px] font-mono text-indigo-700 font-semibold mt-3 pt-3 border-t border-slate-100">Step 3: Native DOM Nodes &rarr;</div>
235
+ </div>
236
+
237
+ <!-- Stage 4 -->
238
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm flex flex-col justify-between hover:border-emerald-400 transition">
239
+ <div>
240
+ <div class="flex items-center justify-between mb-3">
241
+ <span class="step-badge bg-emerald-100 text-emerald-700 border border-emerald-200">4</span>
242
+ <span class="text-xs font-mono text-slate-500">Live Mount</span>
243
+ </div>
244
+ <h3 class="font-bold text-slate-900 mb-2">Mounted in Page</h3>
245
+ <p class="text-xs text-slate-600 leading-relaxed mb-3">
246
+ The dropdown is mounted into your container element, ready for user interactions:
247
+ </p>
248
+ <pre class="bg-slate-900 p-2.5 rounded-lg text-[11px] text-emerald-300 font-mono overflow-x-auto"><code>&lt;div id="container"&gt;
249
+ &lt;!-- &lt;select&gt; appears here! --&gt;
250
+ &lt;/div&gt;</code></pre>
251
+ </div>
252
+ <div class="text-[11px] font-mono text-emerald-700 font-semibold mt-3 pt-3 border-t border-slate-100">Step 4: Interactive in Browser &check;</div>
253
+ </div>
254
+ </div>
255
+ </section>
256
+
257
+ <!-- Method 1: samples/select/byCdn -->
258
+ <section id="method-cdn" class="space-y-6">
259
+ <div class="flex flex-col sm:flex-row sm:items-end justify-between gap-4 border-b border-slate-200 pb-4">
260
+ <div>
261
+ <div class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full bg-cyan-100 text-cyan-800 font-mono text-xs font-medium mb-2 border border-cyan-200">
262
+ Sample Path: samples/select/byCdn/
263
+ </div>
264
+ <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight">Method 1: Direct CDN Import (byCdn)</h2>
265
+ </div>
266
+ <a href="../samples/select/byCdn/index.html" target="_blank" class="px-4 py-2 rounded-xl bg-cyan-600 hover:bg-cyan-700 text-white text-xs font-semibold flex items-center gap-2 transition w-fit shadow-sm">
267
+ <span>▶️</span> Run samples/select/byCdn &rarr;
268
+ </a>
269
+ </div>
270
+
271
+ <div class="bg-white p-6 sm:p-8 rounded-2xl border border-slate-200 shadow-sm space-y-6">
272
+ <div>
273
+ <h3 class="text-lg font-bold text-slate-900 mb-1">How byCdn Works</h3>
274
+ <p class="text-slate-600 text-sm leading-relaxed">
275
+ In this setup, your JavaScript file imports the default <code class="text-cyan-700 bg-cyan-50 px-1 py-0.5 rounded font-mono text-xs font-semibold">render</code> function directly from the CDN link as an ES Module.
276
+ Then, you call <code class="text-cyan-700 bg-cyan-50 px-1 py-0.5 rounded font-mono text-xs font-semibold">render({ type: "select", data, targetHtmlId })</code>.
277
+ </p>
278
+ </div>
279
+
280
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
281
+
282
+ <!-- index.html -->
283
+ <div class="space-y-3">
284
+ <div class="flex items-center justify-between">
285
+ <span class="text-xs font-bold text-slate-800 uppercase tracking-wider font-mono flex items-center gap-1.5">
286
+ <span class="w-2.5 h-2.5 rounded-full bg-cyan-500"></span> 1. index.html (HTML Markup)
287
+ </span>
288
+ <button onclick="copyCode('cdn-html-code')" class="text-xs text-slate-500 hover:text-cyan-600 font-mono font-medium transition">📋 Copy</button>
289
+ </div>
290
+ <pre class="bg-slate-900 text-slate-200 rounded-xl p-4 text-xs font-mono overflow-x-auto shadow-inner"><code id="cdn-html-code">&lt;!DOCTYPE html&gt;
291
+ &lt;html lang="en"&gt;
292
+ &lt;head&gt;
293
+ &lt;meta charset="utf-8"&gt;
294
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
295
+ &lt;title&gt;Select DOM Renderer Sample - json-renderers&lt;/title&gt;
296
+
297
+ &lt;!-- Bootstrap CSS for clean dropdown styling --&gt;
298
+ &lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"&gt;
299
+ &lt;/head&gt;
300
+ &lt;body class="bg-light"&gt;
301
+ &lt;main class="container-fluid py-4"&gt;
302
+ &lt;h1&gt;Select DOM Renderer Demo&lt;/h1&gt;
303
+
304
+ &lt;!-- 1. Target container where the &lt;select&gt; is mounted --&gt;
305
+ &lt;div id="dom-render-container"&gt;
306
+ &lt;div class="text-center py-5 text-muted"&gt;Rendering select dropdown...&lt;/div&gt;
307
+ &lt;/div&gt;
308
+ &lt;/main&gt;
309
+
310
+ &lt;!-- 2. Load ES Module script --&gt;
311
+ &lt;script type="module" src="./index.js"&gt;&lt;/script&gt;
312
+ &lt;/body&gt;
313
+ &lt;/html&gt;</code></pre>
314
+ <p class="text-xs text-slate-500">
315
+ The container <code class="text-cyan-700 font-mono font-semibold">#dom-render-container</code> is all that the runtime needs. The old placeholder content is replaced automatically.
316
+ </p>
317
+ </div>
318
+
319
+ <!-- index.js -->
320
+ <div class="space-y-3">
321
+ <div class="flex items-center justify-between">
322
+ <span class="text-xs font-bold text-slate-800 uppercase tracking-wider font-mono flex items-center gap-1.5">
323
+ <span class="w-2.5 h-2.5 rounded-full bg-cyan-500"></span> 2. index.js (JavaScript Logic)
324
+ </span>
325
+ <button onclick="copyCode('cdn-js-code')" class="text-xs text-slate-500 hover:text-cyan-600 font-mono font-medium transition">📋 Copy</button>
326
+ </div>
327
+ <pre class="bg-slate-900 text-slate-200 rounded-xl p-4 text-xs font-mono overflow-x-auto shadow-inner"><code id="cdn-js-code">// 1. Import render directly from jsDelivr CDN
328
+ import render from "https://cdn.jsdelivr.net/gh/keshavsoft/json-renderers@main/docs/dist/v14/min.js";
329
+
330
+ // 2. Import JSON data
331
+ import data from "./data.json" with { type: "json" };
332
+
333
+ const start = () => {
334
+ try {
335
+ // 3. Render select dropdown
336
+ render({
337
+ type: "select",
338
+ data: data.LedgerName, // Array of option items
339
+ targetHtmlId: "dom-render-container", // Target container ID
340
+ showLog: false
341
+ });
342
+ } catch (err) {
343
+ console.log("error : ", err);
344
+ }
345
+ };
346
+
347
+ start();</code></pre>
348
+ <p class="text-xs text-slate-500">
349
+ <strong class="text-slate-800">Advantage:</strong> Self-contained, tree-shakeable, and standard modern ES module behavior.
350
+ </p>
351
+ </div>
352
+
353
+ </div>
354
+ </div>
355
+ </section>
356
+
357
+ <!-- Method 2: samples/select/byKs -->
358
+ <section id="method-ks" class="space-y-6">
359
+ <div class="flex flex-col sm:flex-row sm:items-end justify-between gap-4 border-b border-slate-200 pb-4">
360
+ <div>
361
+ <div class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full bg-indigo-100 text-indigo-800 font-mono text-xs font-medium mb-2 border border-indigo-200">
362
+ Sample Path: samples/select/byKs/
363
+ </div>
364
+ <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight">Method 2: Global window.ks (byKs)</h2>
365
+ </div>
366
+ <a href="../samples/select/byKs/index.html" target="_blank" class="px-4 py-2 rounded-xl bg-indigo-600 hover:bg-indigo-700 text-white text-xs font-semibold flex items-center gap-2 transition w-fit shadow-sm">
367
+ <span>▶️</span> Run samples/select/byKs &rarr;
368
+ </a>
369
+ </div>
370
+
371
+ <div class="bg-white p-6 sm:p-8 rounded-2xl border border-slate-200 shadow-sm space-y-6">
372
+ <div>
373
+ <h3 class="text-lg font-bold text-slate-900 mb-1">How byKs Works</h3>
374
+ <p class="text-slate-600 text-sm leading-relaxed">
375
+ In this setup, you import the CDN bundle once for its side-effects (<code class="text-indigo-700 bg-indigo-50 px-1 py-0.5 rounded font-mono text-xs font-semibold">import "https://...";</code>).
376
+ The bundle automatically attaches its rendering method to the global browser scope: <code class="text-indigo-700 bg-indigo-50 px-1 py-0.5 rounded font-mono text-xs font-semibold">window.ks.jsonRenderers.renderToDom</code>.
377
+ </p>
378
+ </div>
379
+
380
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
381
+
382
+ <!-- index.html -->
383
+ <div class="space-y-3">
384
+ <div class="flex items-center justify-between">
385
+ <span class="text-xs font-bold text-slate-800 uppercase tracking-wider font-mono flex items-center gap-1.5">
386
+ <span class="w-2.5 h-2.5 rounded-full bg-indigo-500"></span> 1. index.html (HTML Markup)
387
+ </span>
388
+ <button onclick="copyCode('ks-html-code')" class="text-xs text-slate-500 hover:text-indigo-600 font-mono font-medium transition">📋 Copy</button>
389
+ </div>
390
+ <pre class="bg-slate-900 text-slate-200 rounded-xl p-4 text-xs font-mono overflow-x-auto shadow-inner"><code id="ks-html-code">&lt;!DOCTYPE html&gt;
391
+ &lt;html lang="en"&gt;
392
+ &lt;head&gt;
393
+ &lt;meta charset="utf-8"&gt;
394
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
395
+ &lt;title&gt;Select DOM Renderer Sample - json-renderers&lt;/title&gt;
396
+
397
+ &lt;!-- Bootstrap CSS --&gt;
398
+ &lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"&gt;
399
+ &lt;/head&gt;
400
+ &lt;body class="bg-light"&gt;
401
+ &lt;main class="container-fluid py-4"&gt;
402
+ &lt;h1&gt;Select DOM Renderer Demo&lt;/h1&gt;
403
+
404
+ &lt;!-- Target container --&gt;
405
+ &lt;div id="dom-render-container"&gt;
406
+ &lt;div class="text-center py-5 text-muted"&gt;Rendering select dropdown...&lt;/div&gt;
407
+ &lt;/div&gt;
408
+ &lt;/main&gt;
409
+
410
+ &lt;!-- Load Module script --&gt;
411
+ &lt;script type="module" src="./index.js"&gt;&lt;/script&gt;
412
+ &lt;/body&gt;
413
+ &lt;/html&gt;</code></pre>
414
+ <p class="text-xs text-slate-500">
415
+ The HTML markup is identical between both methods, keeping your page structure clean.
416
+ </p>
417
+ </div>
418
+
419
+ <!-- index.js -->
420
+ <div class="space-y-3">
421
+ <div class="flex items-center justify-between">
422
+ <span class="text-xs font-bold text-slate-800 uppercase tracking-wider font-mono flex items-center gap-1.5">
423
+ <span class="w-2.5 h-2.5 rounded-full bg-indigo-500"></span> 2. index.js (Using window.ks)
424
+ </span>
425
+ <button onclick="copyCode('ks-js-code')" class="text-xs text-slate-500 hover:text-indigo-600 font-mono font-medium transition">📋 Copy</button>
426
+ </div>
427
+ <pre class="bg-slate-900 text-slate-200 rounded-xl p-4 text-xs font-mono overflow-x-auto shadow-inner"><code id="ks-js-code">// 1. Load bundle for side effects (registers window.ks)
428
+ import "https://cdn.jsdelivr.net/gh/keshavsoft/json-renderers@main/docs/dist/v14/min.js";
429
+
430
+ // 2. Import JSON data
431
+ import data from "./data.json" with { type: "json" };
432
+
433
+ const start = () => {
434
+ try {
435
+ // 3. Call the globally attached function:
436
+ // window.ks.jsonRenderers.renderToDom(...)
437
+ window.ks.jsonRenderers.renderToDom({
438
+ type: "select",
439
+ data: data.LedgerName,
440
+ targetHtmlId: "dom-render-container",
441
+ showLog: false
442
+ });
443
+ } catch (err) {
444
+ console.log("error : ", err);
445
+ }
446
+ };
447
+
448
+ start();</code></pre>
449
+ <p class="text-xs text-slate-500">
450
+ <strong class="text-slate-800">Advantage:</strong> Ideal when other files or scripts need to render selects without importing <code class="text-indigo-700 font-mono text-[11px]">render</code> repeatedly.
451
+ </p>
452
+ </div>
453
+
454
+ </div>
455
+ </div>
456
+ </section>
457
+
458
+ <!-- Side-by-Side Comparison -->
459
+ <section id="comparison" class="space-y-6">
460
+ <div class="border-b border-slate-200 pb-4">
461
+ <span class="text-xs uppercase font-mono tracking-wider text-cyan-600 font-semibold">Side-by-Side</span>
462
+ <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight mt-1">byCdn vs byKs Quick Comparison</h2>
463
+ <p class="text-slate-500 text-sm mt-1">Comparing syntax and usage patterns.</p>
464
+ </div>
465
+
466
+ <div class="bg-white rounded-2xl overflow-hidden border border-slate-200 shadow-sm">
467
+ <div class="overflow-x-auto">
468
+ <table class="w-full text-left text-sm text-slate-700">
469
+ <thead class="bg-slate-50 text-xs uppercase font-mono text-slate-600 border-b border-slate-200">
470
+ <tr>
471
+ <th class="p-4">Feature</th>
472
+ <th class="p-4 text-cyan-700">byCdn (Direct Module Import)</th>
473
+ <th class="p-4 text-indigo-700">byKs (Global window.ks)</th>
474
+ </tr>
475
+ </thead>
476
+ <tbody class="divide-y divide-slate-100">
477
+ <tr class="hover:bg-slate-50/70">
478
+ <td class="p-4 font-semibold text-slate-900">Import Statement</td>
479
+ <td class="p-4 font-mono text-xs text-cyan-700"><code>import render from ".../min.js";</code></td>
480
+ <td class="p-4 font-mono text-xs text-indigo-700"><code>import ".../min.js";</code></td>
481
+ </tr>
482
+ <tr class="hover:bg-slate-50/70">
483
+ <td class="p-4 font-semibold text-slate-900">Execution Call</td>
484
+ <td class="p-4 font-mono text-xs text-cyan-700"><code>render({ type: "select", ... });</code></td>
485
+ <td class="p-4 font-mono text-xs text-indigo-700"><code>window.ks.jsonRenderers.renderToDom({ ... });</code></td>
486
+ </tr>
487
+ <tr class="hover:bg-slate-50/70">
488
+ <td class="p-4 font-semibold text-slate-900">Global Variable</td>
489
+ <td class="p-4 text-xs">None (encapsulated within module)</td>
490
+ <td class="p-4 text-xs">Exposed at <code>window.ks.jsonRenderers</code></td>
491
+ </tr>
492
+ <tr class="hover:bg-slate-50/70">
493
+ <td class="p-4 font-semibold text-slate-900">Best Use Case</td>
494
+ <td class="p-4 text-xs">Modular frontend apps, Vite, Webpack, modern SPAs</td>
495
+ <td class="p-4 text-xs">Legacy codebases, multi-script pages, rapid prototyping in DevTools</td>
496
+ </tr>
497
+ <tr class="hover:bg-slate-50/70">
498
+ <td class="p-4 font-semibold text-slate-900">Sample Path</td>
499
+ <td class="p-4 font-mono text-xs"><a href="../samples/select/byCdn/index.html" class="text-cyan-600 hover:underline">samples/select/byCdn/</a></td>
500
+ <td class="p-4 font-mono text-xs"><a href="../samples/select/byKs/index.html" class="text-indigo-600 hover:underline">samples/select/byKs/</a></td>
501
+ </tr>
502
+ </tbody>
503
+ </table>
504
+ </div>
505
+ </div>
506
+ </section>
507
+
508
+ <!-- Parameters Reference -->
509
+ <section class="space-y-6">
510
+ <div class="border-b border-slate-200 pb-4">
511
+ <span class="text-xs uppercase font-mono tracking-wider text-teal-600 font-semibold">Options Guide</span>
512
+ <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight mt-1">Select Configuration Options</h2>
513
+ <p class="text-slate-500 text-sm mt-1">Everything you can pass to the render function for select dropdowns.</p>
514
+ </div>
515
+
516
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-5">
517
+
518
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm">
519
+ <div class="flex items-center justify-between mb-2">
520
+ <span class="font-mono text-sm font-bold text-cyan-700">type</span>
521
+ <span class="text-[10px] uppercase font-mono bg-cyan-100 text-cyan-800 px-2 py-0.5 rounded font-semibold">Required</span>
522
+ </div>
523
+ <p class="text-xs text-slate-600 mb-2">Must be <code class="text-cyan-800 bg-cyan-50 px-1 rounded font-mono">"select"</code> to render a select dropdown.</p>
524
+ <div class="text-[11px] font-mono text-slate-700 bg-slate-100 p-2 rounded">type: "select"</div>
525
+ </div>
526
+
527
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm">
528
+ <div class="flex items-center justify-between mb-2">
529
+ <span class="font-mono text-sm font-bold text-cyan-700">targetHtmlId</span>
530
+ <span class="text-[10px] uppercase font-mono bg-cyan-100 text-cyan-800 px-2 py-0.5 rounded font-semibold">Required</span>
531
+ </div>
532
+ <p class="text-xs text-slate-600 mb-2">The <code class="text-cyan-800 font-mono">id</code> of the element where the select element will be mounted.</p>
533
+ <div class="text-[11px] font-mono text-slate-700 bg-slate-100 p-2 rounded">targetHtmlId: "dom-render-container"</div>
534
+ </div>
535
+
536
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm">
537
+ <div class="flex items-center justify-between mb-2">
538
+ <span class="font-mono text-sm font-bold text-cyan-700">data</span>
539
+ <span class="text-[10px] uppercase font-mono bg-cyan-100 text-cyan-800 px-2 py-0.5 rounded font-semibold">Required</span>
540
+ </div>
541
+ <p class="text-xs text-slate-600 mb-2">An array of strings (e.g. <code class="text-cyan-800 font-mono">["Option 1", "Option 2"]</code>) or objects.</p>
542
+ <div class="text-[11px] font-mono text-slate-700 bg-slate-100 p-2 rounded">data: ["HDFC Bank", "SBI"]</div>
543
+ </div>
544
+
545
+ <div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm">
546
+ <div class="flex items-center justify-between mb-2">
547
+ <span class="font-mono text-sm font-bold text-cyan-700">showLog</span>
548
+ <span class="text-[10px] uppercase font-mono bg-slate-100 text-slate-600 px-2 py-0.5 rounded font-semibold">Optional</span>
549
+ </div>
550
+ <p class="text-xs text-slate-600 mb-2">Boolean (<code class="text-cyan-800 font-mono">true</code> / <code class="text-cyan-800 font-mono">false</code>). Enables console debug information.</p>
551
+ <div class="text-[11px] font-mono text-slate-700 bg-slate-100 p-2 rounded">showLog: false</div>
552
+ </div>
553
+
554
+ </div>
555
+ </section>
556
+
557
+ <!-- Alternative: Using fetch() -->
558
+ <section class="bg-white p-6 sm:p-8 rounded-2xl border border-slate-200 shadow-sm space-y-4">
559
+ <div class="flex items-center gap-2">
560
+ <span class="text-2xl">🌐</span>
561
+ <h3 class="text-lg font-bold text-slate-900">How to Populate Select Using fetch() from a REST API</h3>
562
+ </div>
563
+ <p class="text-slate-600 text-sm leading-relaxed">
564
+ If you are fetching options asynchronously from a backend endpoint or a local JSON file, wrap the call inside an <code class="text-cyan-700 bg-cyan-50 px-1 py-0.5 rounded font-mono text-xs font-semibold">async/await</code> function:
565
+ </p>
566
+
567
+ <pre class="bg-slate-900 text-slate-200 rounded-xl p-4 text-xs font-mono overflow-x-auto shadow-inner"><code>// 1. Import renderer
568
+ import render from "https://cdn.jsdelivr.net/gh/keshavsoft/json-renderers@main/docs/dist/v14/min.js";
569
+
570
+ async function loadDropdown() {
571
+ try {
572
+ // 2. Fetch the JSON data
573
+ const response = await fetch("./data.json");
574
+ const json = await response.json();
575
+
576
+ // 3. Mount select dropdown into DOM
577
+ render({
578
+ type: "select",
579
+ data: json.LedgerName, // e.g. ["Bank A", "Bank B", "Bank C"]
580
+ targetHtmlId: "dom-render-container"
581
+ });
582
+ } catch (error) {
583
+ console.error("Failed to load select options:", error);
584
+ }
585
+ }
586
+
587
+ loadDropdown();</code></pre>
588
+ </section>
589
+
590
+ <!-- Interactive Live Playground (White Background & Clean UI) -->
591
+ <section id="interactive-playground" class="space-y-6">
592
+ <div class="flex flex-col sm:flex-row sm:items-end justify-between gap-4 border-b border-slate-200 pb-4">
593
+ <div>
594
+ <span class="text-xs uppercase font-mono tracking-wider text-teal-600 font-semibold">Live Sandbox</span>
595
+ <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight mt-1">Interactive Select Playground</h2>
596
+ <p class="text-slate-500 text-sm mt-1">Test both CDN import and window.ks rendering right now in your browser.</p>
597
+ </div>
598
+ </div>
599
+
600
+ <div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
601
+
602
+ <!-- Controls Column -->
603
+ <div class="lg:col-span-5 bg-white p-6 rounded-2xl border border-slate-200 shadow-sm space-y-5">
604
+ <h3 class="text-sm font-bold text-slate-900 uppercase tracking-wider font-mono flex items-center gap-2">
605
+ <span>⚙️</span> Interactive Controls
606
+ </h3>
607
+
608
+ <!-- Mode Toggle -->
609
+ <div>
610
+ <label class="text-xs font-mono text-slate-600 block mb-2 font-medium">Rendering Mode:</label>
611
+ <div class="grid grid-cols-2 gap-2">
612
+ <button id="btn-mode-cdn" class="px-3 py-2 text-xs font-semibold rounded-lg bg-cyan-600 text-white transition flex items-center justify-center gap-1.5 shadow-sm">
613
+ <span>⚡</span> byCdn Import
614
+ </button>
615
+ <button id="btn-mode-ks" class="px-3 py-2 text-xs font-semibold rounded-lg bg-slate-100 text-slate-700 hover:bg-slate-200 transition flex items-center justify-center gap-1.5">
616
+ <span>🌐</span> byKs (window.ks)
617
+ </button>
618
+ </div>
619
+ </div>
620
+
621
+ <!-- Dataset Presets -->
622
+ <div>
623
+ <label class="text-xs font-mono text-slate-600 block mb-2 font-medium">Choose Dataset Preset:</label>
624
+ <select id="preset-selector" class="w-full bg-slate-50 border border-slate-300 text-xs rounded-lg px-3 py-2 text-slate-800 font-mono focus:ring-2 focus:ring-cyan-500 focus:outline-none">
625
+ <option value="ledgers">Preset 1: Banking &amp; Ledgers (from data.json)</option>
626
+ <option value="cities">Preset 2: Indian Tech Cities</option>
627
+ <option value="categories">Preset 3: Product Categories</option>
628
+ <option value="departments">Preset 4: Corporate Departments</option>
629
+ </select>
630
+ </div>
631
+
632
+ <!-- Render Button -->
633
+ <button id="btn-run-renderer" class="w-full py-2.5 px-4 rounded-xl bg-gradient-to-r from-cyan-600 to-teal-600 hover:from-cyan-700 hover:to-teal-700 text-white font-bold text-sm shadow-md transition flex items-center justify-center gap-2">
634
+ <span>🚀</span> Render Select to DOM Now
635
+ </button>
636
+
637
+ <!-- Code Snippet Preview -->
638
+ <div>
639
+ <div class="flex items-center justify-between mb-1">
640
+ <span class="text-xs font-mono text-slate-600 font-medium">Generated JavaScript:</span>
641
+ <button onclick="copyCode('active-snippet')" class="text-[11px] text-cyan-600 hover:underline font-mono">Copy Code</button>
642
+ </div>
643
+ <pre class="bg-slate-900 p-3 rounded-xl text-[11px] text-cyan-300 font-mono overflow-x-auto shadow-inner"><code id="active-snippet">render({
644
+ type: "select",
645
+ data: ["HDFC Bank", "State Bank of India", ...],
646
+ targetHtmlId: "live-select-output"
647
+ });</code></pre>
648
+ </div>
649
+ </div>
650
+
651
+ <!-- Output Column -->
652
+ <div class="lg:col-span-7 space-y-6">
653
+ <div class="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm space-y-4">
654
+ <div class="flex items-center justify-between pb-3 border-b border-slate-100">
655
+ <div class="flex items-center gap-2">
656
+ <span class="w-3 h-3 rounded-full bg-cyan-500 animate-pulse"></span>
657
+ <h3 class="text-sm font-bold text-slate-900 uppercase tracking-wider font-mono">
658
+ Container: <code class="text-cyan-700 font-semibold">#live-select-output</code>
659
+ </h3>
660
+ </div>
661
+ <span id="status-badge" class="px-2.5 py-0.5 text-[11px] font-mono rounded bg-cyan-100 text-cyan-800 border border-cyan-200 font-medium">
662
+ Ready
663
+ </span>
664
+ </div>
665
+
666
+ <!-- The Real Container where Select mounts -->
667
+ <div class="py-4">
668
+ <label class="block text-xs font-bold text-slate-700 uppercase tracking-wider font-mono mb-2">Rendered &lt;select&gt; Element:</label>
669
+ <div id="live-select-output" class="min-h-[60px] p-2 bg-slate-50 border border-slate-200 rounded-xl flex items-center justify-center text-slate-400 text-sm">
670
+ Click "Render Select to DOM Now" to mount the dropdown.
671
+ </div>
672
+ </div>
673
+
674
+ <!-- Selected Option Display -->
675
+ <div class="p-3 bg-cyan-50/60 border border-cyan-200 rounded-xl flex items-center justify-between text-xs">
676
+ <span class="text-slate-600 font-medium">Currently Selected Value:</span>
677
+ <span id="selected-val-badge" class="font-mono font-bold text-cyan-800 bg-white px-2.5 py-1 rounded border border-cyan-200">
678
+ (None selected yet)
679
+ </span>
680
+ </div>
681
+ </div>
682
+
683
+ <!-- Console Simulator -->
684
+ <div class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm">
685
+ <div class="flex items-center justify-between mb-2">
686
+ <span class="text-xs font-mono text-slate-600 font-semibold flex items-center gap-1.5">
687
+ <span>💻</span> Execution Status &amp; Logs
688
+ </span>
689
+ <button id="btn-clear-console" class="text-[11px] text-slate-400 hover:text-slate-700 font-mono">Clear</button>
690
+ </div>
691
+ <pre id="demo-console" class="bg-slate-900 p-3 rounded-xl text-xs text-emerald-400 font-mono border border-slate-800 h-28 overflow-y-auto"><code>[Ready] Select renderer module loaded. Ready to mount.</code></pre>
692
+ </div>
693
+ </div>
694
+
695
+ </div>
696
+ </section>
697
+
698
+ <!-- Quick Links & Samples Hub -->
699
+ <section class="bg-slate-50 p-8 rounded-2xl border border-slate-200 space-y-6">
700
+ <div class="border-b border-slate-200 pb-4">
701
+ <h3 class="text-xl font-bold text-slate-900 tracking-tight">Run Samples in Browser</h3>
702
+ <p class="text-slate-500 text-sm mt-1">Both select samples are available locally in the repository:</p>
703
+ </div>
704
+
705
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
706
+ <a href="../samples/select/byCdn/index.html" class="bg-white p-5 rounded-xl border border-slate-200 hover:border-cyan-400 hover:shadow-md transition group flex flex-col justify-between">
707
+ <div>
708
+ <div class="text-2xl mb-2">⚡</div>
709
+ <h4 class="font-bold text-slate-900 group-hover:text-cyan-700 transition text-sm">samples/select/byCdn</h4>
710
+ <p class="text-xs text-slate-500 mt-1 leading-relaxed">Direct ES Module CDN import demo.</p>
711
+ </div>
712
+ <span class="text-xs text-cyan-600 font-semibold font-mono mt-4">Open Sample &rarr;</span>
713
+ </a>
714
+
715
+ <a href="../samples/select/byKs/index.html" class="bg-white p-5 rounded-xl border border-slate-200 hover:border-indigo-400 hover:shadow-md transition group flex flex-col justify-between">
716
+ <div>
717
+ <div class="text-2xl mb-2">🌐</div>
718
+ <h4 class="font-bold text-slate-900 group-hover:text-indigo-700 transition text-sm">samples/select/byKs</h4>
719
+ <p class="text-xs text-slate-500 mt-1 leading-relaxed">Global window.ks namespace demo.</p>
720
+ </div>
721
+ <span class="text-xs text-indigo-600 font-semibold font-mono mt-4">Open Sample &rarr;</span>
722
+ </a>
723
+
724
+ <a href="table/index.html" class="bg-white p-5 rounded-xl border border-slate-200 hover:border-emerald-400 hover:shadow-md transition group flex flex-col justify-between">
725
+ <div>
726
+ <div class="text-2xl mb-2">📊</div>
727
+ <h4 class="font-bold text-slate-900 group-hover:text-emerald-700 transition text-sm">About Table Guide</h4>
728
+ <p class="text-xs text-slate-500 mt-1 leading-relaxed">Read guide for table mounting with CDN &amp; ks.</p>
729
+ </div>
730
+ <span class="text-xs text-emerald-600 font-semibold font-mono mt-4">Read Table Guide &rarr;</span>
731
+ </a>
732
+
733
+ <a href="index.html" class="bg-white p-5 rounded-xl border border-slate-200 hover:border-teal-400 hover:shadow-md transition group flex flex-col justify-between">
734
+ <div>
735
+ <div class="text-2xl mb-2">🏠</div>
736
+ <h4 class="font-bold text-slate-900 group-hover:text-teal-700 transition text-sm">Main Documentation</h4>
737
+ <p class="text-xs text-slate-500 mt-1 leading-relaxed">Return to the json-renderers homepage.</p>
738
+ </div>
739
+ <span class="text-xs text-teal-600 font-semibold font-mono mt-4">Visit Home &rarr;</span>
740
+ </a>
741
+ </div>
742
+ </section>
743
+
744
+ </main>
745
+
746
+ <!-- Clean White Footer -->
747
+ <footer class="border-t border-slate-200 bg-white py-6 mt-12">
748
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 flex flex-col sm:flex-row items-center justify-between gap-4 text-xs text-slate-500">
749
+ <div>
750
+ <span class="text-slate-800 font-semibold">json-renderers</span> &bull; Documentation for <code class="text-cyan-700 font-mono font-medium">byCdn</code> &amp; <code class="text-indigo-700 font-mono font-medium">byKs</code>
751
+ </div>
752
+ <div>
753
+ White background edition designed for high readability.
754
+ </div>
755
+ </div>
756
+ </footer>
757
+
758
+ <!-- Interactive JavaScript Logic -->
759
+ <script type="module">
760
+ import renderDirect from "./dist/v14/min.js";
761
+
762
+ // Sample datasets for dropdown testing
763
+ const datasets = {
764
+ ledgers: [
765
+ "360 one Quant Fund on 20.08.24",
766
+ "3F Industries Ltd",
767
+ "A 1 Furniture (Subbarao)",
768
+ "Aadarana Expns",
769
+ "Aadarna Supplies",
770
+ "AAFILAH FISHING NET INDUSTRIES",
771
+ "AAK South East India Pvt Ltd",
772
+ "Aarish Enterprises(Jayram Agencies)",
773
+ "A.ARJUNRAJU, (LIL)",
774
+ "AARON MARKETING, CHENNAI",
775
+ "Aaron Nets",
776
+ "AARON TECHONOLOGIES,VIZAG"
777
+ ],
778
+ cities: [
779
+ "Hyderabad",
780
+ "Bengaluru",
781
+ "Pune",
782
+ "Mumbai",
783
+ "Chennai",
784
+ "Gurugram",
785
+ "Noida",
786
+ "Kolkata"
787
+ ],
788
+ categories: [
789
+ "Electronics & Hardware",
790
+ "Mechanical Components",
791
+ "Raw Metals & Pipes",
792
+ "Lubricants & Chemical Additives",
793
+ "Electrical Wiring",
794
+ "Safety Gear & Apparel"
795
+ ],
796
+ departments: [
797
+ "Engineering & Development",
798
+ "Quality Assurance",
799
+ "Product Management",
800
+ "Logistics & Supply Chain",
801
+ "Finance & Accounts",
802
+ "Customer Support"
803
+ ]
804
+ };
805
+
806
+ let currentMode = "cdn"; // "cdn" or "ks"
807
+
808
+ const btnCdn = document.getElementById("btn-mode-cdn");
809
+ const btnKs = document.getElementById("btn-mode-ks");
810
+ const presetSelector = document.getElementById("preset-selector");
811
+ const runBtn = document.getElementById("btn-run-renderer");
812
+ const statusBadge = document.getElementById("status-badge");
813
+ const demoConsole = document.getElementById("demo-console");
814
+ const snippetCode = document.getElementById("active-snippet");
815
+ const selectedBadge = document.getElementById("selected-val-badge");
816
+ const clearBtn = document.getElementById("btn-clear-console");
817
+ const outputContainer = document.getElementById("live-select-output");
818
+
819
+ function logConsole(msg) {
820
+ demoConsole.innerHTML += "\n" + msg;
821
+ demoConsole.scrollTop = demoConsole.scrollHeight;
822
+ }
823
+
824
+ if (clearBtn) {
825
+ clearBtn.addEventListener("click", () => {
826
+ demoConsole.innerHTML = "<code>Console cleared.</code>";
827
+ });
828
+ }
829
+
830
+ // Toggle Modes
831
+ btnCdn.addEventListener("click", () => {
832
+ currentMode = "cdn";
833
+ btnCdn.className = "px-3 py-2 text-xs font-semibold rounded-lg bg-cyan-600 text-white transition flex items-center justify-center gap-1.5 shadow-sm";
834
+ btnKs.className = "px-3 py-2 text-xs font-semibold rounded-lg bg-slate-100 text-slate-700 hover:bg-slate-200 transition flex items-center justify-center gap-1.5";
835
+ updateSnippet();
836
+ logConsole("[Mode Changed] Switched to Method 1: Direct CDN Import (render)");
837
+ });
838
+
839
+ btnKs.addEventListener("click", () => {
840
+ currentMode = "ks";
841
+ btnKs.className = "px-3 py-2 text-xs font-semibold rounded-lg bg-indigo-600 text-white transition flex items-center justify-center gap-1.5 shadow-sm";
842
+ btnCdn.className = "px-3 py-2 text-xs font-semibold rounded-lg bg-slate-100 text-slate-700 hover:bg-slate-200 transition flex items-center justify-center gap-1.5";
843
+ updateSnippet();
844
+ logConsole("[Mode Changed] Switched to Method 2: Global window.ks (window.ks.jsonRenderers.renderToDom)");
845
+ });
846
+
847
+ presetSelector.addEventListener("change", () => {
848
+ updateSnippet();
849
+ runBtn.click();
850
+ });
851
+
852
+ function updateSnippet() {
853
+ const selectedPresetKey = presetSelector.value;
854
+ const dataItems = datasets[selectedPresetKey] || datasets.ledgers;
855
+ const samplePreview = JSON.stringify(dataItems.slice(0, 3)).replace(/]$/, ", ...]");
856
+
857
+ if (currentMode === "cdn") {
858
+ snippetCode.textContent = `// Method 1: CDN ES Module import
859
+ import render from "https://cdn.jsdelivr.net/gh/keshavsoft/json-renderers@main/docs/dist/v14/min.js";
860
+
861
+ render({
862
+ type: "select",
863
+ data: ${samplePreview},
864
+ targetHtmlId: "live-select-output",
865
+ showLog: true
866
+ });`;
867
+ } else {
868
+ snippetCode.textContent = `// Method 2: window.ks Global
869
+ import "https://cdn.jsdelivr.net/gh/keshavsoft/json-renderers@main/docs/dist/v14/min.js";
870
+
871
+ window.ks.jsonRenderers.renderToDom({
872
+ type: "select",
873
+ data: ${samplePreview},
874
+ targetHtmlId: "live-select-output",
875
+ showLog: true
876
+ });`;
877
+ }
878
+ }
879
+
880
+ // Run Renderer
881
+ runBtn.addEventListener("click", () => {
882
+ const selectedPresetKey = presetSelector.value;
883
+ const items = datasets[selectedPresetKey] || datasets.ledgers;
884
+
885
+ statusBadge.textContent = "Rendering...";
886
+ statusBadge.className = "px-2.5 py-0.5 text-[11px] font-mono rounded bg-amber-100 text-amber-800 border border-amber-200 font-medium";
887
+
888
+ try {
889
+ if (currentMode === "cdn") {
890
+ logConsole(`[Executing] Calling render({ type: "select", data: [${items.length} items], targetHtmlId: "live-select-output" })...`);
891
+ renderDirect({
892
+ type: "select",
893
+ data: items,
894
+ targetHtmlId: "live-select-output",
895
+ showLog: true
896
+ });
897
+ logConsole(`[Success] render() mounted select into #live-select-output.`);
898
+ } else {
899
+ logConsole(`[Executing] Calling window.ks.jsonRenderers.renderToDom({ type: "select" })...`);
900
+ if (window.ks && window.ks.jsonRenderers && window.ks.jsonRenderers.renderToDom) {
901
+ window.ks.jsonRenderers.renderToDom({
902
+ type: "select",
903
+ data: items,
904
+ targetHtmlId: "live-select-output",
905
+ showLog: true
906
+ });
907
+ logConsole(`[Success] window.ks.jsonRenderers.renderToDom() mounted select dropdown.`);
908
+ } else {
909
+ renderDirect({
910
+ type: "select",
911
+ data: items,
912
+ targetHtmlId: "live-select-output",
913
+ showLog: true
914
+ });
915
+ logConsole(`[Note] Fallback to direct renderer executed.`);
916
+ }
917
+ }
918
+
919
+ // Attach change listener to mounted select element
920
+ const mountedSelect = outputContainer.querySelector("select");
921
+ if (mountedSelect) {
922
+ mountedSelect.classList.add("form-select");
923
+ selectedBadge.textContent = mountedSelect.value || "(First option selected)";
924
+
925
+ mountedSelect.addEventListener("change", (e) => {
926
+ selectedBadge.textContent = e.target.value;
927
+ logConsole(`[Event] User selected: "${e.target.value}"`);
928
+ });
929
+ }
930
+
931
+ statusBadge.textContent = "Mounted (" + items.length + " options)";
932
+ statusBadge.className = "px-2.5 py-0.5 text-[11px] font-mono rounded bg-emerald-100 text-emerald-800 border border-emerald-200 font-medium";
933
+
934
+ } catch (err) {
935
+ logConsole(`[Error] ` + err.message);
936
+ statusBadge.textContent = "Error";
937
+ statusBadge.className = "px-2.5 py-0.5 text-[11px] font-mono rounded bg-red-100 text-red-800 border border-red-200 font-medium";
938
+ }
939
+ });
940
+
941
+ // Auto-render on load
942
+ setTimeout(() => {
943
+ runBtn.click();
944
+ }, 200);
945
+
946
+ // Copy to clipboard helper
947
+ window.copyCode = (elementId) => {
948
+ const el = document.getElementById(elementId);
949
+ if (!el) return;
950
+ navigator.clipboard.writeText(el.textContent).then(() => {
951
+ alert("Code snippet copied to clipboard!");
952
+ }).catch(() => {
953
+ const textarea = document.createElement("textarea");
954
+ textarea.value = el.textContent;
955
+ document.body.appendChild(textarea);
956
+ textarea.select();
957
+ document.execCommand("copy");
958
+ document.body.removeChild(textarea);
959
+ alert("Code snippet copied to clipboard!");
960
+ });
961
+ };
962
+ </script>
963
+ </body>
964
+ </html>