@seed-ship/mcp-ui-solid 6.15.0 → 6.17.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 (265) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +20 -3
  3. package/dist/_virtual/leaflet.markercluster-src.cjs +30 -7
  4. package/dist/_virtual/leaflet.markercluster-src.cjs.map +1 -1
  5. package/dist/_virtual/leaflet.markercluster-src.js +28 -5
  6. package/dist/_virtual/leaflet.markercluster-src.js.map +1 -1
  7. package/dist/_virtual/{leaflet.markercluster-src2.cjs → leaflet2.markercluster-src.cjs} +1 -1
  8. package/dist/_virtual/leaflet2.markercluster-src.cjs.map +1 -0
  9. package/dist/_virtual/{leaflet.markercluster-src2.js → leaflet2.markercluster-src.js} +1 -1
  10. package/dist/_virtual/leaflet2.markercluster-src.js.map +1 -0
  11. package/dist/adapters/connector.js +1 -1
  12. package/dist/components/ActionGroupRenderer.js +1 -1
  13. package/dist/components/ActionRenderer.js +1 -1
  14. package/dist/components/AgentCard.js +1 -1
  15. package/dist/components/AgentHandoff.js +1 -1
  16. package/dist/components/ArtifactRenderer.js +1 -1
  17. package/dist/components/AutocompleteDropdown.cjs +1 -2
  18. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  19. package/dist/components/AutocompleteDropdown.js +2 -3
  20. package/dist/components/AutocompleteFormField.cjs +1 -2
  21. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  22. package/dist/components/AutocompleteFormField.js +2 -3
  23. package/dist/components/BriefingDiff.js +1 -1
  24. package/dist/components/CarouselRenderer.js +1 -1
  25. package/dist/components/ChartJSRenderer.js +1 -1
  26. package/dist/components/ChatPrompt.js +1 -1
  27. package/dist/components/CodeBlockRenderer.js +1 -1
  28. package/dist/components/ComponentToolbar.js +1 -1
  29. package/dist/components/DataPreviewSection.js +1 -1
  30. package/dist/components/DegradedFallback.cjs.map +1 -1
  31. package/dist/components/DegradedFallback.d.ts +1 -1
  32. package/dist/components/DegradedFallback.js +1 -1
  33. package/dist/components/DegradedFallback.js.map +1 -1
  34. package/dist/components/DraggableGridItem.cjs +1 -2
  35. package/dist/components/DraggableGridItem.cjs.map +1 -1
  36. package/dist/components/DraggableGridItem.js +2 -3
  37. package/dist/components/EditableUIResourceRenderer.cjs +1 -2
  38. package/dist/components/EditableUIResourceRenderer.cjs.map +1 -1
  39. package/dist/components/EditableUIResourceRenderer.js +2 -3
  40. package/dist/components/ExpandableWrapper.js +2 -2
  41. package/dist/components/FeedbackInline.js +1 -1
  42. package/dist/components/FooterRenderer.js +1 -1
  43. package/dist/components/FormFieldRenderer.js +1 -1
  44. package/dist/components/FormRenderer.js +1 -1
  45. package/dist/components/GenerativeUIErrorBoundary.js +1 -1
  46. package/dist/components/GhostText.cjs +1 -2
  47. package/dist/components/GhostText.cjs.map +1 -1
  48. package/dist/components/GhostText.js +2 -3
  49. package/dist/components/GraphRenderer.cjs +2 -19
  50. package/dist/components/GraphRenderer.cjs.map +1 -1
  51. package/dist/components/GraphRenderer.d.ts.map +1 -1
  52. package/dist/components/GraphRenderer.js +2 -19
  53. package/dist/components/GraphRenderer.js.map +1 -1
  54. package/dist/components/GridRenderer.cjs +1 -2
  55. package/dist/components/GridRenderer.cjs.map +1 -1
  56. package/dist/components/GridRenderer.js +2 -3
  57. package/dist/components/ImageGalleryRenderer.js +1 -1
  58. package/dist/components/LightboxOverlay.js +1 -1
  59. package/dist/components/MapRenderer.cjs +10 -11
  60. package/dist/components/MapRenderer.cjs.map +1 -1
  61. package/dist/components/MapRenderer.d.ts +6 -1
  62. package/dist/components/MapRenderer.d.ts.map +1 -1
  63. package/dist/components/MapRenderer.js +7 -8
  64. package/dist/components/MapRenderer.js.map +1 -1
  65. package/dist/components/ModalRenderer.js +1 -1
  66. package/dist/components/PortalDropdownMenu.js +1 -1
  67. package/dist/components/PresentationFeedback.js +1 -1
  68. package/dist/components/RenderContext.js +1 -1
  69. package/dist/components/ResizeHandle.cjs +1 -2
  70. package/dist/components/ResizeHandle.cjs.map +1 -1
  71. package/dist/components/ResizeHandle.js +2 -3
  72. package/dist/components/ScratchpadPanel.js +1 -1
  73. package/dist/components/SplitStepper.js +1 -1
  74. package/dist/components/StreamingUIRenderer.js +1 -1
  75. package/dist/components/UIResourceRenderer.cjs +12 -1
  76. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  77. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  78. package/dist/components/UIResourceRenderer.js +13 -2
  79. package/dist/components/UIResourceRenderer.js.map +1 -1
  80. package/dist/components/VerifiedText.js +1 -1
  81. package/dist/components/VideoRenderer.js +1 -1
  82. package/dist/components/index.d.ts.map +1 -1
  83. package/dist/index.d.cts +1 -1
  84. package/dist/index.d.ts +1 -1
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/core/component.cjs +1 -1
  87. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/core/component.js +1 -1
  88. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/axis.cjs +1 -1
  89. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/axis.js +1 -1
  90. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/constant.cjs +1 -1
  91. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/constant.js +1 -1
  92. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/grid.cjs +2 -2
  93. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/grid.js +2 -2
  94. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/labels.cjs +6 -6
  95. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/labels.js +6 -6
  96. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/line.cjs +1 -1
  97. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/line.js +1 -1
  98. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/ticks.cjs +2 -2
  99. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/ticks.js +2 -2
  100. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/title.cjs +1 -1
  101. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/title.js +1 -1
  102. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/utils.cjs +1 -1
  103. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/axis/guides/utils.js +1 -1
  104. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/grid/index.cjs +3 -3
  105. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/grid/index.js +3 -3
  106. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/indicator/indicator.cjs +4 -4
  107. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/indicator/indicator.js +4 -4
  108. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/category/item.cjs +5 -5
  109. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/category/item.js +5 -5
  110. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/category/items.cjs +5 -5
  111. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/category/items.js +5 -5
  112. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/category.cjs +2 -2
  113. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/category.js +2 -2
  114. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/continuous/handle.cjs +1 -1
  115. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/continuous/handle.js +1 -1
  116. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/title/index.cjs +3 -3
  117. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/legend/title/index.js +3 -3
  118. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/marker/utils.cjs +1 -1
  119. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/marker/utils.js +1 -1
  120. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/navigator/index.cjs +5 -5
  121. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/navigator/index.js +5 -5
  122. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/poptip/index.cjs +2 -2
  123. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/poptip/index.js +2 -2
  124. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/select/option.cjs +2 -2
  125. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/select/option.js +2 -2
  126. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/select/select.cjs +2 -2
  127. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/select/select.js +2 -2
  128. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/slider/handle.cjs +2 -2
  129. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/slider/handle.js +2 -2
  130. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/slider/index.cjs +4 -4
  131. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/slider/index.js +4 -4
  132. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/columns.cjs +1 -1
  133. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/columns.js +1 -1
  134. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/index.cjs +2 -2
  135. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/index.js +2 -2
  136. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/lines.cjs +1 -1
  137. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/lines.js +1 -1
  138. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/utils.cjs +2 -2
  139. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/sparkline/utils.js +2 -2
  140. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/controller.cjs +2 -2
  141. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/controller.js +2 -2
  142. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/handle.cjs +1 -1
  143. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/handle.js +1 -1
  144. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/icons.cjs +4 -4
  145. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/icons.js +4 -4
  146. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/timebar.cjs +3 -3
  147. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/timebar/timebar.js +3 -3
  148. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/tooltip/index.cjs +1 -1
  149. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/ui/tooltip/index.js +1 -1
  150. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/util/selection.cjs +1 -1
  151. package/dist/node_modules/.pnpm/@antv_component@2.1.11/node_modules/@antv/component/esm/util/selection.js +1 -1
  152. package/dist/node_modules/.pnpm/@antv_g-lite@2.7.0/node_modules/@antv/g-lite/dist/index.esm.js +1 -1
  153. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/behaviors/scroll-canvas.cjs +1 -1
  154. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/behaviors/scroll-canvas.js +1 -1
  155. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/elements/combos/base-combo.cjs +1 -1
  156. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/elements/combos/base-combo.js +1 -1
  157. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/elements/edges/base-edge.cjs +1 -1
  158. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/elements/edges/base-edge.js +1 -1
  159. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/index.cjs +58 -58
  160. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/legend.cjs +1 -1
  161. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/legend.js +1 -1
  162. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/minimap/index.cjs +1 -1
  163. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/minimap/index.js +1 -1
  164. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/snapline/index.cjs +1 -1
  165. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/snapline/index.js +1 -1
  166. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/tooltip.cjs +1 -1
  167. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/plugins/tooltip.js +1 -1
  168. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/registry/build-in.cjs +1 -1
  169. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/registry/build-in.js +1 -1
  170. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/data.cjs +1 -1
  171. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/data.js +1 -1
  172. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/element.cjs +1 -1
  173. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/element.js +1 -1
  174. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/graph.cjs +1 -1
  175. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/graph.js +1 -1
  176. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/layout.cjs +2 -2
  177. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/layout.js +2 -2
  178. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/viewport.cjs +1 -1
  179. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/runtime/viewport.js +1 -1
  180. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/utils/element.cjs +1 -1
  181. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/utils/element.js +1 -1
  182. package/dist/node_modules/.pnpm/@antv_g6@5.1.0/node_modules/@antv/g6/esm/utils/point.js +1 -1
  183. package/dist/node_modules/.pnpm/@antv_layout@2.0.0/node_modules/@antv/layout/lib/algorithm/antv-dagre/rank/index.js +1 -1
  184. package/dist/node_modules/.pnpm/@antv_layout@2.0.0/node_modules/@antv/layout/lib/algorithm/concentric/index.js +1 -1
  185. package/dist/node_modules/.pnpm/@antv_scale@0.4.16/node_modules/@antv/scale/esm/scales/continuous.cjs +1 -1
  186. package/dist/node_modules/.pnpm/@antv_scale@0.4.16/node_modules/@antv/scale/esm/scales/continuous.js +1 -1
  187. package/dist/node_modules/.pnpm/@tanstack_solid-virtual@3.13.18_solid-js@1.9.11/node_modules/@tanstack/solid-virtual/dist/esm/index.cjs +13 -0
  188. package/dist/node_modules/.pnpm/@tanstack_solid-virtual@3.13.18_solid-js@1.9.11/node_modules/@tanstack/solid-virtual/dist/esm/index.cjs.map +1 -1
  189. package/dist/node_modules/.pnpm/@tanstack_solid-virtual@3.13.18_solid-js@1.9.11/node_modules/@tanstack/solid-virtual/dist/esm/index.js +15 -2
  190. package/dist/node_modules/.pnpm/@tanstack_solid-virtual@3.13.18_solid-js@1.9.11/node_modules/@tanstack/solid-virtual/dist/esm/index.js.map +1 -1
  191. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/index.cjs +64 -0
  192. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/index.cjs.map +1 -1
  193. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/index.js +66 -2
  194. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/index.js.map +1 -1
  195. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/utils.cjs +1 -1
  196. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/utils.cjs.map +1 -1
  197. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/utils.js +1 -1
  198. package/dist/node_modules/.pnpm/@tanstack_virtual-core@3.13.18/node_modules/@tanstack/virtual-core/dist/esm/utils.js.map +1 -1
  199. package/dist/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.cjs +6 -6
  200. package/dist/node_modules/.pnpm/{dompurify@3.4.1 → dompurify@3.4.13}/node_modules/dompurify/dist/purify.es.cjs +671 -233
  201. package/dist/node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/dist/purify.es.cjs.map +1 -0
  202. package/dist/node_modules/.pnpm/{dompurify@3.4.1 → dompurify@3.4.13}/node_modules/dompurify/dist/purify.es.js +671 -233
  203. package/dist/node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/dist/purify.es.js.map +1 -0
  204. package/dist/node_modules/.pnpm/leaflet.markercluster@1.5.3_leaflet@1.9.4/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.cjs +7 -7
  205. package/dist/node_modules/.pnpm/leaflet.markercluster@1.5.3_leaflet@1.9.4/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.cjs.map +1 -1
  206. package/dist/node_modules/.pnpm/leaflet.markercluster@1.5.3_leaflet@1.9.4/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js +7 -7
  207. package/dist/node_modules/.pnpm/leaflet.markercluster@1.5.3_leaflet@1.9.4/node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js.map +1 -1
  208. package/dist/node_modules/.pnpm/leaflet@1.9.4/node_modules/leaflet/dist/leaflet-src.cjs +83 -83
  209. package/dist/node_modules/.pnpm/leaflet@1.9.4/node_modules/leaflet/dist/leaflet-src.cjs.map +1 -1
  210. package/dist/node_modules/.pnpm/leaflet@1.9.4/node_modules/leaflet/dist/leaflet-src.js +83 -83
  211. package/dist/node_modules/.pnpm/leaflet@1.9.4/node_modules/leaflet/dist/leaflet-src.js.map +1 -1
  212. package/dist/plugins/groq.cjs +1 -2
  213. package/dist/plugins/groq.cjs.map +1 -1
  214. package/dist/plugins/groq.js +1 -2
  215. package/dist/plugins/rest.cjs +1 -2
  216. package/dist/plugins/rest.cjs.map +1 -1
  217. package/dist/plugins/rest.js +1 -2
  218. package/dist/plugins/supabase.cjs +1 -2
  219. package/dist/plugins/supabase.cjs.map +1 -1
  220. package/dist/plugins/supabase.js +1 -2
  221. package/dist/services/component-registry.cjs +223 -7
  222. package/dist/services/component-registry.cjs.map +1 -1
  223. package/dist/services/component-registry.d.ts +0 -3
  224. package/dist/services/component-registry.d.ts.map +1 -1
  225. package/dist/services/component-registry.js +223 -7
  226. package/dist/services/component-registry.js.map +1 -1
  227. package/dist/services/validation.cjs +1 -23
  228. package/dist/services/validation.cjs.map +1 -1
  229. package/dist/services/validation.d.ts.map +1 -1
  230. package/dist/services/validation.js +2 -24
  231. package/dist/services/validation.js.map +1 -1
  232. package/dist/types/index.d.ts +12 -6
  233. package/dist/types/index.d.ts.map +1 -1
  234. package/dist/types.d.cts +12 -6
  235. package/dist/types.d.ts +12 -6
  236. package/dist/utils/escape-html.cjs +10 -0
  237. package/dist/utils/escape-html.cjs.map +1 -0
  238. package/dist/utils/escape-html.d.ts +13 -0
  239. package/dist/utils/escape-html.d.ts.map +1 -0
  240. package/dist/utils/escape-html.js +10 -0
  241. package/dist/utils/escape-html.js.map +1 -0
  242. package/docs/briefs/BRIEF-graph-component-g6.md +10 -0
  243. package/package.json +2 -2
  244. package/src/components/DegradedFallback.tsx +1 -1
  245. package/src/components/GraphRenderer.tsx +1 -19
  246. package/src/components/MapRenderer.security.test.ts +55 -2
  247. package/src/components/MapRenderer.tsx +15 -13
  248. package/src/components/UIResourceRenderer.tsx +8 -0
  249. package/src/components/UnsupportedComponent.test.tsx +28 -1
  250. package/src/components/index.ts +3 -0
  251. package/src/hooks/useStreamingUI.test.ts +194 -0
  252. package/src/index.ts +1 -0
  253. package/src/services/component-registry.test.ts +104 -2
  254. package/src/services/component-registry.ts +236 -7
  255. package/src/services/validation.test.ts +26 -0
  256. package/src/services/validation.ts +12 -24
  257. package/src/types/index.ts +12 -26
  258. package/src/types/map-types.test.ts +20 -0
  259. package/src/utils/escape-html.test.ts +30 -0
  260. package/src/utils/escape-html.ts +24 -0
  261. package/tsconfig.tsbuildinfo +1 -1
  262. package/dist/_virtual/leaflet.markercluster-src2.cjs.map +0 -1
  263. package/dist/_virtual/leaflet.markercluster-src2.js.map +0 -1
  264. package/dist/node_modules/.pnpm/dompurify@3.4.1/node_modules/dompurify/dist/purify.es.cjs.map +0 -1
  265. package/dist/node_modules/.pnpm/dompurify@3.4.1/node_modules/dompurify/dist/purify.es.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GraphRenderer.cjs","sources":["../../src/components/GraphRenderer.tsx"],"sourcesContent":["/**\n * GraphRenderer (v6.0.0) — generic node-link visualization powered by\n * `@antv/g6 ^5` (peer-optional). Same lazy-load pattern as\n * `ChartJSRenderer` and `MapRenderer` : the heavy lib is dynamically\n * imported only on first mount, and apps that don't install the peer\n * see an informative fallback instead of a crash.\n *\n * Spec : `@seed-ship/mcp-ui-spec@5.0.4` exports `GraphComponentParamsSchema`,\n * `GraphNode`, `GraphEdge`, `GraphLayoutName`, `GraphLayout`,\n * `GraphComponentParams` — the shape consumed here. Domain semantics\n * (`weight` etc.) are opaque to this renderer ; consumers decide what\n * the values mean.\n *\n * Copy + export : the renderer ships with `<ExpandableWrapper>` (default\n * copy = JSON of `{nodes, edges}`) plus a 3-format export menu — **PNG**\n * (visual snapshot via the underlying canvas/SVG), **Mermaid** (markdown\n * / GitHub-renderable `flowchart` syntax), **JSON** (raw reimportable\n * data). All three are computed lazily on click.\n */\n\nimport { Component, createSignal, onCleanup, onMount, Show, For } from 'solid-js';\nimport type { UIComponent } from '../types';\nimport type {\n GraphComponentParams,\n GraphLayout,\n GraphNode,\n GraphEdge,\n} from '@seed-ship/mcp-ui-spec';\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper';\nimport { PortalDropdownMenu } from './PortalDropdownMenu';\nimport { DegradedFallback } from './DegradedFallback';\nimport { graphToDegradedTable } from '../utils/degraded-projections';\nimport { useTelemetry } from '../context/MCPUITelemetryContext';\n\n// Module-scoped lazy import promise — first call triggers the dynamic\n// import, subsequent calls reuse the resolved module.\nlet g6ModulePromise: Promise<typeof import('@antv/g6')> | undefined;\n\n/**\n * Whether the `@antv/g6` peer dependency is installed and importable.\n * Resolves to `true` when the lib is available, `false` otherwise.\n *\n * Mirrors `isChartJSAvailable()` from `ChartJSRenderer`.\n */\nexport async function isG6Available(): Promise<boolean> {\n try {\n if (!g6ModulePromise) {\n g6ModulePromise = import('@antv/g6');\n }\n await g6ModulePromise;\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the spec layout shorthand or object form into the config object\n * G6 v5 expects. When `layout` is omitted, picks `'force'` if edges are\n * present (universal default) or `'circular'` otherwise.\n */\nfunction resolveLayout(params: GraphComponentParams): { type: string; [key: string]: unknown } {\n const layout: GraphLayout | undefined = params.layout;\n if (layout === undefined) {\n const hasEdges = (params.edges?.length ?? 0) > 0;\n return { type: hasEdges ? 'force' : 'circular' };\n }\n if (typeof layout === 'string') {\n return { type: layout };\n }\n // Object form: spread the passthrough options alongside `type`.\n return { type: layout.type, ...(layout.options ?? {}) };\n}\n\n/**\n * Build the G6 v5 `Graph` constructor config from the component params.\n *\n * Pure (no DOM/lib side effects beyond reading `container`), so it can be\n * unit-tested directly without a jsdom render — this is the contract the\n * 2026-05-30 audit (P0.2) wants locked.\n *\n * ⚠️ G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n * (that was the v4 contract). Passing the string `'canvas'` / `'svg'` makes\n * G6 throw `renderer is not a function` — and because the default path used\n * to pass the string `'canvas'`, EVERY graph crashed, not just svg. So we\n * **omit `renderer` entirely**: G6 then uses its built-in canvas renderer\n * (documented default `() => new CanvasRenderer()`).\n *\n * `rendererPref: 'svg'` is reserved but NOT wired yet — a real G6 v5 SVG\n * renderer needs the `@antv/g-svg` factory (a transitive dep of `@antv/g6`,\n * not statically resolvable at build time). Until that's wired behind proper\n * optional-peer resolution, svg degrades to the canvas default with a\n * one-time warning. It must NEVER inject a string `renderer`.\n */\nexport function buildGraphConfig(\n p: GraphComponentParams,\n container?: HTMLElement\n): Record<string, unknown> {\n const config: Record<string, unknown> = {\n container,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n\n if (p.tooltip !== false) {\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>` : ''\n }</div>`;\n },\n },\n ];\n }\n\n return config;\n}\n\n/**\n * Build the G6 v5 `behaviors` array from the params interactivity flags.\n * Defaults : drag-canvas + zoom-canvas + drag-element + click-select.\n * Any flag set to `false` opts out.\n */\nfunction resolveBehaviors(params: GraphComponentParams): string[] {\n const behaviors: string[] = [];\n if (params.enableDrag !== false) behaviors.push('drag-element');\n if (params.enableZoom !== false) {\n behaviors.push('zoom-canvas', 'drag-canvas');\n }\n if (params.enableSelect !== false) behaviors.push('click-select');\n return behaviors;\n}\n\n/**\n * Pick a sensible Mermaid `flowchart` direction from the resolved layout.\n * `dagre` / `tree` / `mindmap` are top-down hierarchies → TD ; everything\n * else (force, concentric, circular, grid) → LR (default mermaid).\n */\nfunction mermaidDirection(layoutType: string): 'TD' | 'LR' {\n return layoutType === 'dagre' || layoutType === 'tree' || layoutType === 'mindmap' ? 'TD' : 'LR';\n}\n\n/**\n * Sanitize a string for use inside a Mermaid node label. Mermaid breaks\n * on raw quotes / brackets / pipes ; we strip the worst offenders.\n */\nfunction mermaidLabel(s: string): string {\n return s\n .replace(/[\"[\\]|]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Convert the graph data to Mermaid `flowchart` syntax. The edge label\n * carries the optional `weight` prefix when present (e.g. `|3| label`).\n */\nfunction toMermaid(params: GraphComponentParams): string {\n const layoutType = resolveLayout(params).type;\n const dir = mermaidDirection(layoutType);\n const lines: string[] = [`flowchart ${dir}`];\n for (const n of params.nodes) {\n const label = mermaidLabel(n.label ?? n.id);\n lines.push(` ${n.id}[\"${label}\"]`);\n }\n for (const e of params.edges ?? []) {\n const labelParts: string[] = [];\n if (e.weight !== undefined) labelParts.push(String(e.weight));\n if (e.label) labelParts.push(mermaidLabel(e.label));\n const labelText = labelParts.join(' · ');\n if (labelText) {\n lines.push(` ${e.source} -->|${labelText}| ${e.target}`);\n } else {\n lines.push(` ${e.source} --> ${e.target}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction toJSON(params: GraphComponentParams): string {\n return JSON.stringify({ nodes: params.nodes, edges: params.edges ?? [] }, null, 2);\n}\n\nfunction downloadBlob(content: string | Blob, filename: string, mimeType?: string): void {\n const blob =\n typeof content === 'string' ? new Blob([content], { type: mimeType ?? 'text/plain' }) : content;\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n\nexport interface GraphRendererProps {\n component: UIComponent;\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible';\n}\n\nexport const GraphRenderer: Component<GraphRendererProps> = (props) => {\n const params = () => props.component.params as GraphComponentParams;\n const isExpanded = useExpanded();\n const telemetry = useTelemetry();\n const [available, setAvailable] = createSignal<boolean | null>(null);\n const [error, setError] = createSignal<string | undefined>();\n const [exportMenuOpen, setExportMenuOpen] = createSignal(false);\n let containerRef: HTMLDivElement | undefined;\n // v6.4.0 — trigger ref consumed by <PortalDropdownMenu> for positioning\n let exportTriggerRef: HTMLButtonElement | undefined;\n // Loosely typed because G6 is a peer-optional — we don't pull its\n // types into the bundle just to type a transient local handle.\n let graphInstance: any | undefined;\n\n onMount(async () => {\n const g6Available = await isG6Available();\n setAvailable(g6Available);\n if (!g6Available || !containerRef) return;\n\n try {\n const { Graph } = await g6ModulePromise!;\n const p = params();\n const config: Record<string, unknown> = {\n container: containerRef,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n // G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n // (that was the v4 contract). Passing the string `'canvas'` / `'svg'`\n // makes G6 throw `renderer is not a function` — and because the default\n // path also passed the string `'canvas'`, EVERY graph crashed, not just\n // the svg one.\n //\n // Fix: omit `renderer` entirely. G6 then uses its built-in canvas\n // renderer (documented default `() => new CanvasRenderer()`), which is\n // what we want for every graph.\n //\n // `rendererPref: 'svg'` is NOT wired yet: a real G6 v5 SVG renderer\n // needs the `@antv/g-svg` factory, which is a *transitive* dep of\n // `@antv/g6` (not a declared peer) and isn't statically resolvable at\n // build time. Rather than ship a fragile/unresolvable import, we treat\n // svg as \"not yet supported\" and fall back to the canvas default with a\n // one-time warning. Tracked for a follow-up that wires the factory\n // behind a proper optional-peer resolution. (Never pass a string here.)\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n if (p.tooltip !== false) {\n // Built-in tooltip plugin — shows label + a compact dump of\n // node.data on hover. Consumers can opt out with `tooltip: false`.\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data\n ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>`\n : ''\n }</div>`;\n },\n },\n ];\n }\n graphInstance = new (Graph as any)(config);\n await graphInstance.render();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to render graph';\n setError(message);\n // Fallback ladder (P2.5): the native G6 render threw — emit telemetry\n // so the failure is observable, then degrade to the edge/node table\n // below instead of leaving a blank canvas.\n telemetry?.dispatch({\n type: 'render:error',\n errorMessage: message,\n id: props.component.id ?? '',\n componentType: 'graph',\n ts: Date.now(),\n });\n }\n });\n\n onCleanup(() => {\n try {\n graphInstance?.destroy();\n } catch {\n // G6 destroy can throw on already-destroyed instances or partial\n // init failures — silent because the component is unmounting anyway.\n }\n graphInstance = undefined;\n });\n\n // ─── Export handlers ────────────────────────────────────────────────\n const handleExportJSON = () => {\n downloadBlob(toJSON(params()), `${graphFilenameStem(params())}.json`, 'application/json');\n setExportMenuOpen(false);\n };\n\n const handleExportMermaid = () => {\n downloadBlob(toMermaid(params()), `${graphFilenameStem(params())}.mmd`, 'text/plain');\n setExportMenuOpen(false);\n };\n\n const handleExportPNG = async () => {\n if (!graphInstance) return;\n try {\n // G6 v5 exposes `toDataURL()` on the graph instance.\n const dataUrl: string = await graphInstance.toDataURL?.('image/png');\n if (!dataUrl) {\n // Fallback: try to grab the underlying canvas directly.\n const canvas = containerRef?.querySelector('canvas');\n if (canvas) {\n const url = (canvas as HTMLCanvasElement).toDataURL('image/png');\n await downloadDataUrl(url, `${graphFilenameStem(params())}.png`);\n } else {\n setError('PNG export not supported in current renderer mode');\n }\n } else {\n await downloadDataUrl(dataUrl, `${graphFilenameStem(params())}.png`);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'PNG export failed');\n }\n setExportMenuOpen(false);\n };\n\n return (\n <Show\n when={available() === true}\n fallback={\n <Show\n when={available() === false}\n fallback={\n // Loading skeleton while we determine peer availability\n <div class=\"w-full p-4 bg-gray-50 dark:bg-gray-800/40 border border-gray-200 dark:border-gray-700 rounded-lg animate-pulse\">\n <div class=\"h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-2\" />\n <div class=\"h-3 w-48 bg-gray-200 dark:bg-gray-700 rounded\" />\n </div>\n }\n >\n <div class=\"w-full p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg\">\n <p class=\"text-sm font-medium text-yellow-900 dark:text-yellow-100\">\n Graph rendering unavailable\n </p>\n <p class=\"text-xs text-yellow-700 dark:text-yellow-300 mt-1\">\n Install <code>@antv/g6</code> peer dependency to render <code>type: \"graph\"</code>{' '}\n components.\n </p>\n </div>\n </Show>\n }\n >\n <ExpandableWrapper\n title={params().title ?? 'Graph'}\n copyData={toJSON(params())}\n copyLabel=\"Copy graph (JSON)\"\n toolbarVariant={props.toolbarVariant}\n >\n <div\n class={`relative w-full ${params().className ?? ''} ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}\n >\n {/* Export menu — top-right, mirrors TableRenderer's pattern */}\n <div class=\"absolute right-2 top-2 z-10\">\n <button\n ref={exportTriggerRef}\n type=\"button\"\n onClick={() => setExportMenuOpen((v) => !v)}\n class=\"px-2 py-1 text-xs bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300\"\n title=\"Export graph\"\n aria-label=\"Export graph\"\n aria-haspopup=\"menu\"\n aria-expanded={exportMenuOpen()}\n >\n Export ▾\n </button>\n <PortalDropdownMenu\n open={exportMenuOpen()}\n onClose={() => setExportMenuOpen(false)}\n trigger={exportTriggerRef}\n width={176}\n class=\"text-xs\"\n >\n <For\n each={[\n { label: 'Download PNG', onClick: handleExportPNG, hint: 'visual snapshot' },\n {\n label: 'Download Mermaid',\n onClick: handleExportMermaid,\n hint: 'markdown / GitHub',\n },\n { label: 'Download JSON', onClick: handleExportJSON, hint: 'raw data' },\n ]}\n >\n {(item) => (\n <button\n type=\"button\"\n onClick={item.onClick}\n class=\"w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-700 last:border-b-0\"\n >\n <div class=\"font-medium\">{item.label}</div>\n <div class=\"text-[10px] text-gray-500 dark:text-gray-400\">{item.hint}</div>\n </button>\n )}\n </For>\n </PortalDropdownMenu>\n </div>\n\n {/* Native G6 canvas — hidden once a render error degrades us. */}\n <div\n ref={containerRef}\n class={`bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n error() ? 'hidden' : ''\n } ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={\n isExpanded()\n ? `height: 100%; width: ${params().width ?? '100%'};`\n : `height: ${params().height ?? '400px'}; width: ${params().width ?? '100%'};`\n }\n />\n {/* Fallback ladder (P2.5): degrade to an edge/node table on error\n rather than showing a bare message. Export menu stays usable. */}\n <Show when={error()}>\n <DegradedFallback\n message={`Graph rendering failed: ${error()}`}\n caption=\"Showing the graph data as a table — the interactive view is unavailable.\"\n {...graphToDegradedTable(params())}\n />\n </Show>\n </div>\n </ExpandableWrapper>\n </Show>\n );\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────\n\nfunction graphFilenameStem(params: GraphComponentParams): string {\n const base = (params.title ?? 'graph').replace(/[^a-z0-9-_]+/gi, '-').replace(/^-+|-+$/g, '');\n return base || 'graph';\n}\n\nasync function downloadDataUrl(dataUrl: string, filename: string): Promise<void> {\n const res = await fetch(dataUrl);\n const blob = await res.blob();\n downloadBlob(blob, filename);\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => {\n switch (c) {\n case '&':\n return '&amp;';\n case '<':\n return '&lt;';\n case '>':\n return '&gt;';\n case '\"':\n return '&quot;';\n case \"'\":\n return '&#39;';\n default:\n return c;\n }\n });\n}\n\n// Re-export for tests + consumers that want to compose their own export menu\nexport { toMermaid as graphToMermaid, toJSON as graphToJSON };\n"],"names":["g6ModulePromise","isG6Available","resolveLayout","params","layout","undefined","hasEdges","edges","length","type","options","resolveBehaviors","behaviors","enableDrag","push","enableZoom","enableSelect","mermaidDirection","layoutType","mermaidLabel","s","replace","trim","toMermaid","dir","lines","n","nodes","label","id","e","labelParts","weight","String","labelText","join","source","target","toJSON","JSON","stringify","downloadBlob","content","filename","mimeType","blob","Blob","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","GraphRenderer","props","component","isExpanded","useExpanded","telemetry","useTelemetry","available","setAvailable","createSignal","error","setError","exportMenuOpen","setExportMenuOpen","containerRef","exportTriggerRef","graphInstance","onMount","g6Available","Graph","p","config","container","data","rendererPref","console","warn","fitView","autoFit","tooltip","plugins","getContent","_evt","items","item","escapeHtml","render","err","message","Error","dispatch","errorMessage","componentType","ts","Date","now","onCleanup","destroy","handleExportJSON","graphFilenameStem","handleExportMermaid","handleExportPNG","dataUrl","toDataURL","canvas","querySelector","downloadDataUrl","_$createComponent","Show","when","fallback","_$getNextElement","_tmpl$3","children","_tmpl$2","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_co$","_$getNextMarker","_el$6","_el$7","_el$8","_co$2","$$click","v","_ref$","_$use","_$insert","PortalDropdownMenu","open","onClose","trigger","width","For","each","onClick","hint","_el$1","_tmpl$4","_el$10","_el$11","_$addEventListener","_$runHydrationEvents","_ref$2","DegradedFallback","_$mergeProps","caption","graphToDegradedTable","_$effect","_p$","_v$","className","_v$2","_v$3","_v$4","height","_$className","t","_$setAttribute","o","_$style","base","res","fetch","c","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"GraphRenderer.cjs","sources":["../../src/components/GraphRenderer.tsx"],"sourcesContent":["/**\n * GraphRenderer (v6.0.0) — generic node-link visualization powered by\n * `@antv/g6 ^5` (peer-optional). Same lazy-load pattern as\n * `ChartJSRenderer` and `MapRenderer` : the heavy lib is dynamically\n * imported only on first mount, and apps that don't install the peer\n * see an informative fallback instead of a crash.\n *\n * Spec : `@seed-ship/mcp-ui-spec@5.0.4` exports `GraphComponentParamsSchema`,\n * `GraphNode`, `GraphEdge`, `GraphLayoutName`, `GraphLayout`,\n * `GraphComponentParams` — the shape consumed here. Domain semantics\n * (`weight` etc.) are opaque to this renderer ; consumers decide what\n * the values mean.\n *\n * Copy + export : the renderer ships with `<ExpandableWrapper>` (default\n * copy = JSON of `{nodes, edges}`) plus a 3-format export menu — **PNG**\n * (visual snapshot via the underlying canvas/SVG), **Mermaid** (markdown\n * / GitHub-renderable `flowchart` syntax), **JSON** (raw reimportable\n * data). All three are computed lazily on click.\n */\n\nimport { Component, createSignal, onCleanup, onMount, Show, For } from 'solid-js';\nimport type { UIComponent } from '../types';\nimport type {\n GraphComponentParams,\n GraphLayout,\n GraphNode,\n GraphEdge,\n} from '@seed-ship/mcp-ui-spec';\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper';\nimport { PortalDropdownMenu } from './PortalDropdownMenu';\nimport { DegradedFallback } from './DegradedFallback';\nimport { graphToDegradedTable } from '../utils/degraded-projections';\nimport { escapeHtml } from '../utils/escape-html';\nimport { useTelemetry } from '../context/MCPUITelemetryContext';\n\n// Module-scoped lazy import promise — first call triggers the dynamic\n// import, subsequent calls reuse the resolved module.\nlet g6ModulePromise: Promise<typeof import('@antv/g6')> | undefined;\n\n/**\n * Whether the `@antv/g6` peer dependency is installed and importable.\n * Resolves to `true` when the lib is available, `false` otherwise.\n *\n * Mirrors `isChartJSAvailable()` from `ChartJSRenderer`.\n */\nexport async function isG6Available(): Promise<boolean> {\n try {\n if (!g6ModulePromise) {\n g6ModulePromise = import('@antv/g6');\n }\n await g6ModulePromise;\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the spec layout shorthand or object form into the config object\n * G6 v5 expects. When `layout` is omitted, picks `'force'` if edges are\n * present (universal default) or `'circular'` otherwise.\n */\nfunction resolveLayout(params: GraphComponentParams): { type: string; [key: string]: unknown } {\n const layout: GraphLayout | undefined = params.layout;\n if (layout === undefined) {\n const hasEdges = (params.edges?.length ?? 0) > 0;\n return { type: hasEdges ? 'force' : 'circular' };\n }\n if (typeof layout === 'string') {\n return { type: layout };\n }\n // Object form: spread the passthrough options alongside `type`.\n return { type: layout.type, ...(layout.options ?? {}) };\n}\n\n/**\n * Build the G6 v5 `Graph` constructor config from the component params.\n *\n * Pure (no DOM/lib side effects beyond reading `container`), so it can be\n * unit-tested directly without a jsdom render — this is the contract the\n * 2026-05-30 audit (P0.2) wants locked.\n *\n * ⚠️ G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n * (that was the v4 contract). Passing the string `'canvas'` / `'svg'` makes\n * G6 throw `renderer is not a function` — and because the default path used\n * to pass the string `'canvas'`, EVERY graph crashed, not just svg. So we\n * **omit `renderer` entirely**: G6 then uses its built-in canvas renderer\n * (documented default `() => new CanvasRenderer()`).\n *\n * `rendererPref: 'svg'` is reserved but NOT wired yet — a real G6 v5 SVG\n * renderer needs the `@antv/g-svg` factory (a transitive dep of `@antv/g6`,\n * not statically resolvable at build time). Until that's wired behind proper\n * optional-peer resolution, svg degrades to the canvas default with a\n * one-time warning. It must NEVER inject a string `renderer`.\n */\nexport function buildGraphConfig(\n p: GraphComponentParams,\n container?: HTMLElement\n): Record<string, unknown> {\n const config: Record<string, unknown> = {\n container,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n\n if (p.tooltip !== false) {\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>` : ''\n }</div>`;\n },\n },\n ];\n }\n\n return config;\n}\n\n/**\n * Build the G6 v5 `behaviors` array from the params interactivity flags.\n * Defaults : drag-canvas + zoom-canvas + drag-element + click-select.\n * Any flag set to `false` opts out.\n */\nfunction resolveBehaviors(params: GraphComponentParams): string[] {\n const behaviors: string[] = [];\n if (params.enableDrag !== false) behaviors.push('drag-element');\n if (params.enableZoom !== false) {\n behaviors.push('zoom-canvas', 'drag-canvas');\n }\n if (params.enableSelect !== false) behaviors.push('click-select');\n return behaviors;\n}\n\n/**\n * Pick a sensible Mermaid `flowchart` direction from the resolved layout.\n * `dagre` / `tree` / `mindmap` are top-down hierarchies → TD ; everything\n * else (force, concentric, circular, grid) → LR (default mermaid).\n */\nfunction mermaidDirection(layoutType: string): 'TD' | 'LR' {\n return layoutType === 'dagre' || layoutType === 'tree' || layoutType === 'mindmap' ? 'TD' : 'LR';\n}\n\n/**\n * Sanitize a string for use inside a Mermaid node label. Mermaid breaks\n * on raw quotes / brackets / pipes ; we strip the worst offenders.\n */\nfunction mermaidLabel(s: string): string {\n return s\n .replace(/[\"[\\]|]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Convert the graph data to Mermaid `flowchart` syntax. The edge label\n * carries the optional `weight` prefix when present (e.g. `|3| label`).\n */\nfunction toMermaid(params: GraphComponentParams): string {\n const layoutType = resolveLayout(params).type;\n const dir = mermaidDirection(layoutType);\n const lines: string[] = [`flowchart ${dir}`];\n for (const n of params.nodes) {\n const label = mermaidLabel(n.label ?? n.id);\n lines.push(` ${n.id}[\"${label}\"]`);\n }\n for (const e of params.edges ?? []) {\n const labelParts: string[] = [];\n if (e.weight !== undefined) labelParts.push(String(e.weight));\n if (e.label) labelParts.push(mermaidLabel(e.label));\n const labelText = labelParts.join(' · ');\n if (labelText) {\n lines.push(` ${e.source} -->|${labelText}| ${e.target}`);\n } else {\n lines.push(` ${e.source} --> ${e.target}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction toJSON(params: GraphComponentParams): string {\n return JSON.stringify({ nodes: params.nodes, edges: params.edges ?? [] }, null, 2);\n}\n\nfunction downloadBlob(content: string | Blob, filename: string, mimeType?: string): void {\n const blob =\n typeof content === 'string' ? new Blob([content], { type: mimeType ?? 'text/plain' }) : content;\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n\nexport interface GraphRendererProps {\n component: UIComponent;\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible';\n}\n\nexport const GraphRenderer: Component<GraphRendererProps> = (props) => {\n const params = () => props.component.params as GraphComponentParams;\n const isExpanded = useExpanded();\n const telemetry = useTelemetry();\n const [available, setAvailable] = createSignal<boolean | null>(null);\n const [error, setError] = createSignal<string | undefined>();\n const [exportMenuOpen, setExportMenuOpen] = createSignal(false);\n let containerRef: HTMLDivElement | undefined;\n // v6.4.0 — trigger ref consumed by <PortalDropdownMenu> for positioning\n let exportTriggerRef: HTMLButtonElement | undefined;\n // Loosely typed because G6 is a peer-optional — we don't pull its\n // types into the bundle just to type a transient local handle.\n let graphInstance: any | undefined;\n\n onMount(async () => {\n const g6Available = await isG6Available();\n setAvailable(g6Available);\n if (!g6Available || !containerRef) return;\n\n try {\n const { Graph } = await g6ModulePromise!;\n const p = params();\n const config: Record<string, unknown> = {\n container: containerRef,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n // G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n // (that was the v4 contract). Passing the string `'canvas'` / `'svg'`\n // makes G6 throw `renderer is not a function` — and because the default\n // path also passed the string `'canvas'`, EVERY graph crashed, not just\n // the svg one.\n //\n // Fix: omit `renderer` entirely. G6 then uses its built-in canvas\n // renderer (documented default `() => new CanvasRenderer()`), which is\n // what we want for every graph.\n //\n // `rendererPref: 'svg'` is NOT wired yet: a real G6 v5 SVG renderer\n // needs the `@antv/g-svg` factory, which is a *transitive* dep of\n // `@antv/g6` (not a declared peer) and isn't statically resolvable at\n // build time. Rather than ship a fragile/unresolvable import, we treat\n // svg as \"not yet supported\" and fall back to the canvas default with a\n // one-time warning. Tracked for a follow-up that wires the factory\n // behind a proper optional-peer resolution. (Never pass a string here.)\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n if (p.tooltip !== false) {\n // Built-in tooltip plugin — shows label + a compact dump of\n // node.data on hover. Consumers can opt out with `tooltip: false`.\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data\n ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>`\n : ''\n }</div>`;\n },\n },\n ];\n }\n graphInstance = new (Graph as any)(config);\n await graphInstance.render();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to render graph';\n setError(message);\n // Fallback ladder (P2.5): the native G6 render threw — emit telemetry\n // so the failure is observable, then degrade to the edge/node table\n // below instead of leaving a blank canvas.\n telemetry?.dispatch({\n type: 'render:error',\n errorMessage: message,\n id: props.component.id ?? '',\n componentType: 'graph',\n ts: Date.now(),\n });\n }\n });\n\n onCleanup(() => {\n try {\n graphInstance?.destroy();\n } catch {\n // G6 destroy can throw on already-destroyed instances or partial\n // init failures — silent because the component is unmounting anyway.\n }\n graphInstance = undefined;\n });\n\n // ─── Export handlers ────────────────────────────────────────────────\n const handleExportJSON = () => {\n downloadBlob(toJSON(params()), `${graphFilenameStem(params())}.json`, 'application/json');\n setExportMenuOpen(false);\n };\n\n const handleExportMermaid = () => {\n downloadBlob(toMermaid(params()), `${graphFilenameStem(params())}.mmd`, 'text/plain');\n setExportMenuOpen(false);\n };\n\n const handleExportPNG = async () => {\n if (!graphInstance) return;\n try {\n // G6 v5 exposes `toDataURL()` on the graph instance.\n const dataUrl: string = await graphInstance.toDataURL?.('image/png');\n if (!dataUrl) {\n // Fallback: try to grab the underlying canvas directly.\n const canvas = containerRef?.querySelector('canvas');\n if (canvas) {\n const url = (canvas as HTMLCanvasElement).toDataURL('image/png');\n await downloadDataUrl(url, `${graphFilenameStem(params())}.png`);\n } else {\n setError('PNG export not supported in current renderer mode');\n }\n } else {\n await downloadDataUrl(dataUrl, `${graphFilenameStem(params())}.png`);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'PNG export failed');\n }\n setExportMenuOpen(false);\n };\n\n return (\n <Show\n when={available() === true}\n fallback={\n <Show\n when={available() === false}\n fallback={\n // Loading skeleton while we determine peer availability\n <div class=\"w-full p-4 bg-gray-50 dark:bg-gray-800/40 border border-gray-200 dark:border-gray-700 rounded-lg animate-pulse\">\n <div class=\"h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-2\" />\n <div class=\"h-3 w-48 bg-gray-200 dark:bg-gray-700 rounded\" />\n </div>\n }\n >\n <div class=\"w-full p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg\">\n <p class=\"text-sm font-medium text-yellow-900 dark:text-yellow-100\">\n Graph rendering unavailable\n </p>\n <p class=\"text-xs text-yellow-700 dark:text-yellow-300 mt-1\">\n Install <code>@antv/g6</code> peer dependency to render <code>type: \"graph\"</code>{' '}\n components.\n </p>\n </div>\n </Show>\n }\n >\n <ExpandableWrapper\n title={params().title ?? 'Graph'}\n copyData={toJSON(params())}\n copyLabel=\"Copy graph (JSON)\"\n toolbarVariant={props.toolbarVariant}\n >\n <div\n class={`relative w-full ${params().className ?? ''} ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}\n >\n {/* Export menu — top-right, mirrors TableRenderer's pattern */}\n <div class=\"absolute right-2 top-2 z-10\">\n <button\n ref={exportTriggerRef}\n type=\"button\"\n onClick={() => setExportMenuOpen((v) => !v)}\n class=\"px-2 py-1 text-xs bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300\"\n title=\"Export graph\"\n aria-label=\"Export graph\"\n aria-haspopup=\"menu\"\n aria-expanded={exportMenuOpen()}\n >\n Export ▾\n </button>\n <PortalDropdownMenu\n open={exportMenuOpen()}\n onClose={() => setExportMenuOpen(false)}\n trigger={exportTriggerRef}\n width={176}\n class=\"text-xs\"\n >\n <For\n each={[\n { label: 'Download PNG', onClick: handleExportPNG, hint: 'visual snapshot' },\n {\n label: 'Download Mermaid',\n onClick: handleExportMermaid,\n hint: 'markdown / GitHub',\n },\n { label: 'Download JSON', onClick: handleExportJSON, hint: 'raw data' },\n ]}\n >\n {(item) => (\n <button\n type=\"button\"\n onClick={item.onClick}\n class=\"w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-700 last:border-b-0\"\n >\n <div class=\"font-medium\">{item.label}</div>\n <div class=\"text-[10px] text-gray-500 dark:text-gray-400\">{item.hint}</div>\n </button>\n )}\n </For>\n </PortalDropdownMenu>\n </div>\n\n {/* Native G6 canvas — hidden once a render error degrades us. */}\n <div\n ref={containerRef}\n class={`bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n error() ? 'hidden' : ''\n } ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={\n isExpanded()\n ? `height: 100%; width: ${params().width ?? '100%'};`\n : `height: ${params().height ?? '400px'}; width: ${params().width ?? '100%'};`\n }\n />\n {/* Fallback ladder (P2.5): degrade to an edge/node table on error\n rather than showing a bare message. Export menu stays usable. */}\n <Show when={error()}>\n <DegradedFallback\n message={`Graph rendering failed: ${error()}`}\n caption=\"Showing the graph data as a table — the interactive view is unavailable.\"\n {...graphToDegradedTable(params())}\n />\n </Show>\n </div>\n </ExpandableWrapper>\n </Show>\n );\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────\n\nfunction graphFilenameStem(params: GraphComponentParams): string {\n const base = (params.title ?? 'graph').replace(/[^a-z0-9-_]+/gi, '-').replace(/^-+|-+$/g, '');\n return base || 'graph';\n}\n\nasync function downloadDataUrl(dataUrl: string, filename: string): Promise<void> {\n const res = await fetch(dataUrl);\n const blob = await res.blob();\n downloadBlob(blob, filename);\n}\n\n// Re-export for tests + consumers that want to compose their own export menu\nexport { toMermaid as graphToMermaid, toJSON as graphToJSON };\n"],"names":["g6ModulePromise","isG6Available","resolveLayout","params","layout","undefined","hasEdges","edges","length","type","options","resolveBehaviors","behaviors","enableDrag","push","enableZoom","enableSelect","mermaidDirection","layoutType","mermaidLabel","s","replace","trim","toMermaid","dir","lines","n","nodes","label","id","e","labelParts","weight","String","labelText","join","source","target","toJSON","JSON","stringify","downloadBlob","content","filename","mimeType","blob","Blob","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","GraphRenderer","props","component","isExpanded","useExpanded","telemetry","useTelemetry","available","setAvailable","createSignal","error","setError","exportMenuOpen","setExportMenuOpen","containerRef","exportTriggerRef","graphInstance","onMount","g6Available","Graph","p","config","container","data","rendererPref","console","warn","fitView","autoFit","tooltip","plugins","getContent","_evt","items","item","escapeHtml","render","err","message","Error","dispatch","errorMessage","componentType","ts","Date","now","onCleanup","destroy","handleExportJSON","graphFilenameStem","handleExportMermaid","handleExportPNG","dataUrl","toDataURL","canvas","querySelector","downloadDataUrl","_$createComponent","Show","when","fallback","_$getNextElement","_tmpl$3","children","_tmpl$2","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_co$","_$getNextMarker","_el$6","_el$7","_el$8","_co$2","$$click","v","_ref$","_$use","_$insert","PortalDropdownMenu","open","onClose","trigger","width","For","each","onClick","hint","_el$1","_tmpl$4","_el$10","_el$11","_$addEventListener","_$runHydrationEvents","_ref$2","DegradedFallback","_$mergeProps","caption","graphToDegradedTable","_$effect","_p$","_v$","className","_v$2","_v$3","_v$4","height","_$className","t","_$setAttribute","o","_$style","base","res","fetch","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"GraphRenderer.d.ts","sourceRoot":"","sources":["../../src/components/GraphRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAA+C,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,wBAAwB,CAAC;AAWhC;;;;;GAKG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAUtD;AAoBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,oBAAoB,EACvB,SAAS,CAAC,EAAE,WAAW,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoCzB;AAqCD;;;GAGG;AACH,iBAAS,SAAS,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAoBvD;AAED,iBAAS,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAEpD;AAeD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,WAAW,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CAC7C;AAED,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,kBAAkB,CAoPvD,CAAC;AAmCF,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,IAAI,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"GraphRenderer.d.ts","sourceRoot":"","sources":["../../src/components/GraphRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAA+C,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,wBAAwB,CAAC;AAYhC;;;;;GAKG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAUtD;AAoBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,oBAAoB,EACvB,SAAS,CAAC,EAAE,WAAW,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoCzB;AAqCD;;;GAGG;AACH,iBAAS,SAAS,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAoBvD;AAED,iBAAS,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAEpD;AAeD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,WAAW,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CAC7C;AAED,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,kBAAkB,CAoPvD,CAAC;AAgBF,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,IAAI,WAAW,EAAE,CAAC"}
@@ -1,9 +1,10 @@
1
- import { delegateEvents, createComponent, getNextElement, template, getNextMarker, insert, addEventListener, runHydrationEvents, mergeProps, effect, className, setAttribute, style, use } from "solid-js/web";
1
+ import { delegateEvents, createComponent, getNextElement, getNextMarker, insert, addEventListener, runHydrationEvents, mergeProps, effect, className, setAttribute, style, template, use } from "solid-js/web";
2
2
  import { createSignal, onMount, onCleanup, Show, For } from "solid-js";
3
3
  import { useExpanded, ExpandableWrapper } from "./ExpandableWrapper.js";
4
4
  import { PortalDropdownMenu } from "./PortalDropdownMenu.js";
5
5
  import { DegradedFallback } from "./DegradedFallback.js";
6
6
  import { graphToDegradedTable } from "../utils/degraded-projections.js";
7
+ import { escapeHtml } from "../utils/escape-html.js";
7
8
  import { useTelemetry } from "../context/MCPUITelemetryContext.js";
8
9
  var _tmpl$ = /* @__PURE__ */ template(`<div><div class="absolute right-2 top-2 z-10"><button type=button class="px-2 py-1 text-xs bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300"title="Export graph"aria-label="Export graph"aria-haspopup=menu>Export ▾</button><!$><!/></div><div></div><!$><!/>`), _tmpl$2 = /* @__PURE__ */ template(`<div class="w-full p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg"><p class="text-sm font-medium text-yellow-900 dark:text-yellow-100">Graph rendering unavailable</p><p class="text-xs text-yellow-700 dark:text-yellow-300 mt-1">Install <code>@antv/g6</code> peer dependency to render <code>type: "graph"</code> components.`), _tmpl$3 = /* @__PURE__ */ template(`<div class="w-full p-4 bg-gray-50 dark:bg-gray-800/40 border border-gray-200 dark:border-gray-700 rounded-lg animate-pulse"><div class="h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-2"></div><div class="h-3 w-48 bg-gray-200 dark:bg-gray-700 rounded">`), _tmpl$4 = /* @__PURE__ */ template(`<button type=button class="w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-700 last:border-b-0"><div class=font-medium></div><div class="text-[10px] text-gray-500 dark:text-gray-400">`);
9
10
  let g6ModulePromise;
@@ -303,24 +304,6 @@ async function downloadDataUrl(dataUrl, filename) {
303
304
  const blob = await res.blob();
304
305
  downloadBlob(blob, filename);
305
306
  }
306
- function escapeHtml(s) {
307
- return s.replace(/[&<>"']/g, (c) => {
308
- switch (c) {
309
- case "&":
310
- return "&amp;";
311
- case "<":
312
- return "&lt;";
313
- case ">":
314
- return "&gt;";
315
- case '"':
316
- return "&quot;";
317
- case "'":
318
- return "&#39;";
319
- default:
320
- return c;
321
- }
322
- });
323
- }
324
307
  delegateEvents(["click"]);
325
308
  export {
326
309
  GraphRenderer,
@@ -1 +1 @@
1
- {"version":3,"file":"GraphRenderer.js","sources":["../../src/components/GraphRenderer.tsx"],"sourcesContent":["/**\n * GraphRenderer (v6.0.0) — generic node-link visualization powered by\n * `@antv/g6 ^5` (peer-optional). Same lazy-load pattern as\n * `ChartJSRenderer` and `MapRenderer` : the heavy lib is dynamically\n * imported only on first mount, and apps that don't install the peer\n * see an informative fallback instead of a crash.\n *\n * Spec : `@seed-ship/mcp-ui-spec@5.0.4` exports `GraphComponentParamsSchema`,\n * `GraphNode`, `GraphEdge`, `GraphLayoutName`, `GraphLayout`,\n * `GraphComponentParams` — the shape consumed here. Domain semantics\n * (`weight` etc.) are opaque to this renderer ; consumers decide what\n * the values mean.\n *\n * Copy + export : the renderer ships with `<ExpandableWrapper>` (default\n * copy = JSON of `{nodes, edges}`) plus a 3-format export menu — **PNG**\n * (visual snapshot via the underlying canvas/SVG), **Mermaid** (markdown\n * / GitHub-renderable `flowchart` syntax), **JSON** (raw reimportable\n * data). All three are computed lazily on click.\n */\n\nimport { Component, createSignal, onCleanup, onMount, Show, For } from 'solid-js';\nimport type { UIComponent } from '../types';\nimport type {\n GraphComponentParams,\n GraphLayout,\n GraphNode,\n GraphEdge,\n} from '@seed-ship/mcp-ui-spec';\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper';\nimport { PortalDropdownMenu } from './PortalDropdownMenu';\nimport { DegradedFallback } from './DegradedFallback';\nimport { graphToDegradedTable } from '../utils/degraded-projections';\nimport { useTelemetry } from '../context/MCPUITelemetryContext';\n\n// Module-scoped lazy import promise — first call triggers the dynamic\n// import, subsequent calls reuse the resolved module.\nlet g6ModulePromise: Promise<typeof import('@antv/g6')> | undefined;\n\n/**\n * Whether the `@antv/g6` peer dependency is installed and importable.\n * Resolves to `true` when the lib is available, `false` otherwise.\n *\n * Mirrors `isChartJSAvailable()` from `ChartJSRenderer`.\n */\nexport async function isG6Available(): Promise<boolean> {\n try {\n if (!g6ModulePromise) {\n g6ModulePromise = import('@antv/g6');\n }\n await g6ModulePromise;\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the spec layout shorthand or object form into the config object\n * G6 v5 expects. When `layout` is omitted, picks `'force'` if edges are\n * present (universal default) or `'circular'` otherwise.\n */\nfunction resolveLayout(params: GraphComponentParams): { type: string; [key: string]: unknown } {\n const layout: GraphLayout | undefined = params.layout;\n if (layout === undefined) {\n const hasEdges = (params.edges?.length ?? 0) > 0;\n return { type: hasEdges ? 'force' : 'circular' };\n }\n if (typeof layout === 'string') {\n return { type: layout };\n }\n // Object form: spread the passthrough options alongside `type`.\n return { type: layout.type, ...(layout.options ?? {}) };\n}\n\n/**\n * Build the G6 v5 `Graph` constructor config from the component params.\n *\n * Pure (no DOM/lib side effects beyond reading `container`), so it can be\n * unit-tested directly without a jsdom render — this is the contract the\n * 2026-05-30 audit (P0.2) wants locked.\n *\n * ⚠️ G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n * (that was the v4 contract). Passing the string `'canvas'` / `'svg'` makes\n * G6 throw `renderer is not a function` — and because the default path used\n * to pass the string `'canvas'`, EVERY graph crashed, not just svg. So we\n * **omit `renderer` entirely**: G6 then uses its built-in canvas renderer\n * (documented default `() => new CanvasRenderer()`).\n *\n * `rendererPref: 'svg'` is reserved but NOT wired yet — a real G6 v5 SVG\n * renderer needs the `@antv/g-svg` factory (a transitive dep of `@antv/g6`,\n * not statically resolvable at build time). Until that's wired behind proper\n * optional-peer resolution, svg degrades to the canvas default with a\n * one-time warning. It must NEVER inject a string `renderer`.\n */\nexport function buildGraphConfig(\n p: GraphComponentParams,\n container?: HTMLElement\n): Record<string, unknown> {\n const config: Record<string, unknown> = {\n container,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n\n if (p.tooltip !== false) {\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>` : ''\n }</div>`;\n },\n },\n ];\n }\n\n return config;\n}\n\n/**\n * Build the G6 v5 `behaviors` array from the params interactivity flags.\n * Defaults : drag-canvas + zoom-canvas + drag-element + click-select.\n * Any flag set to `false` opts out.\n */\nfunction resolveBehaviors(params: GraphComponentParams): string[] {\n const behaviors: string[] = [];\n if (params.enableDrag !== false) behaviors.push('drag-element');\n if (params.enableZoom !== false) {\n behaviors.push('zoom-canvas', 'drag-canvas');\n }\n if (params.enableSelect !== false) behaviors.push('click-select');\n return behaviors;\n}\n\n/**\n * Pick a sensible Mermaid `flowchart` direction from the resolved layout.\n * `dagre` / `tree` / `mindmap` are top-down hierarchies → TD ; everything\n * else (force, concentric, circular, grid) → LR (default mermaid).\n */\nfunction mermaidDirection(layoutType: string): 'TD' | 'LR' {\n return layoutType === 'dagre' || layoutType === 'tree' || layoutType === 'mindmap' ? 'TD' : 'LR';\n}\n\n/**\n * Sanitize a string for use inside a Mermaid node label. Mermaid breaks\n * on raw quotes / brackets / pipes ; we strip the worst offenders.\n */\nfunction mermaidLabel(s: string): string {\n return s\n .replace(/[\"[\\]|]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Convert the graph data to Mermaid `flowchart` syntax. The edge label\n * carries the optional `weight` prefix when present (e.g. `|3| label`).\n */\nfunction toMermaid(params: GraphComponentParams): string {\n const layoutType = resolveLayout(params).type;\n const dir = mermaidDirection(layoutType);\n const lines: string[] = [`flowchart ${dir}`];\n for (const n of params.nodes) {\n const label = mermaidLabel(n.label ?? n.id);\n lines.push(` ${n.id}[\"${label}\"]`);\n }\n for (const e of params.edges ?? []) {\n const labelParts: string[] = [];\n if (e.weight !== undefined) labelParts.push(String(e.weight));\n if (e.label) labelParts.push(mermaidLabel(e.label));\n const labelText = labelParts.join(' · ');\n if (labelText) {\n lines.push(` ${e.source} -->|${labelText}| ${e.target}`);\n } else {\n lines.push(` ${e.source} --> ${e.target}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction toJSON(params: GraphComponentParams): string {\n return JSON.stringify({ nodes: params.nodes, edges: params.edges ?? [] }, null, 2);\n}\n\nfunction downloadBlob(content: string | Blob, filename: string, mimeType?: string): void {\n const blob =\n typeof content === 'string' ? new Blob([content], { type: mimeType ?? 'text/plain' }) : content;\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n\nexport interface GraphRendererProps {\n component: UIComponent;\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible';\n}\n\nexport const GraphRenderer: Component<GraphRendererProps> = (props) => {\n const params = () => props.component.params as GraphComponentParams;\n const isExpanded = useExpanded();\n const telemetry = useTelemetry();\n const [available, setAvailable] = createSignal<boolean | null>(null);\n const [error, setError] = createSignal<string | undefined>();\n const [exportMenuOpen, setExportMenuOpen] = createSignal(false);\n let containerRef: HTMLDivElement | undefined;\n // v6.4.0 — trigger ref consumed by <PortalDropdownMenu> for positioning\n let exportTriggerRef: HTMLButtonElement | undefined;\n // Loosely typed because G6 is a peer-optional — we don't pull its\n // types into the bundle just to type a transient local handle.\n let graphInstance: any | undefined;\n\n onMount(async () => {\n const g6Available = await isG6Available();\n setAvailable(g6Available);\n if (!g6Available || !containerRef) return;\n\n try {\n const { Graph } = await g6ModulePromise!;\n const p = params();\n const config: Record<string, unknown> = {\n container: containerRef,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n // G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n // (that was the v4 contract). Passing the string `'canvas'` / `'svg'`\n // makes G6 throw `renderer is not a function` — and because the default\n // path also passed the string `'canvas'`, EVERY graph crashed, not just\n // the svg one.\n //\n // Fix: omit `renderer` entirely. G6 then uses its built-in canvas\n // renderer (documented default `() => new CanvasRenderer()`), which is\n // what we want for every graph.\n //\n // `rendererPref: 'svg'` is NOT wired yet: a real G6 v5 SVG renderer\n // needs the `@antv/g-svg` factory, which is a *transitive* dep of\n // `@antv/g6` (not a declared peer) and isn't statically resolvable at\n // build time. Rather than ship a fragile/unresolvable import, we treat\n // svg as \"not yet supported\" and fall back to the canvas default with a\n // one-time warning. Tracked for a follow-up that wires the factory\n // behind a proper optional-peer resolution. (Never pass a string here.)\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n if (p.tooltip !== false) {\n // Built-in tooltip plugin — shows label + a compact dump of\n // node.data on hover. Consumers can opt out with `tooltip: false`.\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data\n ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>`\n : ''\n }</div>`;\n },\n },\n ];\n }\n graphInstance = new (Graph as any)(config);\n await graphInstance.render();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to render graph';\n setError(message);\n // Fallback ladder (P2.5): the native G6 render threw — emit telemetry\n // so the failure is observable, then degrade to the edge/node table\n // below instead of leaving a blank canvas.\n telemetry?.dispatch({\n type: 'render:error',\n errorMessage: message,\n id: props.component.id ?? '',\n componentType: 'graph',\n ts: Date.now(),\n });\n }\n });\n\n onCleanup(() => {\n try {\n graphInstance?.destroy();\n } catch {\n // G6 destroy can throw on already-destroyed instances or partial\n // init failures — silent because the component is unmounting anyway.\n }\n graphInstance = undefined;\n });\n\n // ─── Export handlers ────────────────────────────────────────────────\n const handleExportJSON = () => {\n downloadBlob(toJSON(params()), `${graphFilenameStem(params())}.json`, 'application/json');\n setExportMenuOpen(false);\n };\n\n const handleExportMermaid = () => {\n downloadBlob(toMermaid(params()), `${graphFilenameStem(params())}.mmd`, 'text/plain');\n setExportMenuOpen(false);\n };\n\n const handleExportPNG = async () => {\n if (!graphInstance) return;\n try {\n // G6 v5 exposes `toDataURL()` on the graph instance.\n const dataUrl: string = await graphInstance.toDataURL?.('image/png');\n if (!dataUrl) {\n // Fallback: try to grab the underlying canvas directly.\n const canvas = containerRef?.querySelector('canvas');\n if (canvas) {\n const url = (canvas as HTMLCanvasElement).toDataURL('image/png');\n await downloadDataUrl(url, `${graphFilenameStem(params())}.png`);\n } else {\n setError('PNG export not supported in current renderer mode');\n }\n } else {\n await downloadDataUrl(dataUrl, `${graphFilenameStem(params())}.png`);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'PNG export failed');\n }\n setExportMenuOpen(false);\n };\n\n return (\n <Show\n when={available() === true}\n fallback={\n <Show\n when={available() === false}\n fallback={\n // Loading skeleton while we determine peer availability\n <div class=\"w-full p-4 bg-gray-50 dark:bg-gray-800/40 border border-gray-200 dark:border-gray-700 rounded-lg animate-pulse\">\n <div class=\"h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-2\" />\n <div class=\"h-3 w-48 bg-gray-200 dark:bg-gray-700 rounded\" />\n </div>\n }\n >\n <div class=\"w-full p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg\">\n <p class=\"text-sm font-medium text-yellow-900 dark:text-yellow-100\">\n Graph rendering unavailable\n </p>\n <p class=\"text-xs text-yellow-700 dark:text-yellow-300 mt-1\">\n Install <code>@antv/g6</code> peer dependency to render <code>type: \"graph\"</code>{' '}\n components.\n </p>\n </div>\n </Show>\n }\n >\n <ExpandableWrapper\n title={params().title ?? 'Graph'}\n copyData={toJSON(params())}\n copyLabel=\"Copy graph (JSON)\"\n toolbarVariant={props.toolbarVariant}\n >\n <div\n class={`relative w-full ${params().className ?? ''} ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}\n >\n {/* Export menu — top-right, mirrors TableRenderer's pattern */}\n <div class=\"absolute right-2 top-2 z-10\">\n <button\n ref={exportTriggerRef}\n type=\"button\"\n onClick={() => setExportMenuOpen((v) => !v)}\n class=\"px-2 py-1 text-xs bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300\"\n title=\"Export graph\"\n aria-label=\"Export graph\"\n aria-haspopup=\"menu\"\n aria-expanded={exportMenuOpen()}\n >\n Export ▾\n </button>\n <PortalDropdownMenu\n open={exportMenuOpen()}\n onClose={() => setExportMenuOpen(false)}\n trigger={exportTriggerRef}\n width={176}\n class=\"text-xs\"\n >\n <For\n each={[\n { label: 'Download PNG', onClick: handleExportPNG, hint: 'visual snapshot' },\n {\n label: 'Download Mermaid',\n onClick: handleExportMermaid,\n hint: 'markdown / GitHub',\n },\n { label: 'Download JSON', onClick: handleExportJSON, hint: 'raw data' },\n ]}\n >\n {(item) => (\n <button\n type=\"button\"\n onClick={item.onClick}\n class=\"w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-700 last:border-b-0\"\n >\n <div class=\"font-medium\">{item.label}</div>\n <div class=\"text-[10px] text-gray-500 dark:text-gray-400\">{item.hint}</div>\n </button>\n )}\n </For>\n </PortalDropdownMenu>\n </div>\n\n {/* Native G6 canvas — hidden once a render error degrades us. */}\n <div\n ref={containerRef}\n class={`bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n error() ? 'hidden' : ''\n } ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={\n isExpanded()\n ? `height: 100%; width: ${params().width ?? '100%'};`\n : `height: ${params().height ?? '400px'}; width: ${params().width ?? '100%'};`\n }\n />\n {/* Fallback ladder (P2.5): degrade to an edge/node table on error\n rather than showing a bare message. Export menu stays usable. */}\n <Show when={error()}>\n <DegradedFallback\n message={`Graph rendering failed: ${error()}`}\n caption=\"Showing the graph data as a table — the interactive view is unavailable.\"\n {...graphToDegradedTable(params())}\n />\n </Show>\n </div>\n </ExpandableWrapper>\n </Show>\n );\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────\n\nfunction graphFilenameStem(params: GraphComponentParams): string {\n const base = (params.title ?? 'graph').replace(/[^a-z0-9-_]+/gi, '-').replace(/^-+|-+$/g, '');\n return base || 'graph';\n}\n\nasync function downloadDataUrl(dataUrl: string, filename: string): Promise<void> {\n const res = await fetch(dataUrl);\n const blob = await res.blob();\n downloadBlob(blob, filename);\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => {\n switch (c) {\n case '&':\n return '&amp;';\n case '<':\n return '&lt;';\n case '>':\n return '&gt;';\n case '\"':\n return '&quot;';\n case \"'\":\n return '&#39;';\n default:\n return c;\n }\n });\n}\n\n// Re-export for tests + consumers that want to compose their own export menu\nexport { toMermaid as graphToMermaid, toJSON as graphToJSON };\n"],"names":["g6ModulePromise","isG6Available","resolveLayout","params","layout","undefined","hasEdges","edges","length","type","options","resolveBehaviors","behaviors","enableDrag","push","enableZoom","enableSelect","mermaidDirection","layoutType","mermaidLabel","s","replace","trim","toMermaid","dir","lines","n","nodes","label","id","e","labelParts","weight","String","labelText","join","source","target","toJSON","JSON","stringify","downloadBlob","content","filename","mimeType","blob","Blob","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","GraphRenderer","props","component","isExpanded","useExpanded","telemetry","useTelemetry","available","setAvailable","createSignal","error","setError","exportMenuOpen","setExportMenuOpen","containerRef","exportTriggerRef","graphInstance","onMount","g6Available","Graph","p","config","container","data","rendererPref","console","warn","fitView","autoFit","tooltip","plugins","getContent","_evt","items","item","escapeHtml","render","err","message","Error","dispatch","errorMessage","componentType","ts","Date","now","onCleanup","destroy","handleExportJSON","graphFilenameStem","handleExportMermaid","handleExportPNG","dataUrl","toDataURL","canvas","querySelector","downloadDataUrl","_$createComponent","Show","when","fallback","_$getNextElement","_tmpl$3","children","_tmpl$2","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_co$","_$getNextMarker","_el$6","_el$7","_el$8","_co$2","$$click","v","_ref$","_$use","_$insert","PortalDropdownMenu","open","onClose","trigger","width","For","each","onClick","hint","_el$1","_tmpl$4","_el$10","_el$11","_$addEventListener","_$runHydrationEvents","_ref$2","DegradedFallback","_$mergeProps","caption","graphToDegradedTable","_$effect","_p$","_v$","className","_v$2","_v$3","_v$4","height","_$className","t","_$setAttribute","o","_$style","base","res","fetch","c","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"GraphRenderer.js","sources":["../../src/components/GraphRenderer.tsx"],"sourcesContent":["/**\n * GraphRenderer (v6.0.0) — generic node-link visualization powered by\n * `@antv/g6 ^5` (peer-optional). Same lazy-load pattern as\n * `ChartJSRenderer` and `MapRenderer` : the heavy lib is dynamically\n * imported only on first mount, and apps that don't install the peer\n * see an informative fallback instead of a crash.\n *\n * Spec : `@seed-ship/mcp-ui-spec@5.0.4` exports `GraphComponentParamsSchema`,\n * `GraphNode`, `GraphEdge`, `GraphLayoutName`, `GraphLayout`,\n * `GraphComponentParams` — the shape consumed here. Domain semantics\n * (`weight` etc.) are opaque to this renderer ; consumers decide what\n * the values mean.\n *\n * Copy + export : the renderer ships with `<ExpandableWrapper>` (default\n * copy = JSON of `{nodes, edges}`) plus a 3-format export menu — **PNG**\n * (visual snapshot via the underlying canvas/SVG), **Mermaid** (markdown\n * / GitHub-renderable `flowchart` syntax), **JSON** (raw reimportable\n * data). All three are computed lazily on click.\n */\n\nimport { Component, createSignal, onCleanup, onMount, Show, For } from 'solid-js';\nimport type { UIComponent } from '../types';\nimport type {\n GraphComponentParams,\n GraphLayout,\n GraphNode,\n GraphEdge,\n} from '@seed-ship/mcp-ui-spec';\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper';\nimport { PortalDropdownMenu } from './PortalDropdownMenu';\nimport { DegradedFallback } from './DegradedFallback';\nimport { graphToDegradedTable } from '../utils/degraded-projections';\nimport { escapeHtml } from '../utils/escape-html';\nimport { useTelemetry } from '../context/MCPUITelemetryContext';\n\n// Module-scoped lazy import promise — first call triggers the dynamic\n// import, subsequent calls reuse the resolved module.\nlet g6ModulePromise: Promise<typeof import('@antv/g6')> | undefined;\n\n/**\n * Whether the `@antv/g6` peer dependency is installed and importable.\n * Resolves to `true` when the lib is available, `false` otherwise.\n *\n * Mirrors `isChartJSAvailable()` from `ChartJSRenderer`.\n */\nexport async function isG6Available(): Promise<boolean> {\n try {\n if (!g6ModulePromise) {\n g6ModulePromise = import('@antv/g6');\n }\n await g6ModulePromise;\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the spec layout shorthand or object form into the config object\n * G6 v5 expects. When `layout` is omitted, picks `'force'` if edges are\n * present (universal default) or `'circular'` otherwise.\n */\nfunction resolveLayout(params: GraphComponentParams): { type: string; [key: string]: unknown } {\n const layout: GraphLayout | undefined = params.layout;\n if (layout === undefined) {\n const hasEdges = (params.edges?.length ?? 0) > 0;\n return { type: hasEdges ? 'force' : 'circular' };\n }\n if (typeof layout === 'string') {\n return { type: layout };\n }\n // Object form: spread the passthrough options alongside `type`.\n return { type: layout.type, ...(layout.options ?? {}) };\n}\n\n/**\n * Build the G6 v5 `Graph` constructor config from the component params.\n *\n * Pure (no DOM/lib side effects beyond reading `container`), so it can be\n * unit-tested directly without a jsdom render — this is the contract the\n * 2026-05-30 audit (P0.2) wants locked.\n *\n * ⚠️ G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n * (that was the v4 contract). Passing the string `'canvas'` / `'svg'` makes\n * G6 throw `renderer is not a function` — and because the default path used\n * to pass the string `'canvas'`, EVERY graph crashed, not just svg. So we\n * **omit `renderer` entirely**: G6 then uses its built-in canvas renderer\n * (documented default `() => new CanvasRenderer()`).\n *\n * `rendererPref: 'svg'` is reserved but NOT wired yet — a real G6 v5 SVG\n * renderer needs the `@antv/g-svg` factory (a transitive dep of `@antv/g6`,\n * not statically resolvable at build time). Until that's wired behind proper\n * optional-peer resolution, svg degrades to the canvas default with a\n * one-time warning. It must NEVER inject a string `renderer`.\n */\nexport function buildGraphConfig(\n p: GraphComponentParams,\n container?: HTMLElement\n): Record<string, unknown> {\n const config: Record<string, unknown> = {\n container,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n\n if (p.tooltip !== false) {\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>` : ''\n }</div>`;\n },\n },\n ];\n }\n\n return config;\n}\n\n/**\n * Build the G6 v5 `behaviors` array from the params interactivity flags.\n * Defaults : drag-canvas + zoom-canvas + drag-element + click-select.\n * Any flag set to `false` opts out.\n */\nfunction resolveBehaviors(params: GraphComponentParams): string[] {\n const behaviors: string[] = [];\n if (params.enableDrag !== false) behaviors.push('drag-element');\n if (params.enableZoom !== false) {\n behaviors.push('zoom-canvas', 'drag-canvas');\n }\n if (params.enableSelect !== false) behaviors.push('click-select');\n return behaviors;\n}\n\n/**\n * Pick a sensible Mermaid `flowchart` direction from the resolved layout.\n * `dagre` / `tree` / `mindmap` are top-down hierarchies → TD ; everything\n * else (force, concentric, circular, grid) → LR (default mermaid).\n */\nfunction mermaidDirection(layoutType: string): 'TD' | 'LR' {\n return layoutType === 'dagre' || layoutType === 'tree' || layoutType === 'mindmap' ? 'TD' : 'LR';\n}\n\n/**\n * Sanitize a string for use inside a Mermaid node label. Mermaid breaks\n * on raw quotes / brackets / pipes ; we strip the worst offenders.\n */\nfunction mermaidLabel(s: string): string {\n return s\n .replace(/[\"[\\]|]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Convert the graph data to Mermaid `flowchart` syntax. The edge label\n * carries the optional `weight` prefix when present (e.g. `|3| label`).\n */\nfunction toMermaid(params: GraphComponentParams): string {\n const layoutType = resolveLayout(params).type;\n const dir = mermaidDirection(layoutType);\n const lines: string[] = [`flowchart ${dir}`];\n for (const n of params.nodes) {\n const label = mermaidLabel(n.label ?? n.id);\n lines.push(` ${n.id}[\"${label}\"]`);\n }\n for (const e of params.edges ?? []) {\n const labelParts: string[] = [];\n if (e.weight !== undefined) labelParts.push(String(e.weight));\n if (e.label) labelParts.push(mermaidLabel(e.label));\n const labelText = labelParts.join(' · ');\n if (labelText) {\n lines.push(` ${e.source} -->|${labelText}| ${e.target}`);\n } else {\n lines.push(` ${e.source} --> ${e.target}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction toJSON(params: GraphComponentParams): string {\n return JSON.stringify({ nodes: params.nodes, edges: params.edges ?? [] }, null, 2);\n}\n\nfunction downloadBlob(content: string | Blob, filename: string, mimeType?: string): void {\n const blob =\n typeof content === 'string' ? new Blob([content], { type: mimeType ?? 'text/plain' }) : content;\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n\nexport interface GraphRendererProps {\n component: UIComponent;\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible';\n}\n\nexport const GraphRenderer: Component<GraphRendererProps> = (props) => {\n const params = () => props.component.params as GraphComponentParams;\n const isExpanded = useExpanded();\n const telemetry = useTelemetry();\n const [available, setAvailable] = createSignal<boolean | null>(null);\n const [error, setError] = createSignal<string | undefined>();\n const [exportMenuOpen, setExportMenuOpen] = createSignal(false);\n let containerRef: HTMLDivElement | undefined;\n // v6.4.0 — trigger ref consumed by <PortalDropdownMenu> for positioning\n let exportTriggerRef: HTMLButtonElement | undefined;\n // Loosely typed because G6 is a peer-optional — we don't pull its\n // types into the bundle just to type a transient local handle.\n let graphInstance: any | undefined;\n\n onMount(async () => {\n const g6Available = await isG6Available();\n setAvailable(g6Available);\n if (!g6Available || !containerRef) return;\n\n try {\n const { Graph } = await g6ModulePromise!;\n const p = params();\n const config: Record<string, unknown> = {\n container: containerRef,\n data: { nodes: p.nodes, edges: p.edges ?? [] },\n layout: resolveLayout(p),\n behaviors: resolveBehaviors(p),\n };\n\n // G6 v5's `renderer` is a factory `(layer) => IRenderer`, NOT a string\n // (that was the v4 contract). Passing the string `'canvas'` / `'svg'`\n // makes G6 throw `renderer is not a function` — and because the default\n // path also passed the string `'canvas'`, EVERY graph crashed, not just\n // the svg one.\n //\n // Fix: omit `renderer` entirely. G6 then uses its built-in canvas\n // renderer (documented default `() => new CanvasRenderer()`), which is\n // what we want for every graph.\n //\n // `rendererPref: 'svg'` is NOT wired yet: a real G6 v5 SVG renderer\n // needs the `@antv/g-svg` factory, which is a *transitive* dep of\n // `@antv/g6` (not a declared peer) and isn't statically resolvable at\n // build time. Rather than ship a fragile/unresolvable import, we treat\n // svg as \"not yet supported\" and fall back to the canvas default with a\n // one-time warning. Tracked for a follow-up that wires the factory\n // behind a proper optional-peer resolution. (Never pass a string here.)\n if (p.rendererPref === 'svg') {\n console.warn(\n '[MCP-UI] GraphRenderer: rendererPref \"svg\" is not yet supported; using the default canvas renderer.'\n );\n }\n if (p.fitView !== false) {\n config.autoFit = 'view';\n }\n if (p.tooltip !== false) {\n // Built-in tooltip plugin — shows label + a compact dump of\n // node.data on hover. Consumers can opt out with `tooltip: false`.\n config.plugins = [\n {\n type: 'tooltip',\n getContent: (_evt: unknown, items: any[]) => {\n const item = items?.[0];\n if (!item) return '';\n const label = item.label ?? item.id ?? '';\n const data = item.data ? JSON.stringify(item.data) : '';\n return `<div style=\"padding:4px 8px\"><strong>${escapeHtml(String(label))}</strong>${\n data\n ? `<br><span style=\"font-size:11px;opacity:0.7\">${escapeHtml(data)}</span>`\n : ''\n }</div>`;\n },\n },\n ];\n }\n graphInstance = new (Graph as any)(config);\n await graphInstance.render();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to render graph';\n setError(message);\n // Fallback ladder (P2.5): the native G6 render threw — emit telemetry\n // so the failure is observable, then degrade to the edge/node table\n // below instead of leaving a blank canvas.\n telemetry?.dispatch({\n type: 'render:error',\n errorMessage: message,\n id: props.component.id ?? '',\n componentType: 'graph',\n ts: Date.now(),\n });\n }\n });\n\n onCleanup(() => {\n try {\n graphInstance?.destroy();\n } catch {\n // G6 destroy can throw on already-destroyed instances or partial\n // init failures — silent because the component is unmounting anyway.\n }\n graphInstance = undefined;\n });\n\n // ─── Export handlers ────────────────────────────────────────────────\n const handleExportJSON = () => {\n downloadBlob(toJSON(params()), `${graphFilenameStem(params())}.json`, 'application/json');\n setExportMenuOpen(false);\n };\n\n const handleExportMermaid = () => {\n downloadBlob(toMermaid(params()), `${graphFilenameStem(params())}.mmd`, 'text/plain');\n setExportMenuOpen(false);\n };\n\n const handleExportPNG = async () => {\n if (!graphInstance) return;\n try {\n // G6 v5 exposes `toDataURL()` on the graph instance.\n const dataUrl: string = await graphInstance.toDataURL?.('image/png');\n if (!dataUrl) {\n // Fallback: try to grab the underlying canvas directly.\n const canvas = containerRef?.querySelector('canvas');\n if (canvas) {\n const url = (canvas as HTMLCanvasElement).toDataURL('image/png');\n await downloadDataUrl(url, `${graphFilenameStem(params())}.png`);\n } else {\n setError('PNG export not supported in current renderer mode');\n }\n } else {\n await downloadDataUrl(dataUrl, `${graphFilenameStem(params())}.png`);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'PNG export failed');\n }\n setExportMenuOpen(false);\n };\n\n return (\n <Show\n when={available() === true}\n fallback={\n <Show\n when={available() === false}\n fallback={\n // Loading skeleton while we determine peer availability\n <div class=\"w-full p-4 bg-gray-50 dark:bg-gray-800/40 border border-gray-200 dark:border-gray-700 rounded-lg animate-pulse\">\n <div class=\"h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-2\" />\n <div class=\"h-3 w-48 bg-gray-200 dark:bg-gray-700 rounded\" />\n </div>\n }\n >\n <div class=\"w-full p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg\">\n <p class=\"text-sm font-medium text-yellow-900 dark:text-yellow-100\">\n Graph rendering unavailable\n </p>\n <p class=\"text-xs text-yellow-700 dark:text-yellow-300 mt-1\">\n Install <code>@antv/g6</code> peer dependency to render <code>type: \"graph\"</code>{' '}\n components.\n </p>\n </div>\n </Show>\n }\n >\n <ExpandableWrapper\n title={params().title ?? 'Graph'}\n copyData={toJSON(params())}\n copyLabel=\"Copy graph (JSON)\"\n toolbarVariant={props.toolbarVariant}\n >\n <div\n class={`relative w-full ${params().className ?? ''} ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}\n >\n {/* Export menu — top-right, mirrors TableRenderer's pattern */}\n <div class=\"absolute right-2 top-2 z-10\">\n <button\n ref={exportTriggerRef}\n type=\"button\"\n onClick={() => setExportMenuOpen((v) => !v)}\n class=\"px-2 py-1 text-xs bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300\"\n title=\"Export graph\"\n aria-label=\"Export graph\"\n aria-haspopup=\"menu\"\n aria-expanded={exportMenuOpen()}\n >\n Export ▾\n </button>\n <PortalDropdownMenu\n open={exportMenuOpen()}\n onClose={() => setExportMenuOpen(false)}\n trigger={exportTriggerRef}\n width={176}\n class=\"text-xs\"\n >\n <For\n each={[\n { label: 'Download PNG', onClick: handleExportPNG, hint: 'visual snapshot' },\n {\n label: 'Download Mermaid',\n onClick: handleExportMermaid,\n hint: 'markdown / GitHub',\n },\n { label: 'Download JSON', onClick: handleExportJSON, hint: 'raw data' },\n ]}\n >\n {(item) => (\n <button\n type=\"button\"\n onClick={item.onClick}\n class=\"w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-700 last:border-b-0\"\n >\n <div class=\"font-medium\">{item.label}</div>\n <div class=\"text-[10px] text-gray-500 dark:text-gray-400\">{item.hint}</div>\n </button>\n )}\n </For>\n </PortalDropdownMenu>\n </div>\n\n {/* Native G6 canvas — hidden once a render error degrades us. */}\n <div\n ref={containerRef}\n class={`bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n error() ? 'hidden' : ''\n } ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={\n isExpanded()\n ? `height: 100%; width: ${params().width ?? '100%'};`\n : `height: ${params().height ?? '400px'}; width: ${params().width ?? '100%'};`\n }\n />\n {/* Fallback ladder (P2.5): degrade to an edge/node table on error\n rather than showing a bare message. Export menu stays usable. */}\n <Show when={error()}>\n <DegradedFallback\n message={`Graph rendering failed: ${error()}`}\n caption=\"Showing the graph data as a table — the interactive view is unavailable.\"\n {...graphToDegradedTable(params())}\n />\n </Show>\n </div>\n </ExpandableWrapper>\n </Show>\n );\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────\n\nfunction graphFilenameStem(params: GraphComponentParams): string {\n const base = (params.title ?? 'graph').replace(/[^a-z0-9-_]+/gi, '-').replace(/^-+|-+$/g, '');\n return base || 'graph';\n}\n\nasync function downloadDataUrl(dataUrl: string, filename: string): Promise<void> {\n const res = await fetch(dataUrl);\n const blob = await res.blob();\n downloadBlob(blob, filename);\n}\n\n// Re-export for tests + consumers that want to compose their own export menu\nexport { toMermaid as graphToMermaid, toJSON as graphToJSON };\n"],"names":["g6ModulePromise","isG6Available","resolveLayout","params","layout","undefined","hasEdges","edges","length","type","options","resolveBehaviors","behaviors","enableDrag","push","enableZoom","enableSelect","mermaidDirection","layoutType","mermaidLabel","s","replace","trim","toMermaid","dir","lines","n","nodes","label","id","e","labelParts","weight","String","labelText","join","source","target","toJSON","JSON","stringify","downloadBlob","content","filename","mimeType","blob","Blob","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","GraphRenderer","props","component","isExpanded","useExpanded","telemetry","useTelemetry","available","setAvailable","createSignal","error","setError","exportMenuOpen","setExportMenuOpen","containerRef","exportTriggerRef","graphInstance","onMount","g6Available","Graph","p","config","container","data","rendererPref","console","warn","fitView","autoFit","tooltip","plugins","getContent","_evt","items","item","escapeHtml","render","err","message","Error","dispatch","errorMessage","componentType","ts","Date","now","onCleanup","destroy","handleExportJSON","graphFilenameStem","handleExportMermaid","handleExportPNG","dataUrl","toDataURL","canvas","querySelector","downloadDataUrl","_$createComponent","Show","when","fallback","_$getNextElement","_tmpl$3","children","_tmpl$2","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","_el$","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_co$","_$getNextMarker","_el$6","_el$7","_el$8","_co$2","$$click","v","_ref$","_$use","_$insert","PortalDropdownMenu","open","onClose","trigger","width","For","each","onClick","hint","_el$1","_tmpl$4","_el$10","_el$11","_$addEventListener","_$runHydrationEvents","_ref$2","DegradedFallback","_$mergeProps","caption","graphToDegradedTable","_$effect","_p$","_v$","className","_v$2","_v$3","_v$4","height","_$className","t","_$setAttribute","o","_$style","base","res","fetch","_$delegateEvents"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
+ 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 RenderContext = require("./RenderContext.cjs");
@@ -76,5 +76,4 @@ const GridRenderer = (props) => {
76
76
  })();
77
77
  };
78
78
  exports.GridRenderer = GridRenderer;
79
- exports.default = GridRenderer;
80
79
  //# sourceMappingURL=GridRenderer.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"GridRenderer.cjs","sources":["../../src/components/GridRenderer.tsx"],"sourcesContent":["/**\n * GridRenderer - CSS Grid layout component for nested layouts\n * Phase 5.0: Quick Wins - Enables template builder layouts\n * Updated: Uses RenderContext to avoid circular dependencies\n */\n\nimport { Component, For, createMemo } from 'solid-js'\nimport type { UIComponent, GridPosition } from '../types'\nimport { useRenderContext } from './RenderContext'\n\n/**\n * Parameters for GridRenderer component\n */\nexport interface GridComponentParams {\n /**\n * Number of columns (default: 12)\n */\n columns?: number\n\n /**\n * Gap between grid items (default: '1rem')\n */\n gap?: string\n\n /**\n * Minimum row height (optional)\n */\n minRowHeight?: string\n\n /**\n * CSS Grid template areas for named regions\n * Example: [['header', 'header'], ['sidebar', 'main'], ['footer', 'footer']]\n */\n areas?: string[][]\n\n /**\n * Child components to render within the grid\n */\n children: UIComponent[]\n}\n\nexport interface GridRendererProps {\n /**\n * Grid component with params\n */\n component: UIComponent\n\n /**\n * Error callback\n */\n onError?: (error: any) => void\n}\n\n/**\n * Convert grid position to CSS style string\n */\nfunction getGridItemStyle(position: GridPosition | undefined, _areas?: string[][]): string {\n // Default to full width if no position specified\n if (!position) {\n return 'grid-column: 1 / -1; grid-row: auto'\n }\n\n const { colStart, colSpan, rowStart, rowSpan = 1 } = position\n\n // If using named areas and component has area name, use grid-area\n // Otherwise use explicit grid-column/grid-row\n let style = `grid-column: ${colStart} / span ${colSpan}`\n\n if (rowStart) {\n style += `; grid-row: ${rowStart} / span ${rowSpan}`\n } else {\n style += '; grid-row: auto'\n }\n\n return style\n}\n\n/**\n * Build CSS grid-template-areas string from areas array\n */\nfunction buildGridTemplateAreas(areas: string[][]): string {\n return areas.map((row) => `\"${row.join(' ')}\"`).join(' ')\n}\n\n/**\n * GridRenderer Component\n * Renders a CSS Grid container with nested UIComponents\n */\nexport const GridRenderer: Component<GridRendererProps> = (props) => {\n // Use render context to avoid circular dependency\n const { renderComponent } = useRenderContext()\n\n // Extract params with defaults\n const params = createMemo(() => {\n const p = props.component.params as GridComponentParams\n return {\n columns: p.columns ?? 12,\n gap: p.gap ?? '1rem',\n minRowHeight: p.minRowHeight,\n areas: p.areas,\n children: p.children ?? [],\n }\n })\n\n // Build grid container style\n const gridContainerStyle = createMemo(() => {\n const p = params()\n let style = `display: grid; grid-template-columns: repeat(${p.columns}, 1fr); gap: ${p.gap}`\n\n if (p.minRowHeight) {\n style += `; grid-auto-rows: minmax(${p.minRowHeight}, auto)`\n }\n\n if (p.areas && p.areas.length > 0) {\n style += `; grid-template-areas: ${buildGridTemplateAreas(p.areas)}`\n }\n\n return style\n })\n\n return (\n <div\n class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\"\n data-component-type=\"grid\"\n data-component-id={props.component.id}\n >\n <div class=\"p-4 h-full\" style={gridContainerStyle()}>\n <For each={params().children}>\n {(child) => (\n <div\n style={getGridItemStyle(child.position, params().areas)}\n class=\"min-w-0 h-full\"\n >\n {/* Use RenderContext for recursive rendering (avoids circular dependency) */}\n {renderComponent(child, props.onError)}\n </div>\n )}\n </For>\n </div>\n </div>\n )\n}\n\nexport default GridRenderer\n"],"names":["getGridItemStyle","position","_areas","colStart","colSpan","rowStart","rowSpan","style","buildGridTemplateAreas","areas","map","row","join","GridRenderer","props","renderComponent","useRenderContext","params","createMemo","p","component","columns","gap","minRowHeight","children","gridContainerStyle","length","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_$insert","_$createComponent","For","each","child","_el$3","_tmpl$2","onError","_$effect","_$p","_$style","_p$","_v$","id","_v$2","e","_$setAttribute","t","undefined"],"mappings":";;;;;;AAwDA,SAASA,iBAAiBC,UAAoCC,QAA6B;AAEzF,MAAI,CAACD,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM;AAAA,IAAEE;AAAAA,IAAUC;AAAAA,IAASC;AAAAA,IAAUC,UAAU;AAAA,EAAA,IAAML;AAIrD,MAAIM,QAAQ,gBAAgBJ,QAAQ,WAAWC,OAAO;AAEtD,MAAIC,UAAU;AACZE,aAAS,eAAeF,QAAQ,WAAWC,OAAO;AAAA,EACpD,OAAO;AACLC,aAAS;AAAA,EACX;AAEA,SAAOA;AACT;AAKA,SAASC,uBAAuBC,OAA2B;AACzD,SAAOA,MAAMC,IAAKC,CAAAA,QAAQ,IAAIA,IAAIC,KAAK,GAAG,CAAC,GAAG,EAAEA,KAAK,GAAG;AAC1D;AAMO,MAAMC,eAA8CC,CAAAA,UAAU;AAEnE,QAAM;AAAA,IAAEC;AAAAA,EAAAA,IAAoBC,+BAAAA;AAG5B,QAAMC,SAASC,QAAAA,WAAW,MAAM;AAC9B,UAAMC,IAAIL,MAAMM,UAAUH;AAC1B,WAAO;AAAA,MACLI,SAASF,EAAEE,WAAW;AAAA,MACtBC,KAAKH,EAAEG,OAAO;AAAA,MACdC,cAAcJ,EAAEI;AAAAA,MAChBd,OAAOU,EAAEV;AAAAA,MACTe,UAAUL,EAAEK,YAAY,CAAA;AAAA,IAAA;AAAA,EAE5B,CAAC;AAGD,QAAMC,qBAAqBP,QAAAA,WAAW,MAAM;AAC1C,UAAMC,IAAIF,OAAAA;AACV,QAAIV,QAAQ,gDAAgDY,EAAEE,OAAO,gBAAgBF,EAAEG,GAAG;AAE1F,QAAIH,EAAEI,cAAc;AAClBhB,eAAS,4BAA4BY,EAAEI,YAAY;AAAA,IACrD;AAEA,QAAIJ,EAAEV,SAASU,EAAEV,MAAMiB,SAAS,GAAG;AACjCnB,eAAS,0BAA0BC,uBAAuBW,EAAEV,KAAK,CAAC;AAAA,IACpE;AAEA,WAAOF;AAAAA,EACT,CAAC;AAED,UAAA,MAAA;AAAA,QAAAoB,OAAAC,IAAAA,eAAAC,MAAA,GAAAC,QAAAH,KAAAI;AAAAC,eAAAF,OAAAG,IAAAA,gBAOOC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAElB,SAASO;AAAAA,MAAQ;AAAA,MAAAA,UACxBY,YAAK,MAAA;AAAA,YAAAC,QAAAT,IAAAA,eAAAU,OAAA;AAAAN,YAAAA,OAAAK,OAAA,MAMFtB,gBAAgBqB,OAAOtB,MAAMyB,OAAO,CAAC;AAAAC,YAAAA,OAAAC,CAAAA,QAAAC,IAAAA,MAAAL,OAJ/BrC,iBAAiBoC,MAAMnC,UAAUgB,OAAAA,EAASR,KAAK,GAACgC,GAAA,CAAA;AAAA,eAAAJ;AAAAA,MAAA,GAAA;AAAA,IAAA,CAM1D,CAAA;AAAAG,QAAAA,OAAAG,CAAAA,QAAA;AAAA,UAAAC,MAZc9B,MAAMM,UAAUyB,IAAEC,OAENrB,mBAAAA;AAAoBmB,cAAAD,IAAAI,KAAAC,IAAAA,aAAArB,MAAA,qBAAAgB,IAAAI,IAAAH,GAAA;AAAAD,UAAAM,IAAAP,IAAAA,MAAAZ,OAAAgB,MAAAH,IAAAM,CAAA;AAAA,aAAAN;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAA,WAAAvB;AAAAA,EAAA,GAAA;AAezD;;;"}
1
+ {"version":3,"file":"GridRenderer.cjs","sources":["../../src/components/GridRenderer.tsx"],"sourcesContent":["/**\n * GridRenderer - CSS Grid layout component for nested layouts\n * Phase 5.0: Quick Wins - Enables template builder layouts\n * Updated: Uses RenderContext to avoid circular dependencies\n */\n\nimport { Component, For, createMemo } from 'solid-js'\nimport type { UIComponent, GridPosition } from '../types'\nimport { useRenderContext } from './RenderContext'\n\n/**\n * Parameters for GridRenderer component\n */\nexport interface GridComponentParams {\n /**\n * Number of columns (default: 12)\n */\n columns?: number\n\n /**\n * Gap between grid items (default: '1rem')\n */\n gap?: string\n\n /**\n * Minimum row height (optional)\n */\n minRowHeight?: string\n\n /**\n * CSS Grid template areas for named regions\n * Example: [['header', 'header'], ['sidebar', 'main'], ['footer', 'footer']]\n */\n areas?: string[][]\n\n /**\n * Child components to render within the grid\n */\n children: UIComponent[]\n}\n\nexport interface GridRendererProps {\n /**\n * Grid component with params\n */\n component: UIComponent\n\n /**\n * Error callback\n */\n onError?: (error: any) => void\n}\n\n/**\n * Convert grid position to CSS style string\n */\nfunction getGridItemStyle(position: GridPosition | undefined, _areas?: string[][]): string {\n // Default to full width if no position specified\n if (!position) {\n return 'grid-column: 1 / -1; grid-row: auto'\n }\n\n const { colStart, colSpan, rowStart, rowSpan = 1 } = position\n\n // If using named areas and component has area name, use grid-area\n // Otherwise use explicit grid-column/grid-row\n let style = `grid-column: ${colStart} / span ${colSpan}`\n\n if (rowStart) {\n style += `; grid-row: ${rowStart} / span ${rowSpan}`\n } else {\n style += '; grid-row: auto'\n }\n\n return style\n}\n\n/**\n * Build CSS grid-template-areas string from areas array\n */\nfunction buildGridTemplateAreas(areas: string[][]): string {\n return areas.map((row) => `\"${row.join(' ')}\"`).join(' ')\n}\n\n/**\n * GridRenderer Component\n * Renders a CSS Grid container with nested UIComponents\n */\nexport const GridRenderer: Component<GridRendererProps> = (props) => {\n // Use render context to avoid circular dependency\n const { renderComponent } = useRenderContext()\n\n // Extract params with defaults\n const params = createMemo(() => {\n const p = props.component.params as GridComponentParams\n return {\n columns: p.columns ?? 12,\n gap: p.gap ?? '1rem',\n minRowHeight: p.minRowHeight,\n areas: p.areas,\n children: p.children ?? [],\n }\n })\n\n // Build grid container style\n const gridContainerStyle = createMemo(() => {\n const p = params()\n let style = `display: grid; grid-template-columns: repeat(${p.columns}, 1fr); gap: ${p.gap}`\n\n if (p.minRowHeight) {\n style += `; grid-auto-rows: minmax(${p.minRowHeight}, auto)`\n }\n\n if (p.areas && p.areas.length > 0) {\n style += `; grid-template-areas: ${buildGridTemplateAreas(p.areas)}`\n }\n\n return style\n })\n\n return (\n <div\n class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\"\n data-component-type=\"grid\"\n data-component-id={props.component.id}\n >\n <div class=\"p-4 h-full\" style={gridContainerStyle()}>\n <For each={params().children}>\n {(child) => (\n <div\n style={getGridItemStyle(child.position, params().areas)}\n class=\"min-w-0 h-full\"\n >\n {/* Use RenderContext for recursive rendering (avoids circular dependency) */}\n {renderComponent(child, props.onError)}\n </div>\n )}\n </For>\n </div>\n </div>\n )\n}\n\nexport default GridRenderer\n"],"names":["getGridItemStyle","position","_areas","colStart","colSpan","rowStart","rowSpan","style","buildGridTemplateAreas","areas","map","row","join","GridRenderer","props","renderComponent","useRenderContext","params","createMemo","p","component","columns","gap","minRowHeight","children","gridContainerStyle","length","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_$insert","_$createComponent","For","each","child","_el$3","_tmpl$2","onError","_$effect","_$p","_$style","_p$","_v$","id","_v$2","e","_$setAttribute","t","undefined"],"mappings":";;;;;;AAwDA,SAASA,iBAAiBC,UAAoCC,QAA6B;AAEzF,MAAI,CAACD,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM;AAAA,IAAEE;AAAAA,IAAUC;AAAAA,IAASC;AAAAA,IAAUC,UAAU;AAAA,EAAA,IAAML;AAIrD,MAAIM,QAAQ,gBAAgBJ,QAAQ,WAAWC,OAAO;AAEtD,MAAIC,UAAU;AACZE,aAAS,eAAeF,QAAQ,WAAWC,OAAO;AAAA,EACpD,OAAO;AACLC,aAAS;AAAA,EACX;AAEA,SAAOA;AACT;AAKA,SAASC,uBAAuBC,OAA2B;AACzD,SAAOA,MAAMC,IAAKC,CAAAA,QAAQ,IAAIA,IAAIC,KAAK,GAAG,CAAC,GAAG,EAAEA,KAAK,GAAG;AAC1D;AAMO,MAAMC,eAA8CC,CAAAA,UAAU;AAEnE,QAAM;AAAA,IAAEC;AAAAA,EAAAA,IAAoBC,+BAAAA;AAG5B,QAAMC,SAASC,QAAAA,WAAW,MAAM;AAC9B,UAAMC,IAAIL,MAAMM,UAAUH;AAC1B,WAAO;AAAA,MACLI,SAASF,EAAEE,WAAW;AAAA,MACtBC,KAAKH,EAAEG,OAAO;AAAA,MACdC,cAAcJ,EAAEI;AAAAA,MAChBd,OAAOU,EAAEV;AAAAA,MACTe,UAAUL,EAAEK,YAAY,CAAA;AAAA,IAAA;AAAA,EAE5B,CAAC;AAGD,QAAMC,qBAAqBP,QAAAA,WAAW,MAAM;AAC1C,UAAMC,IAAIF,OAAAA;AACV,QAAIV,QAAQ,gDAAgDY,EAAEE,OAAO,gBAAgBF,EAAEG,GAAG;AAE1F,QAAIH,EAAEI,cAAc;AAClBhB,eAAS,4BAA4BY,EAAEI,YAAY;AAAA,IACrD;AAEA,QAAIJ,EAAEV,SAASU,EAAEV,MAAMiB,SAAS,GAAG;AACjCnB,eAAS,0BAA0BC,uBAAuBW,EAAEV,KAAK,CAAC;AAAA,IACpE;AAEA,WAAOF;AAAAA,EACT,CAAC;AAED,UAAA,MAAA;AAAA,QAAAoB,OAAAC,IAAAA,eAAAC,MAAA,GAAAC,QAAAH,KAAAI;AAAAC,eAAAF,OAAAG,IAAAA,gBAOOC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAElB,SAASO;AAAAA,MAAQ;AAAA,MAAAA,UACxBY,YAAK,MAAA;AAAA,YAAAC,QAAAT,IAAAA,eAAAU,OAAA;AAAAN,YAAAA,OAAAK,OAAA,MAMFtB,gBAAgBqB,OAAOtB,MAAMyB,OAAO,CAAC;AAAAC,YAAAA,OAAAC,CAAAA,QAAAC,IAAAA,MAAAL,OAJ/BrC,iBAAiBoC,MAAMnC,UAAUgB,OAAAA,EAASR,KAAK,GAACgC,GAAA,CAAA;AAAA,eAAAJ;AAAAA,MAAA,GAAA;AAAA,IAAA,CAM1D,CAAA;AAAAG,QAAAA,OAAAG,CAAAA,QAAA;AAAA,UAAAC,MAZc9B,MAAMM,UAAUyB,IAAEC,OAENrB,mBAAAA;AAAoBmB,cAAAD,IAAAI,KAAAC,IAAAA,aAAArB,MAAA,qBAAAgB,IAAAI,IAAAH,GAAA;AAAAD,UAAAM,IAAAP,IAAAA,MAAAZ,OAAAgB,MAAAH,IAAAM,CAAA;AAAA,aAAAN;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAA,WAAAvB;AAAAA,EAAA,GAAA;AAezD;;"}
@@ -1,4 +1,4 @@
1
- import { getNextElement, template, insert, createComponent, effect, style, setAttribute } from "solid-js/web";
1
+ import { getNextElement, insert, createComponent, effect, style, setAttribute, template } from "solid-js/web";
2
2
  import { createMemo, For } from "solid-js";
3
3
  import { useRenderContext } from "./RenderContext.js";
4
4
  var _tmpl$ = /* @__PURE__ */ template(`<div class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"data-component-type=grid><div class="p-4 h-full">`), _tmpl$2 = /* @__PURE__ */ template(`<div class="min-w-0 h-full">`);
@@ -74,7 +74,6 @@ const GridRenderer = (props) => {
74
74
  })();
75
75
  };
76
76
  export {
77
- GridRenderer,
78
- GridRenderer as default
77
+ GridRenderer
79
78
  };
80
79
  //# sourceMappingURL=GridRenderer.js.map
@@ -1,4 +1,4 @@
1
- import { delegateEvents, createComponent, getNextElement, template, getNextMarker, insert, memo, effect, className, setAttribute, runHydrationEvents } from "solid-js/web";
1
+ import { delegateEvents, createComponent, getNextElement, getNextMarker, insert, memo, effect, className, setAttribute, runHydrationEvents, template } from "solid-js/web";
2
2
  import { createSignal, Show, For } from "solid-js";
3
3
  import { LightboxOverlay } from "./LightboxOverlay.js";
4
4
  import { useExpanded, ExpandableWrapper } from "./ExpandableWrapper.js";
@@ -1,4 +1,4 @@
1
- import { delegateEvents, createComponent, Portal, getNextElement, template, getNextMarker, addEventListener, insert, runHydrationEvents, effect, setAttribute } from "solid-js/web";
1
+ import { delegateEvents, createComponent, Portal, getNextElement, getNextMarker, addEventListener, insert, runHydrationEvents, effect, setAttribute, template } from "solid-js/web";
2
2
  import { createEffect, onCleanup, Show } from "solid-js";
3
3
  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
4
  const LightboxOverlay = (props) => {
@@ -5,6 +5,7 @@ const solidJs = require("solid-js");
5
5
  const ExpandableWrapper = require("./ExpandableWrapper.cjs");
6
6
  const DegradedFallback = require("./DegradedFallback.cjs");
7
7
  const degradedProjections = require("../utils/degraded-projections.cjs");
8
+ const escapeHtml = require("../utils/escape-html.cjs");
8
9
  const MCPUITelemetryContext = require("../context/MCPUITelemetryContext.cjs");
9
10
  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><!$><!/><!$><!/>`);
10
11
  let L = null;
@@ -50,12 +51,12 @@ function buildPopupContent(feature, popup, allowHtml = false) {
50
51
  if (allowHtml && popup.template) {
51
52
  return popup.template.replace(/\{\{(\w+)\}\}/g, (_, key) => {
52
53
  const val = props[key];
53
- return val != null ? escapeHtml(String(val)) : "";
54
+ return val != null ? escapeHtml.escapeHtml(String(val)) : "";
54
55
  });
55
56
  }
56
57
  const parts = [];
57
58
  if (popup.titleField && props[popup.titleField] != null) {
58
- parts.push(`<strong>${escapeHtml(String(props[popup.titleField]))}</strong>`);
59
+ parts.push(`<strong>${escapeHtml.escapeHtml(String(props[popup.titleField]))}</strong>`);
59
60
  }
60
61
  const fields = popup.fields || Object.keys(props).slice(0, 8);
61
62
  for (const key of fields) {
@@ -63,16 +64,13 @@ function buildPopupContent(feature, popup, allowHtml = false) {
63
64
  const val = props[key];
64
65
  if (val == null) continue;
65
66
  const formatted = typeof val === "number" ? val.toLocaleString("fr-FR") : String(val);
66
- parts.push(`<span style="color:#666;font-size:11px">${escapeHtml(key)}</span>: ${escapeHtml(formatted)}`);
67
+ parts.push(`<span style="color:#666;font-size:11px">${escapeHtml.escapeHtml(key)}</span>: ${escapeHtml.escapeHtml(formatted)}`);
67
68
  }
68
69
  return parts.join("<br/>");
69
70
  }
70
- function escapeHtml(str) {
71
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
72
- }
73
71
  function popupSafeText(value, allowHtml = false) {
74
72
  if (value == null) return void 0;
75
- return allowHtml ? value : escapeHtml(value);
73
+ return allowHtml ? value : escapeHtml.escapeHtml(value);
76
74
  }
77
75
  function bindMarkerContent(m, marker, allowHtml) {
78
76
  const tooltip = popupSafeText(marker.tooltip, allowHtml);
@@ -80,7 +78,7 @@ function bindMarkerContent(m, marker, allowHtml) {
80
78
  const popup = popupSafeText(marker.popup, allowHtml);
81
79
  if (popup) m.bindPopup(popup);
82
80
  }
83
- function addGeoJSONLayer(mapInst, leaflet, geojson, style, popup) {
81
+ function addGeoJSONLayer(mapInst, leaflet, geojson, style, popup, allowHtml = false) {
84
82
  const styleFn = buildStyleFn(style);
85
83
  const layer = leaflet.geoJSON(geojson, {
86
84
  style: styleFn,
@@ -96,7 +94,7 @@ function addGeoJSONLayer(mapInst, leaflet, geojson, style, popup) {
96
94
  });
97
95
  },
98
96
  onEachFeature: (feature, featureLayer) => {
99
- const html = buildPopupContent(feature, popup);
97
+ const html = buildPopupContent(feature, popup, allowHtml);
100
98
  if (html) {
101
99
  featureLayer.bindPopup(html, {
102
100
  maxWidth: 300
@@ -251,13 +249,13 @@ const MapRenderer = (props) => {
251
249
  allBoundsLayers.push(...markers);
252
250
  }
253
251
  if (p == null ? void 0 : p.geojson) {
254
- const geoLayer = addGeoJSONLayer(mapInstance, L, p.geojson, p.geojsonStyle, p.popup);
252
+ const geoLayer = addGeoJSONLayer(mapInstance, L, p.geojson, p.geojsonStyle, p.popup, allowHtml());
255
253
  allBoundsLayers.push(geoLayer);
256
254
  }
257
255
  if ((p == null ? void 0 : p.layers) && p.layers.length > 0) {
258
256
  const overlays = {};
259
257
  for (const layerDef of p.layers) {
260
- const geoLayer = addGeoJSONLayer(mapInstance, L, layerDef.geojson, layerDef.style || (p == null ? void 0 : p.geojsonStyle), layerDef.popup || (p == null ? void 0 : p.popup));
258
+ const geoLayer = addGeoJSONLayer(mapInstance, L, layerDef.geojson, layerDef.style || (p == null ? void 0 : p.geojsonStyle), layerDef.popup || (p == null ? void 0 : p.popup), allowHtml());
261
259
  overlays[layerDef.name] = geoLayer;
262
260
  allBoundsLayers.push(geoLayer);
263
261
  if (layerDef.visible === false) {
@@ -421,6 +419,7 @@ const MapRenderer = (props) => {
421
419
  });
422
420
  };
423
421
  exports.MapRenderer = MapRenderer;
422
+ exports.addGeoJSONLayer = addGeoJSONLayer;
424
423
  exports.bindMarkerContent = bindMarkerContent;
425
424
  exports.buildPopupContent = buildPopupContent;
426
425
  exports.popupSafeText = popupSafeText;