@seed-ship/mcp-ui-solid 6.19.1 → 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.
- package/CHANGELOG.md +519 -0
- package/README.md +791 -1
- package/dist/adapters/connector.cjs +15 -4
- package/dist/adapters/connector.cjs.map +1 -1
- package/dist/adapters/connector.d.ts +38 -0
- package/dist/adapters/connector.d.ts.map +1 -1
- package/dist/adapters/connector.js +15 -4
- package/dist/adapters/connector.js.map +1 -1
- package/dist/adapters/index.d.ts +4 -3
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/macro-run.cjs +25 -13
- package/dist/adapters/macro-run.cjs.map +1 -1
- package/dist/adapters/macro-run.d.ts +37 -2
- package/dist/adapters/macro-run.d.ts.map +1 -1
- package/dist/adapters/macro-run.js +25 -13
- package/dist/adapters/macro-run.js.map +1 -1
- package/dist/adapters.cjs +2 -0
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.js +4 -2
- package/dist/components/ActionGroupRenderer.cjs +3 -1
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
- package/dist/components/ActionGroupRenderer.js +3 -1
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/AgentCard.cjs +11 -8
- package/dist/components/AgentCard.cjs.map +1 -1
- package/dist/components/AgentCard.d.ts.map +1 -1
- package/dist/components/AgentCard.js +11 -8
- package/dist/components/AgentCard.js.map +1 -1
- package/dist/components/AgentHandoff.cjs +6 -1
- package/dist/components/AgentHandoff.cjs.map +1 -1
- package/dist/components/AgentHandoff.d.ts.map +1 -1
- package/dist/components/AgentHandoff.js +6 -1
- package/dist/components/AgentHandoff.js.map +1 -1
- package/dist/components/ArtifactRenderer.cjs +25 -6
- package/dist/components/ArtifactRenderer.cjs.map +1 -1
- package/dist/components/ArtifactRenderer.d.ts.map +1 -1
- package/dist/components/ArtifactRenderer.js +25 -6
- package/dist/components/ArtifactRenderer.js.map +1 -1
- package/dist/components/AutocompleteDropdown.cjs +30 -24
- package/dist/components/AutocompleteDropdown.cjs.map +1 -1
- package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
- package/dist/components/AutocompleteDropdown.js +30 -24
- package/dist/components/AutocompleteDropdown.js.map +1 -1
- package/dist/components/AutocompleteFormField.cjs +3 -1
- package/dist/components/AutocompleteFormField.cjs.map +1 -1
- package/dist/components/AutocompleteFormField.d.ts.map +1 -1
- package/dist/components/AutocompleteFormField.js +4 -2
- package/dist/components/AutocompleteFormField.js.map +1 -1
- package/dist/components/BriefingDiff.cjs +45 -39
- package/dist/components/BriefingDiff.cjs.map +1 -1
- package/dist/components/BriefingDiff.d.ts.map +1 -1
- package/dist/components/BriefingDiff.js +45 -39
- package/dist/components/BriefingDiff.js.map +1 -1
- package/dist/components/CarouselRenderer.cjs +8 -2
- package/dist/components/CarouselRenderer.cjs.map +1 -1
- package/dist/components/CarouselRenderer.d.ts.map +1 -1
- package/dist/components/CarouselRenderer.js +8 -2
- package/dist/components/CarouselRenderer.js.map +1 -1
- package/dist/components/ChartJSRenderer.cjs +60 -36
- package/dist/components/ChartJSRenderer.cjs.map +1 -1
- package/dist/components/ChartJSRenderer.d.ts.map +1 -1
- package/dist/components/ChartJSRenderer.js +61 -37
- package/dist/components/ChartJSRenderer.js.map +1 -1
- package/dist/components/ChatPrompt.cjs +15 -9
- package/dist/components/ChatPrompt.cjs.map +1 -1
- package/dist/components/ChatPrompt.d.ts.map +1 -1
- package/dist/components/ChatPrompt.js +15 -9
- package/dist/components/ChatPrompt.js.map +1 -1
- package/dist/components/CodeBlockRenderer.cjs +34 -16
- package/dist/components/CodeBlockRenderer.cjs.map +1 -1
- package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/components/CodeBlockRenderer.js +34 -16
- package/dist/components/CodeBlockRenderer.js.map +1 -1
- package/dist/components/DataPreviewSection.cjs +91 -44
- package/dist/components/DataPreviewSection.cjs.map +1 -1
- package/dist/components/DataPreviewSection.d.ts.map +1 -1
- package/dist/components/DataPreviewSection.js +92 -45
- package/dist/components/DataPreviewSection.js.map +1 -1
- package/dist/components/DegradedFallback.cjs +20 -16
- package/dist/components/DegradedFallback.cjs.map +1 -1
- package/dist/components/DegradedFallback.d.ts.map +1 -1
- package/dist/components/DegradedFallback.js +20 -16
- package/dist/components/DegradedFallback.js.map +1 -1
- package/dist/components/FooterRenderer.cjs +21 -17
- package/dist/components/FooterRenderer.cjs.map +1 -1
- package/dist/components/FooterRenderer.d.ts.map +1 -1
- package/dist/components/FooterRenderer.js +21 -17
- package/dist/components/FooterRenderer.js.map +1 -1
- package/dist/components/FormFieldRenderer.cjs +116 -93
- package/dist/components/FormFieldRenderer.cjs.map +1 -1
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +116 -93
- package/dist/components/FormFieldRenderer.js.map +1 -1
- package/dist/components/FormRenderer.cjs +55 -31
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormRenderer.js +55 -31
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +20 -15
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/GraphRenderer.cjs +56 -33
- package/dist/components/GraphRenderer.cjs.map +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +56 -33
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/ImageGalleryRenderer.cjs +13 -4
- package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
- package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
- package/dist/components/ImageGalleryRenderer.js +13 -4
- package/dist/components/ImageGalleryRenderer.js.map +1 -1
- package/dist/components/LightboxOverlay.cjs +16 -8
- package/dist/components/LightboxOverlay.cjs.map +1 -1
- package/dist/components/LightboxOverlay.d.ts.map +1 -1
- package/dist/components/LightboxOverlay.js +17 -9
- package/dist/components/LightboxOverlay.js.map +1 -1
- package/dist/components/MapRenderer.cjs +59 -29
- package/dist/components/MapRenderer.cjs.map +1 -1
- package/dist/components/MapRenderer.d.ts +10 -2
- package/dist/components/MapRenderer.d.ts.map +1 -1
- package/dist/components/MapRenderer.js +60 -30
- package/dist/components/MapRenderer.js.map +1 -1
- package/dist/components/ModalRenderer.cjs +4 -1
- package/dist/components/ModalRenderer.cjs.map +1 -1
- package/dist/components/ModalRenderer.d.ts.map +1 -1
- package/dist/components/ModalRenderer.js +5 -2
- package/dist/components/ModalRenderer.js.map +1 -1
- package/dist/components/ScratchpadPanel.cjs +578 -535
- package/dist/components/ScratchpadPanel.cjs.map +1 -1
- package/dist/components/ScratchpadPanel.d.ts.map +1 -1
- package/dist/components/ScratchpadPanel.js +578 -535
- package/dist/components/ScratchpadPanel.js.map +1 -1
- package/dist/components/StreamingUIRenderer.cjs +92 -28
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +92 -28
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +456 -363
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts +21 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +458 -365
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/VerifiedText.cjs +39 -20
- package/dist/components/VerifiedText.cjs.map +1 -1
- package/dist/components/VerifiedText.d.ts +2 -1
- package/dist/components/VerifiedText.d.ts.map +1 -1
- package/dist/components/VerifiedText.js +39 -20
- package/dist/components/VerifiedText.js.map +1 -1
- package/dist/components/VideoRenderer.cjs +10 -5
- package/dist/components/VideoRenderer.cjs.map +1 -1
- package/dist/components/VideoRenderer.d.ts.map +1 -1
- package/dist/components/VideoRenderer.js +10 -5
- package/dist/components/VideoRenderer.js.map +1 -1
- package/dist/components/chart-data-table.cjs +38 -17
- package/dist/components/chart-data-table.cjs.map +1 -1
- package/dist/components/chart-data-table.d.ts +30 -1
- package/dist/components/chart-data-table.d.ts.map +1 -1
- package/dist/components/chart-data-table.js +38 -17
- package/dist/components/chart-data-table.js.map +1 -1
- package/dist/context/MCPActionContext.cjs +3 -1
- package/dist/context/MCPActionContext.cjs.map +1 -1
- package/dist/context/MCPActionContext.d.ts.map +1 -1
- package/dist/context/MCPActionContext.js +3 -1
- package/dist/context/MCPActionContext.js.map +1 -1
- package/dist/context/MCPUIStringsContext.cjs +285 -2
- package/dist/context/MCPUIStringsContext.cjs.map +1 -1
- package/dist/context/MCPUIStringsContext.d.ts +600 -3
- package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
- package/dist/context/MCPUIStringsContext.js +285 -2
- package/dist/context/MCPUIStringsContext.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.cjs +28 -10
- package/dist/hooks/useStreamingUI.cjs.map +1 -1
- package/dist/hooks/useStreamingUI.d.ts +37 -0
- package/dist/hooks/useStreamingUI.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.js +28 -10
- package/dist/hooks/useStreamingUI.js.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +2 -1
- package/dist/index.cjs +23 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/services/validation.cjs +41 -16
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts +47 -2
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +41 -16
- package/dist/services/validation.js.map +1 -1
- package/dist/utils/degraded-projections.cjs +37 -12
- package/dist/utils/degraded-projections.cjs.map +1 -1
- package/dist/utils/degraded-projections.d.ts +39 -3
- package/dist/utils/degraded-projections.d.ts.map +1 -1
- package/dist/utils/degraded-projections.js +37 -12
- package/dist/utils/degraded-projections.js.map +1 -1
- package/dist/utils/format-string.cjs +10 -0
- package/dist/utils/format-string.cjs.map +1 -0
- package/dist/utils/format-string.d.ts +26 -0
- package/dist/utils/format-string.d.ts.map +1 -0
- package/dist/utils/format-string.js +10 -0
- package/dist/utils/format-string.js.map +1 -0
- package/dist/validation.cjs +3 -0
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.cts +2 -1
- package/dist/validation.d.ts +2 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +4 -1
- package/package.json +1 -1
- package/src/adapters/connector.ts +58 -4
- package/src/adapters/index.ts +12 -2
- package/src/adapters/macro-run.ts +71 -11
- package/src/components/ActionGroupRenderer.tsx +3 -1
- package/src/components/AgentCard.tsx +27 -9
- package/src/components/AgentHandoff.tsx +4 -1
- package/src/components/ArtifactRenderer.tsx +17 -5
- package/src/components/AutocompleteDropdown.tsx +8 -6
- package/src/components/AutocompleteFormField.tsx +5 -1
- package/src/components/BriefingDiff.tsx +11 -3
- package/src/components/CarouselRenderer.tsx +4 -2
- package/src/components/ChartJSRenderer.tsx +18 -9
- package/src/components/ChatPrompt.tsx +13 -8
- package/src/components/CodeBlockRenderer.tsx +12 -10
- package/src/components/DataPreviewSection.tsx +92 -26
- package/src/components/DegradedFallback.tsx +4 -2
- package/src/components/FooterRenderer.tsx +3 -1
- package/src/components/FormFieldRenderer.tsx +34 -19
- package/src/components/FormRenderer.tsx +38 -10
- package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
- package/src/components/GraphRenderer.tsx +31 -16
- package/src/components/ImageGalleryRenderer.tsx +8 -4
- package/src/components/LightboxOverlay.tsx +6 -4
- package/src/components/MapRenderer.tsx +57 -20
- package/src/components/ModalRenderer.tsx +3 -1
- package/src/components/ScratchpadPanel.tsx +95 -44
- package/src/components/StreamingUIRenderer.tsx +41 -11
- package/src/components/UIResourceRenderer.tsx +145 -63
- package/src/components/VerifiedText.tsx +19 -9
- package/src/components/VideoRenderer.tsx +6 -4
- package/src/components/chart-data-table.ts +68 -14
- package/src/context/MCPActionContext.tsx +4 -1
- package/src/context/MCPUIStringsContext.tsx +1004 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useStreamingUI.ts +64 -10
- package/src/index.ts +23 -0
- package/src/services/validation.ts +93 -16
- package/src/utils/degraded-projections.ts +75 -12
- package/src/utils/format-string.ts +33 -0
- 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":";;;;;;;;;;;;;AA0BA,SAASA,gBAAgBC,MAAoC;AAC3D,UAAQA,MAAAA;AAAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAOC;AAAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAEO,MAAMC,eAA8CC,CAAAA,UAAU;AACnE,QAAMC,UAAUC,oBAAAA,gBAAAA;AAKhB,QAAMC,qBAAqBA,OAAO;AAAA,IAChCC,UAAUH,QAAQI;AAAAA,IAClBC,eAAeL,QAAQM;AAAAA,IACvBC,WAAWP,QAAQQ;AAAAA,IACnBC,WAAWT,QAAQU;AAAAA,IACnBC,gBAAgBX,QAAQY;AAAAA,IACxBC,cAAcb,QAAQc;AAAAA,IACtBC,eAAef,QAAQgB;AAAAA,IACvBC,UAAUjB,QAAQkB;AAAAA,IAClBC,UAAUnB,QAAQoB;AAAAA,IAClBC,SAASrB,QAAQsB;AAAAA,IACjBC,SAASvB,QAAQwB;AAAAA,IACjBC,eAAezB,QAAQ0B;AAAAA,IACvBC,eAAe3B,QAAQ4B;AAAAA,EAAAA;AAEzB,QAAMC,SAASA,MAAM9B,MAAM+B,UAAUD;AACrC,QAAM,CAACE,UAAUC,WAAW,IAAIC,QAAAA,aAAkC,CAAA,CAAE;AACpE,QAAM,CAACC,QAAQC,SAAS,IAAIF,QAAAA,aAAqC,CAAA,CAAE;AACnE,QAAM,CAACG,cAAcC,eAAe,IAAIJ,QAAAA,aAAa,KAAK;AAC1D,QAAM;AAAA,IAAEK;AAAAA,EAAAA,IAAYC,oBAAAA;AACpB,QAAMC,YAAYC,sBAAAA,aAAAA;AAGlB,MAAIC;AAKJ,QAAMC,mBAAmBA,MAAyB;AAChD,WAAOd,OAAAA,EAASe,OAAOC,OAAQC,CAAAA,UAAU;AACvC,UAAI,CAACA,MAAMC,SAAU,QAAO;AAC5B,aAAOC,sCAAkBF,MAAMC,UAAUhB,SAAAA,CAAU;AAAA,IACrD,CAAC;AAAA,EACH;AAGA,QAAM,CAACkB,WAAWC,YAAY,IAAIjB,QAAAA,aAA4B,IAAI;AAClE,MAAIkB,iBAAwD;AAC5D,QAAM,CAACC,gBAAgBC,iBAAiB,IAAIpB,QAAAA,aAAa,KAAK;AAE9D,QAAMqB,kBAAkBA,MAAM;AAC5B,QAAIH,gBAAgB;AAClBI,oBAAcJ,cAAc;AAC5BA,uBAAiB;AAAA,IACnB;AACAD,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAMM,wBAAwBA,MAAM;AAClC,QAAI,CAACJ,kBAAkB;AACrBC,wBAAkB,IAAI;AACtBC,sBAAAA;AAAAA,IACF;AAAA,EACF;AAEAG,UAAAA,UAAU,MAAMH,iBAAiB;AAKjC,QAAMI,uBAAuBA,MAAe;AAC1C,WAAO7B,OAAAA,EAASe,OACbC,OAAQc,CAAAA,MAAMA,EAAExD,QAAQ,EACxByD,MAAOD,CAAAA,MAAMA,EAAEE,WAAW,IAAI;AAAA,EACnC;AAGA,QAAMC,iBAAiBA,CAACC,eAAe,UAAU;AAC/C,UAAMC,UAA+B,CAAA;AACrC,eAAWlB,SAASjB,OAAAA,EAASe,QAAQ;AAEnCoB,cAAQlB,MAAMmB,IAAI,IAAInB,MAAMe,WAAWf,MAAMoB,gBAAgBvE,gBAAgBmD,MAAMlD,IAAI;AAAA,IACzF;AACAoC,gBAAYgC,OAAO;AACnB7B,cAAU,CAAA,CAAE;AAGZ,QAAI4B,gBAAgBrB,gBAAgB;AAClCA,qBAAAA;AAAAA,IACF;AAAA,EACF;AAGAyB,UAAAA,QAAQ,MAAM;AACZL,mBAAAA;AAAAA,EACF,CAAC;AAGDM,UAAAA,aAAa,MAAM;AACjB,UAAMC,aAAaxC,SAASwC;AAC5B,QAAIA,YAAY;AACd,YAAMC,cAAcC,mBAAAA,mBAAmB;AAAA,QACrCF;AAAAA,QACAtC;AAAAA,QACAC;AAAAA,QACAwC,eAAe3C,SAAS4C;AAAAA,QACxBC,WAAW7C,SAAS8C;AAAAA,MAAAA,CACrB;AACDjC,uBAAiB4B,YAAY5B;AAAAA,IAC/B;AAAA,EACF,CAAC;AAGD0B,UAAAA,aAAa,MAAM;AACjB,UAAMQ,QAAQ/C,SAASgD;AACvB,QAAI,CAACD,SAAS,CAAClB,qBAAAA,KAA0BN,iBAAkB;AAE3D,QAAI0B,YAAYC,KAAKC,KAAKJ,QAAQ,GAAI;AACtC1B,iBAAa4B,SAAS;AAEtB3B,qBAAiB8B,YAAY,MAAM;AACjCH;AACA,UAAIA,aAAa,GAAG;AAClBxB,wBAAAA;AAEA,cAAM4B,OAAOC,SAASC,cAAc,SAASrF,MAAM+B,UAAUuD,EAAE,EAAE;AACjE,YAAIH,WAAWI,cAAAA;AAAAA,MACjB,OAAO;AACLpC,qBAAa4B,SAAS;AAAA,MACxB;AAAA,IACF,GAAG,GAAI;AAAA,EACT,CAAC;AAED,QAAMS,oBAAoBA,CAACtB,MAAcuB,UAAe;AACtDhC,0BAAAA;AACAxB,gBAAayD,CAAAA,UAAU;AAAA,MAAE,GAAGA;AAAAA,MAAM,CAACxB,IAAI,GAAGuB;AAAAA,IAAAA,EAAQ;AAElD,QAAItD,OAAAA,EAAS+B,IAAI,GAAG;AAClB9B,gBAAWsD,CAAAA,SAAS;AAElB,cAAM;AAAA,UAAE,CAACxB,IAAI,GAAGyB;AAAAA,UAAU,GAAGC;AAAAA,QAAAA,IAASF;AACtC,eAAOE;AAAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAMC,eAAe,OAAOC,MAAa;;AACvCA,MAAEC,eAAAA;AACFzD,oBAAgB,IAAI;AACpBF,cAAU,CAAA,CAAE;AAGZ,UAAM4D,gBAAgBpD,iBAAAA;AACtB,UAAMqD,oBAAoB,IAAIC,IAAIF,cAAcG,IAAKvC,CAAAA,MAAMA,EAAEM,IAAI,CAAC;AAGlE,UAAMkC,kBAAuC,CAAA;AAC7C,eAAW,CAACC,KAAKZ,KAAK,KAAKa,OAAOC,QAAQvE,SAAAA,CAAU,GAAG;AACrD,UAAIiE,kBAAkBO,IAAIH,GAAG,GAAG;AAC9BD,wBAAgBC,GAAG,IAAIZ;AAAAA,MACzB;AAAA,IACF;AAGA,UAAMgB,mBAAmBC,WAAAA,iBAAiBN,iBAAiBJ,eAAe7F,oBAAoB;AAC9F,QAAI,CAACsG,iBAAiBE,OAAO;AAC3BvE,gBAAUqE,iBAAiBtE,MAAM;AACjCG,sBAAgB,KAAK;AACrBtC,kBAAM4G,YAAN5G,+BAAgByG,iBAAiBtE;AACjC;AAAA,IACF;AAGA,SAAIL,YAAAA,EAAS+E,iBAAT/E,mBAAuBgF,UAAU;AACnC,UAAI;AACF,cAAMC,SAAS,MAAMxE,QAAQT,OAAAA,EAAS+E,aAAcC,UAAU;AAAA,UAC5D,GAAGhF,OAAAA,EAAS+E,aAAc/E;AAAAA,UAC1BE,UAAUoE;AAAAA,QAAAA,CACX;AACD,YAAI,CAACW,OAAOC,SAAS;AACnB5E,oBAAU;AAAA,YAAE6E,OAAOF,OAAOG,SAASjH,QAAQkH;AAAAA,UAAAA,CAAsB;AACjE7E,0BAAgB,KAAK;AACrBtC,sBAAM4G,YAAN5G,+BAAgB;AAAA,YAAEiH,OAAOF,OAAOG,SAASjH,QAAQkH;AAAAA,UAAAA;AACjD;AAAA,QACF;AAAA,MACF,SAASD,OAAO;AACd,cAAME,eACJF,iBAAiBG,QAAQH,MAAMI,UAAUrH,QAAQkH;AACnD/E,kBAAU;AAAA,UAAE6E,OAAOG;AAAAA,QAAAA,CAAc;AACjC9E,wBAAgB,KAAK;AACrBtC,oBAAM4G,YAAN5G,+BAAgB;AAAA,UAAEiH,OAAOG;AAAAA,QAAAA;AACzB;AAAA,MACF;AAAA,IACF;AAGA,QAAIzE,gBAAgB;AAClBA,qBAAAA;AAAAA,IACF;AAIA,QAAIF,WAAW;AACbA,gBAAU8E,SAAS;AAAA,QACjB1H,MAAM;AAAA,QACNyF,IAAItF,MAAM+B,UAAUuD;AAAAA,QACpBkC,eAAe;AAAA,QACfC,cAAY3F,YAAAA,EAAS+E,iBAAT/E,mBAAuBgF,aAAY;AAAA,QAC/CY,IAAIC,KAAKC,IAAAA;AAAAA,MAAI,CACd;AAAA,IACH;AAEA5H,gBAAM6H,aAAN7H,+BAAiBoG;AACjB9D,oBAAgB,KAAK;AAAA,EACvB;AAEA,QAAMwF,cAAcA,MAAM;AACxB,YAAQhG,OAAAA,EAASiG,QAAAA;AAAAA,MACf,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IAAA;AAAA,EAEb;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,OAAA,GAAAC,SAAAH,KAAAI,YAAA,CAAAC,QAAAC,KAAA,IAAAC,IAAAA,cAAAJ,OAAAK,WAAA,GAAAC,QAAAJ,OAAAG,aAAAE,SAAAD,MAAAL,YAAA,CAAAO,QAAAC,KAAA,IAAAL,IAAAA,cAAAG,OAAAF,WAAA,GAAAK,QAAAF,OAAAH,aAAAM,SAAAD,MAAAL,aAAA,CAAAO,QAAAC,KAAA,IAAAT,IAAAA,cAAAO,OAAAN,WAAA,GAAAS,SAAAF,OAAAP,aAAA,CAAAU,QAAAC,KAAA,IAAAZ,IAAAA,cAAAU,OAAAT,WAAA,GAAAY,QAAAF,OAAAV,aAAAa,QAAAD,MAAAhB,YAAAkB,SAAAD,MAAAb,aAAA,CAAAe,QAAAC,IAAA,IAAAjB,IAAAA,cAAAe,OAAAd,WAAA;AAAAiB,eAAAzB,MAAA0B,IAAAA,gBAEKC,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE9H,SAAS+H;AAAAA,MAAK;AAAA,MAAA,IAAAC,WAAA;AAAA,YAAAC,QAAA9B,IAAAA,eAAA+B,MAAA;AAAAP,YAAAA,OAAAM,OAAA,MAErBjI,OAAAA,EAAS+H,KAAK;AAAA,eAAAE;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAA1B,QAAAC,KAAA;AAAAG,UAAAwB,iBAAA,UAI+BpE,YAAY;AAAA4D,eAAAhB,OAAAiB,IAAAA,gBAE3DC,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE9H,SAASe,OAAOqH,KAAMtG,CAAAA,MAAMA,EAAEE,WAAW,IAAI;AAAA,MAAC;AAAA,MAAA,IAAAgG,WAAA;AAAA,gBACtD,MAAM;AACN,gBAAMK,YAAYrI,SAASe,OAAOC,OAAQc,CAAAA,MAAMA,EAAEE,WAAW,IAAI,EAAEsG;AACnE,gBAAMC,QAAQvI,SAASe,OAAOuH;AAC9B,kBAAA,MAAA;AAAA,gBAAAE,SAAArC,IAAAA,eAAAsC,OAAA;AAAAd,uBAAAa,QAAA,MAEKE,aAAAA,kBACCL,cAAc,IAAIlK,QAAQwK,mBAAmBxK,QAAQyK,mBACrD;AAAA,cAAEC,OAAOR;AAAAA,cAAWE;AAAAA,YAAAA,CACtB,CAAC;AAAA,mBAAAC;AAAAA,UAAA,GAAA;AAAA,QAGP,GAAA;AAAA,MAAI;AAAA,IAAA,CAAA,GAAA3B,QAAAC,KAAA;AAAAa,eAAAZ,OAAAa,IAAAA,gBAGHkB,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE/I,SAASe;AAAAA,MAAM;AAAA,MAAAiH,UACtB/G,CAAAA,UAAK2G,IAAAA,gBACJoB,qCAAiB;AAAA,QAChB/H;AAAAA,QAAY,IACZ0C,QAAK;AAAA,iBAAEzD,SAAAA,EAAWe,MAAMmB,IAAI;AAAA,QAAC;AAAA,QAAA,IAC7BgD,QAAK;AAAA,iBAAE/E,OAAAA,EAASY,MAAMmB,IAAI;AAAA,QAAC;AAAA,QAC3B6G,UAAWtF,CAAAA,UAAUD,kBAAkBzC,MAAMmB,MAAMuB,KAAK;AAAA,QAAC,IACzDuF,WAAQ;AAAA,iBAAE3I,aAAAA,KAAkBU,MAAMiI;AAAAA,QAAQ;AAAA,QAC1ChJ;AAAAA,MAAAA,CAAkB;AAAA,IAAA,CAErB,CAAA;AAAAyH,eAAAhB,OAAAiB,IAAAA,gBAIJC,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEzH,SAAS8E;AAAAA,MAAK;AAAA,MAAA,IAAA6C,WAAA;AAAA,YAAAmB,QAAAhD,IAAAA,eAAAiD,OAAA,GAAAC,QAAAF,MAAA7C;AAAAqB,YAAAA,OAAA0B,OAAA,MAGnBhJ,OAAAA,EAAS8E,KAAK;AAAA,eAAAgE;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAlC,QAAAC,KAAA;AAAAS,eAAAhB,OAAAiB,IAAAA,gBAMpBC,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE1G,eAAe;AAAA,MAAI;AAAA,MAAA,IAAA4G,WAAA;AAAA,YAAAsB,QAAAnD,mBAAAoD,OAAA,GAAAC,QAAAF,MAAAhD,YAAAmD,QAAAD,MAAA9C;AAAAiB,YAAAA,OAAA6B,OAAA,MAGxBd,+BAAkBvK,QAAQuL,qBAAqB;AAAA,UAC9CC,OAAO3J,OAAAA,EAAS4J,eAAezL,QAAQ0L;AAAAA,UACvCC,SAAS1I,UAAAA;AAAAA,QAAU,CACpB,CAAC;AAAAqI,cAAAM,UAIO,MAAM;AAAEtI,0BAAAA;AAAmBD,4BAAkB,IAAI;AAAA,QAAE;AAACmG,YAAAA,OAAA8B,OAAA,MAG5DtL,QAAQ6L,MAAM;AAAAC,+BAAAA;AAAA,eAAAX;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAlC,QAAAC,KAAA;AAAAM,QAAAA,OAAAJ,QAAA,MAAA;AAAA,UAAA2C,MAAAC,IAAAA,KAAA,MAAA,CAAA,CAWhB5J,cAAc;AAAA,aAAA,MAAd2J,IAAAA,KAAA,MAAA;AAAA,YAAAE,SAAAjE,IAAAA,eAAAkE,OAAA,GAAAC,SAAAF,OAAA9D,YAAAiE,SAAAD,OAAA5D,aAAA,CAAA8D,QAAAC,KAAA,IAAAhE,IAAAA,cAAA8D,OAAA7D,WAAA;AAAAiB,YAAAA,OAAAyC,QAAA,MAGIjM,QAAQuM,gBAAcF,QAAAC,KAAA;AAAA,eAAAL;AAAAA,MAAA,GAAA,IAGzBpK,OAAAA,EAAS4J,eAAezL,QAAQ0L;AAAAA,IACjC,IAAA;AAAAlC,eAAAL,OAAAM,IAAAA,gBAEFC,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE9H,SAAS2K;AAAAA,MAAS;AAAA,MAAA,IAAA3C,WAAA;AAAA,YAAA4C,SAAAzE,IAAAA,eAAA0E,OAAA;AAAAD,eAAAb,UAGjB,MAAM9H,eAAe,IAAI;AAAC0F,YAAAA,OAAAiD,QAAA,MAIlCzM,QAAQ2M,SAAS;AAAAC,YAAAA,aAAAC,IAAAA,YAAAJ,QAAA,YAHRrK,aAAAA,CAAc,CAAA;AAAA0J,+BAAAA;AAAA,eAAAW;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAnD,QAAAC,IAAA;AAAAqD,QAAAA,OAAAE,CAAAA,QAAA;AAAA,UAAAC,MA7EtB,QAAQhN,MAAM+B,UAAUuD,EAAE,IAAE2H,OAgBxBnF,eAAaoF,OA6CX7K,aAAAA;AAAc2K,cAAAD,IAAAjH,KAAAqH,IAAAA,aAAA1E,OAAA,MAAAsE,IAAAjH,IAAAkH,GAAA;AAAAC,eAAAF,IAAAK,KAAAC,IAAAA,UAAAxE,OAAAkE,IAAAK,IAAAH,IAAA;AAAAC,eAAAH,IAAAO,KAAAR,IAAAA,YAAAzD,OAAA,YAAA0D,IAAAO,IAAAJ,IAAA;AAAA,aAAAH;AAAAA,IAAA,GAAA;AAAA,MAAAjH,GAAAhG;AAAAA,MAAAsN,GAAAtN;AAAAA,MAAAwN,GAAAxN;AAAAA,IAAAA,CAAA;AAAA,WAAAkI;AAAAA,EAAA,GAAA;AA0BpC;AAACuF,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
|
|
@@ -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;
|
|
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
|
-
|
|
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 ||
|
|
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 ||
|
|
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 :
|
|
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$
|
|
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$
|
|
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$
|
|
214
|
-
insert(_el$
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return _el$
|
|
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$
|
|
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$
|
|
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$
|
|
258
|
-
_el$
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
_el$
|
|
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$
|
|
270
|
-
insert(_el$
|
|
288
|
+
}), _el$18, _co$4);
|
|
289
|
+
insert(_el$1, (() => {
|
|
271
290
|
var _c$ = memo(() => !!isSubmitting());
|
|
272
|
-
return () => _c$() ?
|
|
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$
|
|
297
|
+
insert(_el$0, createComponent(Show, {
|
|
275
298
|
get when() {
|
|
276
299
|
return params().showReset;
|
|
277
300
|
},
|
|
278
301
|
get children() {
|
|
279
|
-
var _el$
|
|
280
|
-
_el$
|
|
281
|
-
|
|
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$
|
|
307
|
+
return _el$10;
|
|
284
308
|
}
|
|
285
|
-
}), _el$
|
|
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$
|
|
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
|
-
|
|
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$
|
|
12
|
-
_el$
|
|
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 (
|
|
18
|
-
|
|
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$
|
|
25
|
-
web.insert(_el$
|
|
26
|
-
return _el$
|
|
28
|
+
var _el$7 = web.getNextElement(_tmpl$);
|
|
29
|
+
web.insert(_el$7, () => props.error.message);
|
|
30
|
+
return _el$7;
|
|
27
31
|
}
|
|
28
|
-
}), _el$
|
|
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$
|
|
35
|
-
web.addEventListener(_el$
|
|
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$
|
|
42
|
+
return _el$8;
|
|
38
43
|
}
|
|
39
|
-
}), _el$
|
|
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;
|
|
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"}
|