@seed-ship/mcp-ui-solid 1.2.1 → 1.2.6

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 (40) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/components/ActionRenderer.cjs +34 -0
  3. package/dist/components/ActionRenderer.cjs.map +1 -0
  4. package/dist/components/ActionRenderer.js +34 -0
  5. package/dist/components/ActionRenderer.js.map +1 -0
  6. package/dist/components/ArtifactRenderer.cjs +37 -0
  7. package/dist/components/ArtifactRenderer.cjs.map +1 -0
  8. package/dist/components/ArtifactRenderer.js +37 -0
  9. package/dist/components/ArtifactRenderer.js.map +1 -0
  10. package/dist/components/CarouselRenderer.cjs +58 -0
  11. package/dist/components/CarouselRenderer.cjs.map +1 -0
  12. package/dist/components/CarouselRenderer.js +58 -0
  13. package/dist/components/CarouselRenderer.js.map +1 -0
  14. package/dist/components/UIResourceRenderer.cjs +147 -12
  15. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  16. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  17. package/dist/components/UIResourceRenderer.js +148 -13
  18. package/dist/components/UIResourceRenderer.js.map +1 -1
  19. package/dist/components/index.d.ts +10 -0
  20. package/dist/components/index.d.ts.map +1 -1
  21. package/dist/components.cjs +10 -0
  22. package/dist/components.cjs.map +1 -1
  23. package/dist/components.d.ts +10 -0
  24. package/dist/components.js +10 -0
  25. package/dist/components.js.map +1 -1
  26. package/dist/index.cjs +4 -0
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.js +4 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/services/component-registry.cjs +211 -1
  31. package/dist/services/component-registry.cjs.map +1 -1
  32. package/dist/services/component-registry.d.ts +25 -0
  33. package/dist/services/component-registry.d.ts.map +1 -1
  34. package/dist/services/component-registry.js +211 -1
  35. package/dist/services/component-registry.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/components/UIResourceRenderer.tsx +121 -0
  38. package/src/components/index.ts +16 -0
  39. package/src/services/component-registry.ts +239 -0
  40. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,63 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.2.6] - 2025-11-26
9
+
10
+ ### Fixed - Sprint 12: Component Rendering (tagged release)
11
+ - **CarouselRenderer**: Now actually rendered in UIResourceRenderer's ComponentRenderer
12
+ - **ArtifactRenderer**: Now actually rendered in UIResourceRenderer's ComponentRenderer
13
+ - Components were previously exported and registered but not rendered in the main switch
14
+ - Fixed props mapping for both components
15
+
16
+ ## [1.2.5] - 2025-11-26
17
+
18
+ ### Fixed - Sprint 12: Component Rendering (re-release)
19
+ - **CarouselRenderer**: Now actually rendered in UIResourceRenderer's ComponentRenderer
20
+ - **ArtifactRenderer**: Now actually rendered in UIResourceRenderer's ComponentRenderer
21
+ - Components were previously exported and registered but not rendered in the main switch
22
+ - Fixed props mapping for both components
23
+
24
+ ## [1.2.4] - 2025-11-26
25
+
26
+ ### Note
27
+ - Skipped due to npm publish issue (version already existed)
28
+
29
+ ## [1.2.3] - 2025-11-26
30
+
31
+ ### Fixed - Sprint 9: UI Fixes
32
+ - **ErrorCardRenderer**: Added for proper error display
33
+ - **UIResource vs UILayout routing**: Fixed validation routing
34
+ - **auto-layout.ts**: Fixed label → title property mapping
35
+
36
+ ## [1.2.2] - 2025-11-26
37
+
38
+ ### Added - Sprint 4: Public Exports & Registry
39
+
40
+ #### Component Exports (NEW)
41
+ - **FooterRenderer**: Now publicly exported for custom footer implementations
42
+ - **ActionRenderer**: Interactive button/link component with tool-call support
43
+ - **ArtifactRenderer**: Downloadable artifact display with filename, size, MIME type
44
+ - **CarouselRenderer**: Horizontal carousel with snap scrolling and navigation
45
+ - **GridRenderer**: Nested CSS Grid layout for complex dashboard templates
46
+
47
+ #### Component Registry Entries (NEW)
48
+ - Added 5 new registry entries in `component-registry.ts`:
49
+ - `grid`: Nested CSS Grid layout with columns, gap, areas, children
50
+ - `action`: Interactive button/link with tool-call, link, submit actions
51
+ - `footer`: Metadata display with executionTime, model, sourceCount
52
+ - `carousel`: Horizontal item carousel with snap scrolling
53
+ - `artifact`: Downloadable file display with URL, filename, mimeType, size
54
+
55
+ ### Technical
56
+ - All Sprint 4 components now available via main package export
57
+ - Registry entries enable LLM prompt engineering with schema definitions
58
+ - Full TypeScript types exported for all new components
59
+
60
+ ## [1.2.1] - 2025-11-25
61
+
62
+ ### Fixed
63
+ - Minor build fixes and dependency updates
64
+
8
65
  ## [1.2.0] - 2025-11-25
9
66
 
