@seed-ship/mcp-ui-solid 6.19.1 → 6.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/CHANGELOG.md +663 -0
  2. package/README.md +911 -4
  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/FooterRenderer.cjs +21 -17
  86. package/dist/components/FooterRenderer.cjs.map +1 -1
  87. package/dist/components/FooterRenderer.d.ts.map +1 -1
  88. package/dist/components/FooterRenderer.js +21 -17
  89. package/dist/components/FooterRenderer.js.map +1 -1
  90. package/dist/components/FormFieldRenderer.cjs +116 -93
  91. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  92. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  93. package/dist/components/FormFieldRenderer.js +116 -93
  94. package/dist/components/FormFieldRenderer.js.map +1 -1
  95. package/dist/components/FormRenderer.cjs +55 -31
  96. package/dist/components/FormRenderer.cjs.map +1 -1
  97. package/dist/components/FormRenderer.d.ts.map +1 -1
  98. package/dist/components/FormRenderer.js +55 -31
  99. package/dist/components/FormRenderer.js.map +1 -1
  100. package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
  101. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  102. package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
  103. package/dist/components/GenerativeUIErrorBoundary.js +20 -15
  104. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  105. package/dist/components/GraphRenderer.cjs +56 -33
  106. package/dist/components/GraphRenderer.cjs.map +1 -1
  107. package/dist/components/GraphRenderer.d.ts.map +1 -1
  108. package/dist/components/GraphRenderer.js +56 -33
  109. package/dist/components/GraphRenderer.js.map +1 -1
  110. package/dist/components/IframeFallbackLink.cjs +37 -0
  111. package/dist/components/IframeFallbackLink.cjs.map +1 -0
  112. package/dist/components/IframeFallbackLink.d.ts +23 -0
  113. package/dist/components/IframeFallbackLink.d.ts.map +1 -0
  114. package/dist/components/IframeFallbackLink.js +37 -0
  115. package/dist/components/IframeFallbackLink.js.map +1 -0
  116. package/dist/components/ImageGalleryRenderer.cjs +13 -4
  117. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  118. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  119. package/dist/components/ImageGalleryRenderer.js +13 -4
  120. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  121. package/dist/components/LightboxOverlay.cjs +16 -8
  122. package/dist/components/LightboxOverlay.cjs.map +1 -1
  123. package/dist/components/LightboxOverlay.d.ts.map +1 -1
  124. package/dist/components/LightboxOverlay.js +17 -9
  125. package/dist/components/LightboxOverlay.js.map +1 -1
  126. package/dist/components/MapRenderer.cjs +59 -29
  127. package/dist/components/MapRenderer.cjs.map +1 -1
  128. package/dist/components/MapRenderer.d.ts +10 -2
  129. package/dist/components/MapRenderer.d.ts.map +1 -1
  130. package/dist/components/MapRenderer.js +60 -30
  131. package/dist/components/MapRenderer.js.map +1 -1
  132. package/dist/components/ModalRenderer.cjs +4 -1
  133. package/dist/components/ModalRenderer.cjs.map +1 -1
  134. package/dist/components/ModalRenderer.d.ts.map +1 -1
  135. package/dist/components/ModalRenderer.js +5 -2
  136. package/dist/components/ModalRenderer.js.map +1 -1
  137. package/dist/components/ScratchpadPanel.cjs +578 -535
  138. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  139. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  140. package/dist/components/ScratchpadPanel.js +578 -535
  141. package/dist/components/ScratchpadPanel.js.map +1 -1
  142. package/dist/components/StreamingUIRenderer.cjs +92 -28
  143. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  144. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  145. package/dist/components/StreamingUIRenderer.js +92 -28
  146. package/dist/components/StreamingUIRenderer.js.map +1 -1
  147. package/dist/components/UIResourceRenderer.cjs +481 -365
  148. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  149. package/dist/components/UIResourceRenderer.d.ts +21 -0
  150. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  151. package/dist/components/UIResourceRenderer.js +484 -368
  152. package/dist/components/UIResourceRenderer.js.map +1 -1
  153. package/dist/components/VerifiedText.cjs +39 -20
  154. package/dist/components/VerifiedText.cjs.map +1 -1
  155. package/dist/components/VerifiedText.d.ts +2 -1
  156. package/dist/components/VerifiedText.d.ts.map +1 -1
  157. package/dist/components/VerifiedText.js +39 -20
  158. package/dist/components/VerifiedText.js.map +1 -1
  159. package/dist/components/VideoRenderer.cjs +51 -20
  160. package/dist/components/VideoRenderer.cjs.map +1 -1
  161. package/dist/components/VideoRenderer.d.ts.map +1 -1
  162. package/dist/components/VideoRenderer.js +51 -20
  163. package/dist/components/VideoRenderer.js.map +1 -1
  164. package/dist/components/chart-data-table.cjs +38 -17
  165. package/dist/components/chart-data-table.cjs.map +1 -1
  166. package/dist/components/chart-data-table.d.ts +30 -1
  167. package/dist/components/chart-data-table.d.ts.map +1 -1
  168. package/dist/components/chart-data-table.js +38 -17
  169. package/dist/components/chart-data-table.js.map +1 -1
  170. package/dist/context/MCPActionContext.cjs +3 -1
  171. package/dist/context/MCPActionContext.cjs.map +1 -1
  172. package/dist/context/MCPActionContext.d.ts.map +1 -1
  173. package/dist/context/MCPActionContext.js +3 -1
  174. package/dist/context/MCPActionContext.js.map +1 -1
  175. package/dist/context/MCPUIConfigContext.cjs +29 -0
  176. package/dist/context/MCPUIConfigContext.cjs.map +1 -0
  177. package/dist/context/MCPUIConfigContext.d.ts +124 -0
  178. package/dist/context/MCPUIConfigContext.d.ts.map +1 -0
  179. package/dist/context/MCPUIConfigContext.js +29 -0
  180. package/dist/context/MCPUIConfigContext.js.map +1 -0
  181. package/dist/context/MCPUIStringsContext.cjs +287 -2
  182. package/dist/context/MCPUIStringsContext.cjs.map +1 -1
  183. package/dist/context/MCPUIStringsContext.d.ts +607 -3
  184. package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
  185. package/dist/context/MCPUIStringsContext.js +287 -2
  186. package/dist/context/MCPUIStringsContext.js.map +1 -1
  187. package/dist/hooks/index.d.ts +2 -2
  188. package/dist/hooks/index.d.ts.map +1 -1
  189. package/dist/hooks/useStreamingUI.cjs +28 -10
  190. package/dist/hooks/useStreamingUI.cjs.map +1 -1
  191. package/dist/hooks/useStreamingUI.d.ts +37 -0
  192. package/dist/hooks/useStreamingUI.d.ts.map +1 -1
  193. package/dist/hooks/useStreamingUI.js +28 -10
  194. package/dist/hooks/useStreamingUI.js.map +1 -1
  195. package/dist/hooks.cjs +1 -0
  196. package/dist/hooks.cjs.map +1 -1
  197. package/dist/hooks.js +2 -1
  198. package/dist/index.cjs +29 -8
  199. package/dist/index.cjs.map +1 -1
  200. package/dist/index.d.cts +12 -4
  201. package/dist/index.d.ts +12 -4
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +24 -3
  204. package/dist/index.js.map +1 -1
  205. package/dist/services/index.d.ts +1 -1
  206. package/dist/services/index.d.ts.map +1 -1
  207. package/dist/services/validation.cjs +52 -26
  208. package/dist/services/validation.cjs.map +1 -1
  209. package/dist/services/validation.d.ts +67 -2
  210. package/dist/services/validation.d.ts.map +1 -1
  211. package/dist/services/validation.js +52 -26
  212. package/dist/services/validation.js.map +1 -1
  213. package/dist/utils/degraded-projections.cjs +37 -12
  214. package/dist/utils/degraded-projections.cjs.map +1 -1
  215. package/dist/utils/degraded-projections.d.ts +39 -3
  216. package/dist/utils/degraded-projections.d.ts.map +1 -1
  217. package/dist/utils/degraded-projections.js +37 -12
  218. package/dist/utils/degraded-projections.js.map +1 -1
  219. package/dist/utils/format-string.cjs +10 -0
  220. package/dist/utils/format-string.cjs.map +1 -0
  221. package/dist/utils/format-string.d.ts +26 -0
  222. package/dist/utils/format-string.d.ts.map +1 -0
  223. package/dist/utils/format-string.js +10 -0
  224. package/dist/utils/format-string.js.map +1 -0
  225. package/dist/utils/iframe-coep.cjs +30 -0
  226. package/dist/utils/iframe-coep.cjs.map +1 -0
  227. package/dist/utils/iframe-coep.d.ts +46 -0
  228. package/dist/utils/iframe-coep.d.ts.map +1 -0
  229. package/dist/utils/iframe-coep.js +30 -0
  230. package/dist/utils/iframe-coep.js.map +1 -0
  231. package/dist/validation.cjs +5 -0
  232. package/dist/validation.cjs.map +1 -1
  233. package/dist/validation.d.cts +2 -1
  234. package/dist/validation.d.ts +2 -1
  235. package/dist/validation.d.ts.map +1 -1
  236. package/dist/validation.js +6 -1
  237. package/package.json +1 -1
  238. package/src/adapters/connector.ts +58 -4
  239. package/src/adapters/index.ts +12 -2
  240. package/src/adapters/macro-run.ts +71 -11
  241. package/src/components/ActionGroupRenderer.tsx +3 -1
  242. package/src/components/AgentCard.tsx +27 -9
  243. package/src/components/AgentHandoff.tsx +4 -1
  244. package/src/components/ArtifactRenderer.tsx +17 -5
  245. package/src/components/AutocompleteDropdown.tsx +8 -6
  246. package/src/components/AutocompleteFormField.tsx +5 -1
  247. package/src/components/BriefingDiff.tsx +11 -3
  248. package/src/components/CarouselRenderer.tsx +4 -2
  249. package/src/components/ChartJSRenderer.tsx +18 -9
  250. package/src/components/ChatPrompt.tsx +13 -8
  251. package/src/components/CodeBlockRenderer.tsx +12 -10
  252. package/src/components/DataPreviewSection.tsx +92 -26
  253. package/src/components/DegradedFallback.tsx +4 -2
  254. package/src/components/FooterRenderer.tsx +3 -1
  255. package/src/components/FormFieldRenderer.tsx +34 -19
  256. package/src/components/FormRenderer.tsx +38 -10
  257. package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
  258. package/src/components/GraphRenderer.tsx +31 -16
  259. package/src/components/IframeFallbackLink.tsx +57 -0
  260. package/src/components/ImageGalleryRenderer.tsx +8 -4
  261. package/src/components/LightboxOverlay.tsx +6 -4
  262. package/src/components/MapRenderer.tsx +57 -20
  263. package/src/components/ModalRenderer.tsx +3 -1
  264. package/src/components/ScratchpadPanel.tsx +95 -44
  265. package/src/components/StreamingUIRenderer.tsx +41 -11
  266. package/src/components/UIResourceRenderer.tsx +176 -67
  267. package/src/components/VerifiedText.tsx +19 -9
  268. package/src/components/VideoRenderer.tsx +26 -4
  269. package/src/components/chart-data-table.ts +68 -14
  270. package/src/context/MCPActionContext.tsx +4 -1
  271. package/src/context/MCPUIConfigContext.tsx +151 -0
  272. package/src/context/MCPUIStringsContext.tsx +1014 -1
  273. package/src/hooks/index.ts +2 -1
  274. package/src/hooks/useStreamingUI.ts +64 -10
  275. package/src/index.ts +38 -0
  276. package/src/services/index.ts +1 -0
  277. package/src/services/validation.ts +131 -32
  278. package/src/solid-jsx-attrs.d.ts +24 -0
  279. package/src/utils/degraded-projections.ts +75 -12
  280. package/src/utils/format-string.ts +33 -0
  281. package/src/utils/iframe-coep.ts +74 -0
  282. package/src/validation.ts +9 -0
