@portel/photon 1.20.1 → 1.22.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 (148) hide show
  1. package/README.md +5 -5
  2. package/dist/ag-ui/adapter.d.ts +4 -1
  3. package/dist/ag-ui/adapter.d.ts.map +1 -1
  4. package/dist/ag-ui/adapter.js +58 -3
  5. package/dist/ag-ui/adapter.js.map +1 -1
  6. package/dist/ag-ui/types.d.ts +12 -0
  7. package/dist/ag-ui/types.d.ts.map +1 -1
  8. package/dist/auto-ui/beam/routes/api-browse.d.ts.map +1 -1
  9. package/dist/auto-ui/beam/routes/api-browse.js +8 -49
  10. package/dist/auto-ui/beam/routes/api-browse.js.map +1 -1
  11. package/dist/auto-ui/beam/routes/api-config.d.ts +1 -1
  12. package/dist/auto-ui/beam/routes/api-config.d.ts.map +1 -1
  13. package/dist/auto-ui/beam/routes/api-config.js +79 -1
  14. package/dist/auto-ui/beam/routes/api-config.js.map +1 -1
  15. package/dist/auto-ui/beam.d.ts.map +1 -1
  16. package/dist/auto-ui/beam.js +23 -31
  17. package/dist/auto-ui/beam.js.map +1 -1
  18. package/dist/auto-ui/bridge/index.d.ts.map +1 -1
  19. package/dist/auto-ui/bridge/index.js +107 -11
  20. package/dist/auto-ui/bridge/index.js.map +1 -1
  21. package/dist/auto-ui/bridge/renderers.d.ts +14 -0
  22. package/dist/auto-ui/bridge/renderers.d.ts.map +1 -1
  23. package/dist/auto-ui/bridge/renderers.js +680 -57
  24. package/dist/auto-ui/bridge/renderers.js.map +1 -1
  25. package/dist/auto-ui/frontend/index.html +3 -3
  26. package/dist/auto-ui/frontend/pure-view.html +19 -19
  27. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  28. package/dist/auto-ui/streamable-http-transport.js +53 -2
  29. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  30. package/dist/auto-ui/ui-resolver.d.ts +25 -0
  31. package/dist/auto-ui/ui-resolver.d.ts.map +1 -0
  32. package/dist/auto-ui/ui-resolver.js +95 -0
  33. package/dist/auto-ui/ui-resolver.js.map +1 -0
  34. package/dist/beam-form.bundle.js +7 -7
  35. package/dist/beam-form.bundle.js.map +1 -1
  36. package/dist/beam.bundle.js +905 -185
  37. package/dist/beam.bundle.js.map +4 -4
  38. package/dist/cli/commands/build.d.ts.map +1 -1
  39. package/dist/cli/commands/build.js +9 -5
  40. package/dist/cli/commands/build.js.map +1 -1
  41. package/dist/cli/commands/init.d.ts.map +1 -1
  42. package/dist/cli/commands/init.js +93 -53
  43. package/dist/cli/commands/init.js.map +1 -1
  44. package/dist/cli/commands/publish.d.ts +14 -0
  45. package/dist/cli/commands/publish.d.ts.map +1 -0
  46. package/dist/cli/commands/publish.js +126 -0
  47. package/dist/cli/commands/publish.js.map +1 -0
  48. package/dist/cli/commands/run.d.ts.map +1 -1
  49. package/dist/cli/commands/run.js +2 -0
  50. package/dist/cli/commands/run.js.map +1 -1
  51. package/dist/cli/index.d.ts.map +1 -1
  52. package/dist/cli/index.js +3 -0
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/cli.d.ts +4 -0
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +11 -1
  57. package/dist/cli.js.map +1 -1
  58. package/dist/context.d.ts +6 -0
  59. package/dist/context.d.ts.map +1 -1
  60. package/dist/context.js +17 -5
  61. package/dist/context.js.map +1 -1
  62. package/dist/daemon/client.d.ts +9 -1
  63. package/dist/daemon/client.d.ts.map +1 -1
  64. package/dist/daemon/client.js +54 -1
  65. package/dist/daemon/client.js.map +1 -1
  66. package/dist/daemon/manager.d.ts +3 -0
  67. package/dist/daemon/manager.d.ts.map +1 -1
  68. package/dist/daemon/manager.js +88 -38
  69. package/dist/daemon/manager.js.map +1 -1
  70. package/dist/daemon/ownership.d.ts +12 -0
  71. package/dist/daemon/ownership.d.ts.map +1 -0
  72. package/dist/daemon/ownership.js +55 -0
  73. package/dist/daemon/ownership.js.map +1 -0
  74. package/dist/daemon/protocol.d.ts +4 -2
  75. package/dist/daemon/protocol.d.ts.map +1 -1
  76. package/dist/daemon/protocol.js +15 -2
  77. package/dist/daemon/protocol.js.map +1 -1
  78. package/dist/daemon/server.js +557 -83
  79. package/dist/daemon/server.js.map +1 -1
  80. package/dist/daemon/session-manager.d.ts +9 -1
  81. package/dist/daemon/session-manager.d.ts.map +1 -1
  82. package/dist/daemon/session-manager.js +54 -1
  83. package/dist/daemon/session-manager.js.map +1 -1
  84. package/dist/daemon/worker-manager.d.ts +12 -0
  85. package/dist/daemon/worker-manager.d.ts.map +1 -1
  86. package/dist/daemon/worker-manager.js +89 -6
  87. package/dist/daemon/worker-manager.js.map +1 -1
  88. package/dist/loader.d.ts +17 -9
  89. package/dist/loader.d.ts.map +1 -1
  90. package/dist/loader.js +415 -141
  91. package/dist/loader.js.map +1 -1
  92. package/dist/photon-cli-runner.d.ts.map +1 -1
  93. package/dist/photon-cli-runner.js +26 -2
  94. package/dist/photon-cli-runner.js.map +1 -1
  95. package/dist/photons/canvas/ui/canvas.photon.html +1493 -0
  96. package/dist/photons/canvas.photon.d.ts +400 -0
  97. package/dist/photons/canvas.photon.d.ts.map +1 -0
  98. package/dist/photons/canvas.photon.js +662 -0
  99. package/dist/photons/canvas.photon.js.map +1 -0
  100. package/dist/photons/canvas.photon.ts +814 -0
  101. package/dist/photons/publish.photon.d.ts +97 -0
  102. package/dist/photons/publish.photon.d.ts.map +1 -0
  103. package/dist/photons/publish.photon.js +569 -0
  104. package/dist/photons/publish.photon.js.map +1 -0
  105. package/dist/photons/publish.photon.ts +683 -0
  106. package/dist/photons/ui/canvas.photon.html +624 -0
  107. package/dist/resource-server.d.ts.map +1 -1
  108. package/dist/resource-server.js +7 -1
  109. package/dist/resource-server.js.map +1 -1
  110. package/dist/server.d.ts +7 -0
  111. package/dist/server.d.ts.map +1 -1
  112. package/dist/server.js +67 -37
  113. package/dist/server.js.map +1 -1
  114. package/dist/shared/error-handler.d.ts +1 -0
  115. package/dist/shared/error-handler.d.ts.map +1 -1
  116. package/dist/shared/error-handler.js +68 -10
  117. package/dist/shared/error-handler.js.map +1 -1
  118. package/dist/shared/logger.d.ts.map +1 -1
  119. package/dist/shared/logger.js +34 -0
  120. package/dist/shared/logger.js.map +1 -1
  121. package/dist/shared-utils.d.ts.map +1 -1
  122. package/dist/shared-utils.js +2 -2
  123. package/dist/shared-utils.js.map +1 -1
  124. package/dist/telemetry/context.d.ts +24 -0
  125. package/dist/telemetry/context.d.ts.map +1 -0
  126. package/dist/telemetry/context.js +17 -0
  127. package/dist/telemetry/context.js.map +1 -0
  128. package/dist/telemetry/logs.d.ts +38 -0
  129. package/dist/telemetry/logs.d.ts.map +1 -0
  130. package/dist/telemetry/logs.js +108 -0
  131. package/dist/telemetry/logs.js.map +1 -0
  132. package/dist/telemetry/metrics.d.ts +71 -0
  133. package/dist/telemetry/metrics.d.ts.map +1 -0
  134. package/dist/telemetry/metrics.js +184 -0
  135. package/dist/telemetry/metrics.js.map +1 -0
  136. package/dist/telemetry/otel.d.ts +20 -1
  137. package/dist/telemetry/otel.d.ts.map +1 -1
  138. package/dist/telemetry/otel.js +79 -2
  139. package/dist/telemetry/otel.js.map +1 -1
  140. package/dist/telemetry/sdk.d.ts +49 -0
  141. package/dist/telemetry/sdk.d.ts.map +1 -0
  142. package/dist/telemetry/sdk.js +110 -0
  143. package/dist/telemetry/sdk.js.map +1 -0
  144. package/dist/tsx-compiler.d.ts +23 -0
  145. package/dist/tsx-compiler.d.ts.map +1 -0
  146. package/dist/tsx-compiler.js +221 -0
  147. package/dist/tsx-compiler.js.map +1 -0
  148. 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;');
