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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/CHANGELOG.md +532 -0
  2. package/README.md +798 -1
  3. package/dist/adapters/connector.cjs +15 -4
  4. package/dist/adapters/connector.cjs.map +1 -1
  5. package/dist/adapters/connector.d.ts +38 -0
  6. package/dist/adapters/connector.d.ts.map +1 -1
  7. package/dist/adapters/connector.js +15 -4
  8. package/dist/adapters/connector.js.map +1 -1
  9. package/dist/adapters/index.d.ts +4 -3
  10. package/dist/adapters/index.d.ts.map +1 -1
  11. package/dist/adapters/macro-run.cjs +25 -13
  12. package/dist/adapters/macro-run.cjs.map +1 -1
  13. package/dist/adapters/macro-run.d.ts +37 -2
  14. package/dist/adapters/macro-run.d.ts.map +1 -1
  15. package/dist/adapters/macro-run.js +25 -13
  16. package/dist/adapters/macro-run.js.map +1 -1
  17. package/dist/adapters.cjs +2 -0
  18. package/dist/adapters.cjs.map +1 -1
  19. package/dist/adapters.js +4 -2
  20. package/dist/components/ActionGroupRenderer.cjs +3 -1
  21. package/dist/components/ActionGroupRenderer.cjs.map +1 -1
  22. package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
  23. package/dist/components/ActionGroupRenderer.js +3 -1
  24. package/dist/components/ActionGroupRenderer.js.map +1 -1
  25. package/dist/components/AgentCard.cjs +11 -8
  26. package/dist/components/AgentCard.cjs.map +1 -1
  27. package/dist/components/AgentCard.d.ts.map +1 -1
  28. package/dist/components/AgentCard.js +11 -8
  29. package/dist/components/AgentCard.js.map +1 -1
  30. package/dist/components/AgentHandoff.cjs +6 -1
  31. package/dist/components/AgentHandoff.cjs.map +1 -1
  32. package/dist/components/AgentHandoff.d.ts.map +1 -1
  33. package/dist/components/AgentHandoff.js +6 -1
  34. package/dist/components/AgentHandoff.js.map +1 -1
  35. package/dist/components/ArtifactRenderer.cjs +25 -6
  36. package/dist/components/ArtifactRenderer.cjs.map +1 -1
  37. package/dist/components/ArtifactRenderer.d.ts.map +1 -1
  38. package/dist/components/ArtifactRenderer.js +25 -6
  39. package/dist/components/ArtifactRenderer.js.map +1 -1
  40. package/dist/components/AutocompleteDropdown.cjs +30 -24
  41. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  42. package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
  43. package/dist/components/AutocompleteDropdown.js +30 -24
  44. package/dist/components/AutocompleteDropdown.js.map +1 -1
  45. package/dist/components/AutocompleteFormField.cjs +3 -1
  46. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  47. package/dist/components/AutocompleteFormField.d.ts.map +1 -1
  48. package/dist/components/AutocompleteFormField.js +4 -2
  49. package/dist/components/AutocompleteFormField.js.map +1 -1
  50. package/dist/components/BriefingDiff.cjs +45 -39
  51. package/dist/components/BriefingDiff.cjs.map +1 -1
  52. package/dist/components/BriefingDiff.d.ts.map +1 -1
  53. package/dist/components/BriefingDiff.js +45 -39
  54. package/dist/components/BriefingDiff.js.map +1 -1
  55. package/dist/components/CarouselRenderer.cjs +8 -2
  56. package/dist/components/CarouselRenderer.cjs.map +1 -1
  57. package/dist/components/CarouselRenderer.d.ts.map +1 -1
  58. package/dist/components/CarouselRenderer.js +8 -2
  59. package/dist/components/CarouselRenderer.js.map +1 -1
  60. package/dist/components/ChartJSRenderer.cjs +60 -36
  61. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  62. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  63. package/dist/components/ChartJSRenderer.js +61 -37
  64. package/dist/components/ChartJSRenderer.js.map +1 -1
  65. package/dist/components/ChatPrompt.cjs +15 -9
  66. package/dist/components/ChatPrompt.cjs.map +1 -1
  67. package/dist/components/ChatPrompt.d.ts.map +1 -1
  68. package/dist/components/ChatPrompt.js +15 -9
  69. package/dist/components/ChatPrompt.js.map +1 -1
  70. package/dist/components/CodeBlockRenderer.cjs +34 -16
  71. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  72. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  73. package/dist/components/CodeBlockRenderer.js +34 -16
  74. package/dist/components/CodeBlockRenderer.js.map +1 -1
  75. package/dist/components/DataPreviewSection.cjs +91 -44
  76. package/dist/components/DataPreviewSection.cjs.map +1 -1
  77. package/dist/components/DataPreviewSection.d.ts.map +1 -1
  78. package/dist/components/DataPreviewSection.js +92 -45
  79. package/dist/components/DataPreviewSection.js.map +1 -1
  80. package/dist/components/DegradedFallback.cjs +20 -16
  81. package/dist/components/DegradedFallback.cjs.map +1 -1
  82. package/dist/components/DegradedFallback.d.ts.map +1 -1
  83. package/dist/components/DegradedFallback.js +20 -16
  84. package/dist/components/DegradedFallback.js.map +1 -1
  85. package/dist/components/FeedbackInline.cjs +19 -3
  86. package/dist/components/FeedbackInline.cjs.map +1 -1
  87. package/dist/components/FeedbackInline.js +19 -3
  88. package/dist/components/FeedbackInline.js.map +1 -1
  89. package/dist/components/FooterRenderer.cjs +21 -17
  90. package/dist/components/FooterRenderer.cjs.map +1 -1
  91. package/dist/components/FooterRenderer.d.ts.map +1 -1
  92. package/dist/components/FooterRenderer.js +21 -17
  93. package/dist/components/FooterRenderer.js.map +1 -1
  94. package/dist/components/FormFieldRenderer.cjs +116 -93
  95. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  96. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  97. package/dist/components/FormFieldRenderer.js +116 -93
  98. package/dist/components/FormFieldRenderer.js.map +1 -1
  99. package/dist/components/FormRenderer.cjs +55 -31
  100. package/dist/components/FormRenderer.cjs.map +1 -1
  101. package/dist/components/FormRenderer.d.ts.map +1 -1
  102. package/dist/components/FormRenderer.js +55 -31
  103. package/dist/components/FormRenderer.js.map +1 -1
  104. package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
  105. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  106. package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
  107. package/dist/components/GenerativeUIErrorBoundary.js +20 -15
  108. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  109. package/dist/components/GraphRenderer.cjs +56 -33
  110. package/dist/components/GraphRenderer.cjs.map +1 -1
  111. package/dist/components/GraphRenderer.d.ts.map +1 -1
  112. package/dist/components/GraphRenderer.js +56 -33
  113. package/dist/components/GraphRenderer.js.map +1 -1
  114. package/dist/components/ImageGalleryRenderer.cjs +13 -4
  115. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  116. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  117. package/dist/components/ImageGalleryRenderer.js +13 -4
  118. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  119. package/dist/components/LightboxOverlay.cjs +16 -8
  120. package/dist/components/LightboxOverlay.cjs.map +1 -1
  121. package/dist/components/LightboxOverlay.d.ts.map +1 -1
  122. package/dist/components/LightboxOverlay.js +17 -9
  123. package/dist/components/LightboxOverlay.js.map +1 -1
  124. package/dist/components/MapRenderer.cjs +59 -29
  125. package/dist/components/MapRenderer.cjs.map +1 -1
  126. package/dist/components/MapRenderer.d.ts +10 -2
  127. package/dist/components/MapRenderer.d.ts.map +1 -1
  128. package/dist/components/MapRenderer.js +60 -30
  129. package/dist/components/MapRenderer.js.map +1 -1
  130. package/dist/components/ModalRenderer.cjs +4 -1
  131. package/dist/components/ModalRenderer.cjs.map +1 -1
  132. package/dist/components/ModalRenderer.d.ts.map +1 -1
  133. package/dist/components/ModalRenderer.js +5 -2
  134. package/dist/components/ModalRenderer.js.map +1 -1
  135. package/dist/components/ScratchpadPanel.cjs +578 -535
  136. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  137. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  138. package/dist/components/ScratchpadPanel.js +578 -535
  139. package/dist/components/ScratchpadPanel.js.map +1 -1
  140. package/dist/components/StreamingUIRenderer.cjs +92 -28
  141. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  142. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  143. package/dist/components/StreamingUIRenderer.js +92 -28
  144. package/dist/components/StreamingUIRenderer.js.map +1 -1
  145. package/dist/components/UIResourceRenderer.cjs +456 -363
  146. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  147. package/dist/components/UIResourceRenderer.d.ts +21 -0
  148. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  149. package/dist/components/UIResourceRenderer.js +458 -365
  150. package/dist/components/UIResourceRenderer.js.map +1 -1
  151. package/dist/components/VerifiedText.cjs +39 -20
  152. package/dist/components/VerifiedText.cjs.map +1 -1
  153. package/dist/components/VerifiedText.d.ts +2 -1
  154. package/dist/components/VerifiedText.d.ts.map +1 -1
  155. package/dist/components/VerifiedText.js +39 -20
  156. package/dist/components/VerifiedText.js.map +1 -1
  157. package/dist/components/VideoRenderer.cjs +10 -5
  158. package/dist/components/VideoRenderer.cjs.map +1 -1
  159. package/dist/components/VideoRenderer.d.ts.map +1 -1
  160. package/dist/components/VideoRenderer.js +10 -5
  161. package/dist/components/VideoRenderer.js.map +1 -1
  162. package/dist/components/chart-data-table.cjs +38 -17
  163. package/dist/components/chart-data-table.cjs.map +1 -1
  164. package/dist/components/chart-data-table.d.ts +30 -1
  165. package/dist/components/chart-data-table.d.ts.map +1 -1
  166. package/dist/components/chart-data-table.js +38 -17
  167. package/dist/components/chart-data-table.js.map +1 -1
  168. package/dist/context/MCPActionContext.cjs +3 -1
  169. package/dist/context/MCPActionContext.cjs.map +1 -1
  170. package/dist/context/MCPActionContext.d.ts.map +1 -1
  171. package/dist/context/MCPActionContext.js +3 -1
  172. package/dist/context/MCPActionContext.js.map +1 -1
  173. package/dist/context/MCPUIStringsContext.cjs +285 -2
  174. package/dist/context/MCPUIStringsContext.cjs.map +1 -1
  175. package/dist/context/MCPUIStringsContext.d.ts +600 -3
  176. package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
  177. package/dist/context/MCPUIStringsContext.js +285 -2
  178. package/dist/context/MCPUIStringsContext.js.map +1 -1
  179. package/dist/hooks/index.d.ts +2 -2
  180. package/dist/hooks/index.d.ts.map +1 -1
  181. package/dist/hooks/useStreamingUI.cjs +28 -10
  182. package/dist/hooks/useStreamingUI.cjs.map +1 -1
  183. package/dist/hooks/useStreamingUI.d.ts +37 -0
  184. package/dist/hooks/useStreamingUI.d.ts.map +1 -1
  185. package/dist/hooks/useStreamingUI.js +28 -10
  186. package/dist/hooks/useStreamingUI.js.map +1 -1
  187. package/dist/hooks.cjs +1 -0
  188. package/dist/hooks.cjs.map +1 -1
  189. package/dist/hooks.js +2 -1
  190. package/dist/index.cjs +23 -8
  191. package/dist/index.cjs.map +1 -1
  192. package/dist/index.d.cts +9 -3
  193. package/dist/index.d.ts +9 -3
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +18 -3
  196. package/dist/index.js.map +1 -1
  197. package/dist/services/validation.cjs +41 -16
  198. package/dist/services/validation.cjs.map +1 -1
  199. package/dist/services/validation.d.ts +47 -2
  200. package/dist/services/validation.d.ts.map +1 -1
  201. package/dist/services/validation.js +41 -16
  202. package/dist/services/validation.js.map +1 -1
  203. package/dist/utils/degraded-projections.cjs +37 -12
  204. package/dist/utils/degraded-projections.cjs.map +1 -1
  205. package/dist/utils/degraded-projections.d.ts +39 -3
  206. package/dist/utils/degraded-projections.d.ts.map +1 -1
  207. package/dist/utils/degraded-projections.js +37 -12
  208. package/dist/utils/degraded-projections.js.map +1 -1
  209. package/dist/utils/format-string.cjs +10 -0
  210. package/dist/utils/format-string.cjs.map +1 -0
  211. package/dist/utils/format-string.d.ts +26 -0
  212. package/dist/utils/format-string.d.ts.map +1 -0
  213. package/dist/utils/format-string.js +10 -0
  214. package/dist/utils/format-string.js.map +1 -0
  215. package/dist/validation.cjs +3 -0
  216. package/dist/validation.cjs.map +1 -1
  217. package/dist/validation.d.cts +2 -1
  218. package/dist/validation.d.ts +2 -1
  219. package/dist/validation.d.ts.map +1 -1
  220. package/dist/validation.js +4 -1
  221. package/package.json +1 -1
  222. package/src/adapters/connector.ts +58 -4
  223. package/src/adapters/index.ts +12 -2
  224. package/src/adapters/macro-run.ts +71 -11
  225. package/src/components/ActionGroupRenderer.tsx +3 -1
  226. package/src/components/AgentCard.tsx +27 -9
  227. package/src/components/AgentHandoff.tsx +4 -1
  228. package/src/components/ArtifactRenderer.tsx +17 -5
  229. package/src/components/AutocompleteDropdown.tsx +8 -6
  230. package/src/components/AutocompleteFormField.tsx +5 -1
  231. package/src/components/BriefingDiff.tsx +11 -3
  232. package/src/components/CarouselRenderer.tsx +4 -2
  233. package/src/components/ChartJSRenderer.tsx +18 -9
  234. package/src/components/ChatPrompt.tsx +13 -8
  235. package/src/components/CodeBlockRenderer.tsx +12 -10
  236. package/src/components/DataPreviewSection.tsx +92 -26
  237. package/src/components/DegradedFallback.tsx +4 -2
  238. package/src/components/FeedbackInline.tsx +2 -2
  239. package/src/components/FooterRenderer.tsx +3 -1
  240. package/src/components/FormFieldRenderer.tsx +34 -19
  241. package/src/components/FormRenderer.tsx +38 -10
  242. package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
  243. package/src/components/GraphRenderer.tsx +31 -16
  244. package/src/components/ImageGalleryRenderer.tsx +8 -4
  245. package/src/components/LightboxOverlay.tsx +6 -4
  246. package/src/components/MapRenderer.tsx +57 -20
  247. package/src/components/ModalRenderer.tsx +3 -1
  248. package/src/components/ScratchpadPanel.tsx +95 -44
  249. package/src/components/StreamingUIRenderer.tsx +41 -11
  250. package/src/components/UIResourceRenderer.tsx +145 -63
  251. package/src/components/VerifiedText.tsx +19 -9
  252. package/src/components/VideoRenderer.tsx +6 -4
  253. package/src/components/chart-data-table.ts +68 -14
  254. package/src/context/MCPActionContext.tsx +4 -1
  255. package/src/context/MCPUIStringsContext.tsx +1004 -1
  256. package/src/hooks/index.ts +2 -1
  257. package/src/hooks/useStreamingUI.ts +64 -10
  258. package/src/index.ts +23 -0
  259. package/src/services/validation.ts +93 -16
  260. package/src/utils/degraded-projections.ts +75 -12
  261. package/src/utils/format-string.ts +33 -0
  262. package/src/validation.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"FormRenderer.cjs","sources":["../../src/components/FormRenderer.tsx"],"sourcesContent":["/**\n * FormRenderer - Main form component\n * Sprint 1: Form Foundation\n * Sprint 2: Conditional field visibility (showWhen)\n * Sprint 4: Form state persistence\n */\n\nimport { Component, createSignal, For, Show, onMount, createEffect, onCleanup } from 'solid-js'\nimport { FormFieldRenderer } from './FormFieldRenderer'\nimport type { UIComponent, FormComponentParams, FormFieldParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { validateFormData } from '../services/validation'\nimport { evaluateCondition } from '../hooks/useConditionalField'\nimport { useFormPersistence } from '../hooks/useFormPersistence'\nimport { useTelemetry } from '../context/MCPUITelemetryContext'\n\nexport interface FormRendererProps {\n component: UIComponent\n onSubmit?: (data: Record<string, any>) => void\n onError?: (errors: Record<string, string>) => void\n}\n\n/**\n * Get default value for a field type\n */\nfunction getFieldDefault(type: FormFieldParams['type']): any {\n switch (type) {\n case 'checkbox':\n return false\n case 'number':\n return undefined\n case 'select':\n case 'radio':\n return ''\n default:\n return ''\n }\n}\n\nexport const FormRenderer: Component<FormRendererProps> = (props) => {\n const params = () => props.component.params as FormComponentParams\n const [formData, setFormData] = createSignal<Record<string, any>>({})\n const [errors, setErrors] = createSignal<Record<string, string>>({})\n const [isSubmitting, setIsSubmitting] = createSignal(false)\n const { execute } = useAction()\n const telemetry = useTelemetry()\n\n // Form persistence (Sprint 4)\n let clearPersisted: (() => void) | undefined\n\n /**\n * Get fields that are currently visible based on showWhen conditions\n */\n const getVisibleFields = (): FormFieldParams[] => {\n return params().fields.filter((field) => {\n if (!field.showWhen) return true\n return evaluateCondition(field.showWhen, formData())\n })\n }\n\n // Auto-submit countdown state (v4.2.0)\n const [countdown, setCountdown] = createSignal<number | null>(null)\n let countdownTimer: ReturnType<typeof setInterval> | null = null\n const [userInteracted, setUserInteracted] = createSignal(false)\n\n const cancelCountdown = () => {\n if (countdownTimer) {\n clearInterval(countdownTimer)\n countdownTimer = null\n }\n setCountdown(null)\n }\n\n const handleUserInteraction = () => {\n if (!userInteracted()) {\n setUserInteracted(true)\n cancelCountdown()\n }\n }\n\n onCleanup(() => cancelCountdown())\n\n /**\n * Check if all required fields have prefill values\n */\n const allRequiredPrefilled = (): boolean => {\n return params().fields\n .filter((f) => f.required)\n .every((f) => f.prefill != null)\n }\n\n // Initialize form data with default values, applying prefill (v4.2.0)\n const initializeForm = (clearStorage = false) => {\n const initial: Record<string, any> = {}\n for (const field of params().fields) {\n // prefill takes priority over defaultValue\n initial[field.name] = field.prefill ?? field.defaultValue ?? getFieldDefault(field.type)\n }\n setFormData(initial)\n setErrors({})\n\n // Clear persisted data if requested\n if (clearStorage && clearPersisted) {\n clearPersisted()\n }\n }\n\n // Initialize on mount\n onMount(() => {\n initializeForm()\n })\n\n // Setup persistence if persistKey is provided (Sprint 4)\n createEffect(() => {\n const persistKey = params().persistKey\n if (persistKey) {\n const persistence = useFormPersistence({\n persistKey,\n formData,\n setFormData,\n excludeFields: params().excludeFromPersistence,\n expiresIn: params().persistExpiresIn,\n })\n clearPersisted = persistence.clearPersisted\n }\n })\n\n // Auto-submit countdown (v4.2.0)\n createEffect(() => {\n const delay = params().autoSubmitDelay\n if (!delay || !allRequiredPrefilled() || userInteracted()) return\n\n let remaining = Math.ceil(delay / 1000)\n setCountdown(remaining)\n\n countdownTimer = setInterval(() => {\n remaining--\n if (remaining <= 0) {\n cancelCountdown()\n // Trigger submit programmatically\n const form = document.querySelector(`#form-${props.component.id}`) as HTMLFormElement | null\n if (form) form.requestSubmit()\n } else {\n setCountdown(remaining)\n }\n }, 1000)\n })\n\n const handleFieldChange = (name: string, value: any) => {\n handleUserInteraction()\n setFormData((prev) => ({ ...prev, [name]: value }))\n // Clear error on change\n if (errors()[name]) {\n setErrors((prev) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [name]: _removed, ...rest } = prev\n return rest\n })\n }\n }\n\n const handleSubmit = async (e: Event) => {\n e.preventDefault()\n setIsSubmitting(true)\n setErrors({})\n\n // Get only visible fields for validation and submission\n const visibleFields = getVisibleFields()\n const visibleFieldNames = new Set(visibleFields.map((f) => f.name))\n\n // Filter form data to only include visible fields\n const visibleFormData: Record<string, any> = {}\n for (const [key, value] of Object.entries(formData())) {\n if (visibleFieldNames.has(key)) {\n visibleFormData[key] = value\n }\n }\n\n // Validate only visible fields\n const validationResult = validateFormData(visibleFormData, visibleFields)\n if (!validationResult.valid) {\n setErrors(validationResult.errors)\n setIsSubmitting(false)\n props.onError?.(validationResult.errors)\n return\n }\n\n // Submit via tool call if specified\n if (params().submitAction?.toolName) {\n try {\n const result = await execute(params().submitAction!.toolName, {\n ...params().submitAction!.params,\n formData: visibleFormData,\n })\n if (!result.success) {\n setErrors({ _form: result.error || 'Submission failed' })\n setIsSubmitting(false)\n props.onError?.({ _form: result.error || 'Submission failed' })\n return\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Submission failed'\n setErrors({ _form: errorMessage })\n setIsSubmitting(false)\n props.onError?.({ _form: errorMessage })\n return\n }\n }\n\n // Clear persisted data on successful submit\n if (clearPersisted) {\n clearPersisted()\n }\n\n // Telemetry: action:dispatched on successful submit (B.5 — v5.6.0).\n // Privacy: only the action name (toolName or 'submit'), NO form values.\n if (telemetry) {\n telemetry.dispatch({\n type: 'action:dispatched',\n id: props.component.id,\n componentType: 'form',\n actionName: params().submitAction?.toolName ?? 'submit',\n ts: Date.now(),\n })\n }\n\n props.onSubmit?.(visibleFormData)\n setIsSubmitting(false)\n }\n\n const layoutClass = () => {\n switch (params().layout) {\n case 'horizontal':\n return 'grid grid-cols-2 gap-4'\n case 'inline':\n return 'flex flex-wrap gap-4 items-end'\n default:\n return 'space-y-4'\n }\n }\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <Show when={params().title}>\n <h3 class=\"text-lg font-semibold text-gray-900 dark:text-white mb-4\">\n {params().title}\n </h3>\n </Show>\n\n <form id={`form-${props.component.id}`} onSubmit={handleSubmit} noValidate>\n {/* Proposal 3: prefill summary */}\n <Show when={params().fields.some((f) => f.prefill != null)}>\n {(() => {\n const prefilled = params().fields.filter((f) => f.prefill != null).length\n const total = params().fields.length\n return (\n <p class=\"text-xs text-gray-500 dark:text-gray-400 mb-3\">\n {prefilled} champ{prefilled > 1 ? 's' : ''} pré-rempli{prefilled > 1 ? 's' : ''} sur {total}\n </p>\n )\n })()}\n </Show>\n <div class={layoutClass()}>\n <For each={params().fields}>\n {(field) => (\n <FormFieldRenderer\n field={field}\n value={formData()[field.name]}\n error={errors()[field.name]}\n onChange={(value) => handleFieldChange(field.name, value)}\n disabled={isSubmitting() || field.disabled}\n formData={formData}\n />\n )}\n </For>\n </div>\n\n <Show when={errors()._form}>\n <div class=\"mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md\">\n <p class=\"text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n {errors()._form}\n </p>\n </div>\n </Show>\n\n {/* Auto-submit countdown (v4.2.0) */}\n <Show when={countdown() != null}>\n <div class=\"mt-4 flex items-center gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md\">\n <span class=\"text-sm text-blue-700 dark:text-blue-300\">\n {params().submitLabel || 'Submit'} in {countdown()}s...\n </span>\n <button\n type=\"button\"\n onClick={() => { cancelCountdown(); setUserInteracted(true) }}\n class=\"text-sm text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-200\"\n >\n Cancel\n </button>\n </div>\n </Show>\n\n <div class=\"flex gap-2 pt-4 mt-4 border-t border-gray-200 dark:border-gray-700\">\n <button\n type=\"submit\"\n disabled={isSubmitting()}\n class=\"px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isSubmitting() ? (\n <span class=\"flex items-center gap-2\">\n <span class=\"animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full\" />\n Submitting...\n </span>\n ) : (\n params().submitLabel || 'Submit'\n )}\n </button>\n <Show when={params().showReset}>\n <button\n type=\"button\"\n onClick={() => initializeForm(true)}\n disabled={isSubmitting()}\n class=\"px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n Reset\n </button>\n </Show>\n </div>\n </form>\n </div>\n )\n}\n"],"names":["getFieldDefault","type","undefined","FormRenderer","props","params","component","formData","setFormData","createSignal","errors","setErrors","isSubmitting","setIsSubmitting","execute","useAction","telemetry","useTelemetry","clearPersisted","getVisibleFields","fields","filter","field","showWhen","evaluateCondition","countdown","setCountdown","countdownTimer","userInteracted","setUserInteracted","cancelCountdown","clearInterval","handleUserInteraction","onCleanup","allRequiredPrefilled","f","required","every","prefill","initializeForm","clearStorage","initial","name","defaultValue","onMount","createEffect","persistKey","persistence","useFormPersistence","excludeFields","excludeFromPersistence","expiresIn","persistExpiresIn","delay","autoSubmitDelay","remaining","Math","ceil","setInterval","form","document","querySelector","id","requestSubmit","handleFieldChange","value","prev","_removed","rest","handleSubmit","e","preventDefault","visibleFields","visibleFieldNames","Set","map","visibleFormData","key","Object","entries","has","validationResult","validateFormData","valid","onError","submitAction","toolName","result","success","_form","error","errorMessage","Error","message","dispatch","componentType","actionName","ts","Date","now","onSubmit","layoutClass","layout","_el$","_$getNextElement","_tmpl$5","_el$25","firstChild","_el$26","_co$7","_$getNextMarker","nextSibling","_el$3","_el$19","_el$20","_co$4","_el$4","_el$21","_el$22","_co$5","_el$23","_el$24","_co$6","_el$14","_el$15","_el$17","_el$18","_co$3","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","addEventListener","some","prefilled","length","total","_el$27","_tmpl$6","_el$31","_el$32","_co$8","_el$28","_el$33","_el$34","_co$9","_el$29","_el$35","_el$36","_co$0","_el$30","_el$37","_el$38","_co$1","For","each","FormFieldRenderer","onChange","disabled","_el$5","_tmpl$2","_el$6","_el$7","_tmpl$3","_el$8","_el$1","_el$10","_co$","_el$9","_el$11","_el$12","_co$2","_el$13","submitLabel","$$click","_$runHydrationEvents","_c$","_$memo","_tmpl$7","showReset","_el$16","_tmpl$4","_$effect","_$setProperty","_p$","_v$","_v$2","_v$3","_$setAttribute","t","_$className","a","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"FormRenderer.cjs","sources":["../../src/components/FormRenderer.tsx"],"sourcesContent":["/**\n * FormRenderer - Main form component\n * Sprint 1: Form Foundation\n * Sprint 2: Conditional field visibility (showWhen)\n * Sprint 4: Form state persistence\n */\n\nimport { Component, createSignal, For, Show, onMount, createEffect, onCleanup } from 'solid-js'\nimport { FormFieldRenderer } from './FormFieldRenderer'\nimport type { UIComponent, FormComponentParams, FormFieldParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { validateFormData } from '../services/validation'\nimport { evaluateCondition } from '../hooks/useConditionalField'\nimport { useFormPersistence } from '../hooks/useFormPersistence'\nimport { useTelemetry } from '../context/MCPUITelemetryContext'\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FormRendererProps {\n component: UIComponent\n onSubmit?: (data: Record<string, any>) => void\n onError?: (errors: Record<string, string>) => void\n}\n\n/**\n * Get default value for a field type\n */\nfunction getFieldDefault(type: FormFieldParams['type']): any {\n switch (type) {\n case 'checkbox':\n return false\n case 'number':\n return undefined\n case 'select':\n case 'radio':\n return ''\n default:\n return ''\n }\n}\n\nexport const FormRenderer: Component<FormRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n /**\n * The end-user validation wording, read from the chrome strings and\n * injected into the pure validators (which cannot reach the context).\n */\n const validationMessages = () => ({\n required: strings.fieldRequired,\n mustBeChecked: strings.fieldMustBeChecked,\n minLength: strings.fieldMinLength,\n maxLength: strings.fieldMaxLength,\n invalidPattern: strings.fieldInvalidPattern,\n invalidEmail: strings.fieldInvalidEmail,\n invalidNumber: strings.fieldInvalidNumber,\n minValue: strings.fieldMinValue,\n maxValue: strings.fieldMaxValue,\n minDate: strings.fieldMinDate,\n maxDate: strings.fieldMaxDate,\n invalidOption: strings.fieldInvalidOption,\n invalidFormat: strings.fieldInvalidFormat,\n })\n const params = () => props.component.params as FormComponentParams\n const [formData, setFormData] = createSignal<Record<string, any>>({})\n const [errors, setErrors] = createSignal<Record<string, string>>({})\n const [isSubmitting, setIsSubmitting] = createSignal(false)\n const { execute } = useAction()\n const telemetry = useTelemetry()\n\n // Form persistence (Sprint 4)\n let clearPersisted: (() => void) | undefined\n\n /**\n * Get fields that are currently visible based on showWhen conditions\n */\n const getVisibleFields = (): FormFieldParams[] => {\n return params().fields.filter((field) => {\n if (!field.showWhen) return true\n return evaluateCondition(field.showWhen, formData())\n })\n }\n\n // Auto-submit countdown state (v4.2.0)\n const [countdown, setCountdown] = createSignal<number | null>(null)\n let countdownTimer: ReturnType<typeof setInterval> | null = null\n const [userInteracted, setUserInteracted] = createSignal(false)\n\n const cancelCountdown = () => {\n if (countdownTimer) {\n clearInterval(countdownTimer)\n countdownTimer = null\n }\n setCountdown(null)\n }\n\n const handleUserInteraction = () => {\n if (!userInteracted()) {\n setUserInteracted(true)\n cancelCountdown()\n }\n }\n\n onCleanup(() => cancelCountdown())\n\n /**\n * Check if all required fields have prefill values\n */\n const allRequiredPrefilled = (): boolean => {\n return params().fields\n .filter((f) => f.required)\n .every((f) => f.prefill != null)\n }\n\n // Initialize form data with default values, applying prefill (v4.2.0)\n const initializeForm = (clearStorage = false) => {\n const initial: Record<string, any> = {}\n for (const field of params().fields) {\n // prefill takes priority over defaultValue\n initial[field.name] = field.prefill ?? field.defaultValue ?? getFieldDefault(field.type)\n }\n setFormData(initial)\n setErrors({})\n\n // Clear persisted data if requested\n if (clearStorage && clearPersisted) {\n clearPersisted()\n }\n }\n\n // Initialize on mount\n onMount(() => {\n initializeForm()\n })\n\n // Setup persistence if persistKey is provided (Sprint 4)\n createEffect(() => {\n const persistKey = params().persistKey\n if (persistKey) {\n const persistence = useFormPersistence({\n persistKey,\n formData,\n setFormData,\n excludeFields: params().excludeFromPersistence,\n expiresIn: params().persistExpiresIn,\n })\n clearPersisted = persistence.clearPersisted\n }\n })\n\n // Auto-submit countdown (v4.2.0)\n createEffect(() => {\n const delay = params().autoSubmitDelay\n if (!delay || !allRequiredPrefilled() || userInteracted()) return\n\n let remaining = Math.ceil(delay / 1000)\n setCountdown(remaining)\n\n countdownTimer = setInterval(() => {\n remaining--\n if (remaining <= 0) {\n cancelCountdown()\n // Trigger submit programmatically\n const form = document.querySelector(`#form-${props.component.id}`) as HTMLFormElement | null\n if (form) form.requestSubmit()\n } else {\n setCountdown(remaining)\n }\n }, 1000)\n })\n\n const handleFieldChange = (name: string, value: any) => {\n handleUserInteraction()\n setFormData((prev) => ({ ...prev, [name]: value }))\n // Clear error on change\n if (errors()[name]) {\n setErrors((prev) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [name]: _removed, ...rest } = prev\n return rest\n })\n }\n }\n\n const handleSubmit = async (e: Event) => {\n e.preventDefault()\n setIsSubmitting(true)\n setErrors({})\n\n // Get only visible fields for validation and submission\n const visibleFields = getVisibleFields()\n const visibleFieldNames = new Set(visibleFields.map((f) => f.name))\n\n // Filter form data to only include visible fields\n const visibleFormData: Record<string, any> = {}\n for (const [key, value] of Object.entries(formData())) {\n if (visibleFieldNames.has(key)) {\n visibleFormData[key] = value\n }\n }\n\n // Validate only visible fields\n const validationResult = validateFormData(visibleFormData, visibleFields, validationMessages())\n if (!validationResult.valid) {\n setErrors(validationResult.errors)\n setIsSubmitting(false)\n props.onError?.(validationResult.errors)\n return\n }\n\n // Submit via tool call if specified\n if (params().submitAction?.toolName) {\n try {\n const result = await execute(params().submitAction!.toolName, {\n ...params().submitAction!.params,\n formData: visibleFormData,\n })\n if (!result.success) {\n setErrors({ _form: result.error || strings.formSubmissionFailed })\n setIsSubmitting(false)\n props.onError?.({ _form: result.error || strings.formSubmissionFailed })\n return\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : strings.formSubmissionFailed\n setErrors({ _form: errorMessage })\n setIsSubmitting(false)\n props.onError?.({ _form: errorMessage })\n return\n }\n }\n\n // Clear persisted data on successful submit\n if (clearPersisted) {\n clearPersisted()\n }\n\n // Telemetry: action:dispatched on successful submit (B.5 — v5.6.0).\n // Privacy: only the action name (toolName or 'submit'), NO form values.\n if (telemetry) {\n telemetry.dispatch({\n type: 'action:dispatched',\n id: props.component.id,\n componentType: 'form',\n actionName: params().submitAction?.toolName ?? 'submit',\n ts: Date.now(),\n })\n }\n\n props.onSubmit?.(visibleFormData)\n setIsSubmitting(false)\n }\n\n const layoutClass = () => {\n switch (params().layout) {\n case 'horizontal':\n return 'grid grid-cols-2 gap-4'\n case 'inline':\n return 'flex flex-wrap gap-4 items-end'\n default:\n return 'space-y-4'\n }\n }\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <Show when={params().title}>\n <h3 class=\"text-lg font-semibold text-gray-900 dark:text-white mb-4\">\n {params().title}\n </h3>\n </Show>\n\n <form id={`form-${props.component.id}`} onSubmit={handleSubmit} noValidate>\n {/* Proposal 3: prefill summary */}\n <Show when={params().fields.some((f) => f.prefill != null)}>\n {(() => {\n const prefilled = params().fields.filter((f) => f.prefill != null).length\n const total = params().fields.length\n return (\n <p class=\"text-xs text-gray-500 dark:text-gray-400 mb-3\">\n {formatMCPUIString(\n prefilled === 1 ? strings.formPrefilledOne : strings.formPrefilledMany,\n { count: prefilled, total }\n )}\n </p>\n )\n })()}\n </Show>\n <div class={layoutClass()}>\n <For each={params().fields}>\n {(field) => (\n <FormFieldRenderer\n field={field}\n value={formData()[field.name]}\n error={errors()[field.name]}\n onChange={(value) => handleFieldChange(field.name, value)}\n disabled={isSubmitting() || field.disabled}\n formData={formData}\n />\n )}\n </For>\n </div>\n\n <Show when={errors()._form}>\n <div class=\"mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md\">\n <p class=\"text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n {errors()._form}\n </p>\n </div>\n </Show>\n\n {/* Auto-submit countdown (v4.2.0) */}\n <Show when={countdown() != null}>\n <div class=\"mt-4 flex items-center gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md\">\n <span class=\"text-sm text-blue-700 dark:text-blue-300\">\n {formatMCPUIString(strings.formSubmitCountdown, {\n label: params().submitLabel || strings.submit,\n seconds: countdown()!,\n })}\n </span>\n <button\n type=\"button\"\n onClick={() => { cancelCountdown(); setUserInteracted(true) }}\n class=\"text-sm text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-200\"\n >\n {strings.cancel}\n </button>\n </div>\n </Show>\n\n <div class=\"flex gap-2 pt-4 mt-4 border-t border-gray-200 dark:border-gray-700\">\n <button\n type=\"submit\"\n disabled={isSubmitting()}\n class=\"px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isSubmitting() ? (\n <span class=\"flex items-center gap-2\">\n <span class=\"animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full\" />\n {strings.formSubmitting}\n </span>\n ) : (\n params().submitLabel || strings.submit\n )}\n </button>\n <Show when={params().showReset}>\n <button\n type=\"button\"\n onClick={() => initializeForm(true)}\n disabled={isSubmitting()}\n class=\"px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {strings.formReset}\n </button>\n </Show>\n </div>\n </form>\n </div>\n )\n}\n"],"names":["getFieldDefault","type","undefined","FormRenderer","props","strings","useMCPUIStrings","validationMessages","required","fieldRequired","mustBeChecked","fieldMustBeChecked","minLength","fieldMinLength","maxLength","fieldMaxLength","invalidPattern","fieldInvalidPattern","invalidEmail","fieldInvalidEmail","invalidNumber","fieldInvalidNumber","minValue","fieldMinValue","maxValue","fieldMaxValue","minDate","fieldMinDate","maxDate","fieldMaxDate","invalidOption","fieldInvalidOption","invalidFormat","fieldInvalidFormat","params","component","formData","setFormData","createSignal","errors","setErrors","isSubmitting","setIsSubmitting","execute","useAction","telemetry","useTelemetry","clearPersisted","getVisibleFields","fields","filter","field","showWhen","evaluateCondition","countdown","setCountdown","countdownTimer","userInteracted","setUserInteracted","cancelCountdown","clearInterval","handleUserInteraction","onCleanup","allRequiredPrefilled","f","every","prefill","initializeForm","clearStorage","initial","name","defaultValue","onMount","createEffect","persistKey","persistence","useFormPersistence","excludeFields","excludeFromPersistence","expiresIn","persistExpiresIn","delay","autoSubmitDelay","remaining","Math","ceil","setInterval","form","document","querySelector","id","requestSubmit","handleFieldChange","value","prev","_removed","rest","handleSubmit","e","preventDefault","visibleFields","visibleFieldNames","Set","map","visibleFormData","key","Object","entries","has","validationResult","validateFormData","valid","onError","submitAction","toolName","result","success","_form","error","formSubmissionFailed","errorMessage","Error","message","dispatch","componentType","actionName","ts","Date","now","onSubmit","layoutClass","layout","_el$","_$getNextElement","_tmpl$5","_el$19","firstChild","_el$20","_co$5","_$getNextMarker","nextSibling","_el$3","_el$13","_el$14","_co$2","_el$4","_el$15","_el$16","_co$3","_el$17","_el$18","_co$4","_el$0","_el$1","_el$11","_el$12","_co$","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","addEventListener","some","prefilled","length","total","_el$21","_tmpl$6","formatMCPUIString","formPrefilledOne","formPrefilledMany","count","For","each","FormFieldRenderer","onChange","disabled","_el$5","_tmpl$2","_el$6","_el$7","_tmpl$3","_el$8","_el$9","formSubmitCountdown","label","submitLabel","submit","seconds","$$click","cancel","_$runHydrationEvents","_c$","_$memo","_el$22","_tmpl$7","_el$23","_el$24","_el$25","_co$6","formSubmitting","showReset","_el$10","_tmpl$4","formReset","_$effect","_$setProperty","_p$","_v$","_v$2","_v$3","_$setAttribute","t","_$className","a","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FormRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAA6D,MAAM,UAAU,CAAA;AAE/F,OAAO,KAAK,EAAE,WAAW,EAAwC,MAAM,UAAU,CAAA;AAOjF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,WAAW,CAAA;IACtB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAA;IAC9C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAA;CACnD;AAmBD,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,iBAAiB,CAmSrD,CAAA"}
1
+ {"version":3,"file":"FormRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FormRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAA6D,MAAM,UAAU,CAAA;AAE/F,OAAO,KAAK,EAAE,WAAW,EAAwC,MAAM,UAAU,CAAA;AAQjF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,WAAW,CAAA;IACtB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAA;IAC9C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAA;CACnD;AAmBD,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,iBAAiB,CA8TrD,CAAA"}
@@ -6,7 +6,9 @@ import { validateFormData } from "../services/validation.js";
6
6
  import { evaluateCondition } from "../hooks/useConditionalField.js";
7
7
  import { useFormPersistence } from "../hooks/useFormPersistence.js";
8
8
  import { useTelemetry } from "../context/MCPUITelemetryContext.js";
9
- var _tmpl$ = /* @__PURE__ */ template(`<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">`), _tmpl$2 = /* @__PURE__ */ template(`<div class="mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md"><p class="text-sm text-red-600 dark:text-red-400"role=alert>`), _tmpl$3 = /* @__PURE__ */ template(`<div class="mt-4 flex items-center gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md"><span class="text-sm text-blue-700 dark:text-blue-300"><!$><!/> in <!$><!/>s...</span><button type=button class="text-sm text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-200">Cancel`), _tmpl$4 = /* @__PURE__ */ template(`<button type=button class="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">Reset`), _tmpl$5 = /* @__PURE__ */ template(`<div class="w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><!$><!/><form novalidate><!$><!/><div></div><!$><!/><!$><!/><div class="flex gap-2 pt-4 mt-4 border-t border-gray-200 dark:border-gray-700"><button type=submit class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"></button><!$><!/>`), _tmpl$6 = /* @__PURE__ */ template(`<p class="text-xs text-gray-500 dark:text-gray-400 mb-3"><!$><!/> champ<!$><!/> pré-rempli<!$><!/> sur <!$><!/>`), _tmpl$7 = /* @__PURE__ */ template(`<span class="flex items-center gap-2"><span class="animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full"></span>Submitting...`);
9
+ import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
10
+ import { formatMCPUIString } from "../utils/format-string.js";
11
+ var _tmpl$ = /* @__PURE__ */ template(`<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">`), _tmpl$2 = /* @__PURE__ */ template(`<div class="mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md"><p class="text-sm text-red-600 dark:text-red-400"role=alert>`), _tmpl$3 = /* @__PURE__ */ template(`<div class="mt-4 flex items-center gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md"><span class="text-sm text-blue-700 dark:text-blue-300"></span><button type=button class="text-sm text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-200">`), _tmpl$4 = /* @__PURE__ */ template(`<button type=button class="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">`), _tmpl$5 = /* @__PURE__ */ template(`<div class="w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><!$><!/><form novalidate><!$><!/><div></div><!$><!/><!$><!/><div class="flex gap-2 pt-4 mt-4 border-t border-gray-200 dark:border-gray-700"><button type=submit class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"></button><!$><!/>`), _tmpl$6 = /* @__PURE__ */ template(`<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">`), _tmpl$7 = /* @__PURE__ */ template(`<span class="flex items-center gap-2"><span class="animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full"></span><!$><!/>`);
10
12
  function getFieldDefault(type) {
11
13
  switch (type) {
12
14
  case "checkbox":
@@ -21,6 +23,22 @@ function getFieldDefault(type) {
21
23
  }
22
24
  }
23
25
  const FormRenderer = (props) => {
26
+ const strings = useMCPUIStrings();
27
+ const validationMessages = () => ({
28
+ required: strings.fieldRequired,
29
+ mustBeChecked: strings.fieldMustBeChecked,
30
+ minLength: strings.fieldMinLength,
31
+ maxLength: strings.fieldMaxLength,
32
+ invalidPattern: strings.fieldInvalidPattern,
33
+ invalidEmail: strings.fieldInvalidEmail,
34
+ invalidNumber: strings.fieldInvalidNumber,
35
+ minValue: strings.fieldMinValue,
36
+ maxValue: strings.fieldMaxValue,
37
+ minDate: strings.fieldMinDate,
38
+ maxDate: strings.fieldMaxDate,
39
+ invalidOption: strings.fieldInvalidOption,
40
+ invalidFormat: strings.fieldInvalidFormat
41
+ });
24
42
  const params = () => props.component.params;
25
43
  const [formData, setFormData] = createSignal({});
26
44
  const [errors, setErrors] = createSignal({});
@@ -128,7 +146,7 @@ const FormRenderer = (props) => {
128
146
  visibleFormData[key] = value;
129
147
  }
130
148
  }
131
- const validationResult = validateFormData(visibleFormData, visibleFields);
149
+ const validationResult = validateFormData(visibleFormData, visibleFields, validationMessages());
132
150
  if (!validationResult.valid) {
133
151
  setErrors(validationResult.errors);
134
152
  setIsSubmitting(false);
@@ -143,16 +161,16 @@ const FormRenderer = (props) => {
143
161
  });
144
162
  if (!result.success) {
145
163
  setErrors({
146
- _form: result.error || "Submission failed"
164
+ _form: result.error || strings.formSubmissionFailed
147
165
  });
148
166
  setIsSubmitting(false);
149
167
  (_c = props.onError) == null ? void 0 : _c.call(props, {
150
- _form: result.error || "Submission failed"
168
+ _form: result.error || strings.formSubmissionFailed
151
169
  });
152
170
  return;
153
171
  }
154
172
  } catch (error) {
155
- const errorMessage = error instanceof Error ? error.message : "Submission failed";
173
+ const errorMessage = error instanceof Error ? error.message : strings.formSubmissionFailed;
156
174
  setErrors({
157
175
  _form: errorMessage
158
176
  });
@@ -189,7 +207,7 @@ const FormRenderer = (props) => {
189
207
  }
190
208
  };
191
209
  return (() => {
192
- var _el$ = getNextElement(_tmpl$5), _el$25 = _el$.firstChild, [_el$26, _co$7] = getNextMarker(_el$25.nextSibling), _el$3 = _el$26.nextSibling, _el$19 = _el$3.firstChild, [_el$20, _co$4] = getNextMarker(_el$19.nextSibling), _el$4 = _el$20.nextSibling, _el$21 = _el$4.nextSibling, [_el$22, _co$5] = getNextMarker(_el$21.nextSibling), _el$23 = _el$22.nextSibling, [_el$24, _co$6] = getNextMarker(_el$23.nextSibling), _el$14 = _el$24.nextSibling, _el$15 = _el$14.firstChild, _el$17 = _el$15.nextSibling, [_el$18, _co$3] = getNextMarker(_el$17.nextSibling);
210
+ var _el$ = getNextElement(_tmpl$5), _el$19 = _el$.firstChild, [_el$20, _co$5] = getNextMarker(_el$19.nextSibling), _el$3 = _el$20.nextSibling, _el$13 = _el$3.firstChild, [_el$14, _co$2] = getNextMarker(_el$13.nextSibling), _el$4 = _el$14.nextSibling, _el$15 = _el$4.nextSibling, [_el$16, _co$3] = getNextMarker(_el$15.nextSibling), _el$17 = _el$16.nextSibling, [_el$18, _co$4] = getNextMarker(_el$17.nextSibling), _el$0 = _el$18.nextSibling, _el$1 = _el$0.firstChild, _el$11 = _el$1.nextSibling, [_el$12, _co$] = getNextMarker(_el$11.nextSibling);
193
211
  insert(_el$, createComponent(Show, {
194
212
  get when() {
195
213
  return params().title;
@@ -199,7 +217,7 @@ const FormRenderer = (props) => {
199
217
  insert(_el$2, () => params().title);
200
218
  return _el$2;
201
219
  }
202
- }), _el$26, _co$7);
220
+ }), _el$20, _co$5);
203
221
  _el$3.addEventListener("submit", handleSubmit);
204
222
  insert(_el$3, createComponent(Show, {
205
223
  get when() {
@@ -210,16 +228,16 @@ const FormRenderer = (props) => {
210
228
  const prefilled = params().fields.filter((f) => f.prefill != null).length;
211
229
  const total = params().fields.length;
212
230
  return (() => {
213
- var _el$27 = getNextElement(_tmpl$6), _el$31 = _el$27.firstChild, [_el$32, _co$8] = getNextMarker(_el$31.nextSibling), _el$28 = _el$32.nextSibling, _el$33 = _el$28.nextSibling, [_el$34, _co$9] = getNextMarker(_el$33.nextSibling), _el$29 = _el$34.nextSibling, _el$35 = _el$29.nextSibling, [_el$36, _co$0] = getNextMarker(_el$35.nextSibling), _el$30 = _el$36.nextSibling, _el$37 = _el$30.nextSibling, [_el$38, _co$1] = getNextMarker(_el$37.nextSibling);
214
- insert(_el$27, prefilled, _el$32, _co$8);
215
- insert(_el$27, prefilled > 1 ? "s" : "", _el$34, _co$9);
216
- insert(_el$27, prefilled > 1 ? "s" : "", _el$36, _co$0);
217
- insert(_el$27, total, _el$38, _co$1);
218
- return _el$27;
231
+ var _el$21 = getNextElement(_tmpl$6);
232
+ insert(_el$21, () => formatMCPUIString(prefilled === 1 ? strings.formPrefilledOne : strings.formPrefilledMany, {
233
+ count: prefilled,
234
+ total
235
+ }));
236
+ return _el$21;
219
237
  })();
220
238
  })();
221
239
  }
222
- }), _el$20, _co$4);
240
+ }), _el$14, _co$2);
223
241
  insert(_el$4, createComponent(For, {
224
242
  get each() {
225
243
  return params().fields;
@@ -248,46 +266,52 @@ const FormRenderer = (props) => {
248
266
  insert(_el$6, () => errors()._form);
249
267
  return _el$5;
250
268
  }
251
- }), _el$22, _co$5);
269
+ }), _el$16, _co$3);
252
270
  insert(_el$3, createComponent(Show, {
253
271
  get when() {
254
272
  return countdown() != null;
255
273
  },
256
274
  get children() {
257
- var _el$7 = getNextElement(_tmpl$3), _el$8 = _el$7.firstChild, _el$1 = _el$8.firstChild, [_el$10, _co$] = getNextMarker(_el$1.nextSibling), _el$9 = _el$10.nextSibling, _el$11 = _el$9.nextSibling, [_el$12, _co$2] = getNextMarker(_el$11.nextSibling);
258
- _el$12.nextSibling;
259
- var _el$13 = _el$8.nextSibling;
260
- insert(_el$8, () => params().submitLabel || "Submit", _el$10, _co$);
261
- insert(_el$8, countdown, _el$12, _co$2);
262
- _el$13.$$click = () => {
275
+ var _el$7 = getNextElement(_tmpl$3), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling;
276
+ insert(_el$8, () => formatMCPUIString(strings.formSubmitCountdown, {
277
+ label: params().submitLabel || strings.submit,
278
+ seconds: countdown()
279
+ }));
280
+ _el$9.$$click = () => {
263
281
  cancelCountdown();
264
282
  setUserInteracted(true);
265
283
  };
284
+ insert(_el$9, () => strings.cancel);
266
285
  runHydrationEvents();
267
286
  return _el$7;
268
287
  }
269
- }), _el$24, _co$6);
270
- insert(_el$15, (() => {
288
+ }), _el$18, _co$4);
289
+ insert(_el$1, (() => {
271
290
  var _c$ = memo(() => !!isSubmitting());
272
- return () => _c$() ? getNextElement(_tmpl$7) : params().submitLabel || "Submit";
291
+ return () => _c$() ? (() => {
292
+ var _el$22 = getNextElement(_tmpl$7), _el$23 = _el$22.firstChild, _el$24 = _el$23.nextSibling, [_el$25, _co$6] = getNextMarker(_el$24.nextSibling);
293
+ insert(_el$22, () => strings.formSubmitting, _el$25, _co$6);
294
+ return _el$22;
295
+ })() : params().submitLabel || strings.submit;
273
296
  })());
274
- insert(_el$14, createComponent(Show, {
297
+ insert(_el$0, createComponent(Show, {
275
298
  get when() {
276
299
  return params().showReset;
277
300
  },
278
301
  get children() {
279
- var _el$16 = getNextElement(_tmpl$4);
280
- _el$16.$$click = () => initializeForm(true);
281
- effect(() => setProperty(_el$16, "disabled", isSubmitting()));
302
+ var _el$10 = getNextElement(_tmpl$4);
303
+ _el$10.$$click = () => initializeForm(true);
304
+ insert(_el$10, () => strings.formReset);
305
+ effect(() => setProperty(_el$10, "disabled", isSubmitting()));
282
306
  runHydrationEvents();
283
- return _el$16;
307
+ return _el$10;
284
308
  }
285
- }), _el$18, _co$3);
309
+ }), _el$12, _co$);
286
310
  effect((_p$) => {
287
311
  var _v$ = `form-${props.component.id}`, _v$2 = layoutClass(), _v$3 = isSubmitting();
288
312
  _v$ !== _p$.e && setAttribute(_el$3, "id", _p$.e = _v$);
289
313
  _v$2 !== _p$.t && className(_el$4, _p$.t = _v$2);
290
- _v$3 !== _p$.a && setProperty(_el$15, "disabled", _p$.a = _v$3);
314
+ _v$3 !== _p$.a && setProperty(_el$1, "disabled", _p$.a = _v$3);
291
315
  return _p$;
292
316
  }, {
293
317
  e: void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"FormRenderer.js","sources":["../../src/components/FormRenderer.tsx"],"sourcesContent":["/**\n * FormRenderer - Main form component\n * Sprint 1: Form Foundation\n * Sprint 2: Conditional field visibility (showWhen)\n * Sprint 4: Form state persistence\n */\n\nimport { Component, createSignal, For, Show, onMount, createEffect, onCleanup } from 'solid-js'\nimport { FormFieldRenderer } from './FormFieldRenderer'\nimport type { UIComponent, FormComponentParams, FormFieldParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { validateFormData } from '../services/validation'\nimport { evaluateCondition } from '../hooks/useConditionalField'\nimport { useFormPersistence } from '../hooks/useFormPersistence'\nimport { useTelemetry } from '../context/MCPUITelemetryContext'\n\nexport interface FormRendererProps {\n component: UIComponent\n onSubmit?: (data: Record<string, any>) => void\n onError?: (errors: Record<string, string>) => void\n}\n\n/**\n * Get default value for a field type\n */\nfunction getFieldDefault(type: FormFieldParams['type']): any {\n switch (type) {\n case 'checkbox':\n return false\n case 'number':\n return undefined\n case 'select':\n case 'radio':\n return ''\n default:\n return ''\n }\n}\n\nexport const FormRenderer: Component<FormRendererProps> = (props) => {\n const params = () => props.component.params as FormComponentParams\n const [formData, setFormData] = createSignal<Record<string, any>>({})\n const [errors, setErrors] = createSignal<Record<string, string>>({})\n const [isSubmitting, setIsSubmitting] = createSignal(false)\n const { execute } = useAction()\n const telemetry = useTelemetry()\n\n // Form persistence (Sprint 4)\n let clearPersisted: (() => void) | undefined\n\n /**\n * Get fields that are currently visible based on showWhen conditions\n */\n const getVisibleFields = (): FormFieldParams[] => {\n return params().fields.filter((field) => {\n if (!field.showWhen) return true\n return evaluateCondition(field.showWhen, formData())\n })\n }\n\n // Auto-submit countdown state (v4.2.0)\n const [countdown, setCountdown] = createSignal<number | null>(null)\n let countdownTimer: ReturnType<typeof setInterval> | null = null\n const [userInteracted, setUserInteracted] = createSignal(false)\n\n const cancelCountdown = () => {\n if (countdownTimer) {\n clearInterval(countdownTimer)\n countdownTimer = null\n }\n setCountdown(null)\n }\n\n const handleUserInteraction = () => {\n if (!userInteracted()) {\n setUserInteracted(true)\n cancelCountdown()\n }\n }\n\n onCleanup(() => cancelCountdown())\n\n /**\n * Check if all required fields have prefill values\n */\n const allRequiredPrefilled = (): boolean => {\n return params().fields\n .filter((f) => f.required)\n .every((f) => f.prefill != null)\n }\n\n // Initialize form data with default values, applying prefill (v4.2.0)\n const initializeForm = (clearStorage = false) => {\n const initial: Record<string, any> = {}\n for (const field of params().fields) {\n // prefill takes priority over defaultValue\n initial[field.name] = field.prefill ?? field.defaultValue ?? getFieldDefault(field.type)\n }\n setFormData(initial)\n setErrors({})\n\n // Clear persisted data if requested\n if (clearStorage && clearPersisted) {\n clearPersisted()\n }\n }\n\n // Initialize on mount\n onMount(() => {\n initializeForm()\n })\n\n // Setup persistence if persistKey is provided (Sprint 4)\n createEffect(() => {\n const persistKey = params().persistKey\n if (persistKey) {\n const persistence = useFormPersistence({\n persistKey,\n formData,\n setFormData,\n excludeFields: params().excludeFromPersistence,\n expiresIn: params().persistExpiresIn,\n })\n clearPersisted = persistence.clearPersisted\n }\n })\n\n // Auto-submit countdown (v4.2.0)\n createEffect(() => {\n const delay = params().autoSubmitDelay\n if (!delay || !allRequiredPrefilled() || userInteracted()) return\n\n let remaining = Math.ceil(delay / 1000)\n setCountdown(remaining)\n\n countdownTimer = setInterval(() => {\n remaining--\n if (remaining <= 0) {\n cancelCountdown()\n // Trigger submit programmatically\n const form = document.querySelector(`#form-${props.component.id}`) as HTMLFormElement | null\n if (form) form.requestSubmit()\n } else {\n setCountdown(remaining)\n }\n }, 1000)\n })\n\n const handleFieldChange = (name: string, value: any) => {\n handleUserInteraction()\n setFormData((prev) => ({ ...prev, [name]: value }))\n // Clear error on change\n if (errors()[name]) {\n setErrors((prev) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [name]: _removed, ...rest } = prev\n return rest\n })\n }\n }\n\n const handleSubmit = async (e: Event) => {\n e.preventDefault()\n setIsSubmitting(true)\n setErrors({})\n\n // Get only visible fields for validation and submission\n const visibleFields = getVisibleFields()\n const visibleFieldNames = new Set(visibleFields.map((f) => f.name))\n\n // Filter form data to only include visible fields\n const visibleFormData: Record<string, any> = {}\n for (const [key, value] of Object.entries(formData())) {\n if (visibleFieldNames.has(key)) {\n visibleFormData[key] = value\n }\n }\n\n // Validate only visible fields\n const validationResult = validateFormData(visibleFormData, visibleFields)\n if (!validationResult.valid) {\n setErrors(validationResult.errors)\n setIsSubmitting(false)\n props.onError?.(validationResult.errors)\n return\n }\n\n // Submit via tool call if specified\n if (params().submitAction?.toolName) {\n try {\n const result = await execute(params().submitAction!.toolName, {\n ...params().submitAction!.params,\n formData: visibleFormData,\n })\n if (!result.success) {\n setErrors({ _form: result.error || 'Submission failed' })\n setIsSubmitting(false)\n props.onError?.({ _form: result.error || 'Submission failed' })\n return\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Submission failed'\n setErrors({ _form: errorMessage })\n setIsSubmitting(false)\n props.onError?.({ _form: errorMessage })\n return\n }\n }\n\n // Clear persisted data on successful submit\n if (clearPersisted) {\n clearPersisted()\n }\n\n // Telemetry: action:dispatched on successful submit (B.5 — v5.6.0).\n // Privacy: only the action name (toolName or 'submit'), NO form values.\n if (telemetry) {\n telemetry.dispatch({\n type: 'action:dispatched',\n id: props.component.id,\n componentType: 'form',\n actionName: params().submitAction?.toolName ?? 'submit',\n ts: Date.now(),\n })\n }\n\n props.onSubmit?.(visibleFormData)\n setIsSubmitting(false)\n }\n\n const layoutClass = () => {\n switch (params().layout) {\n case 'horizontal':\n return 'grid grid-cols-2 gap-4'\n case 'inline':\n return 'flex flex-wrap gap-4 items-end'\n default:\n return 'space-y-4'\n }\n }\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <Show when={params().title}>\n <h3 class=\"text-lg font-semibold text-gray-900 dark:text-white mb-4\">\n {params().title}\n </h3>\n </Show>\n\n <form id={`form-${props.component.id}`} onSubmit={handleSubmit} noValidate>\n {/* Proposal 3: prefill summary */}\n <Show when={params().fields.some((f) => f.prefill != null)}>\n {(() => {\n const prefilled = params().fields.filter((f) => f.prefill != null).length\n const total = params().fields.length\n return (\n <p class=\"text-xs text-gray-500 dark:text-gray-400 mb-3\">\n {prefilled} champ{prefilled > 1 ? 's' : ''} pré-rempli{prefilled > 1 ? 's' : ''} sur {total}\n </p>\n )\n })()}\n </Show>\n <div class={layoutClass()}>\n <For each={params().fields}>\n {(field) => (\n <FormFieldRenderer\n field={field}\n value={formData()[field.name]}\n error={errors()[field.name]}\n onChange={(value) => handleFieldChange(field.name, value)}\n disabled={isSubmitting() || field.disabled}\n formData={formData}\n />\n )}\n </For>\n </div>\n\n <Show when={errors()._form}>\n <div class=\"mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md\">\n <p class=\"text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n {errors()._form}\n </p>\n </div>\n </Show>\n\n {/* Auto-submit countdown (v4.2.0) */}\n <Show when={countdown() != null}>\n <div class=\"mt-4 flex items-center gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md\">\n <span class=\"text-sm text-blue-700 dark:text-blue-300\">\n {params().submitLabel || 'Submit'} in {countdown()}s...\n </span>\n <button\n type=\"button\"\n onClick={() => { cancelCountdown(); setUserInteracted(true) }}\n class=\"text-sm text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-200\"\n >\n Cancel\n </button>\n </div>\n </Show>\n\n <div class=\"flex gap-2 pt-4 mt-4 border-t border-gray-200 dark:border-gray-700\">\n <button\n type=\"submit\"\n disabled={isSubmitting()}\n class=\"px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isSubmitting() ? (\n <span class=\"flex items-center gap-2\">\n <span class=\"animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full\" />\n Submitting...\n </span>\n ) : (\n params().submitLabel || 'Submit'\n )}\n </button>\n <Show when={params().showReset}>\n <button\n type=\"button\"\n onClick={() => initializeForm(true)}\n disabled={isSubmitting()}\n class=\"px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n Reset\n </button>\n </Show>\n </div>\n </form>\n </div>\n )\n}\n"],"names":["getFieldDefault","type","undefined","FormRenderer","props","params","component","formData","setFormData","createSignal","errors","setErrors","isSubmitting","setIsSubmitting","execute","useAction","telemetry","useTelemetry","clearPersisted","getVisibleFields","fields","filter","field","showWhen","evaluateCondition","countdown","setCountdown","countdownTimer","userInteracted","setUserInteracted","cancelCountdown","clearInterval","handleUserInteraction","onCleanup","allRequiredPrefilled","f","required","every","prefill","initializeForm","clearStorage","initial","name","defaultValue","onMount","createEffect","persistKey","persistence","useFormPersistence","excludeFields","excludeFromPersistence","expiresIn","persistExpiresIn","delay","autoSubmitDelay","remaining","Math","ceil","setInterval","form","document","querySelector","id","requestSubmit","handleFieldChange","value","prev","_removed","rest","handleSubmit","e","preventDefault","visibleFields","visibleFieldNames","Set","map","visibleFormData","key","Object","entries","has","validationResult","validateFormData","valid","onError","submitAction","toolName","result","success","_form","error","errorMessage","Error","message","dispatch","componentType","actionName","ts","Date","now","onSubmit","layoutClass","layout","_el$","_$getNextElement","_tmpl$5","_el$25","firstChild","_el$26","_co$7","_$getNextMarker","nextSibling","_el$3","_el$19","_el$20","_co$4","_el$4","_el$21","_el$22","_co$5","_el$23","_el$24","_co$6","_el$14","_el$15","_el$17","_el$18","_co$3","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","addEventListener","some","prefilled","length","total","_el$27","_tmpl$6","_el$31","_el$32","_co$8","_el$28","_el$33","_el$34","_co$9","_el$29","_el$35","_el$36","_co$0","_el$30","_el$37","_el$38","_co$1","For","each","FormFieldRenderer","onChange","disabled","_el$5","_tmpl$2","_el$6","_el$7","_tmpl$3","_el$8","_el$1","_el$10","_co$","_el$9","_el$11","_el$12","_co$2","_el$13","submitLabel","$$click","_$runHydrationEvents","_c$","_$memo","_tmpl$7","showReset","_el$16","_tmpl$4","_$effect","_$setProperty","_p$","_v$","_v$2","_v$3","_$setAttribute","t","_$className","a","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"FormRenderer.js","sources":["../../src/components/FormRenderer.tsx"],"sourcesContent":["/**\n * FormRenderer - Main form component\n * Sprint 1: Form Foundation\n * Sprint 2: Conditional field visibility (showWhen)\n * Sprint 4: Form state persistence\n */\n\nimport { Component, createSignal, For, Show, onMount, createEffect, onCleanup } from 'solid-js'\nimport { FormFieldRenderer } from './FormFieldRenderer'\nimport type { UIComponent, FormComponentParams, FormFieldParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { validateFormData } from '../services/validation'\nimport { evaluateCondition } from '../hooks/useConditionalField'\nimport { useFormPersistence } from '../hooks/useFormPersistence'\nimport { useTelemetry } from '../context/MCPUITelemetryContext'\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FormRendererProps {\n component: UIComponent\n onSubmit?: (data: Record<string, any>) => void\n onError?: (errors: Record<string, string>) => void\n}\n\n/**\n * Get default value for a field type\n */\nfunction getFieldDefault(type: FormFieldParams['type']): any {\n switch (type) {\n case 'checkbox':\n return false\n case 'number':\n return undefined\n case 'select':\n case 'radio':\n return ''\n default:\n return ''\n }\n}\n\nexport const FormRenderer: Component<FormRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n /**\n * The end-user validation wording, read from the chrome strings and\n * injected into the pure validators (which cannot reach the context).\n */\n const validationMessages = () => ({\n required: strings.fieldRequired,\n mustBeChecked: strings.fieldMustBeChecked,\n minLength: strings.fieldMinLength,\n maxLength: strings.fieldMaxLength,\n invalidPattern: strings.fieldInvalidPattern,\n invalidEmail: strings.fieldInvalidEmail,\n invalidNumber: strings.fieldInvalidNumber,\n minValue: strings.fieldMinValue,\n maxValue: strings.fieldMaxValue,\n minDate: strings.fieldMinDate,\n maxDate: strings.fieldMaxDate,\n invalidOption: strings.fieldInvalidOption,\n invalidFormat: strings.fieldInvalidFormat,\n })\n const params = () => props.component.params as FormComponentParams\n const [formData, setFormData] = createSignal<Record<string, any>>({})\n const [errors, setErrors] = createSignal<Record<string, string>>({})\n const [isSubmitting, setIsSubmitting] = createSignal(false)\n const { execute } = useAction()\n const telemetry = useTelemetry()\n\n // Form persistence (Sprint 4)\n let clearPersisted: (() => void) | undefined\n\n /**\n * Get fields that are currently visible based on showWhen conditions\n */\n const getVisibleFields = (): FormFieldParams[] => {\n return params().fields.filter((field) => {\n if (!field.showWhen) return true\n return evaluateCondition(field.showWhen, formData())\n })\n }\n\n // Auto-submit countdown state (v4.2.0)\n const [countdown, setCountdown] = createSignal<number | null>(null)\n let countdownTimer: ReturnType<typeof setInterval> | null = null\n const [userInteracted, setUserInteracted] = createSignal(false)\n\n const cancelCountdown = () => {\n if (countdownTimer) {\n clearInterval(countdownTimer)\n countdownTimer = null\n }\n setCountdown(null)\n }\n\n const handleUserInteraction = () => {\n if (!userInteracted()) {\n setUserInteracted(true)\n cancelCountdown()\n }\n }\n\n onCleanup(() => cancelCountdown())\n\n /**\n * Check if all required fields have prefill values\n */\n const allRequiredPrefilled = (): boolean => {\n return params().fields\n .filter((f) => f.required)\n .every((f) => f.prefill != null)\n }\n\n // Initialize form data with default values, applying prefill (v4.2.0)\n const initializeForm = (clearStorage = false) => {\n const initial: Record<string, any> = {}\n for (const field of params().fields) {\n // prefill takes priority over defaultValue\n initial[field.name] = field.prefill ?? field.defaultValue ?? getFieldDefault(field.type)\n }\n setFormData(initial)\n setErrors({})\n\n // Clear persisted data if requested\n if (clearStorage && clearPersisted) {\n clearPersisted()\n }\n }\n\n // Initialize on mount\n onMount(() => {\n initializeForm()\n })\n\n // Setup persistence if persistKey is provided (Sprint 4)\n createEffect(() => {\n const persistKey = params().persistKey\n if (persistKey) {\n const persistence = useFormPersistence({\n persistKey,\n formData,\n setFormData,\n excludeFields: params().excludeFromPersistence,\n expiresIn: params().persistExpiresIn,\n })\n clearPersisted = persistence.clearPersisted\n }\n })\n\n // Auto-submit countdown (v4.2.0)\n createEffect(() => {\n const delay = params().autoSubmitDelay\n if (!delay || !allRequiredPrefilled() || userInteracted()) return\n\n let remaining = Math.ceil(delay / 1000)\n setCountdown(remaining)\n\n countdownTimer = setInterval(() => {\n remaining--\n if (remaining <= 0) {\n cancelCountdown()\n // Trigger submit programmatically\n const form = document.querySelector(`#form-${props.component.id}`) as HTMLFormElement | null\n if (form) form.requestSubmit()\n } else {\n setCountdown(remaining)\n }\n }, 1000)\n })\n\n const handleFieldChange = (name: string, value: any) => {\n handleUserInteraction()\n setFormData((prev) => ({ ...prev, [name]: value }))\n // Clear error on change\n if (errors()[name]) {\n setErrors((prev) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [name]: _removed, ...rest } = prev\n return rest\n })\n }\n }\n\n const handleSubmit = async (e: Event) => {\n e.preventDefault()\n setIsSubmitting(true)\n setErrors({})\n\n // Get only visible fields for validation and submission\n const visibleFields = getVisibleFields()\n const visibleFieldNames = new Set(visibleFields.map((f) => f.name))\n\n // Filter form data to only include visible fields\n const visibleFormData: Record<string, any> = {}\n for (const [key, value] of Object.entries(formData())) {\n if (visibleFieldNames.has(key)) {\n visibleFormData[key] = value\n }\n }\n\n // Validate only visible fields\n const validationResult = validateFormData(visibleFormData, visibleFields, validationMessages())\n if (!validationResult.valid) {\n setErrors(validationResult.errors)\n setIsSubmitting(false)\n props.onError?.(validationResult.errors)\n return\n }\n\n // Submit via tool call if specified\n if (params().submitAction?.toolName) {\n try {\n const result = await execute(params().submitAction!.toolName, {\n ...params().submitAction!.params,\n formData: visibleFormData,\n })\n if (!result.success) {\n setErrors({ _form: result.error || strings.formSubmissionFailed })\n setIsSubmitting(false)\n props.onError?.({ _form: result.error || strings.formSubmissionFailed })\n return\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : strings.formSubmissionFailed\n setErrors({ _form: errorMessage })\n setIsSubmitting(false)\n props.onError?.({ _form: errorMessage })\n return\n }\n }\n\n // Clear persisted data on successful submit\n if (clearPersisted) {\n clearPersisted()\n }\n\n // Telemetry: action:dispatched on successful submit (B.5 — v5.6.0).\n // Privacy: only the action name (toolName or 'submit'), NO form values.\n if (telemetry) {\n telemetry.dispatch({\n type: 'action:dispatched',\n id: props.component.id,\n componentType: 'form',\n actionName: params().submitAction?.toolName ?? 'submit',\n ts: Date.now(),\n })\n }\n\n props.onSubmit?.(visibleFormData)\n setIsSubmitting(false)\n }\n\n const layoutClass = () => {\n switch (params().layout) {\n case 'horizontal':\n return 'grid grid-cols-2 gap-4'\n case 'inline':\n return 'flex flex-wrap gap-4 items-end'\n default:\n return 'space-y-4'\n }\n }\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <Show when={params().title}>\n <h3 class=\"text-lg font-semibold text-gray-900 dark:text-white mb-4\">\n {params().title}\n </h3>\n </Show>\n\n <form id={`form-${props.component.id}`} onSubmit={handleSubmit} noValidate>\n {/* Proposal 3: prefill summary */}\n <Show when={params().fields.some((f) => f.prefill != null)}>\n {(() => {\n const prefilled = params().fields.filter((f) => f.prefill != null).length\n const total = params().fields.length\n return (\n <p class=\"text-xs text-gray-500 dark:text-gray-400 mb-3\">\n {formatMCPUIString(\n prefilled === 1 ? strings.formPrefilledOne : strings.formPrefilledMany,\n { count: prefilled, total }\n )}\n </p>\n )\n })()}\n </Show>\n <div class={layoutClass()}>\n <For each={params().fields}>\n {(field) => (\n <FormFieldRenderer\n field={field}\n value={formData()[field.name]}\n error={errors()[field.name]}\n onChange={(value) => handleFieldChange(field.name, value)}\n disabled={isSubmitting() || field.disabled}\n formData={formData}\n />\n )}\n </For>\n </div>\n\n <Show when={errors()._form}>\n <div class=\"mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md\">\n <p class=\"text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n {errors()._form}\n </p>\n </div>\n </Show>\n\n {/* Auto-submit countdown (v4.2.0) */}\n <Show when={countdown() != null}>\n <div class=\"mt-4 flex items-center gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md\">\n <span class=\"text-sm text-blue-700 dark:text-blue-300\">\n {formatMCPUIString(strings.formSubmitCountdown, {\n label: params().submitLabel || strings.submit,\n seconds: countdown()!,\n })}\n </span>\n <button\n type=\"button\"\n onClick={() => { cancelCountdown(); setUserInteracted(true) }}\n class=\"text-sm text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-200\"\n >\n {strings.cancel}\n </button>\n </div>\n </Show>\n\n <div class=\"flex gap-2 pt-4 mt-4 border-t border-gray-200 dark:border-gray-700\">\n <button\n type=\"submit\"\n disabled={isSubmitting()}\n class=\"px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isSubmitting() ? (\n <span class=\"flex items-center gap-2\">\n <span class=\"animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full\" />\n {strings.formSubmitting}\n </span>\n ) : (\n params().submitLabel || strings.submit\n )}\n </button>\n <Show when={params().showReset}>\n <button\n type=\"button\"\n onClick={() => initializeForm(true)}\n disabled={isSubmitting()}\n class=\"px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {strings.formReset}\n </button>\n </Show>\n </div>\n </form>\n </div>\n )\n}\n"],"names":["getFieldDefault","type","undefined","FormRenderer","props","strings","useMCPUIStrings","validationMessages","required","fieldRequired","mustBeChecked","fieldMustBeChecked","minLength","fieldMinLength","maxLength","fieldMaxLength","invalidPattern","fieldInvalidPattern","invalidEmail","fieldInvalidEmail","invalidNumber","fieldInvalidNumber","minValue","fieldMinValue","maxValue","fieldMaxValue","minDate","fieldMinDate","maxDate","fieldMaxDate","invalidOption","fieldInvalidOption","invalidFormat","fieldInvalidFormat","params","component","formData","setFormData","createSignal","errors","setErrors","isSubmitting","setIsSubmitting","execute","useAction","telemetry","useTelemetry","clearPersisted","getVisibleFields","fields","filter","field","showWhen","evaluateCondition","countdown","setCountdown","countdownTimer","userInteracted","setUserInteracted","cancelCountdown","clearInterval","handleUserInteraction","onCleanup","allRequiredPrefilled","f","every","prefill","initializeForm","clearStorage","initial","name","defaultValue","onMount","createEffect","persistKey","persistence","useFormPersistence","excludeFields","excludeFromPersistence","expiresIn","persistExpiresIn","delay","autoSubmitDelay","remaining","Math","ceil","setInterval","form","document","querySelector","id","requestSubmit","handleFieldChange","value","prev","_removed","rest","handleSubmit","e","preventDefault","visibleFields","visibleFieldNames","Set","map","visibleFormData","key","Object","entries","has","validationResult","validateFormData","valid","onError","submitAction","toolName","result","success","_form","error","formSubmissionFailed","errorMessage","Error","message","dispatch","componentType","actionName","ts","Date","now","onSubmit","layoutClass","layout","_el$","_$getNextElement","_tmpl$5","_el$19","firstChild","_el$20","_co$5","_$getNextMarker","nextSibling","_el$3","_el$13","_el$14","_co$2","_el$4","_el$15","_el$16","_co$3","_el$17","_el$18","_co$4","_el$0","_el$1","_el$11","_el$12","_co$","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","addEventListener","some","prefilled","length","total","_el$21","_tmpl$6","formatMCPUIString","formPrefilledOne","formPrefilledMany","count","For","each","FormFieldRenderer","onChange","disabled","_el$5","_tmpl$2","_el$6","_el$7","_tmpl$3","_el$8","_el$9","formSubmitCountdown","label","submitLabel","submit","seconds","$$click","cancel","_$runHydrationEvents","_c$","_$memo","_el$22","_tmpl$7","_el$23","_el$24","_el$25","_co$6","formSubmitting","showReset","_el$10","_tmpl$4","formReset","_$effect","_$setProperty","_p$","_v$","_v$2","_v$3","_$setAttribute","t","_$className","a","_$delegateEvents"],"mappings":"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"}
@@ -4,39 +4,44 @@ const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
5
  const logger$1 = require("../utils/logger.cjs");
6
6
  const MCPUITelemetryContext = require("../context/MCPUITelemetryContext.cjs");
7
- var _tmpl$ = /* @__PURE__ */ web.template(`<p class="text-xs text-yellow-600 dark:text-yellow-400 mt-2 font-mono">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button class="mt-3 text-xs font-medium text-yellow-800 dark:text-yellow-200 hover:text-yellow-900 dark:hover:text-yellow-100 underline">Retry Rendering`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="w-full h-full bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4"><div class="flex items-start gap-3"><div class=flex-shrink-0><svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><div class="flex-1 min-w-0"><p class="text-sm font-medium text-yellow-900 dark:text-yellow-100">Component Failed to Render</p><p class="text-xs text-yellow-700 dark:text-yellow-300 mt-1">Type: <!$><!/> | ID: <!$><!/>...</p><!$><!/><!$><!/>`);
7
+ const MCPUIStringsContext = require("../context/MCPUIStringsContext.cjs");
8
+ const formatString = require("../utils/format-string.cjs");
9
+ var _tmpl$ = /* @__PURE__ */ web.template(`<p class="text-xs text-yellow-600 dark:text-yellow-400 mt-2 font-mono">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button class="mt-3 text-xs font-medium text-yellow-800 dark:text-yellow-200 hover:text-yellow-900 dark:hover:text-yellow-100 underline">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="w-full h-full bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4"><div class="flex items-start gap-3"><div class=flex-shrink-0><svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><div class="flex-1 min-w-0"><p class="text-sm font-medium text-yellow-900 dark:text-yellow-100"></p><p class="text-xs text-yellow-700 dark:text-yellow-300 mt-1"></p><!$><!/><!$><!/>`);
8
10
  const logger = logger$1.createLogger("generative-ui");
9
11
  function DefaultErrorFallback(props) {
12
+ const strings = MCPUIStringsContext.useMCPUIStrings();
10
13
  return (() => {
11
- var _el$ = web.getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling, _el$7 = _el$6.firstChild, _el$0 = _el$7.nextSibling, [_el$1, _co$] = web.getNextMarker(_el$0.nextSibling), _el$8 = _el$1.nextSibling, _el$10 = _el$8.nextSibling, [_el$11, _co$2] = web.getNextMarker(_el$10.nextSibling);
12
- _el$11.nextSibling;
13
- var _el$14 = _el$6.nextSibling, [_el$15, _co$3] = web.getNextMarker(_el$14.nextSibling), _el$16 = _el$15.nextSibling, [_el$17, _co$4] = web.getNextMarker(_el$16.nextSibling);
14
- web.insert(_el$6, () => props.componentType || "unknown", _el$1, _co$);
14
+ var _el$ = web.getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling, _el$9 = _el$6.nextSibling, [_el$0, _co$] = web.getNextMarker(_el$9.nextSibling), _el$1 = _el$0.nextSibling, [_el$10, _co$2] = web.getNextMarker(_el$1.nextSibling);
15
+ web.insert(_el$5, () => strings.errorBoundaryTitle);
15
16
  web.insert(_el$6, () => {
16
17
  var _a;
17
- return ((_a = props.componentId) == null ? void 0 : _a.slice(0, 8)) || "unknown";
18
- }, _el$11, _co$2);
18
+ return formatString.formatMCPUIString(strings.errorBoundaryMeta, {
19
+ type: props.componentType || strings.unknown,
20
+ id: ((_a = props.componentId) == null ? void 0 : _a.slice(0, 8)) || strings.unknown
21
+ });
22
+ });
19
23
  web.insert(_el$4, web.createComponent(solidJs.Show, {
20
24
  get when() {
21
25
  return false;
22
26
  },
23
27
  get children() {
24
- var _el$12 = web.getNextElement(_tmpl$);
25
- web.insert(_el$12, () => props.error.message);
26
- return _el$12;
28
+ var _el$7 = web.getNextElement(_tmpl$);
29
+ web.insert(_el$7, () => props.error.message);
30
+ return _el$7;
27
31
  }
28
- }), _el$15, _co$3);
32
+ }), _el$0, _co$);
29
33
  web.insert(_el$4, web.createComponent(solidJs.Show, {
30
34
  get when() {
31
35
  return props.allowRetry;
32
36
  },
33
37
  get children() {
34
- var _el$13 = web.getNextElement(_tmpl$2);
35
- web.addEventListener(_el$13, "click", props.onRetry, true);
38
+ var _el$8 = web.getNextElement(_tmpl$2);
39
+ web.addEventListener(_el$8, "click", props.onRetry, true);
40
+ web.insert(_el$8, () => strings.errorBoundaryRetry);
36
41
  web.runHydrationEvents();
37
- return _el$13;
42
+ return _el$8;
38
43
  }
39
- }), _el$17, _co$4);
44
+ }), _el$10, _co$2);
40
45
  return _el$;
41
46
  })();
42
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GenerativeUIErrorBoundary.cjs","sources":["../../src/components/GenerativeUIErrorBoundary.tsx"],"sourcesContent":["/**\n * Generative UI Error Boundary with Telemetry\n * Phase 0: Error isolation + structured logging\n *\n * Features:\n * - Component-level error isolation\n * - Structured logging with context\n * - Performance timing\n * - Retry mechanism\n * - User-friendly fallback UI\n */\n\nimport { Component, ErrorBoundary, createSignal, Show, onMount } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { createLogger } from '../utils/logger'\nimport type { RendererError, ComponentType } from '../types'\nimport { useTelemetry } from '../context/MCPUITelemetryContext'\n\nconst logger = createLogger('generative-ui')\n\n/**\n * Props for GenerativeUIErrorBoundary\n */\nexport interface GenerativeUIErrorBoundaryProps {\n /**\n * Component identifier for telemetry\n */\n componentId: string\n\n /**\n * Component type for context\n */\n componentType: string\n\n /**\n * Error callback\n */\n onError?: (error: RendererError) => void\n\n /**\n * Allow retry on error\n */\n allowRetry?: boolean\n\n /**\n * Child components to wrap\n */\n children: any\n\n /**\n * Custom fallback UI (optional)\n */\n fallback?: (error: Error, retry?: () => void) => any\n}\n\n/**\n * Default fallback UI for errors\n */\nfunction DefaultErrorFallback(props: {\n error: Error\n componentId: string\n componentType: string\n allowRetry?: boolean\n onRetry?: () => void\n}) {\n return (\n <div class=\"w-full h-full bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4\">\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-shrink-0\">\n <svg\n class=\"w-5 h-5 text-yellow-600 dark:text-yellow-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-sm font-medium text-yellow-900 dark:text-yellow-100\">\n Component Failed to Render\n </p>\n <p class=\"text-xs text-yellow-700 dark:text-yellow-300 mt-1\">\n Type: {props.componentType || 'unknown'} | ID: {props.componentId?.slice(0, 8) || 'unknown'}...\n </p>\n <Show when={import.meta.env.DEV}>\n <p class=\"text-xs text-yellow-600 dark:text-yellow-400 mt-2 font-mono\">\n {props.error.message}\n </p>\n </Show>\n <Show when={props.allowRetry}>\n <button\n onClick={props.onRetry}\n class=\"mt-3 text-xs font-medium text-yellow-800 dark:text-yellow-200 hover:text-yellow-900 dark:hover:text-yellow-100 underline\"\n >\n Retry Rendering\n </button>\n </Show>\n </div>\n </div>\n </div>\n )\n}\n\n/**\n * Generative UI Error Boundary Component\n */\nexport const GenerativeUIErrorBoundary: Component<GenerativeUIErrorBoundaryProps> = (props) => {\n const [retryKey, setRetryKey] = createSignal(0)\n const [renderStartTime, setRenderStartTime] = createSignal(0)\n // Telemetry sink (B.5 — v5.6.0). Null when no Provider is mounted.\n const telemetry = useTelemetry()\n\n // SSR-safe: Initialize performance timing on client only\n onMount(() => {\n if (typeof performance !== 'undefined') {\n setRenderStartTime(performance.now())\n }\n })\n\n // Handle error with telemetry\n const handleError = (error: Error) => {\n // SSR-safe: Calculate render duration\n const renderDuration = !isServer && typeof performance !== 'undefined'\n ? performance.now() - renderStartTime()\n : 0\n\n // SSR-safe: Get client-only context\n const userAgent = !isServer && typeof navigator !== 'undefined'\n ? navigator.userAgent\n : 'server'\n const viewport = !isServer && typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 }\n\n // Structure error context\n const errorContext = {\n componentId: props.componentId,\n componentType: props.componentType,\n errorMessage: error.message,\n errorStack: error.stack,\n renderDuration,\n retryCount: retryKey(),\n timestamp: new Date().toISOString(),\n userAgent,\n viewport,\n }\n\n // Log to structured logger\n logger.error(`Component render failed: ${props.componentType}`, errorContext)\n\n // Call error callback\n props.onError?.({\n type: 'render',\n message: error.message,\n componentId: props.componentId,\n details: errorContext,\n })\n\n // Dispatch render:error to telemetry sink (B.5 — v5.6.0). Only the\n // message (capped semantically by the consumer if desired) — NO stack\n // trace, NO component payload, per privacy hard rule (§M.6.2).\n if (telemetry) {\n telemetry.dispatch({\n type: 'render:error',\n id: props.componentId,\n componentType: props.componentType as ComponentType,\n errorMessage: error.message,\n ts: Date.now(),\n })\n }\n\n // In production, send to monitoring service\n if (import.meta.env.PROD) {\n // Future: Send to Sentry or other APM\n // Sentry.captureException(error, { contexts: { component: errorContext } })\n }\n }\n\n // Retry mechanism\n const handleRetry = () => {\n const newRetryCount = retryKey() + 1\n logger.info(`Retrying component render: ${props.componentType}`, {\n componentId: props.componentId,\n retryCount: newRetryCount,\n })\n setRetryKey(newRetryCount)\n }\n\n return (\n <ErrorBoundary\n fallback={(error) => {\n handleError(error)\n\n // Use custom fallback if provided\n if (props.fallback) {\n return props.fallback(error, props.allowRetry ? handleRetry : undefined)\n }\n\n // Default fallback\n return (\n <DefaultErrorFallback\n error={error}\n componentId={props.componentId}\n componentType={props.componentType}\n allowRetry={props.allowRetry}\n onRetry={handleRetry}\n />\n )\n }}\n >\n {/* Key prop for forcing remount on retry */}\n {(() => {\n void retryKey() // Access signal to track changes\n return <>{props.children}</>\n })()}\n </ErrorBoundary>\n )\n}\n\n/**\n * Performance monitoring wrapper\n * Logs render times for performance analysis\n */\nexport function withPerformanceMonitoring<P extends { componentId: string; componentType: string }>(\n WrappedComponent: Component<P>\n) {\n return (props: P) => {\n const [renderStart, setRenderStart] = createSignal(0)\n\n // Log render start\n logger.debug(`Component render start: ${props.componentType}`, {\n componentId: props.componentId,\n timestamp: new Date().toISOString(),\n })\n\n // SSR-safe: Measure on mount completion (client-side only)\n onMount(() => {\n if (typeof performance !== 'undefined') {\n setRenderStart(performance.now())\n\n requestAnimationFrame(() => {\n const renderEnd = performance.now()\n const duration = renderEnd - renderStart()\n\n logger.info(`Component rendered: ${props.componentType}`, {\n componentId: props.componentId,\n renderDuration: duration,\n timestamp: new Date().toISOString(),\n })\n\n // Warn if render is slow (>50ms target)\n if (duration > 50) {\n logger.warn(`Slow component render: ${props.componentType}`, {\n componentId: props.componentId,\n renderDuration: duration,\n threshold: 50,\n })\n }\n })\n }\n })\n\n return <WrappedComponent {...props} />\n }\n}\n\n/**\n * Hook to track component lifecycle events\n */\nexport function useComponentTelemetry(componentId: string, componentType: string) {\n const [mountTime, setMountTime] = createSignal(0)\n\n // SSR-safe: Initialize mount time on client only\n onMount(() => {\n if (typeof performance !== 'undefined') {\n setMountTime(performance.now())\n }\n\n // Log mount\n logger.debug(`Component mounted: ${componentType}`, {\n componentId,\n timestamp: new Date().toISOString(),\n })\n })\n\n // Return cleanup function for unmount\n return () => {\n const lifetime = !isServer && typeof performance !== 'undefined'\n ? performance.now() - mountTime()\n : 0\n logger.debug(`Component unmounted: ${componentType}`, {\n componentId,\n lifetime,\n timestamp: new Date().toISOString(),\n })\n }\n}\n"],"names":["logger","createLogger","DefaultErrorFallback","props","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$7","_el$0","_el$1","_co$","_$getNextMarker","_el$8","_el$10","_el$11","_co$2","_el$14","_el$15","_co$3","_el$16","_el$17","_co$4","_$insert","componentType","componentId","slice","_$createComponent","Show","when","import","children","_el$12","_tmpl$","error","message","allowRetry","_el$13","_tmpl$2","_$addEventListener","onRetry","_$runHydrationEvents","GenerativeUIErrorBoundary","retryKey","setRetryKey","createSignal","renderStartTime","setRenderStartTime","telemetry","useTelemetry","onMount","performance","now","handleError","renderDuration","isServer","userAgent","navigator","viewport","window","width","innerWidth","height","innerHeight","errorContext","errorMessage","errorStack","stack","retryCount","timestamp","Date","toISOString","onError","type","details","dispatch","id","ts","handleRetry","newRetryCount","info","ErrorBoundary","fallback","undefined","_$memo","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"GenerativeUIErrorBoundary.cjs","sources":["../../src/components/GenerativeUIErrorBoundary.tsx"],"sourcesContent":["/**\n * Generative UI Error Boundary with Telemetry\n * Phase 0: Error isolation + structured logging\n *\n * Features:\n * - Component-level error isolation\n * - Structured logging with context\n * - Performance timing\n * - Retry mechanism\n * - User-friendly fallback UI\n */\n\nimport { Component, ErrorBoundary, createSignal, Show, onMount } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { createLogger } from '../utils/logger'\nimport type { RendererError, ComponentType } from '../types'\nimport { useTelemetry } from '../context/MCPUITelemetryContext'\nimport { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nconst logger = createLogger('generative-ui')\n\n/**\n * Props for GenerativeUIErrorBoundary\n */\nexport interface GenerativeUIErrorBoundaryProps {\n /**\n * Component identifier for telemetry\n */\n componentId: string\n\n /**\n * Component type for context\n */\n componentType: string\n\n /**\n * Error callback\n */\n onError?: (error: RendererError) => void\n\n /**\n * Allow retry on error\n */\n allowRetry?: boolean\n\n /**\n * Child components to wrap\n */\n children: any\n\n /**\n * Custom fallback UI (optional)\n */\n fallback?: (error: Error, retry?: () => void) => any\n}\n\n/**\n * Default fallback UI for errors\n */\nfunction DefaultErrorFallback(props: {\n error: Error\n componentId: string\n componentType: string\n allowRetry?: boolean\n onRetry?: () => void\n}) {\n const strings = useMCPUIStrings()\n return (\n <div class=\"w-full h-full bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4\">\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-shrink-0\">\n <svg\n class=\"w-5 h-5 text-yellow-600 dark:text-yellow-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-sm font-medium text-yellow-900 dark:text-yellow-100\">\n {strings.errorBoundaryTitle}\n </p>\n <p class=\"text-xs text-yellow-700 dark:text-yellow-300 mt-1\">\n {formatMCPUIString(strings.errorBoundaryMeta, {\n type: props.componentType || strings.unknown,\n id: props.componentId?.slice(0, 8) || strings.unknown,\n })}\n </p>\n <Show when={import.meta.env.DEV}>\n <p class=\"text-xs text-yellow-600 dark:text-yellow-400 mt-2 font-mono\">\n {props.error.message}\n </p>\n </Show>\n <Show when={props.allowRetry}>\n <button\n onClick={props.onRetry}\n class=\"mt-3 text-xs font-medium text-yellow-800 dark:text-yellow-200 hover:text-yellow-900 dark:hover:text-yellow-100 underline\"\n >\n {strings.errorBoundaryRetry}\n </button>\n </Show>\n </div>\n </div>\n </div>\n )\n}\n\n/**\n * Generative UI Error Boundary Component\n */\nexport const GenerativeUIErrorBoundary: Component<GenerativeUIErrorBoundaryProps> = (props) => {\n const [retryKey, setRetryKey] = createSignal(0)\n const [renderStartTime, setRenderStartTime] = createSignal(0)\n // Telemetry sink (B.5 — v5.6.0). Null when no Provider is mounted.\n const telemetry = useTelemetry()\n\n // SSR-safe: Initialize performance timing on client only\n onMount(() => {\n if (typeof performance !== 'undefined') {\n setRenderStartTime(performance.now())\n }\n })\n\n // Handle error with telemetry\n const handleError = (error: Error) => {\n // SSR-safe: Calculate render duration\n const renderDuration = !isServer && typeof performance !== 'undefined'\n ? performance.now() - renderStartTime()\n : 0\n\n // SSR-safe: Get client-only context\n const userAgent = !isServer && typeof navigator !== 'undefined'\n ? navigator.userAgent\n : 'server'\n const viewport = !isServer && typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 }\n\n // Structure error context\n const errorContext = {\n componentId: props.componentId,\n componentType: props.componentType,\n errorMessage: error.message,\n errorStack: error.stack,\n renderDuration,\n retryCount: retryKey(),\n timestamp: new Date().toISOString(),\n userAgent,\n viewport,\n }\n\n // Log to structured logger\n logger.error(`Component render failed: ${props.componentType}`, errorContext)\n\n // Call error callback\n props.onError?.({\n type: 'render',\n message: error.message,\n componentId: props.componentId,\n details: errorContext,\n })\n\n // Dispatch render:error to telemetry sink (B.5 — v5.6.0). Only the\n // message (capped semantically by the consumer if desired) — NO stack\n // trace, NO component payload, per privacy hard rule (§M.6.2).\n if (telemetry) {\n telemetry.dispatch({\n type: 'render:error',\n id: props.componentId,\n componentType: props.componentType as ComponentType,\n errorMessage: error.message,\n ts: Date.now(),\n })\n }\n\n // In production, send to monitoring service\n if (import.meta.env.PROD) {\n // Future: Send to Sentry or other APM\n // Sentry.captureException(error, { contexts: { component: errorContext } })\n }\n }\n\n // Retry mechanism\n const handleRetry = () => {\n const newRetryCount = retryKey() + 1\n logger.info(`Retrying component render: ${props.componentType}`, {\n componentId: props.componentId,\n retryCount: newRetryCount,\n })\n setRetryKey(newRetryCount)\n }\n\n return (\n <ErrorBoundary\n fallback={(error) => {\n handleError(error)\n\n // Use custom fallback if provided\n if (props.fallback) {\n return props.fallback(error, props.allowRetry ? handleRetry : undefined)\n }\n\n // Default fallback\n return (\n <DefaultErrorFallback\n error={error}\n componentId={props.componentId}\n componentType={props.componentType}\n allowRetry={props.allowRetry}\n onRetry={handleRetry}\n />\n )\n }}\n >\n {/* Key prop for forcing remount on retry */}\n {(() => {\n void retryKey() // Access signal to track changes\n return <>{props.children}</>\n })()}\n </ErrorBoundary>\n )\n}\n\n/**\n * Performance monitoring wrapper\n * Logs render times for performance analysis\n */\nexport function withPerformanceMonitoring<P extends { componentId: string; componentType: string }>(\n WrappedComponent: Component<P>\n) {\n return (props: P) => {\n const [renderStart, setRenderStart] = createSignal(0)\n\n // Log render start\n logger.debug(`Component render start: ${props.componentType}`, {\n componentId: props.componentId,\n timestamp: new Date().toISOString(),\n })\n\n // SSR-safe: Measure on mount completion (client-side only)\n onMount(() => {\n if (typeof performance !== 'undefined') {\n setRenderStart(performance.now())\n\n requestAnimationFrame(() => {\n const renderEnd = performance.now()\n const duration = renderEnd - renderStart()\n\n logger.info(`Component rendered: ${props.componentType}`, {\n componentId: props.componentId,\n renderDuration: duration,\n timestamp: new Date().toISOString(),\n })\n\n // Warn if render is slow (>50ms target)\n if (duration > 50) {\n logger.warn(`Slow component render: ${props.componentType}`, {\n componentId: props.componentId,\n renderDuration: duration,\n threshold: 50,\n })\n }\n })\n }\n })\n\n return <WrappedComponent {...props} />\n }\n}\n\n/**\n * Hook to track component lifecycle events\n */\nexport function useComponentTelemetry(componentId: string, componentType: string) {\n const [mountTime, setMountTime] = createSignal(0)\n\n // SSR-safe: Initialize mount time on client only\n onMount(() => {\n if (typeof performance !== 'undefined') {\n setMountTime(performance.now())\n }\n\n // Log mount\n logger.debug(`Component mounted: ${componentType}`, {\n componentId,\n timestamp: new Date().toISOString(),\n })\n })\n\n // Return cleanup function for unmount\n return () => {\n const lifetime = !isServer && typeof performance !== 'undefined'\n ? performance.now() - mountTime()\n : 0\n logger.debug(`Component unmounted: ${componentType}`, {\n componentId,\n lifetime,\n timestamp: new Date().toISOString(),\n })\n }\n}\n"],"names":["logger","createLogger","DefaultErrorFallback","props","strings","useMCPUIStrings","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$9","_el$0","_co$","_$getNextMarker","_el$1","_el$10","_co$2","_$insert","errorBoundaryTitle","formatMCPUIString","errorBoundaryMeta","type","componentType","unknown","id","componentId","slice","_$createComponent","Show","when","import","children","_el$7","_tmpl$","error","message","allowRetry","_el$8","_tmpl$2","_$addEventListener","onRetry","errorBoundaryRetry","_$runHydrationEvents","GenerativeUIErrorBoundary","retryKey","setRetryKey","createSignal","renderStartTime","setRenderStartTime","telemetry","useTelemetry","onMount","performance","now","handleError","renderDuration","isServer","userAgent","navigator","viewport","window","width","innerWidth","height","innerHeight","errorContext","errorMessage","errorStack","stack","retryCount","timestamp","Date","toISOString","onError","details","dispatch","ts","handleRetry","newRetryCount","info","ErrorBoundary","fallback","undefined","_$memo","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"GenerativeUIErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/components/GenerativeUIErrorBoundary.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAA8C,MAAM,UAAU,CAAA;AAGhF,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAA;AAK5D;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAExC;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAA;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,IAAI,KAAK,GAAG,CAAA;CACrD;AAwDD;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,CAAC,8BAA8B,CA+G/E,CAAA;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAChG,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAC,IAEtB,OAAO,CAAC,oCAsCjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cA2B/E"}
1
+ {"version":3,"file":"GenerativeUIErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/components/GenerativeUIErrorBoundary.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAA8C,MAAM,UAAU,CAAA;AAGhF,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAA;AAM5D;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAExC;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAA;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,IAAI,KAAK,GAAG,CAAA;CACrD;AA4DD;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,CAAC,8BAA8B,CA+G/E,CAAA;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAChG,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAC,IAEtB,OAAO,CAAC,oCAsCjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cA2B/E"}