@seed-ship/mcp-ui-solid 2.1.3 → 2.2.3

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 (62) hide show
  1. package/dist/components/ChartJSRenderer.cjs +79 -36
  2. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  3. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  4. package/dist/components/ChartJSRenderer.js +80 -37
  5. package/dist/components/ChartJSRenderer.js.map +1 -1
  6. package/dist/components/CodeBlockRenderer.cjs +79 -56
  7. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  8. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  9. package/dist/components/CodeBlockRenderer.js +80 -57
  10. package/dist/components/CodeBlockRenderer.js.map +1 -1
  11. package/dist/components/ExpandableWrapper.cjs +136 -0
  12. package/dist/components/ExpandableWrapper.cjs.map +1 -0
  13. package/dist/components/ExpandableWrapper.d.ts +31 -0
  14. package/dist/components/ExpandableWrapper.d.ts.map +1 -0
  15. package/dist/components/ExpandableWrapper.js +136 -0
  16. package/dist/components/ExpandableWrapper.js.map +1 -0
  17. package/dist/components/UIResourceRenderer.cjs +369 -242
  18. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  19. package/dist/components/UIResourceRenderer.d.ts +4 -0
  20. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  21. package/dist/components/UIResourceRenderer.js +370 -243
  22. package/dist/components/UIResourceRenderer.js.map +1 -1
  23. package/dist/index.cjs +3 -0
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +2 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +3 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/node_modules/.pnpm/{dompurify@3.3.0 → dompurify@3.3.3}/node_modules/dompurify/dist/purify.es.cjs +19 -4
  31. package/dist/node_modules/.pnpm/dompurify@3.3.3/node_modules/dompurify/dist/purify.es.cjs.map +1 -0
  32. package/dist/node_modules/.pnpm/{dompurify@3.3.0 → dompurify@3.3.3}/node_modules/dompurify/dist/purify.es.js +19 -4
  33. package/dist/node_modules/.pnpm/dompurify@3.3.3/node_modules/dompurify/dist/purify.es.js.map +1 -0
  34. package/dist/services/component-registry.cjs.map +1 -1
  35. package/dist/services/component-registry.d.ts +1 -0
  36. package/dist/services/component-registry.d.ts.map +1 -1
  37. package/dist/services/component-registry.js.map +1 -1
  38. package/dist/services/validation.cjs +29 -5
  39. package/dist/services/validation.cjs.map +1 -1
  40. package/dist/services/validation.d.ts.map +1 -1
  41. package/dist/services/validation.js +29 -5
  42. package/dist/services/validation.js.map +1 -1
  43. package/dist/types/index.d.ts +17 -0
  44. package/dist/types/index.d.ts.map +1 -1
  45. package/dist/types.d.cts +17 -0
  46. package/dist/types.d.ts +17 -0
  47. package/package.json +3 -3
  48. package/src/components/ChartJSRenderer.tsx +71 -42
  49. package/src/components/CodeBlockRenderer.tsx +33 -14
  50. package/src/components/ExpandableWrapper.test.tsx +229 -0
  51. package/src/components/ExpandableWrapper.tsx +201 -0
  52. package/src/components/UIResourceRenderer.tsx +165 -62
  53. package/src/components/renderCellValue.test.ts +122 -0
  54. package/src/index.ts +2 -0
  55. package/src/services/component-registry.test.ts +81 -0
  56. package/src/services/component-registry.ts +3 -2
  57. package/src/services/validation.test.ts +134 -0
  58. package/src/services/validation.ts +21 -5
  59. package/src/types/index.ts +17 -0
  60. package/tsconfig.tsbuildinfo +1 -1
  61. package/dist/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.cjs.map +0 -1
  62. package/dist/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.js.map +0 -1
@@ -24,7 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
25
  const web = require("solid-js/web");
26
26
  const solidJs = require("solid-js");
