@seed-ship/mcp-ui-solid 6.19.0 → 6.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/CHANGELOG.md +532 -0
  2. package/README.md +798 -1
  3. package/dist/adapters/connector.cjs +15 -4
  4. package/dist/adapters/connector.cjs.map +1 -1
  5. package/dist/adapters/connector.d.ts +38 -0
  6. package/dist/adapters/connector.d.ts.map +1 -1
  7. package/dist/adapters/connector.js +15 -4
  8. package/dist/adapters/connector.js.map +1 -1
  9. package/dist/adapters/index.d.ts +4 -3
  10. package/dist/adapters/index.d.ts.map +1 -1
  11. package/dist/adapters/macro-run.cjs +25 -13
  12. package/dist/adapters/macro-run.cjs.map +1 -1
  13. package/dist/adapters/macro-run.d.ts +37 -2
  14. package/dist/adapters/macro-run.d.ts.map +1 -1
  15. package/dist/adapters/macro-run.js +25 -13
  16. package/dist/adapters/macro-run.js.map +1 -1
  17. package/dist/adapters.cjs +2 -0
  18. package/dist/adapters.cjs.map +1 -1
  19. package/dist/adapters.js +4 -2
  20. package/dist/components/ActionGroupRenderer.cjs +3 -1
  21. package/dist/components/ActionGroupRenderer.cjs.map +1 -1
  22. package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
  23. package/dist/components/ActionGroupRenderer.js +3 -1
  24. package/dist/components/ActionGroupRenderer.js.map +1 -1
  25. package/dist/components/AgentCard.cjs +11 -8
  26. package/dist/components/AgentCard.cjs.map +1 -1
  27. package/dist/components/AgentCard.d.ts.map +1 -1
  28. package/dist/components/AgentCard.js +11 -8
  29. package/dist/components/AgentCard.js.map +1 -1
  30. package/dist/components/AgentHandoff.cjs +6 -1
  31. package/dist/components/AgentHandoff.cjs.map +1 -1
  32. package/dist/components/AgentHandoff.d.ts.map +1 -1
  33. package/dist/components/AgentHandoff.js +6 -1
  34. package/dist/components/AgentHandoff.js.map +1 -1
  35. package/dist/components/ArtifactRenderer.cjs +25 -6
  36. package/dist/components/ArtifactRenderer.cjs.map +1 -1
  37. package/dist/components/ArtifactRenderer.d.ts.map +1 -1
  38. package/dist/components/ArtifactRenderer.js +25 -6
  39. package/dist/components/ArtifactRenderer.js.map +1 -1
  40. package/dist/components/AutocompleteDropdown.cjs +30 -24
  41. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  42. package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
  43. package/dist/components/AutocompleteDropdown.js +30 -24
  44. package/dist/components/AutocompleteDropdown.js.map +1 -1
  45. package/dist/components/AutocompleteFormField.cjs +3 -1
  46. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  47. package/dist/components/AutocompleteFormField.d.ts.map +1 -1
  48. package/dist/components/AutocompleteFormField.js +4 -2
  49. package/dist/components/AutocompleteFormField.js.map +1 -1
  50. package/dist/components/BriefingDiff.cjs +45 -39
  51. package/dist/components/BriefingDiff.cjs.map +1 -1
  52. package/dist/components/BriefingDiff.d.ts.map +1 -1
  53. package/dist/components/BriefingDiff.js +45 -39
  54. package/dist/components/BriefingDiff.js.map +1 -1
  55. package/dist/components/CarouselRenderer.cjs +8 -2
  56. package/dist/components/CarouselRenderer.cjs.map +1 -1
  57. package/dist/components/CarouselRenderer.d.ts.map +1 -1
  58. package/dist/components/CarouselRenderer.js +8 -2
  59. package/dist/components/CarouselRenderer.js.map +1 -1
  60. package/dist/components/ChartJSRenderer.cjs +60 -36
  61. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  62. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  63. package/dist/components/ChartJSRenderer.js +61 -37
  64. package/dist/components/ChartJSRenderer.js.map +1 -1
  65. package/dist/components/ChatPrompt.cjs +15 -9
  66. package/dist/components/ChatPrompt.cjs.map +1 -1
  67. package/dist/components/ChatPrompt.d.ts.map +1 -1
  68. package/dist/components/ChatPrompt.js +15 -9
  69. package/dist/components/ChatPrompt.js.map +1 -1
  70. package/dist/components/CodeBlockRenderer.cjs +34 -16
  71. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  72. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  73. package/dist/components/CodeBlockRenderer.js +34 -16
  74. package/dist/components/CodeBlockRenderer.js.map +1 -1
  75. package/dist/components/DataPreviewSection.cjs +91 -44
  76. package/dist/components/DataPreviewSection.cjs.map +1 -1
  77. package/dist/components/DataPreviewSection.d.ts.map +1 -1
  78. package/dist/components/DataPreviewSection.js +92 -45
  79. package/dist/components/DataPreviewSection.js.map +1 -1
  80. package/dist/components/DegradedFallback.cjs +20 -16
  81. package/dist/components/DegradedFallback.cjs.map +1 -1
  82. package/dist/components/DegradedFallback.d.ts.map +1 -1
  83. package/dist/components/DegradedFallback.js +20 -16
  84. package/dist/components/DegradedFallback.js.map +1 -1
  85. package/dist/components/FeedbackInline.cjs +19 -3
  86. package/dist/components/FeedbackInline.cjs.map +1 -1
  87. package/dist/components/FeedbackInline.js +19 -3
  88. package/dist/components/FeedbackInline.js.map +1 -1
  89. package/dist/components/FooterRenderer.cjs +21 -17
  90. package/dist/components/FooterRenderer.cjs.map +1 -1
  91. package/dist/components/FooterRenderer.d.ts.map +1 -1
  92. package/dist/components/FooterRenderer.js +21 -17
  93. package/dist/components/FooterRenderer.js.map +1 -1
  94. package/dist/components/FormFieldRenderer.cjs +116 -93
  95. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  96. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  97. package/dist/components/FormFieldRenderer.js +116 -93
  98. package/dist/components/FormFieldRenderer.js.map +1 -1
  99. package/dist/components/FormRenderer.cjs +55 -31
  100. package/dist/components/FormRenderer.cjs.map +1 -1
  101. package/dist/components/FormRenderer.d.ts.map +1 -1
  102. package/dist/components/FormRenderer.js +55 -31
  103. package/dist/components/FormRenderer.js.map +1 -1
  104. package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
  105. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  106. package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
  107. package/dist/components/GenerativeUIErrorBoundary.js +20 -15
  108. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  109. package/dist/components/GraphRenderer.cjs +56 -33
  110. package/dist/components/GraphRenderer.cjs.map +1 -1
  111. package/dist/components/GraphRenderer.d.ts.map +1 -1
  112. package/dist/components/GraphRenderer.js +56 -33
  113. package/dist/components/GraphRenderer.js.map +1 -1
  114. package/dist/components/ImageGalleryRenderer.cjs +13 -4
  115. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  116. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  117. package/dist/components/ImageGalleryRenderer.js +13 -4
  118. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  119. package/dist/components/LightboxOverlay.cjs +16 -8
  120. package/dist/components/LightboxOverlay.cjs.map +1 -1
  121. package/dist/components/LightboxOverlay.d.ts.map +1 -1
  122. package/dist/components/LightboxOverlay.js +17 -9
  123. package/dist/components/LightboxOverlay.js.map +1 -1
  124. package/dist/components/MapRenderer.cjs +59 -29
  125. package/dist/components/MapRenderer.cjs.map +1 -1
  126. package/dist/components/MapRenderer.d.ts +10 -2
  127. package/dist/components/MapRenderer.d.ts.map +1 -1
  128. package/dist/components/MapRenderer.js +60 -30
  129. package/dist/components/MapRenderer.js.map +1 -1
  130. package/dist/components/ModalRenderer.cjs +4 -1
  131. package/dist/components/ModalRenderer.cjs.map +1 -1
  132. package/dist/components/ModalRenderer.d.ts.map +1 -1
  133. package/dist/components/ModalRenderer.js +5 -2
  134. package/dist/components/ModalRenderer.js.map +1 -1
  135. package/dist/components/ScratchpadPanel.cjs +578 -535
  136. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  137. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  138. package/dist/components/ScratchpadPanel.js +578 -535
  139. package/dist/components/ScratchpadPanel.js.map +1 -1
  140. package/dist/components/StreamingUIRenderer.cjs +92 -28
  141. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  142. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  143. package/dist/components/StreamingUIRenderer.js +92 -28
  144. package/dist/components/StreamingUIRenderer.js.map +1 -1
  145. package/dist/components/UIResourceRenderer.cjs +456 -363
  146. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  147. package/dist/components/UIResourceRenderer.d.ts +21 -0
  148. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  149. package/dist/components/UIResourceRenderer.js +458 -365
  150. package/dist/components/UIResourceRenderer.js.map +1 -1
  151. package/dist/components/VerifiedText.cjs +39 -20
  152. package/dist/components/VerifiedText.cjs.map +1 -1
  153. package/dist/components/VerifiedText.d.ts +2 -1
  154. package/dist/components/VerifiedText.d.ts.map +1 -1
  155. package/dist/components/VerifiedText.js +39 -20
  156. package/dist/components/VerifiedText.js.map +1 -1
  157. package/dist/components/VideoRenderer.cjs +10 -5
  158. package/dist/components/VideoRenderer.cjs.map +1 -1
  159. package/dist/components/VideoRenderer.d.ts.map +1 -1
  160. package/dist/components/VideoRenderer.js +10 -5
  161. package/dist/components/VideoRenderer.js.map +1 -1
  162. package/dist/components/chart-data-table.cjs +38 -17
  163. package/dist/components/chart-data-table.cjs.map +1 -1
  164. package/dist/components/chart-data-table.d.ts +30 -1
  165. package/dist/components/chart-data-table.d.ts.map +1 -1
  166. package/dist/components/chart-data-table.js +38 -17
  167. package/dist/components/chart-data-table.js.map +1 -1
  168. package/dist/context/MCPActionContext.cjs +3 -1
  169. package/dist/context/MCPActionContext.cjs.map +1 -1
  170. package/dist/context/MCPActionContext.d.ts.map +1 -1
  171. package/dist/context/MCPActionContext.js +3 -1
  172. package/dist/context/MCPActionContext.js.map +1 -1
  173. package/dist/context/MCPUIStringsContext.cjs +285 -2
  174. package/dist/context/MCPUIStringsContext.cjs.map +1 -1
  175. package/dist/context/MCPUIStringsContext.d.ts +600 -3
  176. package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
  177. package/dist/context/MCPUIStringsContext.js +285 -2
  178. package/dist/context/MCPUIStringsContext.js.map +1 -1
  179. package/dist/hooks/index.d.ts +2 -2
  180. package/dist/hooks/index.d.ts.map +1 -1
  181. package/dist/hooks/useStreamingUI.cjs +28 -10
  182. package/dist/hooks/useStreamingUI.cjs.map +1 -1
  183. package/dist/hooks/useStreamingUI.d.ts +37 -0
  184. package/dist/hooks/useStreamingUI.d.ts.map +1 -1
  185. package/dist/hooks/useStreamingUI.js +28 -10
  186. package/dist/hooks/useStreamingUI.js.map +1 -1
  187. package/dist/hooks.cjs +1 -0
  188. package/dist/hooks.cjs.map +1 -1
  189. package/dist/hooks.js +2 -1
  190. package/dist/index.cjs +23 -8
  191. package/dist/index.cjs.map +1 -1
  192. package/dist/index.d.cts +9 -3
  193. package/dist/index.d.ts +9 -3
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +18 -3
  196. package/dist/index.js.map +1 -1
  197. package/dist/services/validation.cjs +41 -16
  198. package/dist/services/validation.cjs.map +1 -1
  199. package/dist/services/validation.d.ts +47 -2
  200. package/dist/services/validation.d.ts.map +1 -1
  201. package/dist/services/validation.js +41 -16
  202. package/dist/services/validation.js.map +1 -1
  203. package/dist/utils/degraded-projections.cjs +37 -12
  204. package/dist/utils/degraded-projections.cjs.map +1 -1
  205. package/dist/utils/degraded-projections.d.ts +39 -3
  206. package/dist/utils/degraded-projections.d.ts.map +1 -1
  207. package/dist/utils/degraded-projections.js +37 -12
  208. package/dist/utils/degraded-projections.js.map +1 -1
  209. package/dist/utils/format-string.cjs +10 -0
  210. package/dist/utils/format-string.cjs.map +1 -0
  211. package/dist/utils/format-string.d.ts +26 -0
  212. package/dist/utils/format-string.d.ts.map +1 -0
  213. package/dist/utils/format-string.js +10 -0
  214. package/dist/utils/format-string.js.map +1 -0
  215. package/dist/validation.cjs +3 -0
  216. package/dist/validation.cjs.map +1 -1
  217. package/dist/validation.d.cts +2 -1
  218. package/dist/validation.d.ts +2 -1
  219. package/dist/validation.d.ts.map +1 -1
  220. package/dist/validation.js +4 -1
  221. package/package.json +1 -1
  222. package/src/adapters/connector.ts +58 -4
  223. package/src/adapters/index.ts +12 -2
  224. package/src/adapters/macro-run.ts +71 -11
  225. package/src/components/ActionGroupRenderer.tsx +3 -1
  226. package/src/components/AgentCard.tsx +27 -9
  227. package/src/components/AgentHandoff.tsx +4 -1
  228. package/src/components/ArtifactRenderer.tsx +17 -5
  229. package/src/components/AutocompleteDropdown.tsx +8 -6
  230. package/src/components/AutocompleteFormField.tsx +5 -1
  231. package/src/components/BriefingDiff.tsx +11 -3
  232. package/src/components/CarouselRenderer.tsx +4 -2
  233. package/src/components/ChartJSRenderer.tsx +18 -9
  234. package/src/components/ChatPrompt.tsx +13 -8
  235. package/src/components/CodeBlockRenderer.tsx +12 -10
  236. package/src/components/DataPreviewSection.tsx +92 -26
  237. package/src/components/DegradedFallback.tsx +4 -2
  238. package/src/components/FeedbackInline.tsx +2 -2
  239. package/src/components/FooterRenderer.tsx +3 -1
  240. package/src/components/FormFieldRenderer.tsx +34 -19
  241. package/src/components/FormRenderer.tsx +38 -10
  242. package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
  243. package/src/components/GraphRenderer.tsx +31 -16
  244. package/src/components/ImageGalleryRenderer.tsx +8 -4
  245. package/src/components/LightboxOverlay.tsx +6 -4
  246. package/src/components/MapRenderer.tsx +57 -20
  247. package/src/components/ModalRenderer.tsx +3 -1
  248. package/src/components/ScratchpadPanel.tsx +95 -44
  249. package/src/components/StreamingUIRenderer.tsx +41 -11
  250. package/src/components/UIResourceRenderer.tsx +145 -63
  251. package/src/components/VerifiedText.tsx +19 -9
  252. package/src/components/VideoRenderer.tsx +6 -4
  253. package/src/components/chart-data-table.ts +68 -14
  254. package/src/context/MCPActionContext.tsx +4 -1
  255. package/src/context/MCPUIStringsContext.tsx +1004 -1
  256. package/src/hooks/index.ts +2 -1
  257. package/src/hooks/useStreamingUI.ts +64 -10
  258. package/src/index.ts +23 -0
  259. package/src/services/validation.ts +93 -16
  260. package/src/utils/degraded-projections.ts +75 -12
  261. package/src/utils/format-string.ts +33 -0
  262. package/src/validation.ts +5 -0