@@ -277,7 +309,7 @@ export function generateRenderersScript() {
277
309
  };
278
310
 
279
311
  // ─── Chart (lazy-loads Chart.js) ───
280
- 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) {
281
313
  opts = opts || {};
282
314
  var items = Array.isArray(data) ? data : (data.data || data.items || data.rows || [data]);
283
315
  if (!items.length || typeof items[0] !== 'object') { container.innerHTML = '<p style="color:' + colors.textMuted + '">No chart data</p>'; return; }
@@ -450,18 +482,7 @@ export function generateRenderersScript() {
450
482
  }
451
483
 
452
484
  // ─── QR code ───
453
- var _qrLoading = false, _qrLoaded = false, _qrQueue = [];
454
- function _loadQRJS(cb) {
455
- if (_qrLoaded) { cb(); return; }
456
- _qrQueue.push(cb);
457
- if (_qrLoading) return;
458
- _qrLoading = true;
459
- var s = document.createElement('script');
460
- s.src = 'https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js';
461
- s.onload = function() { _qrLoaded = true; _qrQueue.forEach(function(fn) { fn(); }); _qrQueue = []; };
462
- s.onerror = function() { _qrQueue.forEach(function(fn) { fn(); }); _qrQueue = []; };
463
- document.head.appendChild(s);
464
- }
485
+ var _loadQRJS = _makeLoader('https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js');
465
486
 
466
487
  renderers.qr = function(container, data) {
467
488
  var text = typeof data === 'object' && data !== null
@@ -482,18 +503,7 @@ export function generateRenderersScript() {
482
503
  });
483
504
  };