@@ -3,12 +3,15 @@ import { createSignal, Show, For } from "solid-js";
3
3
  import { LightboxOverlay } from "./LightboxOverlay.js";
4
4
  import { useExpanded, ExpandableWrapper } from "./ExpandableWrapper.js";
5
5
  import { safeUrl } from "../utils/safe-url.js";
6
+ import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
7
+ import { formatMCPUIString } from "../utils/format-string.js";
6
8
  var _tmpl$ = /* @__PURE__ */ template(`<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ template(`<div><!$><!/><div></div><!$><!/>`), _tmpl$3 = /* @__PURE__ */ template(`<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4"><span class="truncate block">`), _tmpl$4 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200"><div class="bg-white/90 dark:bg-gray-800/90 rounded-full p-2"><svg class="w-5 h-5 text-gray-700 dark:text-gray-200"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7">`), _tmpl$5 = /* @__PURE__ */ template(`<button type=button><img class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"loading=lazy><div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200"></div><!$><!/><!$><!/>`, true, false, false);
7
9
  function imagesToTextList(p) {
8
10
  if (!p) return "";
9
11
  return (p.images ?? []).map((img) => img.caption ? `${img.url} ${img.caption}` : img.url).join("\n");
10
12
  }
11
13
  const ImageGalleryRenderer = (props) => {
14
+ const strings = useMCPUIStrings();
12
15
  const [selectedIndex, setSelectedIndex] = createSignal(null);
13
16
  const isExpanded = useExpanded();
14
17
  const params = () => {
@@ -65,12 +68,14 @@ const ImageGalleryRenderer = (props) => {
65
68
  return createComponent(ExpandableWrapper, {
66
69
  get title() {
67
70
  var _a;
68
- return ((_a = params()) == null ? void 0 : _a.title) || "Gallery";
71
+ return ((_a = params()) == null ? void 0 : _a.title) || strings.galleryTitle;
69
72
  },
70
73
  get copyData() {
71
74
  return imagesToTextList(params());
72
75
  },
73
- copyLabel: "Copy image URLs",
76
+ get copyLabel() {
77
+ return strings.galleryCopy;
78
+ },
74
79
  get toolbarVariant() {
75
80
  return props.toolbarVariant;
76
81
  },
@@ -116,9 +121,13 @@ const ImageGalleryRenderer = (props) => {
116
121
  }
117
122
  }), _el$16, _co$4);
118
123
  effect((_p$) => {
119
- var _v$3 = `relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`, _v$4 = image.alt || `View image ${index() + 1}`, _v$5 = safeUrl(image.thumbnail || image.url, {
124
+ var _v$3 = `relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`, _v$4 = image.alt || formatMCPUIString(strings.galleryViewImage, {
125
+ index: index() + 1
126
+ }), _v$5 = safeUrl(image.thumbnail || image.url, {
120
127
  allowDataImage: true
121
- }), _v$6 = image.alt || `Image ${index() + 1}`, _v$7 = image.srcset, _v$8 = image.sizes;
128
+ }), _v$6 = image.alt || formatMCPUIString(strings.galleryImageAlt, {
129
+ index: index() + 1
130
+ }), _v$7 = image.srcset, _v$8 = image.sizes;
122
131
  _v$3 !== _p$.e && className(_el$9, _p$.e = _v$3);
123
132
  _v$4 !== _p$.t && setAttribute(_el$9, "aria-label", _p$.t = _v$4);
124
133
  _v$5 !== _p$.a && setAttribute(_el$0, "src", _p$.a = _v$5);
@@ -1 +1 @@
1
- {"version":3,"file":"ImageGalleryRenderer.js","sources":["../../src/components/ImageGalleryRenderer.tsx"],"sourcesContent":["/**\n * ImageGalleryRenderer - Gallery view for multiple images\n * Sprint 5: Media Components\n */\n\nimport { Component, createSignal, For, Show } from 'solid-js'\nimport type { UIComponent, ImageGalleryParams } from '../types'\nimport { LightboxOverlay } from './LightboxOverlay'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\nimport { safeUrl } from '../utils/safe-url'\n\nexport interface ImageGalleryRendererProps {\n /**\n * UIComponent containing gallery params\n */\n component?: UIComponent\n\n /**\n * Direct gallery params (alternative to component)\n */\n params?: ImageGalleryParams\n\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\n/** Build a newline-separated list of image URLs (with captions when present)\n * for the ExpandableWrapper copy button. v6.2.0. */\nfunction imagesToTextList(p: ImageGalleryParams | undefined): string {\n if (!p) return ''\n return (p.images ?? [])\n .map((img) => (img.caption ? `${img.url}\\t${img.caption}` : img.url))\n .join('\\n')\n}\n\nexport const ImageGalleryRenderer: Component<ImageGalleryRendererProps> = (props) => {\n const [selectedIndex, setSelectedIndex] = createSignal<number | null>(null)\n const isExpanded = useExpanded()\n\n const params = () => props.params || (props.component?.params as ImageGalleryParams)\n\n const columnsClass = () => {\n switch (params()?.columns) {\n case 2:\n return 'grid-cols-2'\n case 3:\n return 'grid-cols-3'\n case 4:\n return 'grid-cols-4'\n case 5:\n return 'grid-cols-5'\n default:\n return 'grid-cols-3'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default:\n return 'gap-2'\n }\n }\n\n const aspectClass = () => {\n switch (params()?.aspectRatio) {\n case '1:1':\n return 'aspect-square'\n case '16:9':\n return 'aspect-video'\n case '4:3':\n return 'aspect-[4/3]'\n default:\n return ''\n }\n }\n\n const handleImageClick = (index: number) => {\n if (params()?.lightbox !== false) {\n setSelectedIndex(index)\n }\n }\n\n return (\n <ExpandableWrapper\n title={params()?.title || 'Gallery'}\n copyData={imagesToTextList(params())}\n copyLabel=\"Copy image URLs\"\n toolbarVariant={props.toolbarVariant}\n >\n <div class={`w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}>\n {/* Title */}\n <Show when={params()?.title}>\n <div class=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params()!.title}</h3>\n </div>\n </Show>\n\n {/* Gallery Grid */}\n <div class={`grid ${columnsClass()} ${gapClass()} p-4 ${isExpanded() ? 'flex-1 min-h-0 overflow-auto' : ''}`}>\n <For each={params()?.images}>\n {(image, index) => (\n <button\n class={`relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`}\n onClick={() => handleImageClick(index())}\n type=\"button\"\n aria-label={image.alt || `View image ${index() + 1}`}\n >\n <img\n src={safeUrl(image.thumbnail || image.url, { allowDataImage: true })}\n alt={image.alt || `Image ${index() + 1}`}\n srcset={image.srcset}\n sizes={image.sizes}\n class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-200\"\n loading=\"lazy\"\n />\n\n {/* Hover overlay */}\n <div class=\"absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200\" />\n\n {/* Caption overlay */}\n <Show when={image.caption && params()?.showCaptions}>\n <div class=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4\">\n <span class=\"truncate block\">{image.caption}</span>\n </div>\n </Show>\n\n {/* Zoom icon on hover */}\n <Show when={params()?.lightbox !== false}>\n <div class=\"absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n <div class=\"bg-white/90 dark:bg-gray-800/90 rounded-full p-2\">\n <svg\n class=\"w-5 h-5 text-gray-700 dark:text-gray-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7\"\n />\n </svg>\n </div>\n </div>\n </Show>\n </button>\n )}\n </For>\n </div>\n\n {/* Lightbox */}\n <LightboxOverlay\n images={params()?.images || []}\n selectedIndex={selectedIndex()}\n onClose={() => setSelectedIndex(null)}\n onNavigate={setSelectedIndex}\n />\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["imagesToTextList","p","images","map","img","caption","url","join","ImageGalleryRenderer","props","selectedIndex","setSelectedIndex","createSignal","isExpanded","useExpanded","params","component","columnsClass","columns","gapClass","gap","aspectClass","aspectRatio","handleImageClick","index","lightbox","_$createComponent","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","children","_el$","_$getNextElement","_tmpl$2","_el$5","firstChild","_el$6","_co$","_$getNextMarker","nextSibling","_el$4","_el$7","_el$8","_co$2","_$insert","Show","when","_el$2","_tmpl$","_el$3","For","each","image","_el$9","_tmpl$5","_el$0","_el$1","_el$13","_el$14","_co$3","_el$15","_el$16","_co$4","$$click","_$memo","showCaptions","_el$10","_tmpl$3","_el$11","_tmpl$4","_$effect","_p$","_v$3","_v$4","alt","_v$5","safeUrl","thumbnail","allowDataImage","_v$6","_v$7","srcset","_v$8","sizes","e","_$className","t","_$setAttribute","a","o","i","n","undefined","_$runHydrationEvents","LightboxOverlay","onClose","onNavigate","_v$","_v$2","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ImageGalleryRenderer.js","sources":["../../src/components/ImageGalleryRenderer.tsx"],"sourcesContent":["/**\n * ImageGalleryRenderer - Gallery view for multiple images\n * Sprint 5: Media Components\n */\n\nimport { Component, createSignal, For, Show } from 'solid-js'\nimport type { UIComponent, ImageGalleryParams } from '../types'\nimport { LightboxOverlay } from './LightboxOverlay'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\nimport { safeUrl } from '../utils/safe-url'\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface ImageGalleryRendererProps {\n /**\n * UIComponent containing gallery params\n */\n component?: UIComponent\n\n /**\n * Direct gallery params (alternative to component)\n */\n params?: ImageGalleryParams\n\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\n/** Build a newline-separated list of image URLs (with captions when present)\n * for the ExpandableWrapper copy button. v6.2.0. */\nfunction imagesToTextList(p: ImageGalleryParams | undefined): string {\n if (!p) return ''\n return (p.images ?? [])\n .map((img) => (img.caption ? `${img.url}\\t${img.caption}` : img.url))\n .join('\\n')\n}\n\nexport const ImageGalleryRenderer: Component<ImageGalleryRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const [selectedIndex, setSelectedIndex] = createSignal<number | null>(null)\n const isExpanded = useExpanded()\n\n const params = () => props.params || (props.component?.params as ImageGalleryParams)\n\n const columnsClass = () => {\n switch (params()?.columns) {\n case 2:\n return 'grid-cols-2'\n case 3:\n return 'grid-cols-3'\n case 4:\n return 'grid-cols-4'\n case 5:\n return 'grid-cols-5'\n default:\n return 'grid-cols-3'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default:\n return 'gap-2'\n }\n }\n\n const aspectClass = () => {\n switch (params()?.aspectRatio) {\n case '1:1':\n return 'aspect-square'\n case '16:9':\n return 'aspect-video'\n case '4:3':\n return 'aspect-[4/3]'\n default:\n return ''\n }\n }\n\n const handleImageClick = (index: number) => {\n if (params()?.lightbox !== false) {\n setSelectedIndex(index)\n }\n }\n\n return (\n <ExpandableWrapper\n title={params()?.title || strings.galleryTitle}\n copyData={imagesToTextList(params())}\n copyLabel={strings.galleryCopy}\n toolbarVariant={props.toolbarVariant}\n >\n <div class={`w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}>\n {/* Title */}\n <Show when={params()?.title}>\n <div class=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params()!.title}</h3>\n </div>\n </Show>\n\n {/* Gallery Grid */}\n <div class={`grid ${columnsClass()} ${gapClass()} p-4 ${isExpanded() ? 'flex-1 min-h-0 overflow-auto' : ''}`}>\n <For each={params()?.images}>\n {(image, index) => (\n <button\n class={`relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`}\n onClick={() => handleImageClick(index())}\n type=\"button\"\n aria-label={\n image.alt || formatMCPUIString(strings.galleryViewImage, { index: index() + 1 })\n }\n >\n <img\n src={safeUrl(image.thumbnail || image.url, { allowDataImage: true })}\n alt={image.alt || formatMCPUIString(strings.galleryImageAlt, { index: index() + 1 })}\n srcset={image.srcset}\n sizes={image.sizes}\n class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-200\"\n loading=\"lazy\"\n />\n\n {/* Hover overlay */}\n <div class=\"absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200\" />\n\n {/* Caption overlay */}\n <Show when={image.caption && params()?.showCaptions}>\n <div class=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4\">\n <span class=\"truncate block\">{image.caption}</span>\n </div>\n </Show>\n\n {/* Zoom icon on hover */}\n <Show when={params()?.lightbox !== false}>\n <div class=\"absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n <div class=\"bg-white/90 dark:bg-gray-800/90 rounded-full p-2\">\n <svg\n class=\"w-5 h-5 text-gray-700 dark:text-gray-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7\"\n />\n </svg>\n </div>\n </div>\n </Show>\n </button>\n )}\n </For>\n </div>\n\n {/* Lightbox */}\n <LightboxOverlay\n images={params()?.images || []}\n selectedIndex={selectedIndex()}\n onClose={() => setSelectedIndex(null)}\n onNavigate={setSelectedIndex}\n />\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["imagesToTextList","p","images","map","img","caption","url","join","ImageGalleryRenderer","props","strings","useMCPUIStrings","selectedIndex","setSelectedIndex","createSignal","isExpanded","useExpanded","params","component","columnsClass","columns","gapClass","gap","aspectClass","aspectRatio","handleImageClick","index","lightbox","_$createComponent","ExpandableWrapper","title","galleryTitle","copyData","copyLabel","galleryCopy","toolbarVariant","children","_el$","_$getNextElement","_tmpl$2","_el$5","firstChild","_el$6","_co$","_$getNextMarker","nextSibling","_el$4","_el$7","_el$8","_co$2","_$insert","Show","when","_el$2","_tmpl$","_el$3","For","each","image","_el$9","_tmpl$5","_el$0","_el$1","_el$13","_el$14","_co$3","_el$15","_el$16","_co$4","$$click","_$memo","showCaptions","_el$10","_tmpl$3","_el$11","_tmpl$4","_$effect","_p$","_v$3","_v$4","alt","formatMCPUIString","galleryViewImage","_v$5","safeUrl","thumbnail","allowDataImage","_v$6","galleryImageAlt","_v$7","srcset","_v$8","sizes","e","_$className","t","_$setAttribute","a","o","i","n","undefined","_$runHydrationEvents","LightboxOverlay","onClose","onNavigate","_v$","_v$2","_$delegateEvents"],"mappings":"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"}
@@ -3,8 +3,10 @@ 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(`<button class="absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"aria-label="Previous image"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M15 19l-7-7 7-7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button class="absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"aria-label="Next image"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 5l7 7-7 7">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="fixed inset-0 z-50 bg-black/90 flex items-center justify-center"role=dialog aria-modal=true aria-label="Image lightbox"><button class="absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"aria-label="Close lightbox"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12"></path></svg></button><!$><!/><!$><!/><img class="max-w-[90vw] max-h-[90vh] object-contain"><!$><!/><div class="absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm"><!$><!/> / <!$><!/>`);
6
+ const MCPUIStringsContext = require("../context/MCPUIStringsContext.cjs");
7
+ var _tmpl$ = /* @__PURE__ */ web.template(`<button class="absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M15 19l-7-7 7-7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button class="absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 5l7 7-7 7">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="fixed inset-0 z-50 bg-black/90 flex items-center justify-center"role=dialog aria-modal=true><button class="absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12"></path></svg></button><!$><!/><!$><!/><img class="max-w-[90vw] max-h-[90vh] object-contain"><!$><!/><div class="absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm"><!$><!/> / <!$><!/>`);
7
8
  const LightboxOverlay = (props) => {
9
+ const strings = MCPUIStringsContext.useMCPUIStrings();
8
10
  const isOpen = () => props.selectedIndex !== null;
9
11
  const currentImage = () => props.selectedIndex !== null ? props.images[props.selectedIndex] : null;
10
12
  const canGoPrev = () => props.selectedIndex !== null && props.selectedIndex > 0;
@@ -61,6 +63,7 @@ const LightboxOverlay = (props) => {
61
63
  e.stopPropagation();
62
64
  handlePrev();
63
65
  };
66
+ web.effect(() => web.setAttribute(_el$3, "aria-label", strings.lightboxPrevious));
64
67
  web.runHydrationEvents();
65
68
  return _el$3;
66
69
  }
@@ -75,6 +78,7 @@ const LightboxOverlay = (props) => {
75
78
  e.stopPropagation();
76
79
  handleNext();
77
80
  };
81
+ web.effect(() => web.setAttribute(_el$4, "aria-label", strings.lightboxNext));
78
82
  web.runHydrationEvents();
79
83
  return _el$4;
80
84
  }
@@ -95,19 +99,23 @@ const LightboxOverlay = (props) => {
95
99
  web.insert(_el$7, () => props.images.length, _el$10, _co$2);
96
100
  web.effect((_p$) => {
97
101
  var _a, _b, _c, _d;
98
- var _v$ = safeUrl.safeUrl(((_a = currentImage()) == null ? void 0 : _a.url) ?? "", {
102
+ var _v$ = strings.lightboxLabel, _v$2 = strings.lightboxClose, _v$3 = safeUrl.safeUrl(((_a = currentImage()) == null ? void 0 : _a.url) ?? "", {
99
103
  allowDataImage: true
100
- }), _v$2 = ((_b = currentImage()) == null ? void 0 : _b.alt) || "", _v$3 = (_c = currentImage()) == null ? void 0 : _c.srcset, _v$4 = (_d = currentImage()) == null ? void 0 : _d.sizes;
101
- _v$ !== _p$.e && web.setAttribute(_el$5, "src", _p$.e = _v$);
102
- _v$2 !== _p$.t && web.setAttribute(_el$5, "alt", _p$.t = _v$2);
103
- _v$3 !== _p$.a && web.setAttribute(_el$5, "srcset", _p$.a = _v$3);
104
- _v$4 !== _p$.o && web.setAttribute(_el$5, "sizes", _p$.o = _v$4);
104
+ }), _v$4 = ((_b = currentImage()) == null ? void 0 : _b.alt) || "", _v$5 = (_c = currentImage()) == null ? void 0 : _c.srcset, _v$6 = (_d = currentImage()) == null ? void 0 : _d.sizes;
105
+ _v$ !== _p$.e && web.setAttribute(_el$, "aria-label", _p$.e = _v$);
106
+ _v$2 !== _p$.t && web.setAttribute(_el$2, "aria-label", _p$.t = _v$2);
107
+ _v$3 !== _p$.a && web.setAttribute(_el$5, "src", _p$.a = _v$3);
108
+ _v$4 !== _p$.o && web.setAttribute(_el$5, "alt", _p$.o = _v$4);
109
+ _v$5 !== _p$.i && web.setAttribute(_el$5, "srcset", _p$.i = _v$5);
110
+ _v$6 !== _p$.n && web.setAttribute(_el$5, "sizes", _p$.n = _v$6);
105
111
  return _p$;
106
112
  }, {
107
113
  e: void 0,
108
114
  t: void 0,
109
115
  a: void 0,
110
- o: void 0
116
+ o: void 0,
117
+ i: void 0,
118
+ n: void 0
111
119
  });
112
120
  web.runHydrationEvents();
113
121
  return _el$;
@@ -1 +1 @@
1
- {"version":3,"file":"LightboxOverlay.cjs","sources":["../../src/components/LightboxOverlay.tsx"],"sourcesContent":["/**\n * LightboxOverlay - Fullscreen image viewer\n * Sprint 5: Media Components\n */\n\nimport { Component, Show, createEffect, onCleanup } from 'solid-js'\nimport { Portal } from 'solid-js/web'\nimport type { GalleryImage } from '../types'\nimport { safeUrl } from '../utils/safe-url'\n\nexport interface LightboxOverlayProps {\n /**\n * Array of images to navigate through\n */\n images: GalleryImage[]\n\n /**\n * Currently selected image index (null when closed)\n */\n selectedIndex: number | null\n\n /**\n * Callback when lightbox should close\n */\n onClose: () => void\n\n /**\n * Callback when navigating to a different image\n */\n onNavigate: (index: number) => void\n}\n\nexport const LightboxOverlay: Component<LightboxOverlayProps> = (props) => {\n const isOpen = () => props.selectedIndex !== null\n const currentImage = () =>\n props.selectedIndex !== null ? props.images[props.selectedIndex] : null\n const canGoPrev = () => props.selectedIndex !== null && props.selectedIndex > 0\n const canGoNext = () =>\n props.selectedIndex !== null && props.selectedIndex < props.images.length - 1\n\n const handlePrev = () => {\n if (canGoPrev()) {\n props.onNavigate(props.selectedIndex! - 1)\n }\n }\n\n const handleNext = () => {\n if (canGoNext()) {\n props.onNavigate(props.selectedIndex! + 1)\n }\n }\n\n // Keyboard navigation\n createEffect(() => {\n if (!isOpen()) return\n\n const handleKeydown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'Escape':\n props.onClose()\n break\n case 'ArrowLeft':\n handlePrev()\n break\n case 'ArrowRight':\n handleNext()\n break\n }\n }\n\n document.addEventListener('keydown', handleKeydown)\n document.body.style.overflow = 'hidden'\n\n onCleanup(() => {\n document.removeEventListener('keydown', handleKeydown)\n document.body.style.overflow = ''\n })\n })\n\n return (\n <Show when={isOpen()}>\n <Portal>\n <div\n class=\"fixed inset-0 z-50 bg-black/90 flex items-center justify-center\"\n onClick={props.onClose}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Image lightbox\"\n >\n {/* Close button */}\n <button\n class=\"absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={props.onClose}\n aria-label=\"Close lightbox\"\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n\n {/* Previous button */}\n <Show when={canGoPrev()}>\n <button\n class=\"absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handlePrev()\n }}\n aria-label=\"Previous image\"\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Next button */}\n <Show when={canGoNext()}>\n <button\n class=\"absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handleNext()\n }}\n aria-label=\"Next image\"\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Image */}\n <img\n src={safeUrl(currentImage()?.url ?? '', { allowDataImage: true })}\n alt={currentImage()?.alt || ''}\n srcset={currentImage()?.srcset}\n sizes={currentImage()?.sizes}\n class=\"max-w-[90vw] max-h-[90vh] object-contain\"\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Caption */}\n <Show when={currentImage()?.caption}>\n <div class=\"absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center\">\n {currentImage()!.caption}\n </div>\n </Show>\n\n {/* Counter */}\n <div class=\"absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm\">\n {(props.selectedIndex ?? 0) + 1} / {props.images.length}\n </div>\n </div>\n </Portal>\n </Show>\n )\n}\n"],"names":["LightboxOverlay","props","isOpen","selectedIndex","currentImage","images","canGoPrev","canGoNext","length","handlePrev","onNavigate","handleNext","createEffect","handleKeydown","e","key","onClose","document","addEventListener","body","style","overflow","onCleanup","removeEventListener","_$createComponent","Show","when","children","Portal","_el$","_$getNextElement","_tmpl$4","_el$2","firstChild","_el$11","nextSibling","_el$12","_co$3","_$getNextMarker","_el$13","_el$14","_co$4","_el$5","_el$15","_el$16","_co$5","_el$7","_el$9","_el$0","_co$","_el$8","_el$1","_el$10","_co$2","_$addEventListener","_$insert","_el$3","_tmpl$","$$click","stopPropagation","_$runHydrationEvents","_el$4","_tmpl$2","caption","_el$6","_tmpl$3","_$effect","_p$","_v$","safeUrl","url","allowDataImage","_v$2","alt","_v$3","srcset","_v$4","sizes","_$setAttribute","t","a","o","undefined","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"LightboxOverlay.cjs","sources":["../../src/components/LightboxOverlay.tsx"],"sourcesContent":["/**\n * LightboxOverlay - Fullscreen image viewer\n * Sprint 5: Media Components\n */\n\nimport { Component, Show, createEffect, onCleanup } from 'solid-js'\nimport { Portal } from 'solid-js/web'\nimport type { GalleryImage } from '../types'\nimport { safeUrl } from '../utils/safe-url'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface LightboxOverlayProps {\n /**\n * Array of images to navigate through\n */\n images: GalleryImage[]\n\n /**\n * Currently selected image index (null when closed)\n */\n selectedIndex: number | null\n\n /**\n * Callback when lightbox should close\n */\n onClose: () => void\n\n /**\n * Callback when navigating to a different image\n */\n onNavigate: (index: number) => void\n}\n\nexport const LightboxOverlay: Component<LightboxOverlayProps> = (props) => {\n const strings = useMCPUIStrings()\n const isOpen = () => props.selectedIndex !== null\n const currentImage = () =>\n props.selectedIndex !== null ? props.images[props.selectedIndex] : null\n const canGoPrev = () => props.selectedIndex !== null && props.selectedIndex > 0\n const canGoNext = () =>\n props.selectedIndex !== null && props.selectedIndex < props.images.length - 1\n\n const handlePrev = () => {\n if (canGoPrev()) {\n props.onNavigate(props.selectedIndex! - 1)\n }\n }\n\n const handleNext = () => {\n if (canGoNext()) {\n props.onNavigate(props.selectedIndex! + 1)\n }\n }\n\n // Keyboard navigation\n createEffect(() => {\n if (!isOpen()) return\n\n const handleKeydown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'Escape':\n props.onClose()\n break\n case 'ArrowLeft':\n handlePrev()\n break\n case 'ArrowRight':\n handleNext()\n break\n }\n }\n\n document.addEventListener('keydown', handleKeydown)\n document.body.style.overflow = 'hidden'\n\n onCleanup(() => {\n document.removeEventListener('keydown', handleKeydown)\n document.body.style.overflow = ''\n })\n })\n\n return (\n <Show when={isOpen()}>\n <Portal>\n <div\n class=\"fixed inset-0 z-50 bg-black/90 flex items-center justify-center\"\n onClick={props.onClose}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={strings.lightboxLabel}\n >\n {/* Close button */}\n <button\n class=\"absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={props.onClose}\n aria-label={strings.lightboxClose}\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n\n {/* Previous button */}\n <Show when={canGoPrev()}>\n <button\n class=\"absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handlePrev()\n }}\n aria-label={strings.lightboxPrevious}\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Next button */}\n <Show when={canGoNext()}>\n <button\n class=\"absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handleNext()\n }}\n aria-label={strings.lightboxNext}\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Image */}\n <img\n src={safeUrl(currentImage()?.url ?? '', { allowDataImage: true })}\n alt={currentImage()?.alt || ''}\n srcset={currentImage()?.srcset}\n sizes={currentImage()?.sizes}\n class=\"max-w-[90vw] max-h-[90vh] object-contain\"\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Caption */}\n <Show when={currentImage()?.caption}>\n <div class=\"absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center\">\n {currentImage()!.caption}\n </div>\n </Show>\n\n {/* Counter */}\n <div class=\"absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm\">\n {(props.selectedIndex ?? 0) + 1} / {props.images.length}\n </div>\n </div>\n </Portal>\n </Show>\n )\n}\n"],"names":["LightboxOverlay","props","strings","useMCPUIStrings","isOpen","selectedIndex","currentImage","images","canGoPrev","canGoNext","length","handlePrev","onNavigate","handleNext","createEffect","handleKeydown","e","key","onClose","document","addEventListener","body","style","overflow","onCleanup","removeEventListener","_$createComponent","Show","when","children","Portal","_el$","_$getNextElement","_tmpl$4","_el$2","firstChild","_el$11","nextSibling","_el$12","_co$3","_$getNextMarker","_el$13","_el$14","_co$4","_el$5","_el$15","_el$16","_co$5","_el$7","_el$9","_el$0","_co$","_el$8","_el$1","_el$10","_co$2","_$addEventListener","_$insert","_el$3","_tmpl$","$$click","stopPropagation","_$effect","_$setAttribute","lightboxPrevious","_$runHydrationEvents","_el$4","_tmpl$2","lightboxNext","caption","_el$6","_tmpl$3","_p$","_v$","lightboxLabel","_v$2","lightboxClose","_v$3","safeUrl","url","allowDataImage","_v$4","alt","_v$5","srcset","_v$6","sizes","t","a","o","i","n","undefined","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"LightboxOverlay.d.ts","sourceRoot":"","sources":["../../src/components/LightboxOverlay.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAiC,MAAM,UAAU,CAAA;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAG5C,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,MAAM,EAAE,YAAY,EAAE,CAAA;IAEtB;;OAEG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAE5B;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IAEnB;;OAEG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,oBAAoB,CA4I3D,CAAA"}
1
+ {"version":3,"file":"LightboxOverlay.d.ts","sourceRoot":"","sources":["../../src/components/LightboxOverlay.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAiC,MAAM,UAAU,CAAA;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAI5C,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,MAAM,EAAE,YAAY,EAAE,CAAA;IAEtB;;OAEG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAE5B;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IAEnB;;OAEG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,oBAAoB,CA6I3D,CAAA"}
@@ -1,8 +1,10 @@
1
- import { createComponent, Portal, getNextElement, getNextMarker, addEventListener, insert, runHydrationEvents, effect, setAttribute, template, delegateEvents } from "solid-js/web";
1
+ import { createComponent, Portal, getNextElement, getNextMarker, addEventListener, insert, effect, setAttribute, runHydrationEvents, template, delegateEvents } from "solid-js/web";
2
2
  import { createEffect, onCleanup, Show } from "solid-js";
3
3
  import { safeUrl } from "../utils/safe-url.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<button class="absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"aria-label="Previous image"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M15 19l-7-7 7-7">`), _tmpl$2 = /* @__PURE__ */ template(`<button class="absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"aria-label="Next image"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 5l7 7-7 7">`), _tmpl$3 = /* @__PURE__ */ template(`<div class="absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center">`), _tmpl$4 = /* @__PURE__ */ template(`<div class="fixed inset-0 z-50 bg-black/90 flex items-center justify-center"role=dialog aria-modal=true aria-label="Image lightbox"><button class="absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"aria-label="Close lightbox"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12"></path></svg></button><!$><!/><!$><!/><img class="max-w-[90vw] max-h-[90vh] object-contain"><!$><!/><div class="absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm"><!$><!/> / <!$><!/>`);
4
+ import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
5
+ var _tmpl$ = /* @__PURE__ */ template(`<button class="absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M15 19l-7-7 7-7">`), _tmpl$2 = /* @__PURE__ */ template(`<button class="absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M9 5l7 7-7 7">`), _tmpl$3 = /* @__PURE__ */ template(`<div class="absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center">`), _tmpl$4 = /* @__PURE__ */ template(`<div class="fixed inset-0 z-50 bg-black/90 flex items-center justify-center"role=dialog aria-modal=true><button class="absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors"><svg class="w-8 h-8"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12"></path></svg></button><!$><!/><!$><!/><img class="max-w-[90vw] max-h-[90vh] object-contain"><!$><!/><div class="absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm"><!$><!/> / <!$><!/>`);
5
6
  const LightboxOverlay = (props) => {
7
+ const strings = useMCPUIStrings();
6
8
  const isOpen = () => props.selectedIndex !== null;
7
9
  const currentImage = () => props.selectedIndex !== null ? props.images[props.selectedIndex] : null;
8
10
  const canGoPrev = () => props.selectedIndex !== null && props.selectedIndex > 0;
@@ -59,6 +61,7 @@ const LightboxOverlay = (props) => {
59
61
  e.stopPropagation();
60
62
  handlePrev();
61
63
  };
64
+ effect(() => setAttribute(_el$3, "aria-label", strings.lightboxPrevious));
62
65
  runHydrationEvents();
63
66
  return _el$3;
64
67
  }
@@ -73,6 +76,7 @@ const LightboxOverlay = (props) => {
73
76
  e.stopPropagation();
74
77
  handleNext();
75
78
  };
79
+ effect(() => setAttribute(_el$4, "aria-label", strings.lightboxNext));
76
80
  runHydrationEvents();
77
81
  return _el$4;
78
82
  }
@@ -93,19 +97,23 @@ const LightboxOverlay = (props) => {
93
97
  insert(_el$7, () => props.images.length, _el$10, _co$2);
94
98
  effect((_p$) => {
95
99
  var _a, _b, _c, _d;
96
- var _v$ = safeUrl(((_a = currentImage()) == null ? void 0 : _a.url) ?? "", {
100
+ var _v$ = strings.lightboxLabel, _v$2 = strings.lightboxClose, _v$3 = safeUrl(((_a = currentImage()) == null ? void 0 : _a.url) ?? "", {
97
101
  allowDataImage: true
98
- }), _v$2 = ((_b = currentImage()) == null ? void 0 : _b.alt) || "", _v$3 = (_c = currentImage()) == null ? void 0 : _c.srcset, _v$4 = (_d = currentImage()) == null ? void 0 : _d.sizes;
99
- _v$ !== _p$.e && setAttribute(_el$5, "src", _p$.e = _v$);
100
- _v$2 !== _p$.t && setAttribute(_el$5, "alt", _p$.t = _v$2);
101
- _v$3 !== _p$.a && setAttribute(_el$5, "srcset", _p$.a = _v$3);
102
- _v$4 !== _p$.o && setAttribute(_el$5, "sizes", _p$.o = _v$4);
102
+ }), _v$4 = ((_b = currentImage()) == null ? void 0 : _b.alt) || "", _v$5 = (_c = currentImage()) == null ? void 0 : _c.srcset, _v$6 = (_d = currentImage()) == null ? void 0 : _d.sizes;
103
+ _v$ !== _p$.e && setAttribute(_el$, "aria-label", _p$.e = _v$);
104
+ _v$2 !== _p$.t && setAttribute(_el$2, "aria-label", _p$.t = _v$2);
105
+ _v$3 !== _p$.a && setAttribute(_el$5, "src", _p$.a = _v$3);
106
+ _v$4 !== _p$.o && setAttribute(_el$5, "alt", _p$.o = _v$4);
107
+ _v$5 !== _p$.i && setAttribute(_el$5, "srcset", _p$.i = _v$5);
108
+ _v$6 !== _p$.n && setAttribute(_el$5, "sizes", _p$.n = _v$6);
103
109
  return _p$;
104
110
  }, {
105
111
  e: void 0,
106
112
  t: void 0,
107
113
  a: void 0,
108
- o: void 0
114
+ o: void 0,
115
+ i: void 0,
116
+ n: void 0
109
117
  });
110
118
  runHydrationEvents();
111
119
  return _el$;
@@ -1 +1 @@
1
- {"version":3,"file":"LightboxOverlay.js","sources":["../../src/components/LightboxOverlay.tsx"],"sourcesContent":["/**\n * LightboxOverlay - Fullscreen image viewer\n * Sprint 5: Media Components\n */\n\nimport { Component, Show, createEffect, onCleanup } from 'solid-js'\nimport { Portal } from 'solid-js/web'\nimport type { GalleryImage } from '../types'\nimport { safeUrl } from '../utils/safe-url'\n\nexport interface LightboxOverlayProps {\n /**\n * Array of images to navigate through\n */\n images: GalleryImage[]\n\n /**\n * Currently selected image index (null when closed)\n */\n selectedIndex: number | null\n\n /**\n * Callback when lightbox should close\n */\n onClose: () => void\n\n /**\n * Callback when navigating to a different image\n */\n onNavigate: (index: number) => void\n}\n\nexport const LightboxOverlay: Component<LightboxOverlayProps> = (props) => {\n const isOpen = () => props.selectedIndex !== null\n const currentImage = () =>\n props.selectedIndex !== null ? props.images[props.selectedIndex] : null\n const canGoPrev = () => props.selectedIndex !== null && props.selectedIndex > 0\n const canGoNext = () =>\n props.selectedIndex !== null && props.selectedIndex < props.images.length - 1\n\n const handlePrev = () => {\n if (canGoPrev()) {\n props.onNavigate(props.selectedIndex! - 1)\n }\n }\n\n const handleNext = () => {\n if (canGoNext()) {\n props.onNavigate(props.selectedIndex! + 1)\n }\n }\n\n // Keyboard navigation\n createEffect(() => {\n if (!isOpen()) return\n\n const handleKeydown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'Escape':\n props.onClose()\n break\n case 'ArrowLeft':\n handlePrev()\n break\n case 'ArrowRight':\n handleNext()\n break\n }\n }\n\n document.addEventListener('keydown', handleKeydown)\n document.body.style.overflow = 'hidden'\n\n onCleanup(() => {\n document.removeEventListener('keydown', handleKeydown)\n document.body.style.overflow = ''\n })\n })\n\n return (\n <Show when={isOpen()}>\n <Portal>\n <div\n class=\"fixed inset-0 z-50 bg-black/90 flex items-center justify-center\"\n onClick={props.onClose}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Image lightbox\"\n >\n {/* Close button */}\n <button\n class=\"absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={props.onClose}\n aria-label=\"Close lightbox\"\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n\n {/* Previous button */}\n <Show when={canGoPrev()}>\n <button\n class=\"absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handlePrev()\n }}\n aria-label=\"Previous image\"\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Next button */}\n <Show when={canGoNext()}>\n <button\n class=\"absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handleNext()\n }}\n aria-label=\"Next image\"\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Image */}\n <img\n src={safeUrl(currentImage()?.url ?? '', { allowDataImage: true })}\n alt={currentImage()?.alt || ''}\n srcset={currentImage()?.srcset}\n sizes={currentImage()?.sizes}\n class=\"max-w-[90vw] max-h-[90vh] object-contain\"\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Caption */}\n <Show when={currentImage()?.caption}>\n <div class=\"absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center\">\n {currentImage()!.caption}\n </div>\n </Show>\n\n {/* Counter */}\n <div class=\"absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm\">\n {(props.selectedIndex ?? 0) + 1} / {props.images.length}\n </div>\n </div>\n </Portal>\n </Show>\n )\n}\n"],"names":["LightboxOverlay","props","isOpen","selectedIndex","currentImage","images","canGoPrev","canGoNext","length","handlePrev","onNavigate","handleNext","createEffect","handleKeydown","e","key","onClose","document","addEventListener","body","style","overflow","onCleanup","removeEventListener","_$createComponent","Show","when","children","Portal","_el$","_$getNextElement","_tmpl$4","_el$2","firstChild","_el$11","nextSibling","_el$12","_co$3","_$getNextMarker","_el$13","_el$14","_co$4","_el$5","_el$15","_el$16","_co$5","_el$7","_el$9","_el$0","_co$","_el$8","_el$1","_el$10","_co$2","_$addEventListener","_$insert","_el$3","_tmpl$","$$click","stopPropagation","_$runHydrationEvents","_el$4","_tmpl$2","caption","_el$6","_tmpl$3","_$effect","_p$","_v$","safeUrl","url","allowDataImage","_v$2","alt","_v$3","srcset","_v$4","sizes","_$setAttribute","t","a","o","undefined","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"LightboxOverlay.js","sources":["../../src/components/LightboxOverlay.tsx"],"sourcesContent":["/**\n * LightboxOverlay - Fullscreen image viewer\n * Sprint 5: Media Components\n */\n\nimport { Component, Show, createEffect, onCleanup } from 'solid-js'\nimport { Portal } from 'solid-js/web'\nimport type { GalleryImage } from '../types'\nimport { safeUrl } from '../utils/safe-url'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface LightboxOverlayProps {\n /**\n * Array of images to navigate through\n */\n images: GalleryImage[]\n\n /**\n * Currently selected image index (null when closed)\n */\n selectedIndex: number | null\n\n /**\n * Callback when lightbox should close\n */\n onClose: () => void\n\n /**\n * Callback when navigating to a different image\n */\n onNavigate: (index: number) => void\n}\n\nexport const LightboxOverlay: Component<LightboxOverlayProps> = (props) => {\n const strings = useMCPUIStrings()\n const isOpen = () => props.selectedIndex !== null\n const currentImage = () =>\n props.selectedIndex !== null ? props.images[props.selectedIndex] : null\n const canGoPrev = () => props.selectedIndex !== null && props.selectedIndex > 0\n const canGoNext = () =>\n props.selectedIndex !== null && props.selectedIndex < props.images.length - 1\n\n const handlePrev = () => {\n if (canGoPrev()) {\n props.onNavigate(props.selectedIndex! - 1)\n }\n }\n\n const handleNext = () => {\n if (canGoNext()) {\n props.onNavigate(props.selectedIndex! + 1)\n }\n }\n\n // Keyboard navigation\n createEffect(() => {\n if (!isOpen()) return\n\n const handleKeydown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'Escape':\n props.onClose()\n break\n case 'ArrowLeft':\n handlePrev()\n break\n case 'ArrowRight':\n handleNext()\n break\n }\n }\n\n document.addEventListener('keydown', handleKeydown)\n document.body.style.overflow = 'hidden'\n\n onCleanup(() => {\n document.removeEventListener('keydown', handleKeydown)\n document.body.style.overflow = ''\n })\n })\n\n return (\n <Show when={isOpen()}>\n <Portal>\n <div\n class=\"fixed inset-0 z-50 bg-black/90 flex items-center justify-center\"\n onClick={props.onClose}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={strings.lightboxLabel}\n >\n {/* Close button */}\n <button\n class=\"absolute top-4 right-4 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={props.onClose}\n aria-label={strings.lightboxClose}\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n\n {/* Previous button */}\n <Show when={canGoPrev()}>\n <button\n class=\"absolute left-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handlePrev()\n }}\n aria-label={strings.lightboxPrevious}\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Next button */}\n <Show when={canGoNext()}>\n <button\n class=\"absolute right-4 top-1/2 -translate-y-1/2 text-white/80 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors\"\n onClick={(e) => {\n e.stopPropagation()\n handleNext()\n }}\n aria-label={strings.lightboxNext}\n >\n <svg class=\"w-8 h-8\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </button>\n </Show>\n\n {/* Image */}\n <img\n src={safeUrl(currentImage()?.url ?? '', { allowDataImage: true })}\n alt={currentImage()?.alt || ''}\n srcset={currentImage()?.srcset}\n sizes={currentImage()?.sizes}\n class=\"max-w-[90vw] max-h-[90vh] object-contain\"\n onClick={(e) => e.stopPropagation()}\n />\n\n {/* Caption */}\n <Show when={currentImage()?.caption}>\n <div class=\"absolute bottom-16 left-1/2 -translate-x-1/2 bg-black/60 text-white px-4 py-2 rounded-lg max-w-[80vw] text-center\">\n {currentImage()!.caption}\n </div>\n </Show>\n\n {/* Counter */}\n <div class=\"absolute top-4 left-4 text-white/80 bg-black/40 px-3 py-1 rounded-full text-sm\">\n {(props.selectedIndex ?? 0) + 1} / {props.images.length}\n </div>\n </div>\n </Portal>\n </Show>\n )\n}\n"],"names":["LightboxOverlay","props","strings","useMCPUIStrings","isOpen","selectedIndex","currentImage","images","canGoPrev","canGoNext","length","handlePrev","onNavigate","handleNext","createEffect","handleKeydown","e","key","onClose","document","addEventListener","body","style","overflow","onCleanup","removeEventListener","_$createComponent","Show","when","children","Portal","_el$","_$getNextElement","_tmpl$4","_el$2","firstChild","_el$11","nextSibling","_el$12","_co$3","_$getNextMarker","_el$13","_el$14","_co$4","_el$5","_el$15","_el$16","_co$5","_el$7","_el$9","_el$0","_co$","_el$8","_el$1","_el$10","_co$2","_$addEventListener","_$insert","_el$3","_tmpl$","$$click","stopPropagation","_$effect","_$setAttribute","lightboxPrevious","_$runHydrationEvents","_el$4","_tmpl$2","lightboxNext","caption","_el$6","_tmpl$3","_p$","_v$","lightboxLabel","_v$2","lightboxClose","_v$3","safeUrl","url","allowDataImage","_v$4","alt","_v$5","srcset","_v$6","sizes","t","a","o","i","n","undefined","_$delegateEvents"],"mappings":";;;;;AAiCO,MAAMA,kBAAoDC,CAAAA,UAAU;AACzE,QAAMC,UAAUC,gBAAAA;AAChB,QAAMC,SAASA,MAAMH,MAAMI,kBAAkB;AAC7C,QAAMC,eAAeA,MACnBL,MAAMI,kBAAkB,OAAOJ,MAAMM,OAAON,MAAMI,aAAa,IAAI;AACrE,QAAMG,YAAYA,MAAMP,MAAMI,kBAAkB,QAAQJ,MAAMI,gBAAgB;AAC9E,QAAMI,YAAYA,MAChBR,MAAMI,kBAAkB,QAAQJ,MAAMI,gBAAgBJ,MAAMM,OAAOG,SAAS;AAE9E,QAAMC,aAAaA,MAAM;AACvB,QAAIH,aAAa;AACfP,YAAMW,WAAWX,MAAMI,gBAAiB,CAAC;AAAA,IAC3C;AAAA,EACF;AAEA,QAAMQ,aAAaA,MAAM;AACvB,QAAIJ,aAAa;AACfR,YAAMW,WAAWX,MAAMI,gBAAiB,CAAC;AAAA,IAC3C;AAAA,EACF;AAGAS,eAAa,MAAM;AACjB,QAAI,CAACV,SAAU;AAEf,UAAMW,gBAAgBA,CAACC,MAAqB;AAC1C,cAAQA,EAAEC,KAAAA;AAAAA,QACR,KAAK;AACHhB,gBAAMiB,QAAAA;AACN;AAAA,QACF,KAAK;AACHP,qBAAAA;AACA;AAAA,QACF,KAAK;AACHE,qBAAAA;AACA;AAAA,MAAA;AAAA,IAEN;AAEAM,aAASC,iBAAiB,WAAWL,aAAa;AAClDI,aAASE,KAAKC,MAAMC,WAAW;AAE/BC,cAAU,MAAM;AACdL,eAASM,oBAAoB,WAAWV,aAAa;AACrDI,eAASE,KAAKC,MAAMC,WAAW;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AAED,SAAAG,gBACGC,MAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAExB,OAAAA;AAAAA,IAAQ;AAAA,IAAA,IAAAyB,WAAA;AAAA,aAAAH,gBACjBI,QAAM;AAAA,QAAA,IAAAD,WAAA;AAAA,cAAAE,OAAAC,eAAAC,OAAA,GAAAC,QAAAH,KAAAI,YAAAC,SAAAF,MAAAG,aAAA,CAAAC,QAAAC,KAAA,IAAAC,cAAAJ,OAAAC,WAAA,GAAAI,SAAAH,OAAAD,aAAA,CAAAK,QAAAC,KAAA,IAAAH,cAAAC,OAAAJ,WAAA,GAAAO,QAAAF,OAAAL,aAAAQ,SAAAD,MAAAP,aAAA,CAAAS,QAAAC,KAAA,IAAAP,cAAAK,OAAAR,WAAA,GAAAW,QAAAF,OAAAT,aAAAY,QAAAD,MAAAb,YAAA,CAAAe,OAAAC,IAAA,IAAAX,cAAAS,MAAAZ,WAAA,GAAAe,QAAAF,MAAAb,aAAAgB,QAAAD,MAAAf,aAAA,CAAAiB,QAAAC,KAAA,IAAAf,cAAAa,MAAAhB,WAAA;AAAAmB,2BAAAzB,MAAA,SAGM9B,MAAMiB,SAAO,IAAA;AAAAsC,2BAAAtB,OAAA,SAQXjC,MAAMiB,SAAO,IAAA;AAAAuC,iBAAA1B,MAAAL,gBAcvBC,MAAI;AAAA,YAAA,IAACC,OAAI;AAAA,qBAAEpB,UAAAA;AAAAA,YAAW;AAAA,YAAA,IAAAqB,WAAA;AAAA,kBAAA6B,QAAA1B,eAAA2B,MAAA;AAAAD,oBAAAE,UAGT5C,CAAAA,MAAM;AACdA,kBAAE6C,gBAAAA;AACFlD,2BAAAA;AAAAA,cACF;AAACmD,2BAAAC,aAAAL,OAAA,cACWxD,QAAQ8D,gBAAgB,CAAA;AAAAC,iCAAAA;AAAA,qBAAAP;AAAAA,YAAA;AAAA,UAAA,CAAA,GAAApB,QAAAC,KAAA;AAAAkB,iBAAA1B,MAAAL,gBAcvCC,MAAI;AAAA,YAAA,IAACC,OAAI;AAAA,qBAAEnB,UAAAA;AAAAA,YAAW;AAAA,YAAA,IAAAoB,WAAA;AAAA,kBAAAqC,QAAAlC,eAAAmC,OAAA;AAAAD,oBAAAN,UAGT5C,CAAAA,MAAM;AACdA,kBAAE6C,gBAAAA;AACFhD,2BAAAA;AAAAA,cACF;AAACiD,2BAAAC,aAAAG,OAAA,cACWhE,QAAQkE,YAAY,CAAA;AAAAH,iCAAAA;AAAA,qBAAAC;AAAAA,YAAA;AAAA,UAAA,CAAA,GAAAxB,QAAAC,KAAA;AAAAC,gBAAAgB,UAoBxB5C,CAAAA,MAAMA,EAAE6C,gBAAAA;AAAiBJ,iBAAA1B,MAAAL,gBAIpCC,MAAI;AAAA,YAAA,IAACC,OAAI;;AAAA,sBAAEtB,wBAAAA,mBAAgB+D;AAAAA,YAAO;AAAA,YAAA,IAAAxC,WAAA;AAAA,kBAAAyC,QAAAtC,eAAAuC,OAAA;AAAAd,qBAAAa,OAAA,MAE9BhE,aAAAA,EAAgB+D,OAAO;AAAA,qBAAAC;AAAAA,YAAA;AAAA,UAAA,CAAA,GAAAxB,QAAAC,KAAA;AAAAU,iBAAAT,OAAA,OAMxB/C,MAAMI,iBAAiB,KAAK,GAAC6C,OAAAC,IAAA;AAAAM,iBAAAT,OAAA,MAAK/C,MAAMM,OAAOG,QAAM4C,QAAAC,KAAA;AAAAO,iBAAAU,CAAAA,QAAA;;AAAA,gBAAAC,MA/E7CvE,QAAQwE,eAAaC,OAMnBzE,QAAQ0E,eAAaC,OAwD5BC,UAAQxE,wBAAAA,mBAAgByE,QAAO,IAAI;AAAA,cAAEC,gBAAgB;AAAA,YAAA,CAAM,GAACC,SAC5D3E,kBAAAA,MAAAA,mBAAgB4E,QAAO,IAAEC,QACtB7E,kBAAAA,MAAAA,mBAAgB8E,QAAMC,QACvB/E,wBAAAA,mBAAgBgF;AAAKb,oBAAAD,IAAAxD,KAAA+C,aAAAhC,MAAA,cAAAyC,IAAAxD,IAAAyD,GAAA;AAAAE,qBAAAH,IAAAe,KAAAxB,aAAA7B,OAAA,cAAAsC,IAAAe,IAAAZ,IAAA;AAAAE,qBAAAL,IAAAgB,KAAAzB,aAAAnB,OAAA,OAAA4B,IAAAgB,IAAAX,IAAA;AAAAI,qBAAAT,IAAAiB,KAAA1B,aAAAnB,OAAA,OAAA4B,IAAAiB,IAAAR,IAAA;AAAAE,qBAAAX,IAAAkB,KAAA3B,aAAAnB,OAAA,UAAA4B,IAAAkB,IAAAP,IAAA;AAAAE,qBAAAb,IAAAmB,KAAA5B,aAAAnB,OAAA,SAAA4B,IAAAmB,IAAAN,IAAA;AAAA,mBAAAb;AAAAA,UAAA,GAAA;AAAA,YAAAxD,GAAA4E;AAAAA,YAAAL,GAAAK;AAAAA,YAAAJ,GAAAI;AAAAA,YAAAH,GAAAG;AAAAA,YAAAF,GAAAE;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAA3B,6BAAAA;AAAA,iBAAAlC;AAAAA,QAAA;AAAA,MAAA,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA;AAoBxC;AAAC8D,eAAA,CAAA,OAAA,CAAA;"}
@@ -29,7 +29,9 @@ const DegradedFallback = require("./DegradedFallback.cjs");
29
29
  const degradedProjections = require("../utils/degraded-projections.cjs");
30
30
  const escapeHtml = require("../utils/escape-html.cjs");
31
31
  const MCPUITelemetryContext = require("../context/MCPUITelemetryContext.cjs");
32
- var _tmpl$ = /* @__PURE__ */ web.template(`<div class=p-3>`), _tmpl$2 = /* @__PURE__ */ web.template(`<div role=alert class="m-2 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-800 dark:border-amber-700/50 dark:bg-amber-900/20 dark:text-amber-200"><!$><!/> The base map is still shown.`), _tmpl$3 = /* @__PURE__ */ web.template(`<div>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div><!$><!/><!$><!/>`);
32
+ const MCPUIStringsContext = require("../context/MCPUIStringsContext.cjs");
33
+ const formatString = require("../utils/format-string.cjs");
34
+ var _tmpl$ = /* @__PURE__ */ web.template(`<div class=p-3>`), _tmpl$2 = /* @__PURE__ */ web.template(`<div role=alert class="m-2 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-800 dark:border-amber-700/50 dark:bg-amber-900/20 dark:text-amber-200"><!$><!/> <!$><!/>`), _tmpl$3 = /* @__PURE__ */ web.template(`<div>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div><!$><!/><!$><!/>`);
33
35
  let L = null;
34
36
  let clusterCssLoaded = false;
35
37
  function getChoroplethColor(value, scale, fallback) {
@@ -67,7 +69,7 @@ function buildStyleFn(style) {
67
69
  };
68
70
  };
69
71
  }
70
- function buildPopupContent(feature, popup, allowHtml = false) {
72
+ function buildPopupContent(feature, popup, allowHtml = false, locale = MCPUIStringsContext.DEFAULT_MCPUI_STRINGS.locale) {
71
73
  if (!popup || !(feature == null ? void 0 : feature.properties)) return null;
72
74
  const props = feature.properties;
73
75
  if (allowHtml && popup.template) {
@@ -85,7 +87,7 @@ function buildPopupContent(feature, popup, allowHtml = false) {
85
87
  if (key === popup.titleField) continue;
86
88
  const val = props[key];
87
89
  if (val == null) continue;
88
- const formatted = typeof val === "number" ? val.toLocaleString("fr-FR") : String(val);
90
+ const formatted = typeof val === "number" ? val.toLocaleString(locale) : String(val);
89
91
  parts.push(`<span style="color:#666;font-size:11px">${escapeHtml.escapeHtml(key)}</span>: ${escapeHtml.escapeHtml(formatted)}`);
90
92
  }
91
93
  return parts.join("<br/>");
@@ -100,7 +102,7 @@ function bindMarkerContent(m, marker, allowHtml) {
100
102
  const popup = popupSafeText(marker.popup, allowHtml);
101
103
  if (popup) m.bindPopup(popup);
102
104
  }
103
- function addGeoJSONLayer(mapInst, leaflet, geojson, style, popup, allowHtml = false) {
105
+ function addGeoJSONLayer(mapInst, leaflet, geojson, style, popup, allowHtml = false, locale = MCPUIStringsContext.DEFAULT_MCPUI_STRINGS.locale) {
104
106
  const styleFn = buildStyleFn(style);
105
107
  const layer = leaflet.geoJSON(geojson, {
106
108
  style: styleFn,
@@ -116,9 +118,10 @@ function addGeoJSONLayer(mapInst, leaflet, geojson, style, popup, allowHtml = fa
116
118
  });
117
119
  },
118
120
  onEachFeature: (feature, featureLayer) => {
119
- const html = buildPopupContent(feature, popup, allowHtml);
121
+ const currentLocale = () => typeof locale === "function" ? solidJs.untrack(locale) : locale;
122
+ const html = buildPopupContent(feature, popup, allowHtml, currentLocale());
120
123
  if (html) {
121
- featureLayer.bindPopup(html, {
124
+ featureLayer.bindPopup(typeof locale === "function" ? () => buildPopupContent(feature, popup, allowHtml, currentLocale()) ?? "" : html, {
122
125
  maxWidth: 300
123
126
  });
124
127
  }
@@ -157,6 +160,7 @@ function mapToGeoJSON(p) {
157
160
  }, null, 2);
158
161
  }
159
162
  const MapRenderer = (props) => {
163
+ const strings = MCPUIStringsContext.useMCPUIStrings();
160
164
  let mapContainer;
161
165
  let mapInstance = null;
162
166
  const [isLeafletLoaded, setIsLeafletLoaded] = solidJs.createSignal(false);
@@ -188,7 +192,7 @@ const MapRenderer = (props) => {
188
192
  setIsLeafletLoaded(true);
189
193
  } catch (e) {
190
194
  console.warn("Failed to load leaflet", e);
191
- setError("Map library could not be loaded.");
195
+ setError(strings.mapLibraryUnavailable);
192
196
  return;
193
197
  }
194
198
  } else {
@@ -271,13 +275,24 @@ const MapRenderer = (props) => {
271
275
  allBoundsLayers.push(...markers);
272
276
  }
273
277
  if (p == null ? void 0 : p.geojson) {
274
- const geoLayer = addGeoJSONLayer(mapInstance, L, p.geojson, p.geojsonStyle, p.popup, allowHtml());
278
+ const geoLayer = addGeoJSONLayer(
279
+ mapInstance,
280
+ L,
281
+ p.geojson,
282
+ p.geojsonStyle,
283
+ p.popup,
284
+ allowHtml(),
285
+ // A getter, not a value: popups read the current locale when they
286
+ // open. Tracking the locale here would re-run this effect, which is
287
+ // not idempotent (layer control, PMTiles layer, view reset).
288
+ () => strings.locale
289
+ );
275
290
  allBoundsLayers.push(geoLayer);
276
291
  }
277
292
  if ((p == null ? void 0 : p.layers) && p.layers.length > 0) {
278
293
  const overlays = {};
279
294
  for (const layerDef of p.layers) {
280
- const geoLayer = addGeoJSONLayer(mapInstance, L, layerDef.geojson, layerDef.style || (p == null ? void 0 : p.geojsonStyle), layerDef.popup || (p == null ? void 0 : p.popup), allowHtml());
295
+ const geoLayer = addGeoJSONLayer(mapInstance, L, layerDef.geojson, layerDef.style || (p == null ? void 0 : p.geojsonStyle), layerDef.popup || (p == null ? void 0 : p.popup), allowHtml(), () => strings.locale);
281
296
  overlays[layerDef.name] = geoLayer;
282
297
  allBoundsLayers.push(geoLayer);
283
298
  if (layerDef.visible === false) {
@@ -325,12 +340,12 @@ const MapRenderer = (props) => {
325
340
  pmLayer.addTo(mapInstance);
326
341
  } catch (e) {
327
342
  const detail = e instanceof Error ? e.message : String(e);
328
- const message = 'PMTiles layer unavailable — the optional "protomaps-leaflet" peer dependency failed to load or render.';
329
- console.warn("[MCP-UI] " + message, e);
330
- setPmtilesError(message);
343
+ const diagnostic = 'PMTiles layer unavailable — the optional "protomaps-leaflet" peer dependency failed to load or render.';
344
+ console.warn("[MCP-UI] " + diagnostic, e);
345
+ setPmtilesError(strings.mapPmtilesUnavailable);
331
346
  telemetry == null ? void 0 : telemetry.dispatch({
332
347
  type: "render:error",
333
- errorMessage: `${message} (${detail})`,
348
+ errorMessage: `${diagnostic} (${detail})`,
334
349
  id: ((_f = props.component) == null ? void 0 : _f.id) ?? "",
335
350
  componentType: "map",
336
351
  ts: Date.now()
@@ -347,7 +362,7 @@ const MapRenderer = (props) => {
347
362
  mapInstance.setView(p.center, p.zoom || mapInstance.getZoom());
348
363
  }
349
364
  } catch (err) {
350
- const message = err instanceof Error ? err.message : "Failed to render map";
365
+ const message = err instanceof Error ? err.message : strings.mapRenderError;
351
366
  setError(message);
352
367
  telemetry == null ? void 0 : telemetry.dispatch({
353
368
  type: "render:error",
@@ -366,16 +381,20 @@ const MapRenderer = (props) => {
366
381
  }
367
382
  });
368
383
  return web.createComponent(ExpandableWrapper.ExpandableWrapper, {
369
- title: "Map",
384
+ get title() {
385
+ return strings.mapTitle;
386
+ },
370
387
  get copyData() {
371
388
  return mapToGeoJSON(params());
372
389
  },
373
- copyLabel: "Copy markers as GeoJSON",
390
+ get copyLabel() {
391
+ return strings.mapCopy;
392
+ },
374
393
  get toolbarVariant() {
375
394
  return props.toolbarVariant;
376
395
  },
377
396
  get children() {
378
- var _el$ = web.getNextElement(_tmpl$4), _el$8 = _el$.firstChild, [_el$9, _co$2] = web.getNextMarker(_el$8.nextSibling), _el$0 = _el$9.nextSibling, [_el$1, _co$3] = web.getNextMarker(_el$0.nextSibling);
397
+ var _el$ = web.getNextElement(_tmpl$4), _el$0 = _el$.firstChild, [_el$1, _co$3] = web.getNextMarker(_el$0.nextSibling), _el$10 = _el$1.nextSibling, [_el$11, _co$4] = web.getNextMarker(_el$10.nextSibling);
379
398
  web.insert(_el$, web.createComponent(solidJs.Show, {
380
399
  get when() {
381
400
  return error();
@@ -384,13 +403,24 @@ const MapRenderer = (props) => {
384
403
  var _el$2 = web.getNextElement(_tmpl$);
385
404
  web.insert(_el$2, web.createComponent(DegradedFallback.DegradedFallback, web.mergeProps({
386
405
  get message() {
387
- return `Map rendering failed: ${error()}`;
406
+ return formatString.formatMCPUIString(strings.mapRenderFailed, {
407
+ error: String(error())
408
+ });
388
409
  },
389
- caption: "Showing the map data as a coordinate table — the interactive map is unavailable."
390
- }, () => degradedProjections.mapToDegradedTable(params() ?? {}))));
410
+ get caption() {
411
+ return strings.mapDegradedCaption;
412
+ }
413
+ }, () => degradedProjections.mapToDegradedTable(params() ?? {}, {
414
+ type: strings.degradedColType,
415
+ lat: strings.degradedColLat,
416
+ lng: strings.degradedColLng,
417
+ info: strings.degradedColInfo,
418
+ marker: strings.degradedMarker,
419
+ feature: strings.degradedFeature
420
+ }))));
391
421
  return _el$2;
392
422
  }
393
- }), _el$9, _co$2);
423
+ }), _el$1, _co$3);
394
424
  web.insert(_el$, web.createComponent(solidJs.Show, {
395
425
  get when() {
396
426
  return !error();
@@ -401,15 +431,15 @@ const MapRenderer = (props) => {
401
431
  return pmtilesError();
402
432
  },
403
433
  get children() {
404
- var _el$3 = web.getNextElement(_tmpl$2), _el$5 = _el$3.firstChild, [_el$6, _co$] = web.getNextMarker(_el$5.nextSibling);
405
- _el$6.nextSibling;
434
+ var _el$3 = web.getNextElement(_tmpl$2), _el$5 = _el$3.firstChild, [_el$6, _co$] = web.getNextMarker(_el$5.nextSibling), _el$4 = _el$6.nextSibling, _el$7 = _el$4.nextSibling, [_el$8, _co$2] = web.getNextMarker(_el$7.nextSibling);
406
435
  web.insert(_el$3, pmtilesError, _el$6, _co$);
436
+ web.insert(_el$3, () => strings.mapBaseMapStillShown, _el$8, _co$2);
407
437
  return _el$3;
408
438
  }
409
439
  }), (() => {
410
- var _el$7 = web.getNextElement(_tmpl$3);
440
+ var _el$9 = web.getNextElement(_tmpl$3);
411
441
  var _ref$ = mapContainer;
412
- typeof _ref$ === "function" ? web.use(_ref$, _el$7) : mapContainer = _el$7;
442
+ typeof _ref$ === "function" ? web.use(_ref$, _el$9) : mapContainer = _el$9;
413
443
  web.effect((_p$) => {
414
444
  var _a;
415
445
  var _v$ = isExpanded() ? {
@@ -421,17 +451,17 @@ const MapRenderer = (props) => {
421
451
  width: "100%",
422
452
  "z-index": 0
423
453
  }, _v$2 = `relative z-0 ${isExpanded() ? "flex-1 min-h-0" : ""}`;
424
- _p$.e = web.style(_el$7, _v$, _p$.e);
425
- _v$2 !== _p$.t && web.className(_el$7, _p$.t = _v$2);
454
+ _p$.e = web.style(_el$9, _v$, _p$.e);
455
+ _v$2 !== _p$.t && web.className(_el$9, _p$.t = _v$2);
426
456
  return _p$;
427
457
  }, {
428
458
  e: void 0,
429
459
  t: void 0
430
460
  });
431
- return _el$7;
461
+ return _el$9;
432
462
  })()];
433
463
  }
434
- }), _el$1, _co$3);
464
+ }), _el$11, _co$4);
435
465
  web.effect(() => {
436
466
  var _a;
437
467
  return web.className(_el$, `w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${((_a = params()) == null ? void 0 : _a.className) || ""} ${isExpanded() ? "flex-1 min-h-0 flex flex-col" : ""}`);