@@ -1,7 +1,10 @@
1
1
  import { getNextElement, getNextMarker, insert, createComponent, template } from "solid-js/web";
2
2
  import { Show, For } from "solid-js";
3
- var _tmpl$ = /* @__PURE__ */ template(`<div class="mt-2 max-h-64 overflow-auto rounded border border-amber-200 dark:border-amber-800"><table class="w-full border-collapse text-left text-xs"><thead class="sticky top-0 bg-amber-100 dark:bg-amber-900/40"><tr></tr></thead><tbody>`), _tmpl$2 = /* @__PURE__ */ template(`<p class="mt-1 text-[10px] text-amber-600 dark:text-amber-400">+<!$><!/> more rows not shown.`), _tmpl$3 = /* @__PURE__ */ template(`<div class="w-full rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-900/20"role=alert><p class="text-sm font-medium text-amber-900 dark:text-amber-100"></p><p class="mt-0.5 text-xs text-amber-700 dark:text-amber-300"></p><!$><!/>`), _tmpl$4 = /* @__PURE__ */ template(`<th class="px-2 py-1 font-medium text-amber-900 dark:text-amber-100">`), _tmpl$5 = /* @__PURE__ */ template(`<tr class="border-t border-amber-100 dark:border-amber-800/60">`), _tmpl$6 = /* @__PURE__ */ template(`<td class="px-2 py-1 text-amber-800 dark:text-amber-200">`);
3
+ import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
4
+ import { formatMCPUIString } from "../utils/format-string.js";
5
+ var _tmpl$ = /* @__PURE__ */ template(`<div class="mt-2 max-h-64 overflow-auto rounded border border-amber-200 dark:border-amber-800"><table class="w-full border-collapse text-left text-xs"><thead class="sticky top-0 bg-amber-100 dark:bg-amber-900/40"><tr></tr></thead><tbody>`), _tmpl$2 = /* @__PURE__ */ template(`<p class="mt-1 text-[10px] text-amber-600 dark:text-amber-400">`), _tmpl$3 = /* @__PURE__ */ template(`<div class="w-full rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-900/20"role=alert><p class="text-sm font-medium text-amber-900 dark:text-amber-100"></p><p class="mt-0.5 text-xs text-amber-700 dark:text-amber-300"></p><!$><!/>`), _tmpl$4 = /* @__PURE__ */ template(`<th class="px-2 py-1 font-medium text-amber-900 dark:text-amber-100">`), _tmpl$5 = /* @__PURE__ */ template(`<tr class="border-t border-amber-100 dark:border-amber-800/60">`), _tmpl$6 = /* @__PURE__ */ template(`<td class="px-2 py-1 text-amber-800 dark:text-amber-200">`);
4
6
  const DegradedFallback = (props) => {
7
+ const strings = useMCPUIStrings();
5
8
  const maxRows = () => props.maxRows ?? 50;
6
9
  const allRows = () => props.rows ?? [];
7
10
  const shownRows = () => allRows().slice(0, maxRows());
@@ -11,9 +14,9 @@ const DegradedFallback = (props) => {
11
14
  return (((_a = props.columns) == null ? void 0 : _a.length) ?? 0) > 0 && allRows().length > 0;
12
15
  };
13
16
  return (() => {
14
- var _el$ = getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$12 = _el$3.nextSibling, [_el$13, _co$2] = getNextMarker(_el$12.nextSibling);
17
+ var _el$ = getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$0 = _el$3.nextSibling, [_el$1, _co$] = getNextMarker(_el$0.nextSibling);
15
18
  insert(_el$2, () => props.message);
16
- insert(_el$3, () => props.caption ?? "Showing the underlying data — the interactive view is unavailable.");
19
+ insert(_el$3, () => props.caption ?? strings.degradedCaption);
17
20
  insert(_el$, createComponent(Show, {
18
21
  get when() {
19
22
  return hasTable();
@@ -26,9 +29,9 @@ const DegradedFallback = (props) => {
26
29
  return props.columns;
27
30
  },
28
31
  children: (col) => (() => {
29
- var _el$14 = getNextElement(_tmpl$4);
30
- insert(_el$14, col);
31
- return _el$14;
32
+ var _el$10 = getNextElement(_tmpl$4);
33
+ insert(_el$10, col);
34
+ return _el$10;
32
35
  })()
33
36
  }));
34
37
  insert(_el$8, createComponent(For, {
@@ -36,18 +39,18 @@ const DegradedFallback = (props) => {
36
39
  return shownRows();
37
40
  },
38
41
  children: (row) => (() => {
39
- var _el$15 = getNextElement(_tmpl$5);
40
- insert(_el$15, createComponent(For, {
42
+ var _el$11 = getNextElement(_tmpl$5);
43
+ insert(_el$11, createComponent(For, {
41
44
  get each() {
42
45
  return props.columns;
43
46
  },
44
47
  children: (_col, i) => (() => {
45
- var _el$16 = getNextElement(_tmpl$6);
46
- insert(_el$16, () => String(row[i()] ?? ""));
47
- return _el$16;
48
+ var _el$12 = getNextElement(_tmpl$6);
49
+ insert(_el$12, () => String(row[i()] ?? ""));
50
+ return _el$12;
48
51
  })()
49
52
  }));
50
- return _el$15;
53
+ return _el$11;
51
54
  })()
52
55
  }));
53
56
  return _el$4;
@@ -56,14 +59,15 @@ const DegradedFallback = (props) => {
56
59
  return hiddenCount() > 0;
57
60
  },
58
61
  get children() {
59
- var _el$9 = getNextElement(_tmpl$2), _el$0 = _el$9.firstChild, _el$10 = _el$0.nextSibling, [_el$11, _co$] = getNextMarker(_el$10.nextSibling);
60
- _el$11.nextSibling;
61
- insert(_el$9, hiddenCount, _el$11, _co$);
62
+ var _el$9 = getNextElement(_tmpl$2);
63
+ insert(_el$9, () => formatMCPUIString(strings.degradedMoreRows, {
64
+ count: hiddenCount()
65
+ }));
62
66
  return _el$9;
63
67
  }
64
68
  })];
65
69
  }
66
- }), _el$13, _co$2);
70
+ }), _el$1, _co$);
67
71
  return _el$;