484
505
 
485
- var _chartLoading = false, _chartLoaded = false, _chartQueue = [];
486
- function _loadChartJS(cb) {
487
- if (_chartLoaded) { cb(); return; }
488
- _chartQueue.push(cb);
489
- if (_chartLoading) return;
490
- _chartLoading = true;
491
- var s = document.createElement('script');
492
- s.src = 'https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js';
493
- s.onload = function() { _chartLoaded = true; _chartQueue.forEach(function(fn) { fn(); }); _chartQueue = []; };
494
- s.onerror = function() { _chartQueue.forEach(function(fn) { fn(); }); _chartQueue = []; };
495
- document.head.appendChild(s);
496
- }
506
+ var _loadChartJS = _makeLoader('https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js');
497
507
 
498
508
  // ─── Steps/Stepper ───
499
509
  renderers.steps = renderers.stepper = function(container, data) {
@@ -630,8 +640,7 @@ export function generateRenderersScript() {
630
640
  var message = d.message || d.text || d.title || '';
631
641
  var type = (d.type || d.variant || d.severity || 'info').toLowerCase();
632
642
  var icon = d.icon || '';
633
- var bannerColors = { success: '#34d399', error: '#f87171', warning: '#fbbf24', info: colors.accent };
634
- var bc = bannerColors[type] || colors.accent;
643
+ var bc = VARIANT_COLORS[type] || VARIANT_COLORS.info;
635
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 + '">';
636
645
  if (icon) h += '<span style="font-size:18px;flex-shrink:0">' + esc(icon) + '</span>';
637
646
  h += '<span style="font-size:13px;color:' + colors.text + '">' + esc(message) + '</span>';
@@ -1054,24 +1063,10 @@ export function generateRenderersScript() {
1054
1063
  };
1055
1064
 
1056
1065
  // ─── Map (Leaflet) ───
1057
- var _leafletLoading = false, _leafletLoaded = false, _leafletQueue = [];
1058
- function _loadLeaflet(cb) {
1059
- if (_leafletLoaded) { cb(); return; }
1060
- _leafletQueue.push(cb);
1061
- if (_leafletLoading) return;
1062
- _leafletLoading = true;
1063
- // Load CSS
1064
- var link = document.createElement('link');
1065
- link.rel = 'stylesheet';
1066
- link.href = 'https://cdn.jsdelivr.net/npm/leaflet@1.9/dist/leaflet.min.css';
1067
- document.head.appendChild(link);
1068
- // Load JS
1069
- var s = document.createElement('script');
1070
- s.src = 'https://cdn.jsdelivr.net/npm/leaflet@1.9/dist/leaflet.min.js';
1071
- s.onload = function() { _leafletLoaded = true; _leafletQueue.forEach(function(fn) { fn(); }); _leafletQueue = []; };
1072
- s.onerror = function() { _leafletQueue.forEach(function(fn) { fn(); }); _leafletQueue = []; };
1073
- document.head.appendChild(s);
1074
- }
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
+ );
1075
1070
 
1076
1071
  renderers.map = function(container, data) {
1077
1072
  var items = Array.isArray(data) ? data : [data];
@@ -1197,18 +1192,7 @@ export function generateRenderersScript() {
1197
1192
  };
1198
1193
 
1199
1194
  // ─── Network/Graph (force-directed via vis-network) ───
1200
- var _visLoading = false, _visLoaded = false, _visQueue = [];
1201
- function _loadVisNetwork(cb) {
1202
- if (_visLoaded) { cb(); return; }
1203
- _visQueue.push(cb);
1204
- if (_visLoading) return;
1205
- _visLoading = true;
1206
- var s = document.createElement('script');
1207
- s.src = 'https://cdn.jsdelivr.net/npm/vis-network@9/standalone/umd/vis-network.min.js';
1208
- s.onload = function() { _visLoaded = true; _visQueue.forEach(function(fn) { fn(); }); _visQueue = []; };
1209
- s.onerror = function() { _visQueue.forEach(function(fn) { fn(); }); _visQueue = []; };
1210
- document.head.appendChild(s);
1211
- }
1195
+ var _loadVisNetwork = _makeLoader('https://cdn.jsdelivr.net/npm/vis-network@9/standalone/umd/vis-network.min.js');
1212
1196
 
1213
1197
  renderers.network = renderers.graph = function(container, data) {
1214
1198
  var nodes = data.nodes || [];
@@ -1440,6 +1424,391 @@ export function generateRenderersScript() {
1440
1424
  render();
1441
1425
  };
1442
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
+
1443
1812
  // ── Public API ──
1444
1813
 
1445
1814
  window._photonRenderers = {
@@ -1447,6 +1816,8 @@ export function generateRenderersScript() {
1447
1816
  if (!container) return;
1448
1817
  // Refresh colors from CSS vars on every render so theme changes are reflected
1449
1818
  colors = getColors();
1819
+ VARIANT_COLORS.info = colors.accent;
1820
+ VARIANT_COLORS.neutral = colors.textMuted;
1450
1821
  format = format || 'json';
1451
1822
  var key = format.toLowerCase();
1452
1823
  // Try exact match, then prefix match (chart:bar → chart)
@@ -1458,4 +1829,256 @@ export function generateRenderersScript() {
1458
1829
  };
1459
1830
  })();`;
1460
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);
1461
2084
  //# sourceMappingURL=renderers.js.map