27
- var _tmpl$ = /* @__PURE__ */ web.template(`<h3 class="text-sm font-semibold text-gray-900 dark:text-white mb-3">`), _tmpl$2 = /* @__PURE__ */ web.template(`<div class="absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80"><div class="flex flex-col items-center gap-2"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div><span class="text-sm text-gray-500 dark:text-gray-400">Loading chart...`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800"><div class=text-center><div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3"><svg class="w-6 h-6 text-red-600 dark:text-red-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4"><!$><!/><!$><!/><!$><!/><div class="w-full h-[250px]"><canvas>`);
27
+ const ExpandableWrapper = require("./ExpandableWrapper.cjs");
28
+ var _tmpl$ = /* @__PURE__ */ web.template(`<h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button class="opacity-0 group-hover:opacity-60 hover:!opacity-100 px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm"title="Download PNG"aria-label="Download chart as PNG"><svg class="w-3 h-3 text-gray-500 dark:text-gray-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="flex items-center justify-between mb-3"><!$><!/><!$><!/>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80"><div class="flex flex-col items-center gap-2"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div><span class="text-sm text-gray-500 dark:text-gray-400">Loading chart...`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class="absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800"><div class=text-center><div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3"><svg class="w-6 h-6 text-red-600 dark:text-red-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs">`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class="relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4 group"><!$><!/><!$><!/><!$><!/><div class=w-full><canvas>`);
28
29
  let ChartJS = null;
29
30
  let chartJSLoadPromise = null;
30
31
  const loadChartJS = async () => {
@@ -54,6 +55,14 @@ const ChartJSRenderer = (props) => {
54
55
  let canvasRef;
55
56
  let chartInstance;
56
57
  const params = () => props.component.params;
58
+ const handleExportPNG = () => {
59
+ if (!canvasRef) return;
60
+ const url = canvasRef.toDataURL("image/png");
61
+ const a = document.createElement("a");
62
+ a.href = url;
63
+ a.download = `${(params().title || "chart").replace(/\s+/g, "-").toLowerCase()}.png`;
64
+ a.click();
65
+ };
57
66
  solidJs.createEffect(async () => {
58
67
  var _a, _b, _c, _d;
59
68
  if (!canvasRef) return;
@@ -97,42 +106,76 @@ const ChartJSRenderer = (props) => {
97
106
  chartInstance = null;
98
107
  }
99
108
  });
100
- return (() => {
101
- var _el$ = web.getNextElement(_tmpl$4), _el$1 = _el$.firstChild, [_el$10, _co$] = web.getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$2] = web.getNextMarker(_el$11.nextSibling), _el$13 = _el$12.nextSibling, [_el$14, _co$3] = web.getNextMarker(_el$13.nextSibling), _el$9 = _el$14.nextSibling, _el$0 = _el$9.firstChild;
102
- web.insert(_el$, web.createComponent(solidJs.Show, {
103
- get when() {
104
- return params().title;
105
- },
106
- get children() {
107
- var _el$2 = web.getNextElement(_tmpl$);
108
- web.insert(_el$2, () => params().title);
109
- return _el$2;
110
- }
111
- }), _el$10, _co$);
112
- web.insert(_el$, web.createComponent(solidJs.Show, {
113
- get when() {
114
- return isLoading();
115
- },
116
- get children() {
117
- return web.getNextElement(_tmpl$2);
118
- }
119
- }), _el$12, _co$2);
120
- web.insert(_el$, web.createComponent(solidJs.Show, {
121
- get when() {
122
- return error();
123
- },
124
- get children() {
125
- var _el$4 = web.getNextElement(_tmpl$3), _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$7.nextSibling;
126
- web.insert(_el$8, error);
127
- return _el$4;
128
- }
129
- }), _el$14, _co$3);
130
- var _ref$ = canvasRef;
131
- typeof _ref$ === "function" ? web.use(_ref$, _el$0) : canvasRef = _el$0;
132
- web.effect((_$p) => web.setStyleProperty(_el$9, "display", error() ? "none" : "block"));
133
- return _el$;
134
- })();
109
+ return web.createComponent(ExpandableWrapper.ExpandableWrapper, {
110
+ get title() {
111
+ return params().title || "Chart";
112
+ },
113
+ get children() {
114
+ var _el$ = web.getNextElement(_tmpl$6), _el$15 = _el$.firstChild, [_el$16, _co$3] = web.getNextMarker(_el$15.nextSibling), _el$17 = _el$16.nextSibling, [_el$18, _co$4] = web.getNextMarker(_el$17.nextSibling), _el$19 = _el$18.nextSibling, [_el$20, _co$5] = web.getNextMarker(_el$19.nextSibling), _el$13 = _el$20.nextSibling, _el$14 = _el$13.firstChild;
115
+ web.insert(_el$, web.createComponent(solidJs.Show, {
116
+ get when() {
117
+ return params().title || params().exportable;
118
+ },
119
+ get children() {
120
+ var _el$2 = web.getNextElement(_tmpl$3), _el$5 = _el$2.firstChild, [_el$6, _co$] = web.getNextMarker(_el$5.nextSibling), _el$7 = _el$6.nextSibling, [_el$8, _co$2] = web.getNextMarker(_el$7.nextSibling);
121
+ web.insert(_el$2, web.createComponent(solidJs.Show, {
122
+ get when() {
123
+ return params().title;
124
+ },
125
+ get children() {
126
+ var _el$3 = web.getNextElement(_tmpl$);
127
+ web.insert(_el$3, () => params().title);
128
+ return _el$3;
129
+ }
130
+ }), _el$6, _co$);
131
+ web.insert(_el$2, web.createComponent(solidJs.Show, {
132
+ get when() {
133
+ return params().exportable;
134
+ },
135
+ get children() {
136
+ var _el$4 = web.getNextElement(_tmpl$2);
137
+ _el$4.$$click = handleExportPNG;
138
+ web.runHydrationEvents();
139
+ return _el$4;
140
+ }
141
+ }), _el$8, _co$2);
142
+ return _el$2;
143
+ }
144
+ }), _el$16, _co$3);
145
+ web.insert(_el$, web.createComponent(solidJs.Show, {
146
+ get when() {
147
+ return isLoading();
148
+ },
149
+ get children() {
150
+ return web.getNextElement(_tmpl$4);
151
+ }
152
+ }), _el$18, _co$4);
153
+ web.insert(_el$, web.createComponent(solidJs.Show, {
154
+ get when() {
155
+ return error();
156
+ },
157
+ get children() {
158
+ var _el$0 = web.getNextElement(_tmpl$5), _el$1 = _el$0.firstChild, _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$11.nextSibling;
159
+ web.insert(_el$12, error);
160
+ return _el$0;
161
+ }
162
+ }), _el$20, _co$5);
163
+ var _ref$ = canvasRef;
164
+ typeof _ref$ === "function" ? web.use(_ref$, _el$14) : canvasRef = _el$14;
165
+ web.effect((_p$) => {
166
+ var _v$ = params().height || "250px", _v$2 = error() ? "none" : "block";
167
+ _v$ !== _p$.e && web.setStyleProperty(_el$13, "height", _p$.e = _v$);
168
+ _v$2 !== _p$.t && web.setStyleProperty(_el$13, "display", _p$.t = _v$2);
169
+ return _p$;
170
+ }, {
171
+ e: void 0,
172
+ t: void 0
173
+ });
174
+ return _el$;
175
+ }
176
+ });
135
177
  };
178
+ web.delegateEvents(["click"]);
136
179
  exports.ChartJSRenderer = ChartJSRenderer;
137
180
  exports.isChartJSAvailable = isChartJSAvailable;
138
181
  //# sourceMappingURL=ChartJSRenderer.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChartJSRenderer.cjs","sources":["../../src/components/ChartJSRenderer.tsx"],"sourcesContent":["/**\n * ChartJSRenderer - Native Chart.js rendering\n * Sprint 4: State & Charts\n *\n * Requires chart.js peer dependency:\n * ```\n * pnpm add chart.js\n * ```\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show } from 'solid-js'\nimport type { UIComponent, ChartComponentParams } from '../types'\n\n// Lazy load Chart.js to avoid bundling if not used\nlet ChartJS: any = null\nlet chartJSLoadPromise: Promise<any> | null = null\n\nconst loadChartJS = async () => {\n if (ChartJS) return ChartJS\n\n if (!chartJSLoadPromise) {\n chartJSLoadPromise = import('chart.js/auto')\n .then((module) => {\n ChartJS = module.default || module.Chart\n return ChartJS\n })\n .catch((err) => {\n chartJSLoadPromise = null\n throw err\n })\n }\n\n return chartJSLoadPromise\n}\n\n/**\n * Check if Chart.js is available\n */\nexport async function isChartJSAvailable(): Promise<boolean> {\n try {\n await loadChartJS()\n return true\n } catch {\n return false\n }\n}\n\nexport interface ChartJSRendererProps {\n /**\n * UIComponent with chart params\n */\n component: UIComponent\n\n /**\n * Error callback\n */\n onError?: (error: Error) => void\n}\n\n/**\n * Native Chart.js renderer component\n *\n * @example\n * ```tsx\n * const chartComponent: UIComponent = {\n * id: 'revenue-chart',\n * type: 'chart',\n * position: { colStart: 1, colSpan: 6 },\n * params: {\n * type: 'bar',\n * title: 'Monthly Revenue',\n * data: {\n * labels: ['Jan', 'Feb', 'Mar'],\n * datasets: [{ label: 'Revenue', data: [100, 200, 150] }]\n * },\n * renderer: 'native',\n * },\n * }\n * <ChartJSRenderer component={chartComponent} />\n * ```\n */\nexport const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {\n const [isLoading, setIsLoading] = createSignal(true)\n const [error, setError] = createSignal<string>()\n let canvasRef: HTMLCanvasElement | undefined\n let chartInstance: any\n\n const params = () => props.component.params as ChartComponentParams\n\n // Create/update chart when params change\n createEffect(async () => {\n if (!canvasRef) return\n\n // Access params to track dependencies\n const chartParams = params()\n\n setIsLoading(true)\n setError(undefined)\n\n try {\n const Chart = await loadChartJS()\n\n // Destroy previous instance\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n\n // Create new chart\n chartInstance = new Chart(canvasRef, {\n type: chartParams.type,\n data: chartParams.data,\n options: {\n responsive: true,\n maintainAspectRatio: false,\n ...chartParams.options,\n plugins: {\n ...chartParams.options?.plugins,\n legend: {\n display: true,\n position: 'bottom',\n ...chartParams.options?.plugins?.legend,\n },\n },\n },\n })\n\n setIsLoading(false)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Chart rendering failed')\n setError(error.message)\n setIsLoading(false)\n props.onError?.(error)\n }\n })\n\n // Cleanup on unmount\n onCleanup(() => {\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n })\n\n return (\n <div class=\"relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4\">\n <Show when={params().title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white mb-3\">\n {params().title}\n </h3>\n </Show>\n\n <Show when={isLoading()}>\n <div class=\"absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80\">\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\" />\n <span class=\"text-sm text-gray-500 dark:text-gray-400\">Loading chart...</span>\n </div>\n </div>\n </Show>\n\n <Show when={error()}>\n <div class=\"absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800\">\n <div class=\"text-center\">\n <div class=\"inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3\">\n <svg\n class=\"w-6 h-6 text-red-600 dark:text-red-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <p class=\"text-red-600 dark:text-red-400 text-sm font-medium\">Chart Error</p>\n <p class=\"text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs\">{error()}</p>\n </div>\n </div>\n </Show>\n\n <div\n class=\"w-full h-[250px]\"\n style={{ display: error() ? 'none' : 'block' }}\n >\n <canvas ref={canvasRef} />\n </div>\n </div>\n )\n}\n"],"names":["ChartJS","chartJSLoadPromise","loadChartJS","then","module","default","Chart","catch","err","isChartJSAvailable","ChartJSRenderer","props","isLoading","setIsLoading","createSignal","error","setError","canvasRef","chartInstance","params","component","createEffect","chartParams","undefined","destroy","type","data","options","responsive","maintainAspectRatio","plugins","legend","display","position","Error","message","onError","onCleanup","_el$","_$getNextElement","_tmpl$4","_el$1","firstChild","_el$10","_co$","_$getNextMarker","nextSibling","_el$11","_el$12","_co$2","_el$13","_el$14","_co$3","_el$9","_el$0","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","_tmpl$2","_el$4","_tmpl$3","_el$5","_el$6","_el$7","_el$8","_ref$","_$use","_$effect","_$p","_$setStyleProperty"],"mappings":"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"}
1
+ {"version":3,"file":"ChartJSRenderer.cjs","sources":["../../src/components/ChartJSRenderer.tsx"],"sourcesContent":["/**\n * ChartJSRenderer - Native Chart.js rendering\n * Sprint 4: State & Charts\n *\n * Requires chart.js peer dependency:\n * ```\n * pnpm add chart.js\n * ```\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show } from 'solid-js'\nimport type { UIComponent, ChartComponentParams } from '../types'\nimport { ExpandableWrapper } from './ExpandableWrapper'\n\n// Lazy load Chart.js to avoid bundling if not used\nlet ChartJS: any = null\nlet chartJSLoadPromise: Promise<any> | null = null\n\nconst loadChartJS = async () => {\n if (ChartJS) return ChartJS\n\n if (!chartJSLoadPromise) {\n chartJSLoadPromise = import('chart.js/auto')\n .then((module) => {\n ChartJS = module.default || module.Chart\n return ChartJS\n })\n .catch((err) => {\n chartJSLoadPromise = null\n throw err\n })\n }\n\n return chartJSLoadPromise\n}\n\n/**\n * Check if Chart.js is available\n */\nexport async function isChartJSAvailable(): Promise<boolean> {\n try {\n await loadChartJS()\n return true\n } catch {\n return false\n }\n}\n\nexport interface ChartJSRendererProps {\n /**\n * UIComponent with chart params\n */\n component: UIComponent\n\n /**\n * Error callback\n */\n onError?: (error: Error) => void\n}\n\n/**\n * Native Chart.js renderer component\n *\n * @example\n * ```tsx\n * const chartComponent: UIComponent = {\n * id: 'revenue-chart',\n * type: 'chart',\n * position: { colStart: 1, colSpan: 6 },\n * params: {\n * type: 'bar',\n * title: 'Monthly Revenue',\n * data: {\n * labels: ['Jan', 'Feb', 'Mar'],\n * datasets: [{ label: 'Revenue', data: [100, 200, 150] }]\n * },\n * renderer: 'native',\n * },\n * }\n * <ChartJSRenderer component={chartComponent} />\n * ```\n */\nexport const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {\n const [isLoading, setIsLoading] = createSignal(true)\n const [error, setError] = createSignal<string>()\n let canvasRef: HTMLCanvasElement | undefined\n let chartInstance: any\n\n const params = () => props.component.params as ChartComponentParams\n\n // Chart PNG export\n const handleExportPNG = () => {\n if (!canvasRef) return\n const url = canvasRef.toDataURL('image/png')\n const a = document.createElement('a')\n a.href = url\n a.download = `${(params().title || 'chart').replace(/\\s+/g, '-').toLowerCase()}.png`\n a.click()\n }\n\n // Create/update chart when params change\n createEffect(async () => {\n if (!canvasRef) return\n\n // Access params to track dependencies\n const chartParams = params()\n\n setIsLoading(true)\n setError(undefined)\n\n try {\n const Chart = await loadChartJS()\n\n // Destroy previous instance\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n\n // Create new chart\n chartInstance = new Chart(canvasRef, {\n type: chartParams.type,\n data: chartParams.data,\n options: {\n responsive: true,\n maintainAspectRatio: false,\n ...chartParams.options,\n plugins: {\n ...chartParams.options?.plugins,\n legend: {\n display: true,\n position: 'bottom',\n ...chartParams.options?.plugins?.legend,\n },\n },\n },\n })\n\n setIsLoading(false)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Chart rendering failed')\n setError(error.message)\n setIsLoading(false)\n props.onError?.(error)\n }\n })\n\n // Cleanup on unmount\n onCleanup(() => {\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n })\n\n return (\n <ExpandableWrapper title={params().title || 'Chart'}>\n <div class=\"relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4 group\">\n <Show when={params().title || params().exportable}>\n <div class=\"flex items-center justify-between mb-3\">\n <Show when={params().title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">\n {params().title}\n </h3>\n </Show>\n <Show when={params().exportable}>\n <button\n onClick={handleExportPNG}\n class=\"opacity-0 group-hover:opacity-60 hover:!opacity-100 px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm\"\n title=\"Download PNG\"\n aria-label=\"Download chart as PNG\"\n >\n <svg class=\"w-3 h-3 text-gray-500 dark:text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n </button>\n </Show>\n </div>\n </Show>\n\n <Show when={isLoading()}>\n <div class=\"absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80\">\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\" />\n <span class=\"text-sm text-gray-500 dark:text-gray-400\">Loading chart...</span>\n </div>\n </div>\n </Show>\n\n <Show when={error()}>\n <div class=\"absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800\">\n <div class=\"text-center\">\n <div class=\"inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3\">\n <svg\n class=\"w-6 h-6 text-red-600 dark:text-red-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <p class=\"text-red-600 dark:text-red-400 text-sm font-medium\">Chart Error</p>\n <p class=\"text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs\">{error()}</p>\n </div>\n </div>\n </Show>\n\n <div\n class=\"w-full\"\n style={{ height: params().height || '250px', display: error() ? 'none' : 'block' }}\n >\n <canvas ref={canvasRef} />\n </div>\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["ChartJS","chartJSLoadPromise","loadChartJS","then","module","default","Chart","catch","err","isChartJSAvailable","ChartJSRenderer","props","isLoading","setIsLoading","createSignal","error","setError","canvasRef","chartInstance","params","component","handleExportPNG","url","toDataURL","a","document","createElement","href","download","title","replace","toLowerCase","click","createEffect","chartParams","undefined","destroy","type","data","options","responsive","maintainAspectRatio","plugins","legend","display","position","Error","message","onError","onCleanup","_$createComponent","ExpandableWrapper","children","_el$","_$getNextElement","_tmpl$6","_el$15","firstChild","_el$16","_co$3","_$getNextMarker","nextSibling","_el$17","_el$18","_co$4","_el$19","_el$20","_co$5","_el$13","_el$14","_$insert","Show","when","exportable","_el$2","_tmpl$3","_el$5","_el$6","_co$","_el$7","_el$8","_co$2","_el$3","_tmpl$","_el$4","_tmpl$2","$$click","_$runHydrationEvents","_tmpl$4","_el$0","_tmpl$5","_el$1","_el$10","_el$11","_el$12","_ref$","_$use","_$effect","_p$","_v$","height","_v$2","e","_$setStyleProperty","t","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChartJSRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ChartJSRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAA+C,MAAM,UAAU,CAAA;AACjF,OAAO,KAAK,EAAE,WAAW,EAAwB,MAAM,UAAU,CAAA;AAwBjE;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,SAAS,EAAE,WAAW,CAAA;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,oBAAoB,CAgH3D,CAAA"}
1
+ {"version":3,"file":"ChartJSRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ChartJSRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAA+C,MAAM,UAAU,CAAA;AACjF,OAAO,KAAK,EAAE,WAAW,EAAwB,MAAM,UAAU,CAAA;AAyBjE;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,SAAS,EAAE,WAAW,CAAA;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,oBAAoB,CA4I3D,CAAA"}
@@ -1,6 +1,7 @@
1
- import { getNextElement, template, getNextMarker, insert, createComponent, effect, setStyleProperty, use } from "solid-js/web";
1
+ import { delegateEvents, createComponent, getNextElement, template, getNextMarker, insert, runHydrationEvents, effect, setStyleProperty, use } from "solid-js/web";
2
2
  import { createSignal, createEffect, onCleanup, Show } from "solid-js";
3
- var _tmpl$ = /* @__PURE__ */ template(`<h3 class="text-sm font-semibold text-gray-900 dark:text-white mb-3">`), _tmpl$2 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80"><div class="flex flex-col items-center gap-2"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div><span class="text-sm text-gray-500 dark:text-gray-400">Loading chart...`), _tmpl$3 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800"><div class=text-center><div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3"><svg class="w-6 h-6 text-red-600 dark:text-red-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs">`), _tmpl$4 = /* @__PURE__ */ template(`<div class="relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4"><!$><!/><!$><!/><!$><!/><div class="w-full h-[250px]"><canvas>`);
3
+ import { ExpandableWrapper } from "./ExpandableWrapper.js";
4
+ var _tmpl$ = /* @__PURE__ */ template(`<h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ template(`<button class="opacity-0 group-hover:opacity-60 hover:!opacity-100 px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm"title="Download PNG"aria-label="Download chart as PNG"><svg class="w-3 h-3 text-gray-500 dark:text-gray-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z">`), _tmpl$3 = /* @__PURE__ */ template(`<div class="flex items-center justify-between mb-3"><!$><!/><!$><!/>`), _tmpl$4 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80"><div class="flex flex-col items-center gap-2"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div><span class="text-sm text-gray-500 dark:text-gray-400">Loading chart...`), _tmpl$5 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800"><div class=text-center><div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3"><svg class="w-6 h-6 text-red-600 dark:text-red-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs">`), _tmpl$6 = /* @__PURE__ */ template(`<div class="relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4 group"><!$><!/><!$><!/><!$><!/><div class=w-full><canvas>`);
4
5
  let ChartJS = null;