68
72
  })();
69
73
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DegradedFallback.js","sources":["../../src/components/DegradedFallback.tsx"],"sourcesContent":["/**\n * DegradedFallback — the middle rung of the renderer fallback ladder\n * (audit 2026-05-30, P2.5).\n *\n * Each heavy renderer (graph / map / chart) follows the same contract:\n * 1. native render when its peer lib is available and succeeds;\n * 2. **degraded but useful** view when the native render throws — this\n * component: a visible notice + a plain data table so the user still\n * sees the underlying data instead of a blank space;\n * 3. (the caller also emits a `render:error` telemetry event).\n *\n * Pure / presentational — no peer deps, no side effects — so a render-path\n * failure in a heavy lib can never cascade into the fallback itself, and it\n * is trivially unit-testable. Rows/cells are rendered as text; callers are\n * responsible for stringifying complex cell values.\n */\n\nimport { Component, For, Show } from 'solid-js';\n\nexport interface DegradedFallbackProps {\n /** Short, human-readable reason the native render was skipped/failed. */\n message: string;\n /**\n * Column headers for the degraded data table. When omitted (or empty),\n * only the notice banner is shown.\n */\n columns?: string[];\n /** Row data — each row is an array of cells aligned to `columns`. */\n rows?: Array<Array<string | number>>;\n /**\n * Caption under the table. Defaults to a generic\n * \"interactive view unavailable\" line.\n */\n caption?: string;\n /** Max rows to render before truncating (default 50). */\n maxRows?: number;\n}\n\nexport const DegradedFallback: Component<DegradedFallbackProps> = (props) => {\n const maxRows = () => props.maxRows ?? 50;\n const allRows = () => props.rows ?? [];\n const shownRows = () => allRows().slice(0, maxRows());\n const hiddenCount = () => Math.max(0, allRows().length - shownRows().length);\n const hasTable = () => (props.columns?.length ?? 0) > 0 && allRows().length > 0;\n\n return (\n <div\n class=\"w-full rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-900/20\"\n role=\"alert\"\n >\n <p class=\"text-sm font-medium text-amber-900 dark:text-amber-100\">{props.message}</p>\n <p class=\"mt-0.5 text-xs text-amber-700 dark:text-amber-300\">\n {props.caption ?? 'Showing the underlying data — the interactive view is unavailable.'}\n </p>\n\n <Show when={hasTable()}>\n <div class=\"mt-2 max-h-64 overflow-auto rounded border border-amber-200 dark:border-amber-800\">\n <table class=\"w-full border-collapse text-left text-xs\">\n <thead class=\"sticky top-0 bg-amber-100 dark:bg-amber-900/40\">\n <tr>\n <For each={props.columns}>\n {(col) => (\n <th class=\"px-2 py-1 font-medium text-amber-900 dark:text-amber-100\">{col}</th>\n )}\n </For>\n </tr>\n </thead>\n <tbody>\n <For each={shownRows()}>\n {(row) => (\n <tr class=\"border-t border-amber-100 dark:border-amber-800/60\">\n <For each={props.columns}>\n {(_col, i) => (\n <td class=\"px-2 py-1 text-amber-800 dark:text-amber-200\">\n {String(row[i()] ?? '')}\n </td>\n )}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n <Show when={hiddenCount() > 0}>\n <p class=\"mt-1 text-[10px] text-amber-600 dark:text-amber-400\">\n +{hiddenCount()} more rows not shown.\n </p>\n </Show>\n </Show>\n </div>\n );\n};\n"],"names":["DegradedFallback","props","maxRows","allRows","rows","shownRows","slice","hiddenCount","Math","max","length","hasTable","columns","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","nextSibling","_el$12","_el$13","_co$2","_$getNextMarker","_$insert","message","caption","_$createComponent","Show","when","children","_el$4","_tmpl$","_el$5","_el$6","_el$7","_el$8","For","each","col","_el$14","_tmpl$4","row","_el$15","_tmpl$5","_col","i","_el$16","_tmpl$6","String","_el$9","_tmpl$2","_el$0","_el$10","_el$11","_co$"],"mappings":";;;AAsCO,MAAMA,mBAAsDC,CAAAA,UAAU;AAC3E,QAAMC,UAAUA,MAAMD,MAAMC,WAAW;AACvC,QAAMC,UAAUA,MAAMF,MAAMG,QAAQ,CAAA;AACpC,QAAMC,YAAYA,MAAMF,QAAAA,EAAUG,MAAM,GAAGJ,SAAS;AACpD,QAAMK,cAAcA,MAAMC,KAAKC,IAAI,GAAGN,UAAUO,SAASL,UAAAA,EAAYK,MAAM;AAC3E,QAAMC,WAAWA,MAAAA;;AAAOV,yBAAMW,YAANX,mBAAeS,WAAU,KAAK,KAAKP,UAAUO,SAAS;AAAA;AAE9E,UAAA,MAAA;AAAA,QAAAG,OAAAC,eAAAC,OAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAG,aAAAC,SAAAF,MAAAC,aAAA,CAAAE,QAAAC,KAAA,IAAAC,cAAAH,OAAAD,WAAA;AAAAK,WAAAR,OAAA,MAKuEf,MAAMwB,OAAO;AAAAD,WAAAN,OAAA,MAE7EjB,MAAMyB,WAAW,oEAAoE;AAAAF,WAAAX,MAAAc,gBAGvFC,MAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAElB,SAAAA;AAAAA,MAAU;AAAA,MAAA,IAAAmB,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAjB,eAAAkB,MAAA,GAAAC,QAAAF,MAAAd,YAAAiB,QAAAD,MAAAhB,YAAAkB,QAAAD,MAAAjB,YAAAmB,QAAAF,MAAAf;AAAAK,iBAAAW,OAAAR,gBAKXU,KAAG;AAAA,YAAA,IAACC,OAAI;AAAA,qBAAErC,MAAMW;AAAAA,YAAO;AAAA,YAAAkB,UACpBS,UAAG,MAAA;AAAA,kBAAAC,SAAA1B,eAAA2B,OAAA;AAAAjB,qBAAAgB,QACmED,GAAG;AAAA,qBAAAC;AAAAA,YAAA,GAAA;AAAA,UAAA,CAC1E,CAAA;AAAAhB,iBAAAY,OAAAT,gBAKJU,KAAG;AAAA,YAAA,IAACC,OAAI;AAAA,qBAAEjC,UAAAA;AAAAA,YAAW;AAAA,YAAAyB,UAClBY,UAAG,MAAA;AAAA,kBAAAC,SAAA7B,eAAA8B,OAAA;AAAApB,qBAAAmB,QAAAhB,gBAEAU,KAAG;AAAA,gBAAA,IAACC,OAAI;AAAA,yBAAErC,MAAMW;AAAAA,gBAAO;AAAA,gBAAAkB,UACrBA,CAACe,MAAMC,OAAC,MAAA;AAAA,sBAAAC,SAAAjC,eAAAkC,OAAA;AAAAxB,yBAAAuB,QAAA,MAEJE,OAAOP,IAAII,GAAG,KAAK,EAAE,CAAC;AAAA,yBAAAC;AAAAA,gBAAA,GAAA;AAAA,cAAA,CAE1B,CAAA;AAAA,qBAAAJ;AAAAA,YAAA,GAAA;AAAA,UAAA,CAGN,CAAA;AAAA,iBAAAZ;AAAAA,QAAA,GAAA,GAAAJ,gBAKRC,MAAI;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAEtB,gBAAgB;AAAA,UAAC;AAAA,UAAA,IAAAuB,WAAA;AAAA,gBAAAoB,QAAApC,eAAAqC,OAAA,GAAAC,QAAAF,MAAAjC,YAAAoC,SAAAD,MAAAjC,aAAA,CAAAmC,QAAAC,IAAA,IAAAhC,cAAA8B,OAAAlC,WAAA;AAAAmC,mBAAAnC;AAAAK,mBAAA0B,OAEvB3C,aAAW+C,QAAAC,IAAA;AAAA,mBAAAL;AAAAA,UAAA;AAAA,QAAA,CAAA,CAAA;AAAA,MAAA;AAAA,IAAA,CAAA,GAAA7B,QAAAC,KAAA;AAAA,WAAAT;AAAAA,EAAA,GAAA;AAMzB;"}
1
+ {"version":3,"file":"DegradedFallback.js","sources":["../../src/components/DegradedFallback.tsx"],"sourcesContent":["/**\n * DegradedFallback — the middle rung of the renderer fallback ladder\n * (audit 2026-05-30, P2.5).\n *\n * Each heavy renderer (graph / map / chart) follows the same contract:\n * 1. native render when its peer lib is available and succeeds;\n * 2. **degraded but useful** view when the native render throws — this\n * component: a visible notice + a plain data table so the user still\n * sees the underlying data instead of a blank space;\n * 3. (the caller also emits a `render:error` telemetry event).\n *\n * Pure / presentational — no peer deps, no side effects — so a render-path\n * failure in a heavy lib can never cascade into the fallback itself, and it\n * is trivially unit-testable. Rows/cells are rendered as text; callers are\n * responsible for stringifying complex cell values.\n */\n\nimport { Component, For, Show } from 'solid-js';\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext';\n\nexport interface DegradedFallbackProps {\n /** Short, human-readable reason the native render was skipped/failed. */\n message: string;\n /**\n * Column headers for the degraded data table. When omitted (or empty),\n * only the notice banner is shown.\n */\n columns?: string[];\n /** Row data — each row is an array of cells aligned to `columns`. */\n rows?: Array<Array<string | number>>;\n /**\n * Caption under the table. Defaults to a generic\n * \"interactive view unavailable\" line.\n */\n caption?: string;\n /** Max rows to render before truncating (default 50). */\n maxRows?: number;\n}\n\nexport const DegradedFallback: Component<DegradedFallbackProps> = (props) => {\n const strings = useMCPUIStrings();\n const maxRows = () => props.maxRows ?? 50;\n const allRows = () => props.rows ?? [];\n const shownRows = () => allRows().slice(0, maxRows());\n const hiddenCount = () => Math.max(0, allRows().length - shownRows().length);\n const hasTable = () => (props.columns?.length ?? 0) > 0 && allRows().length > 0;\n\n return (\n <div\n class=\"w-full rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-900/20\"\n role=\"alert\"\n >\n <p class=\"text-sm font-medium text-amber-900 dark:text-amber-100\">{props.message}</p>\n <p class=\"mt-0.5 text-xs text-amber-700 dark:text-amber-300\">\n {props.caption ?? strings.degradedCaption}\n </p>\n\n <Show when={hasTable()}>\n <div class=\"mt-2 max-h-64 overflow-auto rounded border border-amber-200 dark:border-amber-800\">\n <table class=\"w-full border-collapse text-left text-xs\">\n <thead class=\"sticky top-0 bg-amber-100 dark:bg-amber-900/40\">\n <tr>\n <For each={props.columns}>\n {(col) => (\n <th class=\"px-2 py-1 font-medium text-amber-900 dark:text-amber-100\">{col}</th>\n )}\n </For>\n </tr>\n </thead>\n <tbody>\n <For each={shownRows()}>\n {(row) => (\n <tr class=\"border-t border-amber-100 dark:border-amber-800/60\">\n <For each={props.columns}>\n {(_col, i) => (\n <td class=\"px-2 py-1 text-amber-800 dark:text-amber-200\">\n {String(row[i()] ?? '')}\n </td>\n )}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n <Show when={hiddenCount() > 0}>\n <p class=\"mt-1 text-[10px] text-amber-600 dark:text-amber-400\">\n {formatMCPUIString(strings.degradedMoreRows, { count: hiddenCount() })}\n </p>\n </Show>\n </Show>\n </div>\n );\n};\n"],"names":["DegradedFallback","props","strings","useMCPUIStrings","maxRows","allRows","rows","shownRows","slice","hiddenCount","Math","max","length","hasTable","columns","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","nextSibling","_el$0","_el$1","_co$","_$getNextMarker","_$insert","message","caption","degradedCaption","_$createComponent","Show","when","children","_el$4","_tmpl$","_el$5","_el$6","_el$7","_el$8","For","each","col","_el$10","_tmpl$4","row","_el$11","_tmpl$5","_col","i","_el$12","_tmpl$6","String","_el$9","_tmpl$2","formatMCPUIString","degradedMoreRows","count"],"mappings":";;;;;AAuCO,MAAMA,mBAAsDC,CAAAA,UAAU;AAC3E,QAAMC,UAAUC,gBAAAA;AAChB,QAAMC,UAAUA,MAAMH,MAAMG,WAAW;AACvC,QAAMC,UAAUA,MAAMJ,MAAMK,QAAQ,CAAA;AACpC,QAAMC,YAAYA,MAAMF,QAAAA,EAAUG,MAAM,GAAGJ,SAAS;AACpD,QAAMK,cAAcA,MAAMC,KAAKC,IAAI,GAAGN,UAAUO,SAASL,UAAAA,EAAYK,MAAM;AAC3E,QAAMC,WAAWA,MAAAA;;AAAOZ,yBAAMa,YAANb,mBAAeW,WAAU,KAAK,KAAKP,UAAUO,SAAS;AAAA;AAE9E,UAAA,MAAA;AAAA,QAAAG,OAAAC,eAAAC,OAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAG,aAAAC,QAAAF,MAAAC,aAAA,CAAAE,OAAAC,IAAA,IAAAC,cAAAH,MAAAD,WAAA;AAAAK,WAAAR,OAAA,MAKuEjB,MAAM0B,OAAO;AAAAD,WAAAN,OAAA,MAE7EnB,MAAM2B,WAAW1B,QAAQ2B,eAAe;AAAAH,WAAAX,MAAAe,gBAG1CC,MAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEnB,SAAAA;AAAAA,MAAU;AAAA,MAAA,IAAAoB,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAlB,eAAAmB,MAAA,GAAAC,QAAAF,MAAAf,YAAAkB,QAAAD,MAAAjB,YAAAmB,QAAAD,MAAAlB,YAAAoB,QAAAF,MAAAhB;AAAAK,iBAAAY,OAAAR,gBAKXU,KAAG;AAAA,YAAA,IAACC,OAAI;AAAA,qBAAExC,MAAMa;AAAAA,YAAO;AAAA,YAAAmB,UACpBS,UAAG,MAAA;AAAA,kBAAAC,SAAA3B,eAAA4B,OAAA;AAAAlB,qBAAAiB,QACmED,GAAG;AAAA,qBAAAC;AAAAA,YAAA,GAAA;AAAA,UAAA,CAC1E,CAAA;AAAAjB,iBAAAa,OAAAT,gBAKJU,KAAG;AAAA,YAAA,IAACC,OAAI;AAAA,qBAAElC,UAAAA;AAAAA,YAAW;AAAA,YAAA0B,UAClBY,UAAG,MAAA;AAAA,kBAAAC,SAAA9B,eAAA+B,OAAA;AAAArB,qBAAAoB,QAAAhB,gBAEAU,KAAG;AAAA,gBAAA,IAACC,OAAI;AAAA,yBAAExC,MAAMa;AAAAA,gBAAO;AAAA,gBAAAmB,UACrBA,CAACe,MAAMC,OAAC,MAAA;AAAA,sBAAAC,SAAAlC,eAAAmC,OAAA;AAAAzB,yBAAAwB,QAAA,MAEJE,OAAOP,IAAII,GAAG,KAAK,EAAE,CAAC;AAAA,yBAAAC;AAAAA,gBAAA,GAAA;AAAA,cAAA,CAE1B,CAAA;AAAA,qBAAAJ;AAAAA,YAAA,GAAA;AAAA,UAAA,CAGN,CAAA;AAAA,iBAAAZ;AAAAA,QAAA,GAAA,GAAAJ,gBAKRC,MAAI;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAEvB,gBAAgB;AAAA,UAAC;AAAA,UAAA,IAAAwB,WAAA;AAAA,gBAAAoB,QAAArC,eAAAsC,OAAA;AAAA5B,mBAAA2B,OAAA,MAExBE,kBAAkBrD,QAAQsD,kBAAkB;AAAA,cAAEC,OAAOhD,YAAAA;AAAAA,YAAY,CAAG,CAAC;AAAA,mBAAA4C;AAAAA,UAAA;AAAA,QAAA,CAAA,CAAA;AAAA,MAAA;AAAA,IAAA,CAAA,GAAA9B,OAAAC,IAAA;AAAA,WAAAT;AAAAA,EAAA,GAAA;AAMlF;"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
5
  const MCPUIStringsContext = require("../context/MCPUIStringsContext.cjs");
6
- var _tmpl$ = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"aria-label="Mark response as useful"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"aria-label="Mark response as not useful"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div>`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="text-[11px] text-deposium-slate-500">`);
6
+ var _tmpl$ = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div>`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="text-[11px] text-deposium-slate-500">`);
7
7
  const FeedbackInline = (props) => {
8
8
  const [rating, setRating] = solidJs.createSignal(null);
9
9
  const strings = MCPUIStringsContext.useMCPUIStrings();
@@ -39,13 +39,29 @@ const FeedbackInline = (props) => {
39
39
  return [(() => {
40
40
  var _el$2 = web.getNextElement(_tmpl$);
41
41
  _el$2.$$click = () => handle("positive");
42
- web.effect(() => web.setAttribute(_el$2, "title", strings.feedbackUseful));
42
+ web.effect((_p$) => {
43
+ var _v$ = strings.feedbackUseful, _v$2 = strings.feedbackUseful;
44
+ _v$ !== _p$.e && web.setAttribute(_el$2, "title", _p$.e = _v$);
45
+ _v$2 !== _p$.t && web.setAttribute(_el$2, "aria-label", _p$.t = _v$2);
46
+ return _p$;
47
+ }, {
48
+ e: void 0,
49
+ t: void 0
50
+ });
43
51
  web.runHydrationEvents();
44
52
  return _el$2;
45
53
  })(), (() => {
46
54
  var _el$3 = web.getNextElement(_tmpl$2);
47
55
  _el$3.$$click = () => handle("negative");
48
- web.effect(() => web.setAttribute(_el$3, "title", strings.feedbackNotUseful));
56
+ web.effect((_p$) => {
57
+ var _v$3 = strings.feedbackNotUseful, _v$4 = strings.feedbackNotUseful;
58
+ _v$3 !== _p$.e && web.setAttribute(_el$3, "title", _p$.e = _v$3);
59
+ _v$4 !== _p$.t && web.setAttribute(_el$3, "aria-label", _p$.t = _v$4);
60
+ return _p$;
61
+ }, {
62
+ e: void 0,
63
+ t: void 0
64
+ });
49
65
  web.runHydrationEvents();
50
66
  return _el$3;
51
67
  })()];
@@ -1 +1 @@
1
- {"version":3,"file":"FeedbackInline.cjs","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label=\"Mark response as useful\"\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label=\"Mark response as not useful\"\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_$setAttribute","feedbackUseful","_$runHydrationEvents","_el$3","_tmpl$2","feedbackNotUseful","_$className","class","trim","_$delegateEvents"],"mappings":";;;;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,QAAAA,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,oBAAAA,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,OAAA;AAAAC,eAAAH,MAAAI,IAAAA,gBAEKC,cAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,IAAAA,eAAAQ,OAAA;AAAAN,cAAAA,OAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,IAAAA,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,IAAAA,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,aAAAC,IAAAA,aAAAJ,OAAA,SAE1BzB,QAAQ8B,cAAc,CAAA;AAAAC,iCAAAA;AAAA,iBAAAN;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAO,QAAAvB,IAAAA,eAAAwB,OAAA;AAAAD,gBAAAL,UAepB,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,aAAAC,IAAAA,aAAAG,OAAA,SAE1BhC,QAAQkC,iBAAiB,CAAA;AAAAH,iCAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAJ,QAAAA,OAAA,MAAAO,IAAAA,UAAA3B,MAhC1B,2BAA2BZ,MAAMwC,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAA7B;AAAAA,EAAA,GAAA;AAgDrE;AAAC8B,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
1
+ {"version":3,"file":"FeedbackInline.cjs","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label={strings.feedbackUseful}\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label={strings.feedbackNotUseful}\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_p$","_v$","feedbackUseful","_v$2","e","_$setAttribute","t","undefined","_$runHydrationEvents","_el$3","_tmpl$2","_v$3","feedbackNotUseful","_v$4","_$className","class","trim","_$delegateEvents"],"mappings":";;;;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,QAAAA,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,oBAAAA,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,OAAA;AAAAC,eAAAH,MAAAI,IAAAA,gBAEKC,cAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,IAAAA,eAAAQ,OAAA;AAAAN,cAAAA,OAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,IAAAA,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,IAAAA,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,OAAAC,CAAAA,QAAA;AAAA,gBAAAC,MAE1B9B,QAAQ+B,gBAAcC,OACjBhC,QAAQ+B;AAAcD,oBAAAD,IAAAI,KAAAC,IAAAA,aAAAT,OAAA,SAAAI,IAAAI,IAAAH,GAAA;AAAAE,qBAAAH,IAAAM,KAAAD,IAAAA,aAAAT,OAAA,cAAAI,IAAAM,IAAAH,IAAA;AAAA,mBAAAH;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,iCAAAA;AAAA,iBAAAZ;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAa,QAAA7B,IAAAA,eAAA8B,OAAA;AAAAD,gBAAAX,UAczB,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,OAAAC,CAAAA,QAAA;AAAA,gBAAAW,OAE1BxC,QAAQyC,mBAAiBC,OACpB1C,QAAQyC;AAAiBD,qBAAAX,IAAAI,KAAAC,IAAAA,aAAAI,OAAA,SAAAT,IAAAI,IAAAO,IAAA;AAAAE,qBAAAb,IAAAM,KAAAD,IAAAA,aAAAI,OAAA,cAAAT,IAAAM,IAAAO,IAAA;AAAA,mBAAAb;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,iCAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAV,QAAAA,OAAA,MAAAe,IAAAA,UAAAnC,MAjC/B,2BAA2BZ,MAAMgD,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAArC;AAAAA,EAAA,GAAA;AAgDrE;AAACsC,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
@@ -1,7 +1,7 @@
1
1
  import { getNextElement, insert, createComponent, effect, setAttribute, runHydrationEvents, memo, className, template, delegateEvents } from "solid-js/web";
2
2
  import { createSignal, Show } from "solid-js";
3
3
  import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"aria-label="Mark response as useful"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"aria-label="Mark response as not useful"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ template(`<div>`), _tmpl$4 = /* @__PURE__ */ template(`<span class="text-[11px] text-deposium-slate-500">`);
4
+ var _tmpl$ = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ template(`<div>`), _tmpl$4 = /* @__PURE__ */ template(`<span class="text-[11px] text-deposium-slate-500">`);
5
5
  const FeedbackInline = (props) => {
6
6
  const [rating, setRating] = createSignal(null);
7
7
  const strings = useMCPUIStrings();
@@ -37,13 +37,29 @@ const FeedbackInline = (props) => {
37
37
  return [(() => {
38
38
  var _el$2 = getNextElement(_tmpl$);
39
39
  _el$2.$$click = () => handle("positive");
40
- effect(() => setAttribute(_el$2, "title", strings.feedbackUseful));
40
+ effect((_p$) => {
41
+ var _v$ = strings.feedbackUseful, _v$2 = strings.feedbackUseful;
42
+ _v$ !== _p$.e && setAttribute(_el$2, "title", _p$.e = _v$);
43
+ _v$2 !== _p$.t && setAttribute(_el$2, "aria-label", _p$.t = _v$2);
44
+ return _p$;
45
+ }, {
46
+ e: void 0,
47
+ t: void 0
48
+ });
41
49
  runHydrationEvents();
42
50
  return _el$2;
43
51
  })(), (() => {
44
52
  var _el$3 = getNextElement(_tmpl$2);
45
53
  _el$3.$$click = () => handle("negative");
46
- effect(() => setAttribute(_el$3, "title", strings.feedbackNotUseful));
54
+ effect((_p$) => {
55
+ var _v$3 = strings.feedbackNotUseful, _v$4 = strings.feedbackNotUseful;
56
+ _v$3 !== _p$.e && setAttribute(_el$3, "title", _p$.e = _v$3);
57
+ _v$4 !== _p$.t && setAttribute(_el$3, "aria-label", _p$.t = _v$4);
58
+ return _p$;
59
+ }, {
60
+ e: void 0,
61
+ t: void 0
62
+ });
47
63
  runHydrationEvents();
48
64
  return _el$3;
49
65
  })()];
@@ -1 +1 @@
1
- {"version":3,"file":"FeedbackInline.js","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label=\"Mark response as useful\"\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label=\"Mark response as not useful\"\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_$setAttribute","feedbackUseful","_$runHydrationEvents","_el$3","_tmpl$2","feedbackNotUseful","_$className","class","trim","_$delegateEvents"],"mappings":";;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,OAAA;AAAAC,WAAAH,MAAAI,gBAEKC,MAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,eAAAQ,OAAA;AAAAN,iBAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,uBAAAC,aAAAJ,OAAA,SAE1BzB,QAAQ8B,cAAc,CAAA;AAAAC,6BAAAA;AAAA,iBAAAN;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAO,QAAAvB,eAAAwB,OAAA;AAAAD,gBAAAL,UAepB,MAAMzB,OAAO,UAAU;AAAC0B,uBAAAC,aAAAG,OAAA,SAE1BhC,QAAQkC,iBAAiB,CAAA;AAAAH,6BAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAJ,WAAA,MAAAO,UAAA3B,MAhC1B,2BAA2BZ,MAAMwC,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAA7B;AAAAA,EAAA,GAAA;AAgDrE;AAAC8B,eAAA,CAAA,OAAA,CAAA;"}
1
+ {"version":3,"file":"FeedbackInline.js","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label={strings.feedbackUseful}\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label={strings.feedbackNotUseful}\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_p$","_v$","feedbackUseful","_v$2","e","_$setAttribute","t","undefined","_$runHydrationEvents","_el$3","_tmpl$2","_v$3","feedbackNotUseful","_v$4","_$className","class","trim","_$delegateEvents"],"mappings":";;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,OAAA;AAAAC,WAAAH,MAAAI,gBAEKC,MAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,eAAAQ,OAAA;AAAAN,iBAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,iBAAAC,CAAAA,QAAA;AAAA,gBAAAC,MAE1B9B,QAAQ+B,gBAAcC,OACjBhC,QAAQ+B;AAAcD,oBAAAD,IAAAI,KAAAC,aAAAT,OAAA,SAAAI,IAAAI,IAAAH,GAAA;AAAAE,qBAAAH,IAAAM,KAAAD,aAAAT,OAAA,cAAAI,IAAAM,IAAAH,IAAA;AAAA,mBAAAH;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,6BAAAA;AAAA,iBAAAZ;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAa,QAAA7B,eAAA8B,OAAA;AAAAD,gBAAAX,UAczB,MAAMzB,OAAO,UAAU;AAAC0B,iBAAAC,CAAAA,QAAA;AAAA,gBAAAW,OAE1BxC,QAAQyC,mBAAiBC,OACpB1C,QAAQyC;AAAiBD,qBAAAX,IAAAI,KAAAC,aAAAI,OAAA,SAAAT,IAAAI,IAAAO,IAAA;AAAAE,qBAAAb,IAAAM,KAAAD,aAAAI,OAAA,cAAAT,IAAAM,IAAAO,IAAA;AAAA,mBAAAb;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,6BAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAV,WAAA,MAAAe,UAAAnC,MAjC/B,2BAA2BZ,MAAMgD,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAArC;AAAAA,EAAA,GAAA;AAgDrE;AAACsC,eAAA,CAAA,OAAA,CAAA;"}
@@ -3,10 +3,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
5
  const safeUrl = require("../utils/safe-url.cjs");
6
- var _tmpl$ = /* @__PURE__ */ web.template(`<span class=font-medium>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><!$><!/>ms`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path></svg><!$><!/>`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 12h6m-6 4h6m2 5H7a2 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"></path></svg><!$><!/> sources`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class="flex gap-3">`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class="mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4"><!$><!/><!$><!/><!$><!/><!$><!/><div class=flex-grow></div><!$><!/>`), _tmpl$7 = /* @__PURE__ */ web.template(`<a target=_blank rel="noopener noreferrer"class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">`);
6
+ const MCPUIStringsContext = require("../context/MCPUIStringsContext.cjs");
7
+ const formatString = require("../utils/format-string.cjs");
8
+ var _tmpl$ = /* @__PURE__ */ web.template(`<span class=font-medium>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><!$><!/>ms`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path></svg><!$><!/>`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 12h6m-6 4h6m2 5H7a2 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"></path></svg><!$><!/>`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class="flex gap-3">`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class="mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4"><!$><!/><!$><!/><!$><!/><!$><!/><div class=flex-grow></div><!$><!/>`), _tmpl$7 = /* @__PURE__ */ web.template(`<a target=_blank rel="noopener noreferrer"class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">`);
7
9
  const FooterRenderer = (props) => {
10
+ const strings = MCPUIStringsContext.useMCPUIStrings();
8
11
  return (() => {
9
- var _el$ = web.getNextElement(_tmpl$6), _el$17 = _el$.firstChild, [_el$18, _co$4] = web.getNextMarker(_el$17.nextSibling), _el$19 = _el$18.nextSibling, [_el$20, _co$5] = web.getNextMarker(_el$19.nextSibling), _el$21 = _el$20.nextSibling, [_el$22, _co$6] = web.getNextMarker(_el$21.nextSibling), _el$23 = _el$22.nextSibling, [_el$24, _co$7] = web.getNextMarker(_el$23.nextSibling), _el$15 = _el$24.nextSibling, _el$25 = _el$15.nextSibling, [_el$26, _co$8] = web.getNextMarker(_el$25.nextSibling);
12
+ var _el$ = web.getNextElement(_tmpl$6), _el$16 = _el$.firstChild, [_el$17, _co$4] = web.getNextMarker(_el$16.nextSibling), _el$18 = _el$17.nextSibling, [_el$19, _co$5] = web.getNextMarker(_el$18.nextSibling), _el$20 = _el$19.nextSibling, [_el$21, _co$6] = web.getNextMarker(_el$20.nextSibling), _el$22 = _el$21.nextSibling, [_el$23, _co$7] = web.getNextMarker(_el$22.nextSibling), _el$14 = _el$23.nextSibling, _el$24 = _el$14.nextSibling, [_el$25, _co$8] = web.getNextMarker(_el$24.nextSibling);
10
13
  web.insert(_el$, web.createComponent(solidJs.Show, {
11
14
  get when() {
12
15
  return props.params.poweredBy;
@@ -16,7 +19,7 @@ const FooterRenderer = (props) => {
16
19
  web.insert(_el$2, () => props.params.poweredBy);
17
20
  return _el$2;
18
21
  }
19
- }), _el$18, _co$4);
22
+ }), _el$17, _co$4);
20
23
  web.insert(_el$, web.createComponent(solidJs.Show, {
21
24
  get when() {
22
25
  return props.params.executionTime;
@@ -27,7 +30,7 @@ const FooterRenderer = (props) => {
27
30
  web.insert(_el$3, () => props.params.executionTime, _el$7, _co$);
28
31
  return _el$3;
29
32
  }
30
- }), _el$20, _co$5);
33
+ }), _el$19, _co$5);
31
34
  web.insert(_el$, web.createComponent(solidJs.Show, {
32
35
  get when() {
33
36
  return props.params.model;
@@ -37,38 +40,39 @@ const FooterRenderer = (props) => {
37
40
  web.insert(_el$8, () => props.params.model, _el$1, _co$2);
38
41
  return _el$8;
39
42
  }
40
- }), _el$22, _co$6);
43
+ }), _el$21, _co$6);
41
44
  web.insert(_el$, web.createComponent(solidJs.Show, {
42
45
  get when() {
43
46
  return props.params.sourceCount;
44
47
  },
45
48
  get children() {
46
- var _el$10 = web.getNextElement(_tmpl$4), _el$11 = _el$10.firstChild, _el$13 = _el$11.nextSibling, [_el$14, _co$3] = web.getNextMarker(_el$13.nextSibling);
47
- _el$14.nextSibling;
48
- web.insert(_el$10, () => props.params.sourceCount, _el$14, _co$3);
49
+ var _el$10 = web.getNextElement(_tmpl$4), _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, [_el$13, _co$3] = web.getNextMarker(_el$12.nextSibling);
50
+ web.insert(_el$10, () => formatString.formatMCPUIString(strings.footerSources, {
51
+ count: props.params.sourceCount
52
+ }), _el$13, _co$3);
49
53
  return _el$10;
50
54
  }
51
- }), _el$24, _co$7);
55
+ }), _el$23, _co$7);
52
56
  web.insert(_el$, web.createComponent(solidJs.Show, {
53
57
  get when() {
54
58
  return props.params.links;
55
59
  },
56
60
  get children() {
57
- var _el$16 = web.getNextElement(_tmpl$5);
58
- web.insert(_el$16, web.createComponent(solidJs.For, {
61
+ var _el$15 = web.getNextElement(_tmpl$5);
62
+ web.insert(_el$15, web.createComponent(solidJs.For, {
59
63
  get each() {
60
64
  return props.params.links;
61
65
  },
62
66
  children: (link) => (() => {
63
- var _el$27 = web.getNextElement(_tmpl$7);
64
- web.insert(_el$27, () => link.label);
65
- web.effect(() => web.setAttribute(_el$27, "href", safeUrl.safeUrl(link.url)));
66
- return _el$27;
67
+ var _el$26 = web.getNextElement(_tmpl$7);
68
+ web.insert(_el$26, () => link.label);
69
+ web.effect(() => web.setAttribute(_el$26, "href", safeUrl.safeUrl(link.url)));
70
+ return _el$26;
67
71
  })()
68
72
  }));
69
- return _el$16;
73
+ return _el$15;
70
74
  }
71
- }), _el$26, _co$8);
75
+ }), _el$25, _co$8);
72
76
  return _el$;
