@portel/photon 1.20.0 → 1.21.0

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.
Files changed (149) hide show
  1. package/README.md +5 -5
  2. package/dist/ag-ui/adapter.d.ts.map +1 -1
  3. package/dist/ag-ui/adapter.js +25 -0
  4. package/dist/ag-ui/adapter.js.map +1 -1
  5. package/dist/auto-ui/beam/routes/api-browse.d.ts.map +1 -1
  6. package/dist/auto-ui/beam/routes/api-browse.js +8 -49
  7. package/dist/auto-ui/beam/routes/api-browse.js.map +1 -1
  8. package/dist/auto-ui/beam/routes/api-config.d.ts.map +1 -1
  9. package/dist/auto-ui/beam/routes/api-config.js +161 -20
  10. package/dist/auto-ui/beam/routes/api-config.js.map +1 -1
  11. package/dist/auto-ui/beam.d.ts.map +1 -1
  12. package/dist/auto-ui/beam.js +24 -31
  13. package/dist/auto-ui/beam.js.map +1 -1
  14. package/dist/auto-ui/bridge/index.d.ts.map +1 -1
  15. package/dist/auto-ui/bridge/index.js +107 -11
  16. package/dist/auto-ui/bridge/index.js.map +1 -1
  17. package/dist/auto-ui/bridge/renderers.d.ts +14 -0
  18. package/dist/auto-ui/bridge/renderers.d.ts.map +1 -1
  19. package/dist/auto-ui/bridge/renderers.js +692 -61
  20. package/dist/auto-ui/bridge/renderers.js.map +1 -1
  21. package/dist/auto-ui/frontend/index.html +3 -3
  22. package/dist/auto-ui/frontend/pure-view.html +19 -19
  23. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  24. package/dist/auto-ui/streamable-http-transport.js +144 -28
  25. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  26. package/dist/auto-ui/ui-resolver.d.ts +25 -0
  27. package/dist/auto-ui/ui-resolver.d.ts.map +1 -0
  28. package/dist/auto-ui/ui-resolver.js +95 -0
  29. package/dist/auto-ui/ui-resolver.js.map +1 -0
  30. package/dist/beam-form.bundle.js +26 -189
  31. package/dist/beam-form.bundle.js.map +4 -4
  32. package/dist/beam.bundle.js +1646 -494
  33. package/dist/beam.bundle.js.map +4 -4
  34. package/dist/cli/commands/beam.d.ts.map +1 -1
  35. package/dist/cli/commands/beam.js +47 -30
  36. package/dist/cli/commands/beam.js.map +1 -1
  37. package/dist/cli/commands/build.d.ts.map +1 -1
  38. package/dist/cli/commands/build.js +36 -7
  39. package/dist/cli/commands/build.js.map +1 -1
  40. package/dist/cli/commands/daemon.d.ts.map +1 -1
  41. package/dist/cli/commands/daemon.js +12 -6
  42. package/dist/cli/commands/daemon.js.map +1 -1
  43. package/dist/cli/commands/init.d.ts.map +1 -1
  44. package/dist/cli/commands/init.js +90 -50
  45. package/dist/cli/commands/init.js.map +1 -1
  46. package/dist/cli/commands/mcp.d.ts.map +1 -1
  47. package/dist/cli/commands/mcp.js +18 -6
  48. package/dist/cli/commands/mcp.js.map +1 -1
  49. package/dist/cli/commands/publish.d.ts +14 -0
  50. package/dist/cli/commands/publish.d.ts.map +1 -0
  51. package/dist/cli/commands/publish.js +126 -0
  52. package/dist/cli/commands/publish.js.map +1 -0
  53. package/dist/cli/commands/run.d.ts.map +1 -1
  54. package/dist/cli/commands/run.js +2 -0
  55. package/dist/cli/commands/run.js.map +1 -1
  56. package/dist/cli/commands/serve.d.ts.map +1 -1
  57. package/dist/cli/commands/serve.js +14 -2
  58. package/dist/cli/commands/serve.js.map +1 -1
  59. package/dist/cli/index.d.ts.map +1 -1
  60. package/dist/cli/index.js +3 -0
  61. package/dist/cli/index.js.map +1 -1
  62. package/dist/cli-alias.d.ts.map +1 -1
  63. package/dist/cli-alias.js +2 -3
  64. package/dist/cli-alias.js.map +1 -1
  65. package/dist/context-store.d.ts +4 -4
  66. package/dist/context-store.d.ts.map +1 -1
  67. package/dist/context-store.js +18 -15
  68. package/dist/context-store.js.map +1 -1
  69. package/dist/context.d.ts +31 -2
  70. package/dist/context.d.ts.map +1 -1
  71. package/dist/context.js +86 -9
  72. package/dist/context.js.map +1 -1
  73. package/dist/daemon/client.d.ts +9 -1
  74. package/dist/daemon/client.d.ts.map +1 -1
  75. package/dist/daemon/client.js +58 -2
  76. package/dist/daemon/client.js.map +1 -1
  77. package/dist/daemon/manager.d.ts +5 -0
  78. package/dist/daemon/manager.d.ts.map +1 -1
  79. package/dist/daemon/manager.js +116 -34
  80. package/dist/daemon/manager.js.map +1 -1
  81. package/dist/daemon/ownership.d.ts +12 -0
  82. package/dist/daemon/ownership.d.ts.map +1 -0
  83. package/dist/daemon/ownership.js +55 -0
  84. package/dist/daemon/ownership.js.map +1 -0
  85. package/dist/daemon/protocol.d.ts +3 -1
  86. package/dist/daemon/protocol.d.ts.map +1 -1
  87. package/dist/daemon/protocol.js +14 -2
  88. package/dist/daemon/protocol.js.map +1 -1
  89. package/dist/daemon/server.js +587 -77
  90. package/dist/daemon/server.js.map +1 -1
  91. package/dist/daemon/session-manager.d.ts +9 -1
  92. package/dist/daemon/session-manager.d.ts.map +1 -1
  93. package/dist/daemon/session-manager.js +54 -1
  94. package/dist/daemon/session-manager.js.map +1 -1
  95. package/dist/daemon/worker-host.js +7 -0
  96. package/dist/daemon/worker-host.js.map +1 -1
  97. package/dist/daemon/worker-manager.d.ts +12 -0
  98. package/dist/daemon/worker-manager.d.ts.map +1 -1
  99. package/dist/daemon/worker-manager.js +147 -16
  100. package/dist/daemon/worker-manager.js.map +1 -1
  101. package/dist/daemon/worker-protocol.d.ts +3 -0
  102. package/dist/daemon/worker-protocol.d.ts.map +1 -1
  103. package/dist/deploy/cloudflare.d.ts.map +1 -1
  104. package/dist/deploy/cloudflare.js +2 -4
  105. package/dist/deploy/cloudflare.js.map +1 -1
  106. package/dist/loader.d.ts +10 -9
  107. package/dist/loader.d.ts.map +1 -1
  108. package/dist/loader.js +224 -115
  109. package/dist/loader.js.map +1 -1
  110. package/dist/marketplace-manager.d.ts +1 -1
  111. package/dist/marketplace-manager.d.ts.map +1 -1
  112. package/dist/marketplace-manager.js +5 -4
  113. package/dist/marketplace-manager.js.map +1 -1
  114. package/dist/photon-cli-runner.d.ts.map +1 -1
  115. package/dist/photon-cli-runner.js +66 -23
  116. package/dist/photon-cli-runner.js.map +1 -1
  117. package/dist/photon-doc-extractor.d.ts.map +1 -1
  118. package/dist/photon-doc-extractor.js +59 -15
  119. package/dist/photon-doc-extractor.js.map +1 -1
  120. package/dist/photons/canvas/ui/canvas.photon.html +1493 -0
  121. package/dist/photons/canvas.photon.d.ts +400 -0
  122. package/dist/photons/canvas.photon.d.ts.map +1 -0
  123. package/dist/photons/canvas.photon.js +662 -0
  124. package/dist/photons/canvas.photon.js.map +1 -0
  125. package/dist/photons/canvas.photon.ts +814 -0
  126. package/dist/photons/publish.photon.d.ts +97 -0
  127. package/dist/photons/publish.photon.d.ts.map +1 -0
  128. package/dist/photons/publish.photon.js +569 -0
  129. package/dist/photons/publish.photon.js.map +1 -0
  130. package/dist/photons/publish.photon.ts +683 -0
  131. package/dist/photons/ui/canvas.photon.html +624 -0
  132. package/dist/resource-server.d.ts.map +1 -1
  133. package/dist/resource-server.js +7 -1
  134. package/dist/resource-server.js.map +1 -1
  135. package/dist/server.d.ts.map +1 -1
  136. package/dist/server.js +14 -16
  137. package/dist/server.js.map +1 -1
  138. package/dist/shared-utils.d.ts +4 -0
  139. package/dist/shared-utils.d.ts.map +1 -1
  140. package/dist/shared-utils.js +24 -2
  141. package/dist/shared-utils.js.map +1 -1
  142. package/dist/template-manager.d.ts.map +1 -1
  143. package/dist/template-manager.js +56 -234
  144. package/dist/template-manager.js.map +1 -1
  145. package/dist/tsx-compiler.d.ts +23 -0
  146. package/dist/tsx-compiler.d.ts.map +1 -0
  147. package/dist/tsx-compiler.js +221 -0
  148. package/dist/tsx-compiler.js.map +1 -0
  149. package/package.json +7 -7