5
6
  let chartJSLoadPromise = null;
6
7
  const loadChartJS = async () => {
@@ -30,6 +31,14 @@ const ChartJSRenderer = (props) => {
30
31
  let canvasRef;
31
32
  let chartInstance;
32
33
  const params = () => props.component.params;
34
+ const handleExportPNG = () => {
35
+ if (!canvasRef) return;
36
+ const url = canvasRef.toDataURL("image/png");
37
+ const a = document.createElement("a");
38
+ a.href = url;
39
+ a.download = `${(params().title || "chart").replace(/\s+/g, "-").toLowerCase()}.png`;
40
+ a.click();
41
+ };
33
42
  createEffect(async () => {
34
43
  var _a, _b, _c, _d;
35
44
  if (!canvasRef) return;
@@ -73,42 +82,76 @@ const ChartJSRenderer = (props) => {
73
82
  chartInstance = null;
74
83
  }
75
84
  });
76
- return (() => {
77
- var _el$ = getNextElement(_tmpl$4), _el$1 = _el$.firstChild, [_el$10, _co$] = getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$2] = getNextMarker(_el$11.nextSibling), _el$13 = _el$12.nextSibling, [_el$14, _co$3] = getNextMarker(_el$13.nextSibling), _el$9 = _el$14.nextSibling, _el$0 = _el$9.firstChild;
78
- insert(_el$, createComponent(Show, {
79
- get when() {
80
- return params().title;
81
- },
82
- get children() {
83
- var _el$2 = getNextElement(_tmpl$);
84
- insert(_el$2, () => params().title);
85
- return _el$2;
86
- }
87
- }), _el$10, _co$);
88
- insert(_el$, createComponent(Show, {
89
- get when() {
90
- return isLoading();
91
- },
92
- get children() {
93
- return getNextElement(_tmpl$2);
94
- }
95
- }), _el$12, _co$2);
96
- insert(_el$, createComponent(Show, {
97
- get when() {
98
- return error();
99
- },
100
- get children() {
101
- var _el$4 = getNextElement(_tmpl$3), _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$7.nextSibling;
102
- insert(_el$8, error);
103
- return _el$4;
104
- }
105
- }), _el$14, _co$3);
106
- var _ref$ = canvasRef;
107
- typeof _ref$ === "function" ? use(_ref$, _el$0) : canvasRef = _el$0;
108
- effect((_$p) => setStyleProperty(_el$9, "display", error() ? "none" : "block"));
109
- return _el$;
110
- })();
85
+ return createComponent(ExpandableWrapper, {
86
+ get title() {
87
+ return params().title || "Chart";
88
+ },
89
+ get children() {
90
+ var _el$ = getNextElement(_tmpl$6), _el$15 = _el$.firstChild, [_el$16, _co$3] = getNextMarker(_el$15.nextSibling), _el$17 = _el$16.nextSibling, [_el$18, _co$4] = getNextMarker(_el$17.nextSibling), _el$19 = _el$18.nextSibling, [_el$20, _co$5] = getNextMarker(_el$19.nextSibling), _el$13 = _el$20.nextSibling, _el$14 = _el$13.firstChild;
91
+ insert(_el$, createComponent(Show, {
92
+ get when() {
93
+ return params().title || params().exportable;
94
+ },
95
+ get children() {
96
+ var _el$2 = getNextElement(_tmpl$3), _el$5 = _el$2.firstChild, [_el$6, _co$] = getNextMarker(_el$5.nextSibling), _el$7 = _el$6.nextSibling, [_el$8, _co$2] = getNextMarker(_el$7.nextSibling);
97
+ insert(_el$2, createComponent(Show, {
98
+ get when() {
99
+ return params().title;
100
+ },
101
+ get children() {
102
+ var _el$3 = getNextElement(_tmpl$);
103
+ insert(_el$3, () => params().title);
104
+ return _el$3;
105
+ }
106
+ }), _el$6, _co$);
107
+ insert(_el$2, createComponent(Show, {
108
+ get when() {
109
+ return params().exportable;
110
+ },
111
+ get children() {
112
+ var _el$4 = getNextElement(_tmpl$2);
113
+ _el$4.$$click = handleExportPNG;
114
+ runHydrationEvents();
115
+ return _el$4;
116
+ }
117
+ }), _el$8, _co$2);
118
+ return _el$2;
119
+ }
120
+ }), _el$16, _co$3);
121
+ insert(_el$, createComponent(Show, {
122
+ get when() {
123
+ return isLoading();
124
+ },
125
+ get children() {
126
+ return getNextElement(_tmpl$4);
127
+ }
128
+ }), _el$18, _co$4);
129
+ insert(_el$, createComponent(Show, {
130
+ get when() {
131
+ return error();
132
+ },
133
+ get children() {
134
+ var _el$0 = getNextElement(_tmpl$5), _el$1 = _el$0.firstChild, _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$11.nextSibling;
135
+ insert(_el$12, error);
136
+ return _el$0;
137
+ }
138
+ }), _el$20, _co$5);
139
+ var _ref$ = canvasRef;
140
+ typeof _ref$ === "function" ? use(_ref$, _el$14) : canvasRef = _el$14;
141
+ effect((_p$) => {
142
+ var _v$ = params().height || "250px", _v$2 = error() ? "none" : "block";
143
+ _v$ !== _p$.e && setStyleProperty(_el$13, "height", _p$.e = _v$);
144
+ _v$2 !== _p$.t && setStyleProperty(_el$13, "display", _p$.t = _v$2);
145
+ return _p$;
146
+ }, {
147
+ e: void 0,
148
+ t: void 0
149
+ });
150
+ return _el$;
151
+ }
152
+ });
111
153
  };