73
77
  })();
74
78
  };
@@ -1 +1 @@
1
- {"version":3,"file":"FooterRenderer.cjs","sources":["../../src/components/FooterRenderer.tsx"],"sourcesContent":["import { Component, Show, For } from 'solid-js'\nimport { safeUrl } from '../utils/safe-url'\n\nexport interface FooterComponentParams {\n poweredBy?: string\n executionTime?: number\n model?: string\n sourceCount?: number\n customText?: string\n links?: { label: string; url: string }[]\n}\n\nexport const FooterRenderer: Component<{ params: FooterComponentParams }> = (props) => {\n return (\n <div class=\"mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4\">\n <Show when={props.params.poweredBy}>\n <span class=\"font-medium\">{props.params.poweredBy}</span>\n </Show>\n\n <Show when={props.params.executionTime}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n {props.params.executionTime}ms\n </span>\n </Show>\n\n <Show when={props.params.model}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z\" />\n </svg>\n {props.params.model}\n </span>\n </Show>\n\n <Show when={props.params.sourceCount}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 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 {props.params.sourceCount} sources\n </span>\n </Show>\n\n <div class=\"flex-grow\" />\n\n <Show when={props.params.links}>\n <div class=\"flex gap-3\">\n <For each={props.params.links}>\n {(link) => (\n <a\n href={safeUrl(link.url)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"hover:text-blue-600 dark:hover:text-blue-400 transition-colors\"\n >\n {link.label}\n </a>\n )}\n </For>\n </div>\n </Show>\n </div>\n )\n}\n"],"names":["FooterRenderer","props","_el$","_$getNextElement","_tmpl$6","_el$17","firstChild","_el$18","_co$4","_$getNextMarker","nextSibling","_el$19","_el$20","_co$5","_el$21","_el$22","_co$6","_el$23","_el$24","_co$7","_el$15","_el$25","_el$26","_co$8","_$insert","_$createComponent","Show","when","params","poweredBy","children","_el$2","_tmpl$","executionTime","_el$3","_tmpl$2","_el$4","_el$6","_el$7","_co$","model","_el$8","_tmpl$3","_el$9","_el$0","_el$1","_co$2","sourceCount","_el$10","_tmpl$4","_el$11","_el$13","_el$14","_co$3","links","_el$16","_tmpl$5","For","each","link","_el$27","_tmpl$7","label","_$effect","_$setAttribute","safeUrl","url"],"mappings":"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"}
1
+ {"version":3,"file":"FooterRenderer.cjs","sources":["../../src/components/FooterRenderer.tsx"],"sourcesContent":["import { Component, Show, For } from 'solid-js'\nimport { safeUrl } from '../utils/safe-url'\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FooterComponentParams {\n poweredBy?: string\n executionTime?: number\n model?: string\n sourceCount?: number\n customText?: string\n links?: { label: string; url: string }[]\n}\n\nexport const FooterRenderer: Component<{ params: FooterComponentParams }> = (props) => {\n const strings = useMCPUIStrings()\n return (\n <div class=\"mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4\">\n <Show when={props.params.poweredBy}>\n <span class=\"font-medium\">{props.params.poweredBy}</span>\n </Show>\n\n <Show when={props.params.executionTime}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n {props.params.executionTime}ms\n </span>\n </Show>\n\n <Show when={props.params.model}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z\" />\n </svg>\n {props.params.model}\n </span>\n </Show>\n\n <Show when={props.params.sourceCount}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 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 {formatMCPUIString(strings.footerSources, { count: props.params.sourceCount! })}\n </span>\n </Show>\n\n <div class=\"flex-grow\" />\n\n <Show when={props.params.links}>\n <div class=\"flex gap-3\">\n <For each={props.params.links}>\n {(link) => (\n <a\n href={safeUrl(link.url)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"hover:text-blue-600 dark:hover:text-blue-400 transition-colors\"\n >\n {link.label}\n </a>\n )}\n </For>\n </div>\n </Show>\n </div>\n )\n}\n"],"names":["FooterRenderer","props","strings","useMCPUIStrings","_el$","_$getNextElement","_tmpl$6","_el$16","firstChild","_el$17","_co$4","_$getNextMarker","nextSibling","_el$18","_el$19","_co$5","_el$20","_el$21","_co$6","_el$22","_el$23","_co$7","_el$14","_el$24","_el$25","_co$8","_$insert","_$createComponent","Show","when","params","poweredBy","children","_el$2","_tmpl$","executionTime","_el$3","_tmpl$2","_el$4","_el$6","_el$7","_co$","model","_el$8","_tmpl$3","_el$9","_el$0","_el$1","_co$2","sourceCount","_el$10","_tmpl$4","_el$11","_el$12","_el$13","_co$3","formatMCPUIString","footerSources","count","links","_el$15","_tmpl$5","For","each","link","_el$26","_tmpl$7","label","_$effect","_$setAttribute","safeUrl","url"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FooterRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FooterRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,UAAU,CAAA;AAG/C,MAAM,WAAW,qBAAqB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC3C;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC;IAAE,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAsDvE,CAAA"}
1
+ {"version":3,"file":"FooterRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FooterRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,UAAU,CAAA;AAI/C,MAAM,WAAW,qBAAqB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC3C;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC;IAAE,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAuDvE,CAAA"}
@@ -1,10 +1,13 @@
1
1
  import { getNextElement, getNextMarker, insert, createComponent, effect, setAttribute, template } from "solid-js/web";
2
2
  import { Show, For } from "solid-js";
3
3
  import { safeUrl } from "../utils/safe-url.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<span class=font-medium>`), _tmpl$2 = /* @__PURE__ */ template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><!$><!/>ms`), _tmpl$3 = /* @__PURE__ */ template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path></svg><!$><!/>`), _tmpl$4 = /* @__PURE__ */ template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 12h6m-6 4h6m2 5H7a2 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"></path></svg><!$><!/> sources`), _tmpl$5 = /* @__PURE__ */ template(`<div class="flex gap-3">`), _tmpl$6 = /* @__PURE__ */ template(`<div class="mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4"><!$><!/><!$><!/><!$><!/><!$><!/><div class=flex-grow></div><!$><!/>`), _tmpl$7 = /* @__PURE__ */ template(`<a target=_blank rel="noopener noreferrer"class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">`);
4
+ import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
5
+ import { formatMCPUIString } from "../utils/format-string.js";
6
+ var _tmpl$ = /* @__PURE__ */ template(`<span class=font-medium>`), _tmpl$2 = /* @__PURE__ */ template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><!$><!/>ms`), _tmpl$3 = /* @__PURE__ */ template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path></svg><!$><!/>`), _tmpl$4 = /* @__PURE__ */ template(`<span class="flex items-center gap-1"><svg class="w-3 h-3"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 12h6m-6 4h6m2 5H7a2 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"></path></svg><!$><!/>`), _tmpl$5 = /* @__PURE__ */ template(`<div class="flex gap-3">`), _tmpl$6 = /* @__PURE__ */ template(`<div class="mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4"><!$><!/><!$><!/><!$><!/><!$><!/><div class=flex-grow></div><!$><!/>`), _tmpl$7 = /* @__PURE__ */ template(`<a target=_blank rel="noopener noreferrer"class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">`);
5
7
  const FooterRenderer = (props) => {
8
+ const strings = useMCPUIStrings();
6
9
  return (() => {
7
- var _el$ = getNextElement(_tmpl$6), _el$17 = _el$.firstChild, [_el$18, _co$4] = getNextMarker(_el$17.nextSibling), _el$19 = _el$18.nextSibling, [_el$20, _co$5] = getNextMarker(_el$19.nextSibling), _el$21 = _el$20.nextSibling, [_el$22, _co$6] = getNextMarker(_el$21.nextSibling), _el$23 = _el$22.nextSibling, [_el$24, _co$7] = getNextMarker(_el$23.nextSibling), _el$15 = _el$24.nextSibling, _el$25 = _el$15.nextSibling, [_el$26, _co$8] = getNextMarker(_el$25.nextSibling);
10
+ var _el$ = getNextElement(_tmpl$6), _el$16 = _el$.firstChild, [_el$17, _co$4] = getNextMarker(_el$16.nextSibling), _el$18 = _el$17.nextSibling, [_el$19, _co$5] = getNextMarker(_el$18.nextSibling), _el$20 = _el$19.nextSibling, [_el$21, _co$6] = getNextMarker(_el$20.nextSibling), _el$22 = _el$21.nextSibling, [_el$23, _co$7] = getNextMarker(_el$22.nextSibling), _el$14 = _el$23.nextSibling, _el$24 = _el$14.nextSibling, [_el$25, _co$8] = getNextMarker(_el$24.nextSibling);
8
11
  insert(_el$, createComponent(Show, {
9
12
  get when() {
10
13
  return props.params.poweredBy;
@@ -14,7 +17,7 @@ const FooterRenderer = (props) => {
14
17
  insert(_el$2, () => props.params.poweredBy);
15
18
  return _el$2;
16
19
  }
17
- }), _el$18, _co$4);
20
+ }), _el$17, _co$4);
18
21
  insert(_el$, createComponent(Show, {
19
22
  get when() {
20
23
  return props.params.executionTime;
@@ -25,7 +28,7 @@ const FooterRenderer = (props) => {
25
28
  insert(_el$3, () => props.params.executionTime, _el$7, _co$);
26
29
  return _el$3;
27
30
  }
28
- }), _el$20, _co$5);
31
+ }), _el$19, _co$5);
29
32
  insert(_el$, createComponent(Show, {
30
33
  get when() {
31
34
  return props.params.model;
@@ -35,38 +38,39 @@ const FooterRenderer = (props) => {
35
38
  insert(_el$8, () => props.params.model, _el$1, _co$2);
36
39
  return _el$8;
37
40
  }
38
- }), _el$22, _co$6);
41
+ }), _el$21, _co$6);
39
42
  insert(_el$, createComponent(Show, {
40
43
  get when() {
41
44
  return props.params.sourceCount;
42
45
  },
43
46
  get children() {
44
- var _el$10 = getNextElement(_tmpl$4), _el$11 = _el$10.firstChild, _el$13 = _el$11.nextSibling, [_el$14, _co$3] = getNextMarker(_el$13.nextSibling);
45
- _el$14.nextSibling;
46
- insert(_el$10, () => props.params.sourceCount, _el$14, _co$3);
47
+ var _el$10 = getNextElement(_tmpl$4), _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, [_el$13, _co$3] = getNextMarker(_el$12.nextSibling);
48
+ insert(_el$10, () => formatMCPUIString(strings.footerSources, {
49
+ count: props.params.sourceCount
50
+ }), _el$13, _co$3);
47
51
  return _el$10;
48
52
  }
49
- }), _el$24, _co$7);
53
+ }), _el$23, _co$7);
50
54
  insert(_el$, createComponent(Show, {
51
55
  get when() {
52
56
  return props.params.links;
53
57
  },
54
58
  get children() {
55
- var _el$16 = getNextElement(_tmpl$5);
56
- insert(_el$16, createComponent(For, {
59
+ var _el$15 = getNextElement(_tmpl$5);
60
+ insert(_el$15, createComponent(For, {
57
61
  get each() {
58
62
  return props.params.links;
59
63
  },
60
64
  children: (link) => (() => {
61
- var _el$27 = getNextElement(_tmpl$7);
62
- insert(_el$27, () => link.label);
63
- effect(() => setAttribute(_el$27, "href", safeUrl(link.url)));
64
- return _el$27;
65
+ var _el$26 = getNextElement(_tmpl$7);
66
+ insert(_el$26, () => link.label);
67
+ effect(() => setAttribute(_el$26, "href", safeUrl(link.url)));
68
+ return _el$26;
65
69
  })()
66
70
  }));
67
- return _el$16;
71
+ return _el$15;
68
72
  }
69
- }), _el$26, _co$8);
73
+ }), _el$25, _co$8);
70
74
  return _el$;