10
67
  ### Added - Phase 5.0 Quick Wins
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const web = require("solid-js/web");
4
+ var _tmpl$ = /* @__PURE__ */ web.template(`<button>`);
5
+ const ActionRenderer = (props) => {
6
+ const handleClick = async () => {
7
+ if (props.disabled) return;
8
+ await props.onExecute(props.action.toolName, props.action.params);
9
+ };
10
+ const variantClasses = {
11
+ primary: "bg-blue-600 hover:bg-blue-700 text-white",
12
+ secondary: "bg-gray-200 hover:bg-gray-300 text-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-white",
13
+ danger: "bg-red-600 hover:bg-red-700 text-white"
14
+ };
15
+ return (() => {
16
+ var _el$ = web.getNextElement(_tmpl$);
17
+ _el$.$$click = handleClick;
18
+ web.insert(_el$, () => props.action.label);
19
+ web.effect((_p$) => {
20
+ var _v$ = props.disabled, _v$2 = `px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${variantClasses[props.action.variant || "primary"]} ${props.disabled ? "opacity-50 cursor-not-allowed" : ""}`;
21
+ _v$ !== _p$.e && web.setProperty(_el$, "disabled", _p$.e = _v$);
22
+ _v$2 !== _p$.t && web.className(_el$, _p$.t = _v$2);
23
+ return _p$;
24
+ }, {
25
+ e: void 0,
26
+ t: void 0
27
+ });
28
+ web.runHydrationEvents();
29
+ return _el$;
30
+ })();
31
+ };
32
+ web.delegateEvents(["click"]);
33
+ exports.ActionRenderer = ActionRenderer;
34
+ //# sourceMappingURL=ActionRenderer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionRenderer.cjs","sources":["../../src/components/ActionRenderer.tsx"],"sourcesContent":["import { Component, Show } from 'solid-js'\n// import type { ActionSpec } from '@seed-ship/mcp-ui-spec'\ntype ActionSpec = any\n\nexport interface ActionRendererProps {\n action: ActionSpec\n onExecute: (toolName: string, params: any) => Promise<any>\n disabled?: boolean\n}\n\nexport const ActionRenderer: Component<ActionRendererProps> = (props) => {\n const handleClick = async () => {\n if (props.disabled) return\n await props.onExecute(props.action.toolName, props.action.params)\n }\n\n const variantClasses: Record<string, string> = {\n primary: 'bg-blue-600 hover:bg-blue-700 text-white',\n secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-white',\n danger: 'bg-red-600 hover:bg-red-700 text-white'\n }\n\n return (\n <button\n onClick={handleClick}\n disabled={props.disabled}\n class={`px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${variantClasses[props.action.variant || 'primary']\n } ${props.disabled ? 'opacity-50 cursor-not-allowed' : ''}`}\n >\n {props.action.label}\n </button>\n )\n}\n"],"names":["ActionRenderer","props","handleClick","disabled","onExecute","action","toolName","params","variantClasses","primary","secondary","danger","_el$","_$getNextElement","_tmpl$","$$click","_$insert","label","_$effect","_p$","_v$","_v$2","variant","e","_$setProperty","t","_$className","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":";;;;AAUO,MAAMA,iBAAkDC,CAAAA,UAAU;AACrE,QAAMC,cAAc,YAAY;AAC5B,QAAID,MAAME,SAAU;AACpB,UAAMF,MAAMG,UAAUH,MAAMI,OAAOC,UAAUL,MAAMI,OAAOE,MAAM;AAAA,EACpE;AAEA,QAAMC,iBAAyC;AAAA,IAC3CC,SAAS;AAAA,IACTC,WAAW;AAAA,IACXC,QAAQ;AAAA,EAAA;AAGZ,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,MAAA;AAAAF,SAAAG,UAEiBb;AAAWc,QAAAA,OAAAJ,MAAA,MAKnBX,MAAMI,OAAOY,KAAK;AAAAC,QAAAA,OAAAC,CAAAA,QAAA;AAAA,UAAAC,MAJTnB,MAAME,UAAQkB,OACjB,gEAAgEb,eAAeP,MAAMI,OAAOiB,WAAW,SAAS,CAAC,IAChHrB,MAAME,WAAW,kCAAkC,EAAE;AAAEiB,cAAAD,IAAAI,KAAAC,IAAAA,YAAAZ,MAAA,YAAAO,IAAAI,IAAAH,GAAA;AAAAC,eAAAF,IAAAM,KAAAC,IAAAA,UAAAd,MAAAO,IAAAM,IAAAJ,IAAA;AAAA,aAAAF;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAI;AAAAA,MAAAF,GAAAE;AAAAA,IAAAA,CAAA;AAAAC,2BAAAA;AAAA,WAAAhB;AAAAA,EAAA,GAAA;AAK3E;AAACiB,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
@@ -0,0 +1,34 @@
1
+ import { delegateEvents, getNextElement, template, insert, effect, setProperty, className, runHydrationEvents } from "solid-js/web";
2
+ var _tmpl$ = /* @__PURE__ */ template(`<button>`);
3
+ const ActionRenderer = (props) => {
4
+ const handleClick = async () => {
5
+ if (props.disabled) return;
6
+ await props.onExecute(props.action.toolName, props.action.params);
7
+ };
8
+ const variantClasses = {
9
+ primary: "bg-blue-600 hover:bg-blue-700 text-white",
10
+ secondary: "bg-gray-200 hover:bg-gray-300 text-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-white",
11
+ danger: "bg-red-600 hover:bg-red-700 text-white"
12
+ };
13
+ return (() => {
14
+ var _el$ = getNextElement(_tmpl$);
15
+ _el$.$$click = handleClick;
16
+ insert(_el$, () => props.action.label);
17
+ effect((_p$) => {
18
+ var _v$ = props.disabled, _v$2 = `px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${variantClasses[props.action.variant || "primary"]} ${props.disabled ? "opacity-50 cursor-not-allowed" : ""}`;
19
+ _v$ !== _p$.e && setProperty(_el$, "disabled", _p$.e = _v$);
20
+ _v$2 !== _p$.t && className(_el$, _p$.t = _v$2);
21
+ return _p$;
22
+ }, {
23
+ e: void 0,
24
+ t: void 0
25
+ });
26
+ runHydrationEvents();
27
+ return _el$;
28
+ })();
29
+ };
30
+ delegateEvents(["click"]);
31
+ export {
32
+ ActionRenderer
33
+ };
34
+ //# sourceMappingURL=ActionRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionRenderer.js","sources":["../../src/components/ActionRenderer.tsx"],"sourcesContent":["import { Component, Show } from 'solid-js'\n// import type { ActionSpec } from '@seed-ship/mcp-ui-spec'\ntype ActionSpec = any\n\nexport interface ActionRendererProps {\n action: ActionSpec\n onExecute: (toolName: string, params: any) => Promise<any>\n disabled?: boolean\n}\n\nexport const ActionRenderer: Component<ActionRendererProps> = (props) => {\n const handleClick = async () => {\n if (props.disabled) return\n await props.onExecute(props.action.toolName, props.action.params)\n }\n\n const variantClasses: Record<string, string> = {\n primary: 'bg-blue-600 hover:bg-blue-700 text-white',\n secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-white',\n danger: 'bg-red-600 hover:bg-red-700 text-white'\n }\n\n return (\n <button\n onClick={handleClick}\n disabled={props.disabled}\n class={`px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${variantClasses[props.action.variant || 'primary']\n } ${props.disabled ? 'opacity-50 cursor-not-allowed' : ''}`}\n >\n {props.action.label}\n </button>\n )\n}\n"],"names":["ActionRenderer","props","handleClick","disabled","onExecute","action","toolName","params","variantClasses","primary","secondary","danger","_el$","_$getNextElement","_tmpl$","$$click","_$insert","label","_$effect","_p$","_v$","_v$2","variant","e","_$setProperty","t","_$className","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":";;AAUO,MAAMA,iBAAkDC,CAAAA,UAAU;AACrE,QAAMC,cAAc,YAAY;AAC5B,QAAID,MAAME,SAAU;AACpB,UAAMF,MAAMG,UAAUH,MAAMI,OAAOC,UAAUL,MAAMI,OAAOE,MAAM;AAAA,EACpE;AAEA,QAAMC,iBAAyC;AAAA,IAC3CC,SAAS;AAAA,IACTC,WAAW;AAAA,IACXC,QAAQ;AAAA,EAAA;AAGZ,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,MAAA;AAAAF,SAAAG,UAEiBb;AAAWc,WAAAJ,MAAA,MAKnBX,MAAMI,OAAOY,KAAK;AAAAC,WAAAC,CAAAA,QAAA;AAAA,UAAAC,MAJTnB,MAAME,UAAQkB,OACjB,gEAAgEb,eAAeP,MAAMI,OAAOiB,WAAW,SAAS,CAAC,IAChHrB,MAAME,WAAW,kCAAkC,EAAE;AAAEiB,cAAAD,IAAAI,KAAAC,YAAAZ,MAAA,YAAAO,IAAAI,IAAAH,GAAA;AAAAC,eAAAF,IAAAM,KAAAC,UAAAd,MAAAO,IAAAM,IAAAJ,IAAA;AAAA,aAAAF;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAI;AAAAA,MAAAF,GAAAE;AAAAA,IAAAA,CAAA;AAAAC,uBAAAA;AAAA,WAAAhB;AAAAA,EAAA,GAAA;AAK3E;AAACiB,eAAA,CAAA,OAAA,CAAA;"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const web = require("solid-js/web");
4
+ var _tmpl$ = /* @__PURE__ */ web.template(`<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"><div class="flex items-center gap-3"><div class="w-10 h-10 flex items-center justify-center bg-white dark:bg-gray-700 rounded-md shadow-sm text-xl"></div><div><h4 class="text-sm font-medium text-gray-900 dark:text-white truncate max-w-[200px]"></h4><p class="text-xs text-gray-500 dark:text-gray-400"><!$><!/> • <!$><!/></p></div></div><a class="px-3 py-1.5 text-sm font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/40 rounded-md transition-colors flex items-center gap-1"><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="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>Download`);
5
+ const ArtifactRenderer = (props) => {
6
+ const getIcon = () => {
7
+ if (props.params.mimeType.includes("csv")) return "📊";
8
+ if (props.params.mimeType.includes("json")) return "{}";
9
+ if (props.params.mimeType.includes("pdf")) return "📄";
10
+ return "📁";
11
+ };
12
+ const formatSize = (bytes) => {
13
+ if (!bytes) return "";
14
+ if (bytes < 1024) return `${bytes} B`;
15
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
16
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
17
+ };
18
+ return (() => {
19
+ var _el$ = web.getNextElement(_tmpl$), _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$6.firstChild, [_el$9, _co$] = web.getNextMarker(_el$8.nextSibling), _el$7 = _el$9.nextSibling, _el$0 = _el$7.nextSibling, [_el$1, _co$2] = web.getNextMarker(_el$0.nextSibling), _el$10 = _el$2.nextSibling;
20
+ web.insert(_el$3, getIcon);
21
+ web.insert(_el$5, () => props.params.filename);
22
+ web.insert(_el$6, () => formatSize(props.params.size), _el$9, _co$);
23
+ web.insert(_el$6, () => props.params.description || "Generated artifact", _el$1, _co$2);
24
+ web.effect((_p$) => {
25
+ var _v$ = props.params.url, _v$2 = props.params.filename;
26
+ _v$ !== _p$.e && web.setAttribute(_el$10, "href", _p$.e = _v$);
27
+ _v$2 !== _p$.t && web.setAttribute(_el$10, "download", _p$.t = _v$2);
28
+ return _p$;
29
+ }, {
30
+ e: void 0,
31
+ t: void 0
32
+ });
33
+ return _el$;
34
+ })();
35
+ };
36
+ exports.ArtifactRenderer = ArtifactRenderer;
37
+ //# sourceMappingURL=ArtifactRenderer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArtifactRenderer.cjs","sources":["../../src/components/ArtifactRenderer.tsx"],"sourcesContent":["import { Component } from 'solid-js'\n\nexport interface ArtifactComponentParams {\n url: string\n filename: string\n mimeType: string\n size?: number\n description?: string\n}\n\nexport const ArtifactRenderer: Component<{ params: ArtifactComponentParams }> = (props) => {\n const getIcon = () => {\n if (props.params.mimeType.includes('csv')) return '📊'\n if (props.params.mimeType.includes('json')) return '{}'\n if (props.params.mimeType.includes('pdf')) return '📄'\n return '📁'\n }\n\n const formatSize = (bytes?: number) => {\n if (!bytes) return ''\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n }\n\n return (\n <div class=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\n <div class=\"flex items-center gap-3\">\n <div class=\"w-10 h-10 flex items-center justify-center bg-white dark:bg-gray-700 rounded-md shadow-sm text-xl\">\n {getIcon()}\n </div>\n <div>\n <h4 class=\"text-sm font-medium text-gray-900 dark:text-white truncate max-w-[200px]\">\n {props.params.filename}\n </h4>\n <p class=\"text-xs text-gray-500 dark:text-gray-400\">\n {formatSize(props.params.size)} • {props.params.description || 'Generated artifact'}\n </p>\n </div>\n </div>\n\n <a\n href={props.params.url}\n download={props.params.filename}\n class=\"px-3 py-1.5 text-sm font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/40 rounded-md transition-colors flex items-center gap-1\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n Download\n </a>\n </div>\n )\n}\n"],"names":["ArtifactRenderer","props","getIcon","params","mimeType","includes","formatSize","bytes","toFixed","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$8","_el$9","_co$","_$getNextMarker","_el$7","_el$0","_el$1","_co$2","_el$10","_$insert","filename","size","description","_$effect","_p$","_v$","url","_v$2","e","_$setAttribute","t","undefined"],"mappings":";;;;AAUO,MAAMA,mBAAoEC,CAAAA,UAAU;AACvF,QAAMC,UAAUA,MAAM;AAClB,QAAID,MAAME,OAAOC,SAASC,SAAS,KAAK,EAAG,QAAO;AAClD,QAAIJ,MAAME,OAAOC,SAASC,SAAS,MAAM,EAAG,QAAO;AACnD,QAAIJ,MAAME,OAAOC,SAASC,SAAS,KAAK,EAAG,QAAO;AAClD,WAAO;AAAA,EACX;AAEA,QAAMC,aAAaA,CAACC,UAAmB;AACnC,QAAI,CAACA,MAAO,QAAO;AACnB,QAAIA,QAAQ,KAAM,QAAO,GAAGA,KAAK;AACjC,QAAIA,QAAQ,OAAO,KAAM,QAAO,IAAIA,QAAQ,MAAMC,QAAQ,CAAC,CAAC;AAC5D,WAAO,IAAID,SAAS,OAAO,OAAOC,QAAQ,CAAC,CAAC;AAAA,EAChD;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,mBAAAC,MAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAC,YAAAE,QAAAD,MAAAE,aAAAC,QAAAF,MAAAF,YAAAK,QAAAD,MAAAD,aAAAG,QAAAD,MAAAL,YAAA,CAAAO,OAAAC,IAAA,IAAAC,IAAAA,cAAAH,MAAAH,WAAA,GAAAO,QAAAH,MAAAJ,aAAAQ,QAAAD,MAAAP,aAAA,CAAAS,OAAAC,KAAA,IAAAJ,IAAAA,cAAAE,MAAAR,WAAA,GAAAW,SAAAf,MAAAI;AAAAY,QAAAA,OAAAd,OAIiBZ,OAAO;AAAA0B,QAAAA,OAAAX,OAAA,MAIHhB,MAAME,OAAO0B,QAAQ;AAAAD,eAAAV,OAAA,MAGrBZ,WAAWL,MAAME,OAAO2B,IAAI,GAACV,OAAAC,IAAA;AAAAO,eAAAV,OAAA,MAAKjB,MAAME,OAAO4B,eAAe,sBAAoBN,OAAAC,KAAA;AAAAM,QAAAA,OAAAC,CAAAA,QAAA;AAAA,UAAAC,MAMrFjC,MAAME,OAAOgC,KAAGC,OACZnC,MAAME,OAAO0B;AAAQK,cAAAD,IAAAI,KAAAC,IAAAA,aAAAX,QAAA,QAAAM,IAAAI,IAAAH,GAAA;AAAAE,eAAAH,IAAAM,KAAAD,IAAAA,aAAAX,QAAA,YAAAM,IAAAM,IAAAH,IAAA;AAAA,aAAAH;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAA,WAAA/B;AAAAA,EAAA,GAAA;AAU/C;;"}
@@ -0,0 +1,37 @@
1
+ import { getNextElement, template, getNextMarker, insert, effect, setAttribute } from "solid-js/web";
2
+ var _tmpl$ = /* @__PURE__ */ template(`<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"><div class="flex items-center gap-3"><div class="w-10 h-10 flex items-center justify-center bg-white dark:bg-gray-700 rounded-md shadow-sm text-xl"></div><div><h4 class="text-sm font-medium text-gray-900 dark:text-white truncate max-w-[200px]"></h4><p class="text-xs text-gray-500 dark:text-gray-400"><!$><!/> • <!$><!/></p></div></div><a class="px-3 py-1.5 text-sm font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/40 rounded-md transition-colors flex items-center gap-1"><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="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>Download`);
3
+ const ArtifactRenderer = (props) => {
4
+ const getIcon = () => {
5
+ if (props.params.mimeType.includes("csv")) return "📊";
6
+ if (props.params.mimeType.includes("json")) return "{}";
7
+ if (props.params.mimeType.includes("pdf")) return "📄";
8
+ return "📁";
9
+ };
10
+ const formatSize = (bytes) => {
11
+ if (!bytes) return "";
12
+ if (bytes < 1024) return `${bytes} B`;
13
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
14
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
15
+ };
16
+ return (() => {
17
+ var _el$ = getNextElement(_tmpl$), _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$6.firstChild, [_el$9, _co$] = getNextMarker(_el$8.nextSibling), _el$7 = _el$9.nextSibling, _el$0 = _el$7.nextSibling, [_el$1, _co$2] = getNextMarker(_el$0.nextSibling), _el$10 = _el$2.nextSibling;
18
+ insert(_el$3, getIcon);
19
+ insert(_el$5, () => props.params.filename);
20
+ insert(_el$6, () => formatSize(props.params.size), _el$9, _co$);
21
+ insert(_el$6, () => props.params.description || "Generated artifact", _el$1, _co$2);
22
+ effect((_p$) => {
23
+ var _v$ = props.params.url, _v$2 = props.params.filename;
24
+ _v$ !== _p$.e && setAttribute(_el$10, "href", _p$.e = _v$);
25
+ _v$2 !== _p$.t && setAttribute(_el$10, "download", _p$.t = _v$2);
26
+ return _p$;
27
+ }, {
28
+ e: void 0,
29
+ t: void 0
30
+ });
31
+ return _el$;
32
+ })();
33
+ };
34
+ export {
35
+ ArtifactRenderer
36
+ };
37
+ //# sourceMappingURL=ArtifactRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArtifactRenderer.js","sources":["../../src/components/ArtifactRenderer.tsx"],"sourcesContent":["import { Component } from 'solid-js'\n\nexport interface ArtifactComponentParams {\n url: string\n filename: string\n mimeType: string\n size?: number\n description?: string\n}\n\nexport const ArtifactRenderer: Component<{ params: ArtifactComponentParams }> = (props) => {\n const getIcon = () => {\n if (props.params.mimeType.includes('csv')) return '📊'\n if (props.params.mimeType.includes('json')) return '{}'\n if (props.params.mimeType.includes('pdf')) return '📄'\n return '📁'\n }\n\n const formatSize = (bytes?: number) => {\n if (!bytes) return ''\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n }\n\n return (\n <div class=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\n <div class=\"flex items-center gap-3\">\n <div class=\"w-10 h-10 flex items-center justify-center bg-white dark:bg-gray-700 rounded-md shadow-sm text-xl\">\n {getIcon()}\n </div>\n <div>\n <h4 class=\"text-sm font-medium text-gray-900 dark:text-white truncate max-w-[200px]\">\n {props.params.filename}\n </h4>\n <p class=\"text-xs text-gray-500 dark:text-gray-400\">\n {formatSize(props.params.size)} • {props.params.description || 'Generated artifact'}\n </p>\n </div>\n </div>\n\n <a\n href={props.params.url}\n download={props.params.filename}\n class=\"px-3 py-1.5 text-sm font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/40 rounded-md transition-colors flex items-center gap-1\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n Download\n </a>\n </div>\n )\n}\n"],"names":["ArtifactRenderer","props","getIcon","params","mimeType","includes","formatSize","bytes","toFixed","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$8","_el$9","_co$","_$getNextMarker","_el$7","_el$0","_el$1","_co$2","_el$10","_$insert","filename","size","description","_$effect","_p$","_v$","url","_v$2","e","_$setAttribute","t","undefined"],"mappings":";;AAUO,MAAMA,mBAAoEC,CAAAA,UAAU;AACvF,QAAMC,UAAUA,MAAM;AAClB,QAAID,MAAME,OAAOC,SAASC,SAAS,KAAK,EAAG,QAAO;AAClD,QAAIJ,MAAME,OAAOC,SAASC,SAAS,MAAM,EAAG,QAAO;AACnD,QAAIJ,MAAME,OAAOC,SAASC,SAAS,KAAK,EAAG,QAAO;AAClD,WAAO;AAAA,EACX;AAEA,QAAMC,aAAaA,CAACC,UAAmB;AACnC,QAAI,CAACA,MAAO,QAAO;AACnB,QAAIA,QAAQ,KAAM,QAAO,GAAGA,KAAK;AACjC,QAAIA,QAAQ,OAAO,KAAM,QAAO,IAAIA,QAAQ,MAAMC,QAAQ,CAAC,CAAC;AAC5D,WAAO,IAAID,SAAS,OAAO,OAAOC,QAAQ,CAAC,CAAC;AAAA,EAChD;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,MAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAC,YAAAE,QAAAD,MAAAE,aAAAC,QAAAF,MAAAF,YAAAK,QAAAD,MAAAD,aAAAG,QAAAD,MAAAL,YAAA,CAAAO,OAAAC,IAAA,IAAAC,cAAAH,MAAAH,WAAA,GAAAO,QAAAH,MAAAJ,aAAAQ,QAAAD,MAAAP,aAAA,CAAAS,OAAAC,KAAA,IAAAJ,cAAAE,MAAAR,WAAA,GAAAW,SAAAf,MAAAI;AAAAY,WAAAd,OAIiBZ,OAAO;AAAA0B,WAAAX,OAAA,MAIHhB,MAAME,OAAO0B,QAAQ;AAAAD,WAAAV,OAAA,MAGrBZ,WAAWL,MAAME,OAAO2B,IAAI,GAACV,OAAAC,IAAA;AAAAO,WAAAV,OAAA,MAAKjB,MAAME,OAAO4B,eAAe,sBAAoBN,OAAAC,KAAA;AAAAM,WAAAC,CAAAA,QAAA;AAAA,UAAAC,MAMrFjC,MAAME,OAAOgC,KAAGC,OACZnC,MAAME,OAAO0B;AAAQK,cAAAD,IAAAI,KAAAC,aAAAX,QAAA,QAAAM,IAAAI,IAAAH,GAAA;AAAAE,eAAAH,IAAAM,KAAAD,aAAAX,QAAA,YAAAM,IAAAM,IAAAH,IAAA;AAAA,aAAAH;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAA,WAAA/B;AAAAA,EAAA,GAAA;AAU/C;"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const web = require("solid-js/web");
4
+ const solidJs = require("solid-js");
5
+ const UIResourceRenderer = require("./UIResourceRenderer.cjs");
6
+ var _tmpl$ = /* @__PURE__ */ web.template(`<div class="relative group"><button><svg class="w-5 h-5 text-gray-700 dark:text-gray-300"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M15 19l-7-7 7-7"></path></svg></button><button><svg class="w-5 h-5 text-gray-700 dark:text-gray-300"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 5l7 7-7 7"></path></svg></button><div class="flex gap-4 overflow-x-auto snap-x snap-mandatory pb-4 scrollbar-hide"style=scroll-behavior:smooth>`), _tmpl$2 = /* @__PURE__ */ web.template(`<div class="flex-none w-[85%] sm:w-[45%] snap-center"><div class="h-full border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden bg-white dark:bg-gray-800">`);
7
+ const CarouselRenderer = (props) => {
8
+ let scrollContainer;
9
+ const [canScrollLeft, setCanScrollLeft] = solidJs.createSignal(false);
10
+ const [canScrollRight, setCanScrollRight] = solidJs.createSignal(true);
11
+ const checkScroll = () => {
12
+ if (web.isServer || !scrollContainer) return;
13
+ setCanScrollLeft(scrollContainer.scrollLeft > 0);
14
+ setCanScrollRight(scrollContainer.scrollLeft < scrollContainer.scrollWidth - scrollContainer.clientWidth - 10);
15
+ };
16
+ const scroll = (direction) => {
17
+ if (web.isServer || !scrollContainer) return;
18
+ const scrollAmount = scrollContainer.clientWidth * 0.8;
19
+ scrollContainer.scrollBy({
20
+ left: direction === "left" ? -scrollAmount : scrollAmount,
21
+ behavior: "smooth"
22
+ });
23
+ };
24
+ return (() => {
25
+ var _el$ = web.getNextElement(_tmpl$), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.nextSibling;
26
+ _el$2.$$click = () => scroll("left");
27
+ _el$3.$$click = () => scroll("right");
28
+ _el$4.addEventListener("scroll", checkScroll);
29
+ var _ref$ = scrollContainer;
30
+ typeof _ref$ === "function" ? web.use(_ref$, _el$4) : scrollContainer = _el$4;
31
+ web.insert(_el$4, web.createComponent(solidJs.For, {
32
+ get each() {
33
+ return props.items;
34
+ },
35
+ children: (item) => (() => {
36
+ var _el$5 = web.getNextElement(_tmpl$2), _el$6 = _el$5.firstChild;
37
+ web.insert(_el$6, web.createComponent(UIResourceRenderer.UIResourceRenderer, {
38
+ content: item
39
+ }));
40
+ return _el$5;
41
+ })()
42
+ }));
43
+ web.effect((_p$) => {
44
+ var _v$ = `absolute left-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollLeft() ? "opacity-0 group-hover:opacity-100" : "opacity-0 pointer-events-none"}`, _v$2 = `absolute right-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollRight() ? "opacity-0 group-hover:opacity-100" : "opacity-0 pointer-events-none"}`;
45
+ _v$ !== _p$.e && web.className(_el$2, _p$.e = _v$);
46
+ _v$2 !== _p$.t && web.className(_el$3, _p$.t = _v$2);
47
+ return _p$;
48
+ }, {
49
+ e: void 0,
50
+ t: void 0
51
+ });
52
+ web.runHydrationEvents();
53
+ return _el$;
54
+ })();
55
+ };
56
+ web.delegateEvents(["click"]);
57
+ exports.CarouselRenderer = CarouselRenderer;
58
+ //# sourceMappingURL=CarouselRenderer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselRenderer.cjs","sources":["../../src/components/CarouselRenderer.tsx"],"sourcesContent":["import { Component, For, createSignal, onMount } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { UIResourceRenderer } from './UIResourceRenderer'\n\n// Local definition to avoid missing module error\ntype UIComponent = any\n\nexport interface CarouselRendererProps {\n items: UIComponent[]\n height?: string\n}\n\nexport const CarouselRenderer: Component<CarouselRendererProps> = (props) => {\n let scrollContainer: HTMLDivElement | undefined\n const [canScrollLeft, setCanScrollLeft] = createSignal(false)\n const [canScrollRight, setCanScrollRight] = createSignal(true)\n\n const checkScroll = () => {\n if (isServer || !scrollContainer) return\n setCanScrollLeft(scrollContainer.scrollLeft > 0)\n setCanScrollRight(\n scrollContainer.scrollLeft < scrollContainer.scrollWidth - scrollContainer.clientWidth - 10\n )\n }\n\n const scroll = (direction: 'left' | 'right') => {\n if (isServer || !scrollContainer) return\n const scrollAmount = scrollContainer.clientWidth * 0.8\n scrollContainer.scrollBy({\n left: direction === 'left' ? -scrollAmount : scrollAmount,\n behavior: 'smooth'\n })\n }\n\n return (\n <div class=\"relative group\">\n {/* Navigation Buttons */}\n <button\n onClick={() => scroll('left')}\n class={`absolute left-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollLeft() ? 'opacity-0 group-hover:opacity-100' : 'opacity-0 pointer-events-none'\n }`}\n >\n <svg class=\"w-5 h-5 text-gray-700 dark:text-gray-300\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <button\n onClick={() => scroll('right')}\n class={`absolute right-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollRight() ? 'opacity-0 group-hover:opacity-100' : 'opacity-0 pointer-events-none'\n }`}\n >\n <svg class=\"w-5 h-5 text-gray-700 dark:text-gray-300\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n\n {/* Scroll Container */}\n <div\n ref={scrollContainer}\n onScroll={checkScroll}\n class=\"flex gap-4 overflow-x-auto snap-x snap-mandatory pb-4 scrollbar-hide\"\n style={{ \"scroll-behavior\": \"smooth\" }}\n >\n <For each={props.items}>\n {(item) => (\n <div class=\"flex-none w-[85%] sm:w-[45%] snap-center\">\n <div class=\"h-full border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden bg-white dark:bg-gray-800\">\n <UIResourceRenderer content={item} />\n </div>\n </div>\n )}\n </For>\n </div>\n </div>\n )\n}\n"],"names":["CarouselRenderer","props","scrollContainer","canScrollLeft","setCanScrollLeft","createSignal","canScrollRight","setCanScrollRight","checkScroll","isServer","scrollLeft","scrollWidth","clientWidth","scroll","direction","scrollAmount","scrollBy","left","behavior","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","nextSibling","_el$4","$$click","addEventListener","_ref$","_$use","_$insert","_$createComponent","For","each","items","children","item","_el$5","_tmpl$2","_el$6","UIResourceRenderer","content","_$effect","_p$","_v$","_v$2","e","_$className","t","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":";;;;;;AAYO,MAAMA,mBAAsDC,CAAAA,UAAU;AACzE,MAAIC;AACJ,QAAM,CAACC,eAAeC,gBAAgB,IAAIC,QAAAA,aAAa,KAAK;AAC5D,QAAM,CAACC,gBAAgBC,iBAAiB,IAAIF,QAAAA,aAAa,IAAI;AAE7D,QAAMG,cAAcA,MAAM;AACtB,QAAIC,IAAAA,YAAY,CAACP,gBAAiB;AAClCE,qBAAiBF,gBAAgBQ,aAAa,CAAC;AAC/CH,sBACIL,gBAAgBQ,aAAaR,gBAAgBS,cAAcT,gBAAgBU,cAAc,EAC7F;AAAA,EACJ;AAEA,QAAMC,SAASA,CAACC,cAAgC;AAC5C,QAAIL,IAAAA,YAAY,CAACP,gBAAiB;AAClC,UAAMa,eAAeb,gBAAgBU,cAAc;AACnDV,oBAAgBc,SAAS;AAAA,MACrBC,MAAMH,cAAc,SAAS,CAACC,eAAeA;AAAAA,MAC7CG,UAAU;AAAA,IAAA,CACb;AAAA,EACL;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,MAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAG,aAAAC,QAAAF,MAAAC;AAAAH,UAAAK,UAIqB,MAAMd,OAAO,MAAM;AAACW,UAAAG,UAUpB,MAAMd,OAAO,OAAO;AAACa,UAAAE,iBAAA,UAYpBpB,WAAW;AAAA,QAAAqB,QADhB3B;AAAe,WAAA2B,UAAA,aAAAC,IAAAA,IAAAD,OAAAH,KAAA,IAAfxB,kBAAewB;AAAAK,eAAAL,OAAAM,IAAAA,gBAKnBC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEjC,MAAMkC;AAAAA,MAAK;AAAA,MAAAC,UAChBC,WAAI,MAAA;AAAA,YAAAC,QAAAlB,IAAAA,eAAAmB,OAAA,GAAAC,QAAAF,MAAAf;AAAAQ,mBAAAS,OAAAR,IAAAA,gBAGOS,uCAAkB;AAAA,UAACC,SAASL;AAAAA,QAAAA,CAAI,CAAA;AAAA,eAAAC;AAAAA,MAAA,GAAA;AAAA,IAAA,CAG5C,CAAA;AAAAK,QAAAA,OAAAC,CAAAA,QAAA;AAAA,UAAAC,MAhCE,4LAA4L1C,cAAAA,IAAkB,sCAAsC,+BAA+B,IACpR2C,OASC,6LAA6LxC,eAAAA,IAAmB,sCAAsC,+BAA+B;AACtRuC,cAAAD,IAAAG,KAAAC,IAAAA,UAAA1B,OAAAsB,IAAAG,IAAAF,GAAA;AAAAC,eAAAF,IAAAK,KAAAD,IAAAA,UAAAxB,OAAAoB,IAAAK,IAAAH,IAAA;AAAA,aAAAF;AAAAA,IAAA,GAAA;AAAA,MAAAG,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAAC,2BAAAA;AAAA,WAAAhC;AAAAA,EAAA,GAAA;AA0BtB;AAACiC,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
@@ -0,0 +1,58 @@
1
+ import { delegateEvents, getNextElement, template, insert, createComponent, effect, className, runHydrationEvents, isServer, use } from "solid-js/web";
2
+ import { createSignal, For } from "solid-js";
3
+ import { UIResourceRenderer } from "./UIResourceRenderer.js";
4
+ var _tmpl$ = /* @__PURE__ */ template(`<div class="relative group"><button><svg class="w-5 h-5 text-gray-700 dark:text-gray-300"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M15 19l-7-7 7-7"></path></svg></button><button><svg class="w-5 h-5 text-gray-700 dark:text-gray-300"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 5l7 7-7 7"></path></svg></button><div class="flex gap-4 overflow-x-auto snap-x snap-mandatory pb-4 scrollbar-hide"style=scroll-behavior:smooth>`), _tmpl$2 = /* @__PURE__ */ template(`<div class="flex-none w-[85%] sm:w-[45%] snap-center"><div class="h-full border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden bg-white dark:bg-gray-800">`);
5
+ const CarouselRenderer = (props) => {
6
+ let scrollContainer;
7
+ const [canScrollLeft, setCanScrollLeft] = createSignal(false);
8
+ const [canScrollRight, setCanScrollRight] = createSignal(true);
9
+ const checkScroll = () => {
10
+ if (isServer || !scrollContainer) return;
11
+ setCanScrollLeft(scrollContainer.scrollLeft > 0);
12
+ setCanScrollRight(scrollContainer.scrollLeft < scrollContainer.scrollWidth - scrollContainer.clientWidth - 10);
13
+ };
14
+ const scroll = (direction) => {
15
+ if (isServer || !scrollContainer) return;
16
+ const scrollAmount = scrollContainer.clientWidth * 0.8;
17
+ scrollContainer.scrollBy({
18
+ left: direction === "left" ? -scrollAmount : scrollAmount,
19
+ behavior: "smooth"
20
+ });
21
+ };
22
+ return (() => {
23
+ var _el$ = getNextElement(_tmpl$), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.nextSibling;
24
+ _el$2.$$click = () => scroll("left");
25
+ _el$3.$$click = () => scroll("right");
26
+ _el$4.addEventListener("scroll", checkScroll);
27
+ var _ref$ = scrollContainer;
28
+ typeof _ref$ === "function" ? use(_ref$, _el$4) : scrollContainer = _el$4;
29
+ insert(_el$4, createComponent(For, {
30
+ get each() {
31
+ return props.items;
32
+ },
33
+ children: (item) => (() => {
34
+ var _el$5 = getNextElement(_tmpl$2), _el$6 = _el$5.firstChild;
35
+ insert(_el$6, createComponent(UIResourceRenderer, {
36
+ content: item
37
+ }));
38
+ return _el$5;
39
+ })()
40
+ }));
41
+ effect((_p$) => {
42
+ var _v$ = `absolute left-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollLeft() ? "opacity-0 group-hover:opacity-100" : "opacity-0 pointer-events-none"}`, _v$2 = `absolute right-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollRight() ? "opacity-0 group-hover:opacity-100" : "opacity-0 pointer-events-none"}`;
43
+ _v$ !== _p$.e && className(_el$2, _p$.e = _v$);
44
+ _v$2 !== _p$.t && className(_el$3, _p$.t = _v$2);
45
+ return _p$;
46
+ }, {
47
+ e: void 0,
48
+ t: void 0
49
+ });
50
+ runHydrationEvents();
51
+ return _el$;
52
+ })();
53
+ };
54
+ delegateEvents(["click"]);
55
+ export {
56
+ CarouselRenderer
57
+ };
58
+ //# sourceMappingURL=CarouselRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselRenderer.js","sources":["../../src/components/CarouselRenderer.tsx"],"sourcesContent":["import { Component, For, createSignal, onMount } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { UIResourceRenderer } from './UIResourceRenderer'\n\n// Local definition to avoid missing module error\ntype UIComponent = any\n\nexport interface CarouselRendererProps {\n items: UIComponent[]\n height?: string\n}\n\nexport const CarouselRenderer: Component<CarouselRendererProps> = (props) => {\n let scrollContainer: HTMLDivElement | undefined\n const [canScrollLeft, setCanScrollLeft] = createSignal(false)\n const [canScrollRight, setCanScrollRight] = createSignal(true)\n\n const checkScroll = () => {\n if (isServer || !scrollContainer) return\n setCanScrollLeft(scrollContainer.scrollLeft > 0)\n setCanScrollRight(\n scrollContainer.scrollLeft < scrollContainer.scrollWidth - scrollContainer.clientWidth - 10\n )\n }\n\n const scroll = (direction: 'left' | 'right') => {\n if (isServer || !scrollContainer) return\n const scrollAmount = scrollContainer.clientWidth * 0.8\n scrollContainer.scrollBy({\n left: direction === 'left' ? -scrollAmount : scrollAmount,\n behavior: 'smooth'\n })\n }\n\n return (\n <div class=\"relative group\">\n {/* Navigation Buttons */}\n <button\n onClick={() => scroll('left')}\n class={`absolute left-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollLeft() ? 'opacity-0 group-hover:opacity-100' : 'opacity-0 pointer-events-none'\n }`}\n >\n <svg class=\"w-5 h-5 text-gray-700 dark:text-gray-300\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <button\n onClick={() => scroll('right')}\n class={`absolute right-2 top-1/2 -translate-y-1/2 z-10 p-2 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-full shadow-md border border-gray-200 dark:border-gray-700 transition-opacity ${canScrollRight() ? 'opacity-0 group-hover:opacity-100' : 'opacity-0 pointer-events-none'\n }`}\n >\n <svg class=\"w-5 h-5 text-gray-700 dark:text-gray-300\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n\n {/* Scroll Container */}\n <div\n ref={scrollContainer}\n onScroll={checkScroll}\n class=\"flex gap-4 overflow-x-auto snap-x snap-mandatory pb-4 scrollbar-hide\"\n style={{ \"scroll-behavior\": \"smooth\" }}\n >\n <For each={props.items}>\n {(item) => (\n <div class=\"flex-none w-[85%] sm:w-[45%] snap-center\">\n <div class=\"h-full border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden bg-white dark:bg-gray-800\">\n <UIResourceRenderer content={item} />\n </div>\n </div>\n )}\n </For>\n </div>\n </div>\n )\n}\n"],"names":["CarouselRenderer","props","scrollContainer","canScrollLeft","setCanScrollLeft","createSignal","canScrollRight","setCanScrollRight","checkScroll","isServer","scrollLeft","scrollWidth","clientWidth","scroll","direction","scrollAmount","scrollBy","left","behavior","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","nextSibling","_el$4","$$click","addEventListener","_ref$","_$use","_$insert","_$createComponent","For","each","items","children","item","_el$5","_tmpl$2","_el$6","UIResourceRenderer","content","_$effect","_p$","_v$","_v$2","e","_$className","t","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":";;;;AAYO,MAAMA,mBAAsDC,CAAAA,UAAU;AACzE,MAAIC;AACJ,QAAM,CAACC,eAAeC,gBAAgB,IAAIC,aAAa,KAAK;AAC5D,QAAM,CAACC,gBAAgBC,iBAAiB,IAAIF,aAAa,IAAI;AAE7D,QAAMG,cAAcA,MAAM;AACtB,QAAIC,YAAY,CAACP,gBAAiB;AAClCE,qBAAiBF,gBAAgBQ,aAAa,CAAC;AAC/CH,sBACIL,gBAAgBQ,aAAaR,gBAAgBS,cAAcT,gBAAgBU,cAAc,EAC7F;AAAA,EACJ;AAEA,QAAMC,SAASA,CAACC,cAAgC;AAC5C,QAAIL,YAAY,CAACP,gBAAiB;AAClC,UAAMa,eAAeb,gBAAgBU,cAAc;AACnDV,oBAAgBc,SAAS;AAAA,MACrBC,MAAMH,cAAc,SAAS,CAACC,eAAeA;AAAAA,MAC7CG,UAAU;AAAA,IAAA,CACb;AAAA,EACL;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,MAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAG,aAAAC,QAAAF,MAAAC;AAAAH,UAAAK,UAIqB,MAAMd,OAAO,MAAM;AAACW,UAAAG,UAUpB,MAAMd,OAAO,OAAO;AAACa,UAAAE,iBAAA,UAYpBpB,WAAW;AAAA,QAAAqB,QADhB3B;AAAe,WAAA2B,UAAA,aAAAC,IAAAD,OAAAH,KAAA,IAAfxB,kBAAewB;AAAAK,WAAAL,OAAAM,gBAKnBC,KAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEjC,MAAMkC;AAAAA,MAAK;AAAA,MAAAC,UAChBC,WAAI,MAAA;AAAA,YAAAC,QAAAlB,eAAAmB,OAAA,GAAAC,QAAAF,MAAAf;AAAAQ,eAAAS,OAAAR,gBAGOS,oBAAkB;AAAA,UAACC,SAASL;AAAAA,QAAAA,CAAI,CAAA;AAAA,eAAAC;AAAAA,MAAA,GAAA;AAAA,IAAA,CAG5C,CAAA;AAAAK,WAAAC,CAAAA,QAAA;AAAA,UAAAC,MAhCE,4LAA4L1C,cAAAA,IAAkB,sCAAsC,+BAA+B,IACpR2C,OASC,6LAA6LxC,eAAAA,IAAmB,sCAAsC,+BAA+B;AACtRuC,cAAAD,IAAAG,KAAAC,UAAA1B,OAAAsB,IAAAG,IAAAF,GAAA;AAAAC,eAAAF,IAAAK,KAAAD,UAAAxB,OAAAoB,IAAAK,IAAAH,IAAA;AAAA,aAAAF;AAAAA,IAAA,GAAA;AAAA,MAAAG,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAAC,uBAAAA;AAAA,WAAAhC;AAAAA,EAAA,GAAA;AA0BtB;AAACiC,eAAA,CAAA,OAAA,CAAA;"}