@@ -38,6 +38,38 @@ export function generateRenderersScript() {
38
38
  }
39
39
  var colors = getColors();
40
40
 
41
+ // Shared semantic color map — used by badge, banner, ring, alert, sparkline, etc.
42
+ var VARIANT_COLORS = {
43
+ success: '#34d399',
44
+ error: '#f87171',
45
+ warning: '#fbbf24',
46
+ destructive: '#f87171',
47
+ info: colors.accent,
48
+ neutral: colors.textMuted
49
+ };
50
+
51
+ // Factory for lazy-loading CDN scripts with queued callbacks
52
+ function _makeLoader(url, cssUrl) {
53
+ var loading = false, loaded = false, queue = [];
54
+ return function(cb) {
55
+ if (loaded) { cb(); return; }
56
+ queue.push(cb);
57
+ if (loading) return;
58
+ loading = true;
59
+ if (cssUrl) {
60
+ var link = document.createElement('link');
61
+ link.rel = 'stylesheet';
62
+ link.href = cssUrl;
63
+ document.head.appendChild(link);
64
+ }
65
+ var s = document.createElement('script');
66
+ s.src = url;
67
+ s.onload = function() { loaded = true; queue.forEach(function(fn) { fn(); }); queue = []; };
68
+ s.onerror = function() { queue.forEach(function(fn) { fn(); }); queue = []; };
69
+ document.head.appendChild(s);
70
+ };
71
+ }
72
+
41
73
  function esc(s) {
42
74
  if (typeof s !== 'string') return String(s == null ? '' : s);
43
75
  return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
@@ -227,8 +259,6 @@ export function generateRenderersScript() {
227
259
  // ─── Badge ───
228
260
  renderers.badge = function(container, data, opts) {
229
261
  opts = opts || {};
230
- var text = typeof data === 'string' ? data : (data.status || data.label || data.text || data.value || JSON.stringify(data));
231
- var variant = opts.variant || _badgeVariant(text);
232
262
  var badgeColors = {
233
263
  success: { bg: 'rgba(52,211,153,0.15)', text: '#34d399' },
234
264
  error: { bg: 'rgba(248,113,113,0.15)', text: '#f87171' },
@@ -236,8 +266,18 @@ export function generateRenderersScript() {
236
266
  info: { bg: 'rgba(108,158,255,0.15)', text: '#6c9eff' },
237
267
  neutral: { bg: colors.bgAlt, text: colors.textMuted }
238
268
  };
239
- var c = badgeColors[variant] || badgeColors.neutral;
240
- container.innerHTML = '<span style="display:inline-block;padding:3px 10px;border-radius:12px;font-size:12px;font-weight:500;background:' + c.bg + ';color:' + c.text + '">' + esc(text) + '</span>';
269
+ function renderOne(item) {
270
+ var text = typeof item === 'string' ? item : (item.status || item.label || item.text || item.value || JSON.stringify(item));
271
+ var variant = opts.variant || _badgeVariant(text);
272
+ var c = badgeColors[variant] || badgeColors.neutral;
273
+ var namePrefix = (typeof item === 'object' && item !== null && (item.name || item.title)) ? '<span style="font-size:12px;color:' + colors.textMuted + ';margin-right:4px">' + esc(item.name || item.title) + '</span>' : '';
274
+ return namePrefix + '<span style="display:inline-block;padding:3px 10px;border-radius:12px;font-size:12px;font-weight:500;background:' + c.bg + ';color:' + c.text + '">' + esc(text) + '</span>';
275
+ }
276
+ if (Array.isArray(data)) {
277
+ container.innerHTML = '<div style="display:flex;flex-wrap:wrap;gap:8px;align-items:center">' + data.map(renderOne).join('') + '</div>';
278
+ } else {
279
+ container.innerHTML = renderOne(data);
280
+ }
241
281
  };
242
282
 
243
283
  // ─── List ───
@@ -269,7 +309,7 @@ export function generateRenderersScript() {
269
309
  };
270
310
 
271
311
  // ─── Chart (lazy-loads Chart.js) ───
272
- renderers['chart'] = renderers['chart:bar'] = renderers['chart:hbar'] = renderers['chart:line'] = renderers['chart:pie'] = renderers['chart:area'] = renderers['chart:donut'] = function(container, data, opts, formatKey) {
312
+ renderers['chart'] = renderers['chart:bar'] = renderers['chart:hbar'] = renderers['chart:line'] = renderers['chart:pie'] = renderers['chart:area'] = renderers['chart:donut'] = renderers['chart:radar'] = function(container, data, opts, formatKey) {
273
313
  opts = opts || {};
274
314
  var items = Array.isArray(data) ? data : (data.data || data.items || data.rows || [data]);
275
315
  if (!items.length || typeof items[0] !== 'object') { container.innerHTML = '<p style="color:' + colors.textMuted + '">No chart data</p>'; return; }
@@ -442,18 +482,7 @@ export function generateRenderersScript() {
442
482
  }
443
483
 
444
484
  // ─── QR code ───
445
- var _qrLoading = false, _qrLoaded = false, _qrQueue = [];
446
- function _loadQRJS(cb) {
447
- if (_qrLoaded) { cb(); return; }
448
- _qrQueue.push(cb);
449
- if (_qrLoading) return;
450
- _qrLoading = true;
451
- var s = document.createElement('script');
452
- s.src = 'https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js';
453
- s.onload = function() { _qrLoaded = true; _qrQueue.forEach(function(fn) { fn(); }); _qrQueue = []; };
454
- s.onerror = function() { _qrQueue.forEach(function(fn) { fn(); }); _qrQueue = []; };
455
- document.head.appendChild(s);
456
- }
485
+ var _loadQRJS = _makeLoader('https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js');
457
486
 
458
487
  renderers.qr = function(container, data) {
459
488
  var text = typeof data === 'object' && data !== null
@@ -474,18 +503,7 @@ export function generateRenderersScript() {
474
503
  });
475
504
  };
476
505
 
477
- var _chartLoading = false, _chartLoaded = false, _chartQueue = [];
478
- function _loadChartJS(cb) {
479
- if (_chartLoaded) { cb(); return; }
480
- _chartQueue.push(cb);
481
- if (_chartLoading) return;
482
- _chartLoading = true;
483
- var s = document.createElement('script');
484
- s.src = 'https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js';
485
- s.onload = function() { _chartLoaded = true; _chartQueue.forEach(function(fn) { fn(); }); _chartQueue = []; };
486
- s.onerror = function() { _chartQueue.forEach(function(fn) { fn(); }); _chartQueue = []; };
487
- document.head.appendChild(s);
488
- }
506
+ var _loadChartJS = _makeLoader('https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js');
489
507
 
490
508
  // ─── Steps/Stepper ───
491
509
  renderers.steps = renderers.stepper = function(container, data) {
@@ -622,8 +640,7 @@ export function generateRenderersScript() {
622
640
  var message = d.message || d.text || d.title || '';
623
641
  var type = (d.type || d.variant || d.severity || 'info').toLowerCase();
624
642
  var icon = d.icon || '';
625
- var bannerColors = { success: '#34d399', error: '#f87171', warning: '#fbbf24', info: colors.accent };
626
- var bc = bannerColors[type] || colors.accent;
643
+ var bc = VARIANT_COLORS[type] || VARIANT_COLORS.info;
627
644
  var h = '<div style="display:flex;align-items:center;gap:10px;padding:12px 16px;background:' + bc + '18;border:1px solid ' + bc + '44;border-radius:8px;border-left:4px solid ' + bc + '">';
628
645
  if (icon) h += '<span style="font-size:18px;flex-shrink:0">' + esc(icon) + '</span>';
629
646
  h += '<span style="font-size:13px;color:' + colors.text + '">' + esc(message) + '</span>';
@@ -1046,24 +1063,10 @@ export function generateRenderersScript() {
1046
1063
  };
1047
1064
 
1048
1065
  // ─── Map (Leaflet) ───
1049
- var _leafletLoading = false, _leafletLoaded = false, _leafletQueue = [];
1050
- function _loadLeaflet(cb) {
1051
- if (_leafletLoaded) { cb(); return; }
1052
- _leafletQueue.push(cb);
1053
- if (_leafletLoading) return;
1054
- _leafletLoading = true;
1055
- // Load CSS
1056
- var link = document.createElement('link');
1057
- link.rel = 'stylesheet';
1058
- link.href = 'https://cdn.jsdelivr.net/npm/leaflet@1.9/dist/leaflet.min.css';
1059
- document.head.appendChild(link);
1060
- // Load JS
1061
- var s = document.createElement('script');
1062
- s.src = 'https://cdn.jsdelivr.net/npm/leaflet@1.9/dist/leaflet.min.js';
1063
- s.onload = function() { _leafletLoaded = true; _leafletQueue.forEach(function(fn) { fn(); }); _leafletQueue = []; };
1064
- s.onerror = function() { _leafletQueue.forEach(function(fn) { fn(); }); _leafletQueue = []; };
1065
- document.head.appendChild(s);
1066
- }
1066
+ var _loadLeaflet = _makeLoader(
1067
+ 'https://cdn.jsdelivr.net/npm/leaflet@1.9/dist/leaflet.min.js',
1068
+ 'https://cdn.jsdelivr.net/npm/leaflet@1.9/dist/leaflet.min.css'
1069
+ );
1067
1070
 
1068
1071
  renderers.map = function(container, data) {
1069
1072
  var items = Array.isArray(data) ? data : [data];
@@ -1189,18 +1192,7 @@ export function generateRenderersScript() {
1189
1192
  };
1190
1193
 
1191
1194
  // ─── Network/Graph (force-directed via vis-network) ───
1192
- var _visLoading = false, _visLoaded = false, _visQueue = [];
1193
- function _loadVisNetwork(cb) {
1194
- if (_visLoaded) { cb(); return; }
1195
- _visQueue.push(cb);
1196
- if (_visLoading) return;
1197
- _visLoading = true;
1198
- var s = document.createElement('script');
1199
- s.src = 'https://cdn.jsdelivr.net/npm/vis-network@9/standalone/umd/vis-network.min.js';
1200
- s.onload = function() { _visLoaded = true; _visQueue.forEach(function(fn) { fn(); }); _visQueue = []; };
1201
- s.onerror = function() { _visQueue.forEach(function(fn) { fn(); }); _visQueue = []; };
1202
- document.head.appendChild(s);
1203
- }
1195
+ var _loadVisNetwork = _makeLoader('https://cdn.jsdelivr.net/npm/vis-network@9/standalone/umd/vis-network.min.js');
1204
1196
 
1205
1197
  renderers.network = renderers.graph = function(container, data) {
1206
1198
  var nodes = data.nodes || [];
@@ -1432,6 +1424,391 @@ export function generateRenderersScript() {
1432
1424
  render();
1433
1425
  };
1434
1426
 
1427
+ // ─── Ring ───
1428
+ renderers.ring = function(container, data, opts) {
1429
+ opts = opts || {};
1430
+ var value = typeof data === 'number' ? data : (data.value || 0);
1431
+ var label = opts.label || data.label || '';
1432
+ var variant = opts.variant || data.variant || 'info';
1433
+ var max = opts.max != null ? opts.max : (data.max || 100);
1434
+ var pct = Math.max(0, Math.min(100, (value / max) * 100));
1435
+ var size = opts.size || 120;
1436
+ var thickness = opts.thickness || 12;
1437
+ var r = (size - thickness) / 2;
1438
+ var cx = size / 2, cy = size / 2;
1439
+ var c = 2 * Math.PI * r;
1440
+ var offset = c - (pct / 100) * c;
1441
+
1442
+ var ringColor = VARIANT_COLORS[variant] || VARIANT_COLORS.info;
1443
+
1444
+ var h = '<div style="position:relative;width:' + size + 'px;height:' + size + 'px;margin:0 auto">';
1445
+ h += '<svg width="' + size + '" height="' + size + '" viewBox="0 0 ' + size + ' ' + size + '" style="transform:rotate(-90deg)">';
1446
+ h += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="transparent" stroke="' + colors.bgAlt + '" stroke-width="' + thickness + '" />';
1447
+ if (pct > 0) {
1448
+ h += '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="transparent" stroke="' + ringColor + '" stroke-width="' + thickness + '" stroke-dasharray="' + c + '" stroke-dashoffset="' + offset + '" stroke-linecap="round" style="transition:stroke-dashoffset 0.5s ease" />';
1449
+ }
1450
+ h += '</svg>';
1451
+ h += '<div style="position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;color:' + colors.text + '">';
1452
+ h += '<span style="font-size:' + (size * 0.22) + 'px;font-weight:700">' + formatValue(value) + '</span>';
1453
+ if (label) h += '<span style="font-size:11px;color:' + colors.textMuted + ';margin-top:2px">' + esc(label) + '</span>';
1454
+ h += '</div></div>';
1455
+ container.innerHTML = h;
1456
+ };
1457
+
1458
+ // ─── Alert ───
1459
+ renderers.alert = function(container, data, opts) {
1460
+ opts = opts || {};
1461
+ var d = typeof data === 'string' ? { description: data } : data;
1462
+ var title = d.title || d.heading || '';
1463
+ var desc = d.description || d.text || d.message || '';
1464
+ var variant = (opts.variant || d.variant || 'info').toLowerCase();
1465
+ var icon = d.icon || '';
1466
+ var ac = VARIANT_COLORS[variant] || VARIANT_COLORS.info;
1467
+ var bg = ac + '15';
1468
+
1469
+ var h = '<div style="display:flex;gap:12px;padding:16px;background:' + bg + ';border:1px solid ' + ac + '40;border-radius:8px">';
1470
+ if (icon) {
1471
+ h += '<div style="flex-shrink:0;font-size:20px;color:' + ac + '">' + esc(icon) + '</div>';
1472
+ }
1473
+ h += '<div>';
1474
+ if (title) h += '<div style="font-weight:600;font-size:14px;color:' + colors.text + ';margin-bottom:4px">' + esc(title) + '</div>';
1475
+ if (desc) h += '<div style="font-size:13px;color:' + colors.textMuted + ';line-height:1.5">' + esc(desc) + '</div>';
1476
+ h += '</div></div>';
1477
+ container.innerHTML = h;
1478
+ };
1479
+
1480
+ // ─── Sparkline ───
1481
+ renderers.sparkline = function(container, data, opts) {
1482
+ opts = opts || {};
1483
+ var items = Array.isArray(data) ? data : (data.data || []);
1484
+ if (!items.length) { container.innerHTML = ''; return; }
1485
+
1486
+ var variant = opts.variant || data.variant || 'info';
1487
+ var color = VARIANT_COLORS[variant] || VARIANT_COLORS.info;
1488
+
1489
+ var w = container.clientWidth || 100;
1490
+ var h = opts.height || data.height || 40;
1491
+ var min = Math.min.apply(null, items);
1492
+ var max = Math.max.apply(null, items);
1493
+ var range = max - min || 1;
1494
+
1495
+ var points = items.map(function(val, i) {
1496
+ var x = i === 0 ? 0 : i === items.length - 1 ? w : (i / (items.length - 1)) * w;
1497
+ var y = h - ((val - min) / range) * h;
1498
+ return x + ',' + y;
1499
+ }).join(' ');
1500
+
1501
+ var fill = opts.fill != null ? opts.fill : data.fill;
1502
+
1503
+ var svg = '<svg width="100%" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '" preserveAspectRatio="none">';
1504
+ if (fill) {
1505
+ svg += '<polygon points="0,' + h + ' ' + points + ' ' + w + ',' + h + '" fill="' + color + '33" />';
1506
+ }
1507
+ svg += '<polyline points="' + points + '" fill="none" stroke="' + color + '" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />';
1508
+ svg += '</svg>';
1509
+
1510
+ container.innerHTML = svg;
1511
+ };
1512
+
1513
+ // ─── Empty State ───
1514
+ renderers['empty-state'] = renderers.empty = function(container, data) {
1515
+ var d = typeof data === 'string' ? { title: data } : (data || {});
1516
+ var title = d.title || d.heading || d.message || 'No Data';
1517
+ var desc = d.description || d.text || d.detail || '';
1518
+ var icon = d.icon || '\\u2205';
1519
+ var action = d.action || d.button || '';
1520
+
1521
+ var h = '<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;text-align:center;background:' + colors.bgAlt + ';border:1px dashed ' + colors.border + ';border-radius:12px">';
1522
+ h += '<div style="font-size:32px;color:' + colors.textMuted + ';margin-bottom:16px;opacity:0.5">' + esc(icon) + '</div>';
1523
+ h += '<div style="font-size:16px;font-weight:600;color:' + colors.text + ';margin-bottom:4px">' + esc(title) + '</div>';
1524
+ if (desc) h += '<div style="font-size:13px;color:' + colors.textMuted + ';max-width:300px;margin:0 auto 16px">' + esc(desc) + '</div>';
1525
+ if (action) h += '<button style="background:' + colors.accent + ';color:#fff;border:none;padding:8px 16px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer">' + esc(action) + '</button>';
1526
+ h += '</div>';
1527
+ container.innerHTML = h;
1528
+ };
1529
+
1530
+ // ─── Accordion ───
1531
+ renderers.accordion = renderers.collapse = function(container, data) {
1532
+ var items = Array.isArray(data) ? data : (data.items || []);
1533
+ if (!items.length) { container.innerHTML = ''; return; }
1534
+
1535
+ var h = '<div style="border-radius:8px;overflow:hidden;border:1px solid ' + colors.border + '">';
1536
+ for (var i = 0; i < items.length; i++) {
1537
+ var item = items[i];
1538
+ var title = item.title || item.label || item.question || ('Item ' + (i + 1));
1539
+ var content = item.content || item.answer || item.body || item.details || '';
1540
+ var isOpen = !!item.open || !!item.expanded;
1541
+
1542
+ h += '<div style="border-bottom:' + (i < items.length - 1 ? '1px solid ' + colors.border : 'none') + '">';
1543
+ h += '<div class="_acc_trigger" style="display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:' + colors.bgAlt + ';cursor:pointer;font-size:14px;font-weight:600;color:' + colors.text + ';user-select:none">';
1544
+ h += '<span>' + esc(title) + '</span>';
1545
+ h += '<span class="_acc_icon" style="transform:' + (isOpen ? 'rotate(180deg)' : 'rotate(0)') + ';transition:transform 0.2s ease;color:' + colors.textMuted + '">\\u25BC</span>';
1546
+ h += '</div>';
1547
+ h += '<div class="_acc_content" style="display:' + (isOpen ? 'block' : 'none') + ';padding:16px;font-size:13px;color:' + colors.textMuted + ';background:' + colors.bg + ';border-top:1px solid ' + colors.border + '">';
1548
+ h += (typeof content === 'string' ? esc(content).replace(/\\n/g, '<br>') : '<pre style="margin:0;font-family:monospace;font-size:12px">' + esc(JSON.stringify(content, null, 2)) + '</pre>');
1549
+ h += '</div></div>';
1550
+ }
1551
+ h += '</div>';
1552
+ container.innerHTML = h;
1553
+
1554
+ var triggers = container.querySelectorAll('._acc_trigger');
1555
+ for (var j = 0; j < triggers.length; j++) {
1556
+ triggers[j].onclick = function(e) {
1557
+ var t = e.currentTarget;
1558
+ var c = t.nextElementSibling;
1559
+ var icon = t.querySelector('._acc_icon');
1560
+ var isHidden = c.style.display === 'none';
1561
+ c.style.display = isHidden ? 'block' : 'none';
1562
+ icon.style.transform = isHidden ? 'rotate(180deg)' : 'rotate(0)';
1563
+ };
1564
+ }
1565
+ };
1566
+
1567
+ // ─── Feed (Activity Stream) ───
1568
+ renderers.feed = renderers.activity = function(container, data) {
1569
+ var items = Array.isArray(data) ? data : (data.items || []);
1570
+ if (!items.length) { container.innerHTML = ''; return; }
1571
+
1572
+ var h = '<div style="display:flex;flex-direction:column;gap:16px">';
1573
+ for (var i = 0; i < items.length; i++) {
1574
+ var item = items[i];
1575
+ var user = item.user || item.author || item.name || 'System';
1576
+ var action = item.action || item.event || 'performed an action';
1577
+ var target = item.target || item.object || '';
1578
+ var ts = item.timestamp || item.time || item.date || '';
1579
+ var avatar = item.avatar || item.image || '';
1580
+ var details = item.details || item.message || item.body || '';
1581
+
1582
+ h += '<div style="display:flex;gap:12px">';
1583
+ // Avatar
1584
+ if (avatar) {
1585
+ h += '<img src="' + esc(avatar) + '" style="width:32px;height:32px;border-radius:50%;object-fit:cover;flex-shrink:0;border:1px solid ' + colors.border + '" />';
1586
+ } else {
1587
+ h += '<div style="width:32px;height:32px;border-radius:50%;background:' + colors.bgAlt + ';display:flex;align-items:center;justify-content:center;flex-shrink:0;font-weight:600;color:' + colors.text + ';font-size:12px;border:1px solid ' + colors.border + '">' + esc(user.charAt(0).toUpperCase()) + '</div>';
1588
+ }
1589
+ // Content
1590
+ h += '<div style="flex:1;min-width:0">';
1591
+ h += '<div style="font-size:13px;color:' + colors.text + ';margin-bottom:2px">';
1592
+ h += '<span style="font-weight:600">' + esc(user) + '</span> ';
1593
+ h += '<span style="color:' + colors.textMuted + '">' + esc(action) + '</span> ';
1594
+ if (target) h += '<span style="font-weight:500">' + esc(target) + '</span>';
1595
+ h += '</div>';
1596
+ if (ts) h += '<div style="font-size:11px;color:' + colors.textMuted + ';margin-bottom:4px">' + esc(_formatDate(ts)) + '</div>';
1597
+ if (details) {
1598
+ h += '<div style="background:' + colors.bgAlt + ';border:1px solid ' + colors.border + ';border-radius:8px;padding:8px 12px;font-size:13px;color:' + colors.textMuted + ';margin-top:6px">';
1599
+ h += (typeof details === 'string' ? esc(details).replace(/\\n/g, '<br>') : '<pre style="margin:0;font-size:11px">' + esc(JSON.stringify(details, null, 2)) + '</pre>');
1600
+ h += '</div>';
1601
+ }
1602
+ h += '</div></div>';
1603
+ }
1604
+ h += '</div>';
1605
+ container.innerHTML = h;
1606
+ };
1607
+
1608
+ // ─── Tabs ───
1609
+ renderers.tabs = function(container, data) {
1610
+ var items = Array.isArray(data) ? data : (data.items || data.tabs || []);
1611
+ if (!Array.isArray(data) && typeof data === 'object' && !data.items && !data.tabs) {
1612
+ items = Object.keys(data).map(function(k) { return { title: k, content: data[k] }; });
1613
+ }
1614
+ if (!items.length) { container.innerHTML = ''; return; }
1615
+
1616
+ var navId = '_tabs_' + Math.random().toString(36).slice(2, 8);
1617
+ var h = '<div id="' + navId + '">';
1618
+ h += '<div style="display:flex;gap:24px;border-bottom:1px solid ' + colors.border + ';margin-bottom:16px;overflow-x:auto">';
1619
+ for (var i = 0; i < items.length; i++) {
1620
+ var title = items[i].title || items[i].label || items[i].name || ('Tab ' + (i+1));
1621
+ var isActive = i === 0;
1622
+ h += '<div class="_tab_trigger" data-idx="' + i + '" style="padding:8px 4px;font-size:13px;font-weight:600;cursor:pointer;user-select:none;white-space:nowrap;border-bottom:2px solid ' + (isActive ? colors.accent : 'transparent') + ';color:' + (isActive ? colors.accent : colors.textMuted) + ';transition:all 0.2s">' + esc(title) + '</div>';
1623
+ }
1624
+ h += '</div>';
1625
+ h += '<div class="_tab_panels">';
1626
+ for (var j = 0; j < items.length; j++) {
1627
+ var c = items[j].content || items[j].body || items[j].data || items[j];
1628
+ var isJSON = typeof c === 'object';
1629
+ h += '<div class="_tab_panel" data-idx="' + j + '" style="display:' + (j === 0 ? 'block' : 'none') + '">';
1630
+ if (!isJSON) {
1631
+ h += '<div style="font-size:13px;color:' + colors.text + ';line-height:1.5">' + esc(String(c)).replace(/\\n/g, '<br>') + '</div>';
1632
+ } else {
1633
+ h += '<pre style="font-size:12px;background:' + colors.bgAlt + ';padding:12px;border-radius:6px;color:' + colors.text + ';overflow:auto;max-height:400px;margin:0">' + esc(JSON.stringify(c, null, 2)) + '</pre>';
1634
+ }
1635
+ h += '</div>';
1636
+ }
1637
+ h += '</div></div>';
1638
+ container.innerHTML = h;
1639
+
1640
+ var root = document.getElementById(navId);
1641
+ if (!root) return;
1642
+ var triggers = root.querySelectorAll('._tab_trigger');
1643
+ var panels = root.querySelectorAll('._tab_panel');
1644
+ var switchTab = function(idx) {
1645
+ for (var k = 0; k < triggers.length; k++) {
1646
+ var isActive = (k === idx);
1647
+ triggers[k].style.borderBottomColor = isActive ? colors.accent : 'transparent';
1648
+ triggers[k].style.color = isActive ? colors.accent : colors.textMuted;
1649
+ panels[k].style.display = isActive ? 'block' : 'none';
1650
+ }
1651
+ };
1652
+ for (var l = 0; l < triggers.length; l++) {
1653
+ triggers[l].onclick = function(e) {
1654
+ switchTab(parseInt(e.currentTarget.getAttribute('data-idx')));
1655
+ };
1656
+ }
1657
+ };
1658
+
1659
+ // ─── Tree ───
1660
+ renderers.tree = function(container, data) {
1661
+ if (!data) { container.innerHTML = ''; return; }
1662
+
1663
+ var uid = 0;
1664
+ function renderNode(node, label, depth) {
1665
+ if (node == null) return '';
1666
+ uid++;
1667
+ var isObj = typeof node === 'object';
1668
+ var isArr = Array.isArray(node);
1669
+ var isEmpty = isObj && Object.keys(node).length === 0;
1670
+ var h = '<div style="margin-left:' + (depth > 0 ? 16 : 0) + 'px;font-size:13px;font-family:inherit;line-height:1.8">';
1671
+ if (!isObj || isEmpty) {
1672
+ h += '<span style="color:' + colors.textMuted + '">';
1673
+ if (label !== null) h += esc(label) + ': ';
1674
+ h += '</span>';
1675
+ if (isEmpty) h += '<span style="color:' + colors.textMuted + ';font-style:italic">' + (isArr ? '[]' : '{}') + '</span>';
1676
+ else {
1677
+ var valColor = typeof node === 'number' ? '#ff9e64' : typeof node === 'string' ? '#a5d6ff' : typeof node === 'boolean' ? '#ff7b72' : colors.text;
1678
+ h += '<span style="color:' + valColor + '">' + formatValue(node) + '</span>';
1679
+ }
1680
+ } else {
1681
+ var _id = '_tree_' + uid;
1682
+ h += '<div style="display:flex;align-items:center;cursor:pointer;user-select:none" onclick="var e=document.getElementById(\\''+_id+'\\');var s=e.style.display===\\'none\\';e.style.display=s?\\'block\\':\\'none\\';this.children[0].style.transform=s?\\'rotate(90deg)\\':\\'rotate(0deg)\\';">';
1683
+ h += '<span style="display:inline-block;width:12px;text-align:center;font-size:10px;color:' + colors.textMuted + ';transform:rotate(90deg);transition:transform 0.1s;margin-right:4px">\\u25B6</span>';
1684
+ if (label !== null) h += '<span style="font-weight:600;color:' + colors.text + '">' + esc(label) + '</span>';
1685
+ h += '<span style="color:' + colors.textMuted + ';font-size:11px;margin-left:6px">' + (isArr ? '[' + node.length + ']' : '{...}') + '</span>';
1686
+ h += '</div>';
1687
+
1688
+ h += '<div id="' + _id + '">';
1689
+ if (isArr) {
1690
+ for (var i = 0; i < node.length; i++) h += renderNode(node[i], i, depth + 1);
1691
+ } else {
1692
+ for (var k in node) h += renderNode(node[k], k, depth + 1);
1693
+ }
1694
+ h += '</div>';
1695
+ }
1696
+ h += '</div>';
1697
+ return h;
1698
+ }
1699
+
1700
+ container.innerHTML = '<div style="background:' + colors.bgAlt + ';padding:12px;border-radius:8px;border:1px solid ' + colors.border + ';overflow:auto;max-height:500px">' + renderNode(data, null, 0) + '</div>';
1701
+ };
1702
+
1703
+ // ─── DataTable (Searchable + Paginated) ───
1704
+ renderers.datatable = function(container, data, opts) {
1705
+ opts = opts || {};
1706
+ var rows = Array.isArray(data) ? data : (data.rows || data.items || data.data || [data]);
1707
+ if (!rows.length) { renderers.table(container, rows, opts); return; }
1708
+
1709
+ var cols = Object.keys(rows[0]).filter(function(k) { return typeof rows[0][k] !== 'function'; });
1710
+ if (opts.columns) cols = opts.columns;
1711
+
1712
+ var sortCol = null, sortDir = 1;
1713
+ var query = '';
1714
+ var page = 0;
1715
+ var pageSize = opts.pageSize || 10;
1716
+
1717
+ var wrapperId = '_dt_' + Math.random().toString(36).slice(2, 8);
1718
+ var h = '<div id="' + wrapperId + '">';
1719
+ h += '<div style="display:flex;justify-content:space-between;margin-bottom:12px;align-items:center">';
1720
+ h += '<input type="search" placeholder="Search..." class="_dt_search" style="padding:6px 12px;border-radius:6px;border:1px solid ' + colors.border + ';background:' + colors.bgAlt + ';color:' + colors.text + ';font-size:13px;width:200px" />';
1721
+ h += '<div class="_dt_info" style="font-size:12px;color:' + colors.textMuted + '"></div>';
1722
+ h += '</div>';
1723
+ h += '<div style="overflow-x:auto;border:1px solid ' + colors.border + ';border-radius:8px">';
1724
+ h += '<table style="width:100%;border-collapse:collapse;font-size:13px;color:' + colors.text + '">';
1725
+ h += '<thead><tr style="background:' + colors.bgAlt + '">';
1726
+ for (var i = 0; i < cols.length; i++) {
1727
+ h += '<th data-col="' + esc(cols[i]) + '" style="cursor:pointer;text-align:left;padding:10px 12px;border-bottom:2px solid ' + colors.border + ';font-weight:600;white-space:nowrap;color:' + colors.textMuted + ';font-size:12px;user-select:none">';
1728
+ h += esc(formatLabel(cols[i])) + '<span class="_dt_sort" style="margin-left:4px;font-size:10px"></span></th>';
1729
+ }
1730
+ h += '</tr></thead><tbody class="_dt_body"></tbody></table></div>';
1731
+
1732
+ h += '<div style="display:flex;justify-content:flex-end;margin-top:12px;align-items:center;gap:12px">';
1733
+ h += '<button class="_dt_prev" style="padding:4px 10px;background:' + colors.bgAlt + ';border:1px solid ' + colors.border + ';border-radius:4px;color:' + colors.text + ';cursor:pointer;font-size:12px" disabled>&larr; Prev</button>';
1734
+ h += '<span class="_dt_pageStr" style="font-size:12px;color:' + colors.textMuted + '"></span>';
1735
+ h += '<button class="_dt_next" style="padding:4px 10px;background:' + colors.bgAlt + ';border:1px solid ' + colors.border + ';border-radius:4px;color:' + colors.text + ';cursor:pointer;font-size:12px">Next &rarr;</button>';
1736
+ h += '</div></div>';
1737
+ container.innerHTML = h;
1738
+
1739
+ var root = document.getElementById(wrapperId);
1740
+ var searchEl = root.querySelector('._dt_search');
1741
+ var bodyEl = root.querySelector('._dt_body');
1742
+ var infoEl = root.querySelector('._dt_info');
1743
+ var prevEl = root.querySelector('._dt_prev');
1744
+ var nextEl = root.querySelector('._dt_next');
1745
+ var pageStrEl = root.querySelector('._dt_pageStr');
1746
+ var ths = root.querySelectorAll('thead th');
1747
+
1748
+ function renderView() {
1749
+ var filtered = rows;
1750
+ if (query) {
1751
+ var q = query.toLowerCase();
1752
+ filtered = rows.filter(function(r) {
1753
+ for (var c=0; c<cols.length; c++) {
1754
+ var v = r[cols[c]];
1755
+ if (v != null && String(v).toLowerCase().indexOf(q) !== -1) return true;
1756
+ }
1757
+ return false;
1758
+ });
1759
+ }
1760
+ if (sortCol) {
1761
+ filtered.sort(function(a,b) {
1762
+ var va = a[sortCol], vb = b[sortCol];
1763
+ if (typeof va === 'number' && typeof vb === 'number') return (va - vb) * sortDir;
1764
+ return String(va || '').localeCompare(String(vb || '')) * sortDir;
1765
+ });
1766
+ }
1767
+
1768
+ var totalPages = Math.ceil(filtered.length / pageSize) || 1;
1769
+ if (page >= totalPages) page = totalPages - 1;
1770
+ if (page < 0) page = 0;
1771
+ var start = page * pageSize;
1772
+ var viewRows = filtered.slice(start, start + pageSize);
1773
+
1774
+ var bh = '';
1775
+ for (var r=0; r<viewRows.length; r++) {
1776
+ bh += '<tr style="border-bottom:1px solid ' + colors.border + ';background:' + (r%2===0 ? colors.bg : 'rgba(0,0,0,0.02)') + '">';
1777
+ for(var c=0; c<cols.length; c++) {
1778
+ bh += '<td style="padding:8px 12px">' + formatValue(viewRows[r][cols[c]]) + '</td>';
1779
+ }
1780
+ bh += '</tr>';
1781
+ }
1782
+ if (!viewRows.length) bh = '<tr><td colspan="' + cols.length + '" style="padding:20px;text-align:center;color:' + colors.textMuted + '">No matching records found.</td></tr>';
1783
+ bodyEl.innerHTML = bh;
1784
+
1785
+ infoEl.textContent = filtered.length + ' entries';
1786
+ pageStrEl.textContent = 'Page ' + (page+1) + ' of ' + totalPages;
1787
+ prevEl.disabled = page === 0;
1788
+ nextEl.disabled = page >= totalPages - 1;
1789
+ prevEl.style.opacity = prevEl.disabled ? '0.5' : '1';
1790
+ nextEl.style.opacity = nextEl.disabled ? '0.5' : '1';
1791
+
1792
+ for (var l=0; l<ths.length; l++) {
1793
+ var arrow = ths[l].getAttribute('data-col') === sortCol ? (sortDir===1 ? '\\u25B2' : '\\u25BC') : '';
1794
+ ths[l].querySelector('._dt_sort').textContent = arrow;
1795
+ }
1796
+ }
1797
+
1798
+ searchEl.oninput = function(e) { query = e.target.value; page = 0; renderView(); };
1799
+ prevEl.onclick = function() { if (page > 0) { page--; renderView(); } };
1800
+ nextEl.onclick = function() { page++; renderView(); };
1801
+ for (var lh=0; lh<ths.length; lh++) {
1802
+ ths[lh].onclick = function(e) {
1803
+ var col = e.currentTarget.getAttribute('data-col');
1804
+ if (sortCol === col) sortDir *= -1; else { sortCol = col; sortDir = 1; }
1805
+ renderView();
1806
+ }
1807
+ }
1808
+
1809
+ renderView();
1810
+ };
1811
+
1435
1812
  // ── Public API ──
1436
1813
 
1437
1814
  window._photonRenderers = {
@@ -1439,6 +1816,8 @@ export function generateRenderersScript() {
1439
1816
  if (!container) return;
1440
1817
  // Refresh colors from CSS vars on every render so theme changes are reflected
1441
1818
  colors = getColors();
1819
+ VARIANT_COLORS.info = colors.accent;
1820
+ VARIANT_COLORS.neutral = colors.textMuted;
1442
1821
  format = format || 'json';
1443
1822
  var key = format.toLowerCase();
1444
1823
  // Try exact match, then prefix match (chart:bar → chart)
@@ -1450,4 +1829,256 @@ export function generateRenderersScript() {
1450
1829
  };
1451
1830
  })();`;
1452
1831
  }
1832
+ export const FORMAT_CATALOG = {
1833
+ // ── Data Display ──
1834
+ table: {
1835
+ data: 'Array<object>',
1836
+ example: [
1837
+ { name: 'Alice', role: 'Eng' },
1838
+ { name: 'Bob', role: 'PM' },
1839
+ ],
1840
+ },
1841
+ list: {
1842
+ data: 'Array<{ name, subtitle?, status?, badge? }>',
1843
+ example: [{ name: 'Task 1', subtitle: 'In progress', status: 'active' }],
1844
+ },
1845
+ card: {
1846
+ data: '{ key: value, ... }',
1847
+ example: { name: 'Server-1', status: 'healthy', uptime: '99.9%' },
1848
+ },
1849
+ kv: { data: '{ key: value, ... }', example: { host: 'prod-01', region: 'us-east', cpu: '42%' } },
1850
+ json: { data: 'any', example: { debug: true, nested: { key: 'value' } } },
1851
+ text: { data: 'string', example: 'Hello world' },
1852
+ markdown: { data: 'string (markdown)', example: '# Title\n\nSome **bold** text' },
1853
+ code: {
1854
+ data: 'string | { code, language? }',
1855
+ example: { code: 'console.log("hi")', language: 'javascript' },
1856
+ },
1857
+ metric: {
1858
+ data: '{ value, trend?, period?, label? }',
1859
+ example: { value: '$142K', trend: '+12%', period: 'this month' },
1860
+ },
1861
+ gauge: {
1862
+ data: '{ value, max?, min?, label?, unit? }',
1863
+ example: { value: 73, max: 100, label: 'CPU', unit: '%' },
1864
+ },
1865
+ progress: {
1866
+ data: '{ value, max?, label? } (value 0-1 or 0-100)',
1867
+ example: { value: 0.65, label: 'Upload' },
1868
+ },
1869
+ badge: { data: 'string', example: 'active' },
1870
+ chips: { data: 'Array<string>', example: ['React', 'TypeScript', 'Node.js'] },
1871
+ // ── Charts ──
1872
+ 'chart:bar': {
1873
+ data: 'Array<{ label, value }>',
1874
+ example: [
1875
+ { month: 'Jan', revenue: 42000 },
1876
+ { month: 'Feb', revenue: 48000 },
1877
+ ],
1878
+ },
1879
+ 'chart:hbar': {
1880
+ data: 'Array<{ label, value }>',
1881
+ example: [
1882
+ { lang: 'TypeScript', stars: 95000 },
1883
+ { lang: 'Rust', stars: 87000 },
1884
+ ],
1885
+ },
1886
+ 'chart:line': {
1887
+ data: 'Array<{ x, y }>',
1888
+ example: [
1889
+ { date: 'Mon', requests: 1200 },
1890
+ { date: 'Tue', requests: 1500 },
1891
+ ],
1892
+ },
1893
+ 'chart:pie': {
1894
+ data: 'Array<{ label, value }>',
1895
+ example: [
1896
+ { source: 'Organic', users: 4500 },
1897
+ { source: 'Paid', users: 2100 },
1898
+ ],
1899
+ },
1900
+ 'chart:area': {
1901
+ data: 'Array<{ x, y }>',
1902
+ example: [
1903
+ { time: '9am', load: 0.4 },
1904
+ { time: '12pm', load: 0.8 },
1905
+ ],
1906
+ },
1907
+ 'chart:donut': {
1908
+ data: 'Array<{ label, value }>',
1909
+ example: [
1910
+ { status: 'Pass', count: 42 },
1911
+ { status: 'Fail', count: 3 },
1912
+ ],
1913
+ },
1914
+ 'chart:radar': {
1915
+ data: 'Array<{ axis, value }>',
1916
+ example: [
1917
+ { skill: 'Frontend', level: 8 },
1918
+ { skill: 'Backend', level: 9 },
1919
+ ],
1920
+ },
1921
+ sparkline: { data: 'Array<number>', example: [10, 25, 18, 30, 22, 35, 28] },
1922
+ ring: { data: '{ value, max?, label? }', example: { value: 75, max: 100, label: 'Progress' } },
1923
+ // ── Composite Layouts ──
1924
+ tabs: {
1925
+ data: 'Array<{ title, content }> | { tabName: content }',
1926
+ example: [
1927
+ { title: 'Overview', content: 'Main info here' },
1928
+ { title: 'Details', content: 'Extra details' },
1929
+ ],
1930
+ },
1931
+ accordion: {
1932
+ data: 'Array<{ title, content }>',
1933
+ example: [
1934
+ { title: 'FAQ 1', content: 'Answer 1' },
1935
+ { title: 'FAQ 2', content: 'Answer 2' },
1936
+ ],
1937
+ },
1938
+ // ── Timeline & Steps ──
1939
+ timeline: {
1940
+ data: 'Array<{ time, event, details? }>',
1941
+ example: [
1942
+ { time: '10:00', event: 'Deploy started' },
1943
+ { time: '10:05', event: 'Tests passed' },
1944
+ ],
1945
+ },
1946
+ steps: {
1947
+ data: 'Array<{ label, status? }>',
1948
+ example: [
1949
+ { label: 'Build', status: 'complete' },
1950
+ { label: 'Test', status: 'active' },
1951
+ { label: 'Deploy', status: 'pending' },
1952
+ ],
1953
+ },
1954
+ checklist: {
1955
+ data: 'Array<{ name|title, done|completed|checked }>',
1956
+ example: [
1957
+ { name: 'Write tests', done: true },
1958
+ { name: 'Deploy', done: false },
1959
+ ],
1960
+ },
1961
+ // ── Cards & Content ──
1962
+ 'stat-group': {
1963
+ data: 'Array<{ label, value, change? }>',
1964
+ example: [
1965
+ { label: 'Revenue', value: '$42K', change: '+12%' },
1966
+ { label: 'Users', value: '1.2K' },
1967
+ ],
1968
+ },
1969
+ 'feature-grid': {
1970
+ data: 'Array<{ icon, title, description }>',
1971
+ example: [{ icon: '🚀', title: 'Fast', description: 'Sub-ms response times' }],
1972
+ },
1973
+ profile: {
1974
+ data: '{ name, avatar?, role?, bio?, stats? }',
1975
+ example: { name: 'Jane', role: 'Engineer', bio: 'Full-stack dev', stats: { commits: 847 } },
1976
+ },
1977
+ quote: {
1978
+ data: '{ text, author?, source? }',
1979
+ example: { text: 'Ship it.', author: 'Reid Hoffman' },
1980
+ },
1981
+ hero: {
1982
+ data: '{ title, subtitle?, image?, cta? }',
1983
+ example: { title: 'Welcome', subtitle: 'Get started in seconds' },
1984
+ },
1985
+ banner: {
1986
+ data: '{ title, description?, variant? }',
1987
+ example: { title: 'New release', description: 'v2.0 is here', variant: 'info' },
1988
+ },
1989
+ alert: {
1990
+ data: '{ title?, description, variant?, icon? }',
1991
+ example: { description: 'Deployment complete', variant: 'success' },
1992
+ },
1993
+ // ── Media ──
1994
+ image: {
1995
+ data: '{ url, alt?, caption? } | string (url)',
1996
+ example: { url: 'https://example.com/photo.jpg', alt: 'Screenshot' },
1997
+ },
1998
+ carousel: {
1999
+ data: 'Array<{ url, caption? }>',
2000
+ example: [{ url: 'https://example.com/1.jpg' }, { url: 'https://example.com/2.jpg' }],
2001
+ },
2002
+ gallery: {
2003
+ data: 'Array<{ url, caption? }>',
2004
+ example: [{ url: 'https://example.com/1.jpg', caption: 'Photo 1' }],
2005
+ },
2006
+ qr: { data: 'string (url or text)', example: 'https://example.com' },
2007
+ embed: { data: '{ url, type? }', example: { url: 'https://youtube.com/embed/xxx' } },
2008
+ // ── Structured ──
2009
+ invoice: {
2010
+ data: '{ items: Array<{ name, qty, price }>, total?, tax? }',
2011
+ example: { items: [{ name: 'Widget', qty: 2, price: 9.99 }], total: 19.98 },
2012
+ },
2013
+ comparison: {
2014
+ data: 'Array<{ name, ...features }>',
2015
+ example: [
2016
+ { name: 'Plan A', price: '$10', storage: '10GB' },
2017
+ { name: 'Plan B', price: '$20', storage: '50GB' },
2018
+ ],
2019
+ },
2020
+ diff: {
2021
+ data: '{ before, after } | string (unified diff)',
2022
+ example: { before: 'old text', after: 'new text' },
2023
+ },
2024
+ log: {
2025
+ data: 'Array<{ timestamp?, level?, message }>',
2026
+ example: [{ timestamp: '10:00:01', level: 'info', message: 'Started' }],
2027
+ },
2028
+ kanban: {
2029
+ data: '{ columns: Array<{ title, items: Array<{ title, description? }> }> }',
2030
+ example: {
2031
+ columns: [
2032
+ { title: 'Todo', items: [{ title: 'Task 1' }] },
2033
+ { title: 'Done', items: [] },
2034
+ ],
2035
+ },
2036
+ },
2037
+ heatmap: {
2038
+ data: 'Array<Array<number>> | { rows, cols, values }',
2039
+ example: [
2040
+ [1, 2, 3],
2041
+ [4, 5, 6],
2042
+ [7, 8, 9],
2043
+ ],
2044
+ },
2045
+ calendar: {
2046
+ data: 'Array<{ date, title, color? }>',
2047
+ example: [
2048
+ { date: '2026-04-10', title: 'Launch' },
2049
+ { date: '2026-04-15', title: 'Review' },
2050
+ ],
2051
+ },
2052
+ network: {
2053
+ data: '{ nodes: Array<{ id, label? }>, edges: Array<{ from, to }> }',
2054
+ example: {
2055
+ nodes: [
2056
+ { id: 'a', label: 'API' },
2057
+ { id: 'b', label: 'DB' },
2058
+ ],
2059
+ edges: [{ from: 'a', to: 'b' }],
2060
+ },
2061
+ },
2062
+ tree: {
2063
+ data: 'object (nested) | Array',
2064
+ example: { src: { components: { 'App.tsx': null }, utils: { 'helper.ts': null } } },
2065
+ },
2066
+ datatable: {
2067
+ data: 'Array<object> (with search/sort/pagination)',
2068
+ example: [
2069
+ { id: 1, name: 'Item A', price: 10 },
2070
+ { id: 2, name: 'Item B', price: 20 },
2071
+ ],
2072
+ },
2073
+ feed: {
2074
+ data: 'Array<{ user, action, target?, timestamp? }>',
2075
+ example: [{ user: 'Alice', action: 'deployed', target: 'prod', timestamp: '2m ago' }],
2076
+ },
2077
+ 'empty-state': {
2078
+ data: '{ title?, description?, icon? }',
2079
+ example: { title: 'No results', description: 'Try a different query', icon: '🔍' },
2080
+ },
2081
+ };
2082
+ /** Flat list of supported format names */
2083
+ export const SUPPORTED_FORMATS = Object.keys(FORMAT_CATALOG);
1453
2084
  //# sourceMappingURL=renderers.js.map