154
+ delegateEvents(["click"]);
112
155
  export {
113
156
  ChartJSRenderer,
114
157
  isChartJSAvailable
@@ -1 +1 @@
1
- {"version":3,"file":"ChartJSRenderer.js","sources":["../../src/components/ChartJSRenderer.tsx"],"sourcesContent":["/**\n * ChartJSRenderer - Native Chart.js rendering\n * Sprint 4: State & Charts\n *\n * Requires chart.js peer dependency:\n * ```\n * pnpm add chart.js\n * ```\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show } from 'solid-js'\nimport type { UIComponent, ChartComponentParams } from '../types'\n\n// Lazy load Chart.js to avoid bundling if not used\nlet ChartJS: any = null\nlet chartJSLoadPromise: Promise<any> | null = null\n\nconst loadChartJS = async () => {\n if (ChartJS) return ChartJS\n\n if (!chartJSLoadPromise) {\n chartJSLoadPromise = import('chart.js/auto')\n .then((module) => {\n ChartJS = module.default || module.Chart\n return ChartJS\n })\n .catch((err) => {\n chartJSLoadPromise = null\n throw err\n })\n }\n\n return chartJSLoadPromise\n}\n\n/**\n * Check if Chart.js is available\n */\nexport async function isChartJSAvailable(): Promise<boolean> {\n try {\n await loadChartJS()\n return true\n } catch {\n return false\n }\n}\n\nexport interface ChartJSRendererProps {\n /**\n * UIComponent with chart params\n */\n component: UIComponent\n\n /**\n * Error callback\n */\n onError?: (error: Error) => void\n}\n\n/**\n * Native Chart.js renderer component\n *\n * @example\n * ```tsx\n * const chartComponent: UIComponent = {\n * id: 'revenue-chart',\n * type: 'chart',\n * position: { colStart: 1, colSpan: 6 },\n * params: {\n * type: 'bar',\n * title: 'Monthly Revenue',\n * data: {\n * labels: ['Jan', 'Feb', 'Mar'],\n * datasets: [{ label: 'Revenue', data: [100, 200, 150] }]\n * },\n * renderer: 'native',\n * },\n * }\n * <ChartJSRenderer component={chartComponent} />\n * ```\n */\nexport const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {\n const [isLoading, setIsLoading] = createSignal(true)\n const [error, setError] = createSignal<string>()\n let canvasRef: HTMLCanvasElement | undefined\n let chartInstance: any\n\n const params = () => props.component.params as ChartComponentParams\n\n // Create/update chart when params change\n createEffect(async () => {\n if (!canvasRef) return\n\n // Access params to track dependencies\n const chartParams = params()\n\n setIsLoading(true)\n setError(undefined)\n\n try {\n const Chart = await loadChartJS()\n\n // Destroy previous instance\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n\n // Create new chart\n chartInstance = new Chart(canvasRef, {\n type: chartParams.type,\n data: chartParams.data,\n options: {\n responsive: true,\n maintainAspectRatio: false,\n ...chartParams.options,\n plugins: {\n ...chartParams.options?.plugins,\n legend: {\n display: true,\n position: 'bottom',\n ...chartParams.options?.plugins?.legend,\n },\n },\n },\n })\n\n setIsLoading(false)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Chart rendering failed')\n setError(error.message)\n setIsLoading(false)\n props.onError?.(error)\n }\n })\n\n // Cleanup on unmount\n onCleanup(() => {\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n })\n\n return (\n <div class=\"relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4\">\n <Show when={params().title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white mb-3\">\n {params().title}\n </h3>\n </Show>\n\n <Show when={isLoading()}>\n <div class=\"absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80\">\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\" />\n <span class=\"text-sm text-gray-500 dark:text-gray-400\">Loading chart...</span>\n </div>\n </div>\n </Show>\n\n <Show when={error()}>\n <div class=\"absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800\">\n <div class=\"text-center\">\n <div class=\"inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3\">\n <svg\n class=\"w-6 h-6 text-red-600 dark:text-red-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <p class=\"text-red-600 dark:text-red-400 text-sm font-medium\">Chart Error</p>\n <p class=\"text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs\">{error()}</p>\n </div>\n </div>\n </Show>\n\n <div\n class=\"w-full h-[250px]\"\n style={{ display: error() ? 'none' : 'block' }}\n >\n <canvas ref={canvasRef} />\n </div>\n </div>\n )\n}\n"],"names":["ChartJS","chartJSLoadPromise","loadChartJS","then","module","default","Chart","catch","err","isChartJSAvailable","ChartJSRenderer","props","isLoading","setIsLoading","createSignal","error","setError","canvasRef","chartInstance","params","component","createEffect","chartParams","undefined","destroy","type","data","options","responsive","maintainAspectRatio","plugins","legend","display","position","Error","message","onError","onCleanup","_el$","_$getNextElement","_tmpl$4","_el$1","firstChild","_el$10","_co$","_$getNextMarker","nextSibling","_el$11","_el$12","_co$2","_el$13","_el$14","_co$3","_el$9","_el$0","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","_tmpl$2","_el$4","_tmpl$3","_el$5","_el$6","_el$7","_el$8","_ref$","_$use","_$effect","_$p","_$setStyleProperty"],"mappings":"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"}
1
+ {"version":3,"file":"ChartJSRenderer.js","sources":["../../src/components/ChartJSRenderer.tsx"],"sourcesContent":["/**\n * ChartJSRenderer - Native Chart.js rendering\n * Sprint 4: State & Charts\n *\n * Requires chart.js peer dependency:\n * ```\n * pnpm add chart.js\n * ```\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show } from 'solid-js'\nimport type { UIComponent, ChartComponentParams } from '../types'\nimport { ExpandableWrapper } from './ExpandableWrapper'\n\n// Lazy load Chart.js to avoid bundling if not used\nlet ChartJS: any = null\nlet chartJSLoadPromise: Promise<any> | null = null\n\nconst loadChartJS = async () => {\n if (ChartJS) return ChartJS\n\n if (!chartJSLoadPromise) {\n chartJSLoadPromise = import('chart.js/auto')\n .then((module) => {\n ChartJS = module.default || module.Chart\n return ChartJS\n })\n .catch((err) => {\n chartJSLoadPromise = null\n throw err\n })\n }\n\n return chartJSLoadPromise\n}\n\n/**\n * Check if Chart.js is available\n */\nexport async function isChartJSAvailable(): Promise<boolean> {\n try {\n await loadChartJS()\n return true\n } catch {\n return false\n }\n}\n\nexport interface ChartJSRendererProps {\n /**\n * UIComponent with chart params\n */\n component: UIComponent\n\n /**\n * Error callback\n */\n onError?: (error: Error) => void\n}\n\n/**\n * Native Chart.js renderer component\n *\n * @example\n * ```tsx\n * const chartComponent: UIComponent = {\n * id: 'revenue-chart',\n * type: 'chart',\n * position: { colStart: 1, colSpan: 6 },\n * params: {\n * type: 'bar',\n * title: 'Monthly Revenue',\n * data: {\n * labels: ['Jan', 'Feb', 'Mar'],\n * datasets: [{ label: 'Revenue', data: [100, 200, 150] }]\n * },\n * renderer: 'native',\n * },\n * }\n * <ChartJSRenderer component={chartComponent} />\n * ```\n */\nexport const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {\n const [isLoading, setIsLoading] = createSignal(true)\n const [error, setError] = createSignal<string>()\n let canvasRef: HTMLCanvasElement | undefined\n let chartInstance: any\n\n const params = () => props.component.params as ChartComponentParams\n\n // Chart PNG export\n const handleExportPNG = () => {\n if (!canvasRef) return\n const url = canvasRef.toDataURL('image/png')\n const a = document.createElement('a')\n a.href = url\n a.download = `${(params().title || 'chart').replace(/\\s+/g, '-').toLowerCase()}.png`\n a.click()\n }\n\n // Create/update chart when params change\n createEffect(async () => {\n if (!canvasRef) return\n\n // Access params to track dependencies\n const chartParams = params()\n\n setIsLoading(true)\n setError(undefined)\n\n try {\n const Chart = await loadChartJS()\n\n // Destroy previous instance\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n\n // Create new chart\n chartInstance = new Chart(canvasRef, {\n type: chartParams.type,\n data: chartParams.data,\n options: {\n responsive: true,\n maintainAspectRatio: false,\n ...chartParams.options,\n plugins: {\n ...chartParams.options?.plugins,\n legend: {\n display: true,\n position: 'bottom',\n ...chartParams.options?.plugins?.legend,\n },\n },\n },\n })\n\n setIsLoading(false)\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Chart rendering failed')\n setError(error.message)\n setIsLoading(false)\n props.onError?.(error)\n }\n })\n\n // Cleanup on unmount\n onCleanup(() => {\n if (chartInstance) {\n chartInstance.destroy()\n chartInstance = null\n }\n })\n\n return (\n <ExpandableWrapper title={params().title || 'Chart'}>\n <div class=\"relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden p-4 group\">\n <Show when={params().title || params().exportable}>\n <div class=\"flex items-center justify-between mb-3\">\n <Show when={params().title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">\n {params().title}\n </h3>\n </Show>\n <Show when={params().exportable}>\n <button\n onClick={handleExportPNG}\n class=\"opacity-0 group-hover:opacity-60 hover:!opacity-100 px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm\"\n title=\"Download PNG\"\n aria-label=\"Download chart as PNG\"\n >\n <svg class=\"w-3 h-3 text-gray-500 dark:text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n </button>\n </Show>\n </div>\n </Show>\n\n <Show when={isLoading()}>\n <div class=\"absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80\">\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\" />\n <span class=\"text-sm text-gray-500 dark:text-gray-400\">Loading chart...</span>\n </div>\n </div>\n </Show>\n\n <Show when={error()}>\n <div class=\"absolute inset-0 flex items-center justify-center p-4 bg-white dark:bg-gray-800\">\n <div class=\"text-center\">\n <div class=\"inline-flex items-center justify-center w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 mb-3\">\n <svg\n class=\"w-6 h-6 text-red-600 dark:text-red-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <p class=\"text-red-600 dark:text-red-400 text-sm font-medium\">Chart Error</p>\n <p class=\"text-gray-600 dark:text-gray-400 text-xs mt-1 max-w-xs\">{error()}</p>\n </div>\n </div>\n </Show>\n\n <div\n class=\"w-full\"\n style={{ height: params().height || '250px', display: error() ? 'none' : 'block' }}\n >\n <canvas ref={canvasRef} />\n </div>\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["ChartJS","chartJSLoadPromise","loadChartJS","then","module","default","Chart","catch","err","isChartJSAvailable","ChartJSRenderer","props","isLoading","setIsLoading","createSignal","error","setError","canvasRef","chartInstance","params","component","handleExportPNG","url","toDataURL","a","document","createElement","href","download","title","replace","toLowerCase","click","createEffect","chartParams","undefined","destroy","type","data","options","responsive","maintainAspectRatio","plugins","legend","display","position","Error","message","onError","onCleanup","_$createComponent","ExpandableWrapper","children","_el$","_$getNextElement","_tmpl$6","_el$15","firstChild","_el$16","_co$3","_$getNextMarker","nextSibling","_el$17","_el$18","_co$4","_el$19","_el$20","_co$5","_el$13","_el$14","_$insert","Show","when","exportable","_el$2","_tmpl$3","_el$5","_el$6","_co$","_el$7","_el$8","_co$2","_el$3","_tmpl$","_el$4","_tmpl$2","$$click","_$runHydrationEvents","_tmpl$4","_el$0","_tmpl$5","_el$1","_el$10","_el$11","_el$12","_ref$","_$use","_$effect","_p$","_v$","height","_v$2","e","_$setStyleProperty","t","_$delegateEvents"],"mappings":"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"}
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
- var _tmpl$ = /* @__PURE__ */ web.template(`<svg class="w-4 h-4 text-green-500"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M5 13l4 4L19 7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<div class="flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col"><div class="flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0"><div class="font-mono text-xs text-gray-600 dark:text-gray-400"></div><button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors"aria-label="Copy code"title="Copy code"></button></div><div class="relative overflow-auto flex"><!$><!/><pre class="flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5"><code>`), _tmpl$4 = /* @__PURE__ */ web.template(`<svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z">`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class=px-2>`);
5
+ const ExpandableWrapper = require("./ExpandableWrapper.cjs");
6
+ var _tmpl$ = /* @__PURE__ */ web.template(`<svg class="w-4 h-4 text-green-500"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M5 13l4 4L19 7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<div class="flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col"><div class="flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0"><div class="font-mono text-xs text-gray-600 dark:text-gray-400"></div><div class="flex items-center gap-2"><button aria-label="Toggle word wrap"><svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M3 10h10a4 4 0 010 8H9m4 0l-3-3m3 3l-3 3M3 6h18M3 14h4"></path></svg></button><button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors"aria-label="Copy code"title="Copy code"></button></div></div><div class="relative overflow-auto flex"><!$><!/><pre class="flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5"><code>`), _tmpl$4 = /* @__PURE__ */ web.template(`<svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z">`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class=px-2>`);
6
7
  let hljs = null;
7
8
  let stylesLoaded = false;
8
9
  const CodeBlockRenderer = (props) => {
@@ -10,6 +11,7 @@ const CodeBlockRenderer = (props) => {
10
11
  const [isCopied, setIsCopied] = solidJs.createSignal(false);
11
12
  const [isHljsLoaded, setIsHljsLoaded] = solidJs.createSignal(false);
12
13
  const [activeTheme, setActiveTheme] = solidJs.createSignal("dark");
14
+ const [wordWrap, setWordWrap] = solidJs.createSignal(false);
13
15
  const params = () => {
14
16
  var _a;
15
17
  return props.params || ((_a = props.component) == null ? void 0 : _a.params);
@@ -101,63 +103,84 @@ const CodeBlockRenderer = (props) => {
101
103
  }
102
104
  }
103
105
  };
104
- return (() => {
105
- var _el$ = web.getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$6 = _el$2.nextSibling, _el$0 = _el$6.firstChild, [_el$1, _co$] = web.getNextMarker(_el$0.nextSibling), _el$8 = _el$1.nextSibling, _el$9 = _el$8.firstChild;
106
- web.insert(_el$3, () => {
106
+ return web.createComponent(ExpandableWrapper.ExpandableWrapper, {
107
+ get title() {
107
108
  var _a, _b;
108
109
  return ((_a = params()) == null ? void 0 : _a.filename) || ((_b = params()) == null ? void 0 : _b.language) || "Code";
109
- });
110
- _el$4.$$click = handleCopy;
111
- web.insert(_el$4, web.createComponent(solidJs.Show, {
112
- get when() {
113
- return isCopied();
114
- },
115
- get fallback() {
116
- return web.getNextElement(_tmpl$4);
117
- },
118
- get children() {
119
- return web.getNextElement(_tmpl$);
120
- }
121
- }));
122
- web.insert(_el$6, web.createComponent(solidJs.Show, {
123
- get when() {
124
- var _a;
125
- return ((_a = params()) == null ? void 0 : _a.showLineNumbers) !== false;
126
- },
127
- get children() {
128
- var _el$7 = web.getNextElement(_tmpl$2);
129
- web.insert(_el$7, web.createComponent(solidJs.For, {
130
- get each() {
131
- return lineNumbers();
132
- },
133
- children: (num) => (() => {
134
- var _el$11 = web.getNextElement(_tmpl$5);
135
- web.insert(_el$11, num);
136
- return _el$11;
137
- })()
138
- }));
139
- return _el$7;
140
- }
141
- }), _el$1, _co$);
142
- web.effect((_p$) => {
143
- var _a, _b, _c, _d;
144
- var _v$ = ((_a = params()) == null ? void 0 : _a.maxHeight) ? {
145
- "max-height": (_b = params()) == null ? void 0 : _b.maxHeight
146
- } : {}, _v$2 = activeTheme(), _v$3 = `hljs ${((_c = params()) == null ? void 0 : _c.language) ? `language-${(_d = params()) == null ? void 0 : _d.language}` : ""}`, _v$4 = highlightedCode();
147
- _p$.e = web.style(_el$6, _v$, _p$.e);
148
- _v$2 !== _p$.t && web.setAttribute(_el$8, "data-theme", _p$.t = _v$2);
149
- _v$3 !== _p$.a && web.className(_el$9, _p$.a = _v$3);
150
- _v$4 !== _p$.o && web.setProperty(_el$9, "innerHTML", _p$.o = _v$4);
151
- return _p$;
152
- }, {
153
- e: void 0,
154
- t: void 0,
155
- a: void 0,
156
- o: void 0
157
- });
158
- web.runHydrationEvents();
159
- return _el$;
160
- })();
110
+ },
111
+ get copyData() {
112
+ var _a;
113
+ return (_a = params()) == null ? void 0 : _a.code;
114
+ },
115
+ copyLabel: "Copy code",
116
+ get children() {
117
+ var _el$ = web.getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling, _el$8 = _el$2.nextSibling, _el$10 = _el$8.firstChild, [_el$11, _co$] = web.getNextMarker(_el$10.nextSibling), _el$0 = _el$11.nextSibling, _el$1 = _el$0.firstChild;
118
+ web.insert(_el$3, () => {
119
+ var _a, _b;
120
+ return ((_a = params()) == null ? void 0 : _a.filename) || ((_b = params()) == null ? void 0 : _b.language) || "Code";
121
+ });
122
+ _el$5.$$click = () => setWordWrap(!wordWrap());
123
+ _el$6.$$click = handleCopy;
124
+ web.insert(_el$6, web.createComponent(solidJs.Show, {
125
+ get when() {
126
+ return isCopied();
127
+ },
128
+ get fallback() {
129
+ return web.getNextElement(_tmpl$4);
130
+ },
131
+ get children() {
132
+ return web.getNextElement(_tmpl$);
133
+ }
134
+ }));
135
+ web.insert(_el$8, web.createComponent(solidJs.Show, {
136
+ get when() {
137
+ var _a;
138
+ return ((_a = params()) == null ? void 0 : _a.showLineNumbers) !== false;
139
+ },
140
+ get children() {
141
+ var _el$9 = web.getNextElement(_tmpl$2);
142
+ web.insert(_el$9, web.createComponent(solidJs.For, {
143
+ get each() {
144
+ return lineNumbers();
145
+ },
146
+ children: (num) => (() => {
147
+ var _el$13 = web.getNextElement(_tmpl$5);
148
+ web.insert(_el$13, num);
149
+ return _el$13;
150
+ })()
151
+ }));
152
+ return _el$9;
153
+ }
154
+ }), _el$11, _co$);
155
+ web.effect((_p$) => {
156
+ var _a, _b, _c, _d;
157
+ var _v$ = `focus:outline-none transition-colors ${wordWrap() ? "text-blue-500 dark:text-blue-400" : "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"}`, _v$2 = wordWrap() ? "Disable word wrap" : "Enable word wrap", _v$3 = ((_a = params()) == null ? void 0 : _a.maxHeight) ? {
158
+ "max-height": (_b = params()) == null ? void 0 : _b.maxHeight
159
+ } : {}, _v$4 = wordWrap() ? {
160
+ "white-space": "pre-wrap",
161
+ "word-break": "break-all"
162
+ } : {}, _v$5 = activeTheme(), _v$6 = `hljs ${((_c = params()) == null ? void 0 : _c.language) ? `language-${(_d = params()) == null ? void 0 : _d.language}` : ""}`, _v$7 = highlightedCode();
163
+ _v$ !== _p$.e && web.className(_el$5, _p$.e = _v$);
164
+ _v$2 !== _p$.t && web.setAttribute(_el$5, "title", _p$.t = _v$2);
165
+ _p$.a = web.style(_el$8, _v$3, _p$.a);
166
+ _p$.o = web.style(_el$0, _v$4, _p$.o);
167
+ _v$5 !== _p$.i && web.setAttribute(_el$0, "data-theme", _p$.i = _v$5);
168
+ _v$6 !== _p$.n && web.className(_el$1, _p$.n = _v$6);
169
+ _v$7 !== _p$.s && web.setProperty(_el$1, "innerHTML", _p$.s = _v$7);
170
+ return _p$;
171
+ }, {
172
+ e: void 0,
173
+ t: void 0,
174
+ a: void 0,
175
+ o: void 0,
176
+ i: void 0,
177
+ n: void 0,
178
+ s: void 0
179
+ });
180
+ web.runHydrationEvents();
181
+ return _el$;
182
+ }
183
+ });
161
184
  };
162
185
  web.delegateEvents(["click"]);
163
186
  exports.CodeBlockRenderer = CodeBlockRenderer;