71
75
  })();
72
76
  };
@@ -1 +1 @@
1
- {"version":3,"file":"FooterRenderer.js","sources":["../../src/components/FooterRenderer.tsx"],"sourcesContent":["import { Component, Show, For } from 'solid-js'\nimport { safeUrl } from '../utils/safe-url'\n\nexport interface FooterComponentParams {\n poweredBy?: string\n executionTime?: number\n model?: string\n sourceCount?: number\n customText?: string\n links?: { label: string; url: string }[]\n}\n\nexport const FooterRenderer: Component<{ params: FooterComponentParams }> = (props) => {\n return (\n <div class=\"mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4\">\n <Show when={props.params.poweredBy}>\n <span class=\"font-medium\">{props.params.poweredBy}</span>\n </Show>\n\n <Show when={props.params.executionTime}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n {props.params.executionTime}ms\n </span>\n </Show>\n\n <Show when={props.params.model}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z\" />\n </svg>\n {props.params.model}\n </span>\n </Show>\n\n <Show when={props.params.sourceCount}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 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 {props.params.sourceCount} sources\n </span>\n </Show>\n\n <div class=\"flex-grow\" />\n\n <Show when={props.params.links}>\n <div class=\"flex gap-3\">\n <For each={props.params.links}>\n {(link) => (\n <a\n href={safeUrl(link.url)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"hover:text-blue-600 dark:hover:text-blue-400 transition-colors\"\n >\n {link.label}\n </a>\n )}\n </For>\n </div>\n </Show>\n </div>\n )\n}\n"],"names":["FooterRenderer","props","_el$","_$getNextElement","_tmpl$6","_el$17","firstChild","_el$18","_co$4","_$getNextMarker","nextSibling","_el$19","_el$20","_co$5","_el$21","_el$22","_co$6","_el$23","_el$24","_co$7","_el$15","_el$25","_el$26","_co$8","_$insert","_$createComponent","Show","when","params","poweredBy","children","_el$2","_tmpl$","executionTime","_el$3","_tmpl$2","_el$4","_el$6","_el$7","_co$","model","_el$8","_tmpl$3","_el$9","_el$0","_el$1","_co$2","sourceCount","_el$10","_tmpl$4","_el$11","_el$13","_el$14","_co$3","links","_el$16","_tmpl$5","For","each","link","_el$27","_tmpl$7","label","_$effect","_$setAttribute","safeUrl","url"],"mappings":"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"}
1
+ {"version":3,"file":"FooterRenderer.js","sources":["../../src/components/FooterRenderer.tsx"],"sourcesContent":["import { Component, Show, For } from 'solid-js'\nimport { safeUrl } from '../utils/safe-url'\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FooterComponentParams {\n poweredBy?: string\n executionTime?: number\n model?: string\n sourceCount?: number\n customText?: string\n links?: { label: string; url: string }[]\n}\n\nexport const FooterRenderer: Component<{ params: FooterComponentParams }> = (props) => {\n const strings = useMCPUIStrings()\n return (\n <div class=\"mt-4 pt-3 border-t border-gray-200 dark:border-gray-700 text-xs text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-4\">\n <Show when={props.params.poweredBy}>\n <span class=\"font-medium\">{props.params.poweredBy}</span>\n </Show>\n\n <Show when={props.params.executionTime}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n {props.params.executionTime}ms\n </span>\n </Show>\n\n <Show when={props.params.model}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z\" />\n </svg>\n {props.params.model}\n </span>\n </Show>\n\n <Show when={props.params.sourceCount}>\n <span class=\"flex items-center gap-1\">\n <svg class=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 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 {formatMCPUIString(strings.footerSources, { count: props.params.sourceCount! })}\n </span>\n </Show>\n\n <div class=\"flex-grow\" />\n\n <Show when={props.params.links}>\n <div class=\"flex gap-3\">\n <For each={props.params.links}>\n {(link) => (\n <a\n href={safeUrl(link.url)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"hover:text-blue-600 dark:hover:text-blue-400 transition-colors\"\n >\n {link.label}\n </a>\n )}\n </For>\n </div>\n </Show>\n </div>\n )\n}\n"],"names":["FooterRenderer","props","strings","useMCPUIStrings","_el$","_$getNextElement","_tmpl$6","_el$16","firstChild","_el$17","_co$4","_$getNextMarker","nextSibling","_el$18","_el$19","_co$5","_el$20","_el$21","_co$6","_el$22","_el$23","_co$7","_el$14","_el$24","_el$25","_co$8","_$insert","_$createComponent","Show","when","params","poweredBy","children","_el$2","_tmpl$","executionTime","_el$3","_tmpl$2","_el$4","_el$6","_el$7","_co$","model","_el$8","_tmpl$3","_el$9","_el$0","_el$1","_co$2","sourceCount","_el$10","_tmpl$4","_el$11","_el$12","_el$13","_co$3","formatMCPUIString","footerSources","count","links","_el$15","_tmpl$5","For","each","link","_el$26","_tmpl$7","label","_$effect","_$setAttribute","safeUrl","url"],"mappings":"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"}