@seed-ship/mcp-ui-solid 5.0.0 → 5.1.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.
@@ -1,4 +1,4 @@
1
- import { delegateEvents, getNextElement, template, insert, createComponent, effect, setAttribute, className, runHydrationEvents, getNextMarker, addEventListener, setProperty } from "solid-js/web";
1
+ import { delegateEvents, getNextElement, template, insert, createComponent, effect, setAttribute, className, runHydrationEvents, memo, getNextMarker, addEventListener, setProperty } from "solid-js/web";
2
2
  import { Show, Switch, Match, For, createSignal, createEffect, onCleanup } from "solid-js";
3
3
  import { FormFieldRenderer } from "./FormFieldRenderer.js";
4
4
  var _tmpl$ = /* @__PURE__ */ template(`<div class="w-full max-w-2xl mx-auto mb-2 bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-lg overflow-visible"role=dialog style="animation:chat-prompt-slide-up 0.2s ease-out"><div class="flex items-center justify-between px-4 py-2.5 border-b border-gray-100 dark:border-gray-700"><p class="text-sm font-medium text-gray-900 dark:text-white"></p><button></button></div><div class="px-4 py-3"></div><style>
@@ -6,7 +6,7 @@ var _tmpl$ = /* @__PURE__ */ template(`<div class="w-full max-w-2xl mx-auto mb-2
6
6
  from { opacity: 0; transform: translateY(8px); }
7
7
  to { opacity: 1; transform: translateY(0); }
8
8
  }
9
- `), _tmpl$2 = /* @__PURE__ */ template(`<svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12">`), _tmpl$3 = /* @__PURE__ */ template(`<div>`), _tmpl$4 = /* @__PURE__ */ template(`<span class=mr-2>`), _tmpl$5 = /* @__PURE__ */ template(`<span class="block text-xs text-gray-500 dark:text-gray-400 mt-0.5 font-normal">`), _tmpl$6 = /* @__PURE__ */ template(`<button class="px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white hover:bg-blue-50 hover:border-blue-300 dark:hover:bg-blue-900/30 dark:hover:border-blue-600 transition-colors text-left"><!$><!/><!$><!/><!$><!/>`), _tmpl$7 = /* @__PURE__ */ template(`<p class="text-sm text-gray-600 dark:text-gray-400 mb-3">`), _tmpl$8 = /* @__PURE__ */ template(`<div><!$><!/><div class="flex gap-2 justify-end"><button class="px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"></button><button>`), _tmpl$9 = /* @__PURE__ */ template(`<p class="text-blue-400 animate-pulse">Loading preview...`), _tmpl$0 = /* @__PURE__ */ template(`<div class="px-3 py-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800 text-sm">`), _tmpl$1 = /* @__PURE__ */ template(`<form class="flex flex-col gap-3"><!$><!/><!$><!/><div class="flex justify-end"><button type=submit class="px-4 py-2 text-sm font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors">`), _tmpl$10 = /* @__PURE__ */ template(`<p class="text-blue-700 dark:text-blue-300">`);
9
+ `), _tmpl$2 = /* @__PURE__ */ template(`<svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M6 18L18 6M6 6l12 12">`), _tmpl$3 = /* @__PURE__ */ template(`<div>`), _tmpl$4 = /* @__PURE__ */ template(`<button type=button>`), _tmpl$5 = /* @__PURE__ */ template(`<span class=mr-2>`), _tmpl$6 = /* @__PURE__ */ template(`<span class="block text-xs text-gray-500 dark:text-gray-400 mt-0.5 font-normal">`), _tmpl$7 = /* @__PURE__ */ template(`<p class="text-sm text-gray-600 dark:text-gray-400 mb-3">`), _tmpl$8 = /* @__PURE__ */ template(`<div><!$><!/><div class="flex gap-2 justify-end"><button class="px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"></button><button>`), _tmpl$9 = /* @__PURE__ */ template(`<p class="text-blue-400 animate-pulse">Loading preview...`), _tmpl$0 = /* @__PURE__ */ template(`<div class="px-3 py-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800 text-sm">`), _tmpl$1 = /* @__PURE__ */ template(`<form class="flex flex-col gap-3"><!$><!/><!$><!/><div class="flex justify-end"><button type=submit class="px-4 py-2 text-sm font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors">`), _tmpl$10 = /* @__PURE__ */ template(`<p class="text-blue-700 dark:text-blue-300">`);
10
10
  const ChatPrompt = (props) => {
11
11
  if (!props.config) return null;
12
12
  return (() => {
@@ -113,14 +113,23 @@ const ChatPrompt = (props) => {
113
113
  };
114
114
  const ChoiceBody = (props) => {
115
115
  const layoutClass = () => {
116
- switch (props.config.layout) {
117
- case "vertical":
118
- return "flex flex-col gap-2";
119
- case "grid":
120
- return "grid grid-cols-2 gap-2";
121
- default:
122
- return "flex flex-wrap gap-2";
123
- }
116
+ const base = (() => {
117
+ switch (props.config.layout) {
118
+ case "vertical":
119
+ return "flex flex-col gap-2";
120
+ case "grid":
121
+ return "grid grid-cols-2 gap-2";
122
+ default:
123
+ return "flex flex-wrap gap-2";
124
+ }
125
+ })();
126
+ const extra = props.config.containerClass;
127
+ return extra ? `${base} ${extra}` : base;
128
+ };
129
+ const buttonClass = () => {
130
+ const base = "px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white hover:bg-blue-50 hover:border-blue-300 dark:hover:bg-blue-900/30 dark:hover:border-blue-600 transition-colors text-left";
131
+ const extra = props.config.buttonClass;
132
+ return extra ? `${base} ${extra}` : base;
124
133
  };
125
134
  return (() => {
126
135
  var _el$7 = getNextElement(_tmpl$3);
@@ -128,30 +137,39 @@ const ChoiceBody = (props) => {
128
137
  get each() {
129
138
  return props.config.options;
130
139
  },
131
- children: (option) => (() => {
132
- var _el$8 = getNextElement(_tmpl$6), _el$1 = _el$8.firstChild, [_el$10, _co$] = getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$2] = getNextMarker(_el$11.nextSibling), _el$13 = _el$12.nextSibling, [_el$14, _co$3] = getNextMarker(_el$13.nextSibling);
140
+ children: (option, i) => (() => {
141
+ var _el$8 = getNextElement(_tmpl$4);
133
142
  _el$8.$$click = () => props.onSelect(option.value, option.label);
134
143
  insert(_el$8, createComponent(Show, {
135
144
  get when() {
136
- return option.icon;
145
+ return props.config.optionRenderer;
137
146
  },
138
- get children() {
139
- var _el$9 = getNextElement(_tmpl$4);
140
- insert(_el$9, () => option.icon);
141
- return _el$9;
142
- }
143
- }), _el$10, _co$);
144
- insert(_el$8, () => option.label, _el$12, _co$2);
145
- insert(_el$8, createComponent(Show, {
146
- get when() {
147
- return option.description;
147
+ get fallback() {
148
+ return [createComponent(Show, {
149
+ get when() {
150
+ return option.icon;
151
+ },
152
+ get children() {
153
+ var _el$9 = getNextElement(_tmpl$5);
154
+ insert(_el$9, () => option.icon);
155
+ return _el$9;
156
+ }
157
+ }), memo(() => option.label), createComponent(Show, {
158
+ get when() {
159
+ return option.description;
160
+ },
161
+ get children() {
162
+ var _el$0 = getNextElement(_tmpl$6);
163
+ insert(_el$0, () => option.description);
164
+ return _el$0;
165
+ }
166
+ })];
148
167
  },
149
168
  get children() {
150
- var _el$0 = getNextElement(_tmpl$5);
151
- insert(_el$0, () => option.description);
152
- return _el$0;
169
+ return props.config.optionRenderer(option, i());
153
170
  }
154
- }), _el$14, _co$3);
171
+ }));
172
+ effect(() => className(_el$8, buttonClass()));
155
173
  runHydrationEvents();
156
174
  return _el$8;
157
175
  })()
@@ -163,24 +181,24 @@ const ChoiceBody = (props) => {
163
181
  const ConfirmBody = (props) => {
164
182
  const isDanger = () => props.config.variant === "danger";
165
183
  return (() => {
166
- var _el$15 = getNextElement(_tmpl$8), _el$20 = _el$15.firstChild, [_el$21, _co$4] = getNextMarker(_el$20.nextSibling), _el$17 = _el$21.nextSibling, _el$18 = _el$17.firstChild, _el$19 = _el$18.nextSibling;
167
- insert(_el$15, createComponent(Show, {
184
+ var _el$1 = getNextElement(_tmpl$8), _el$14 = _el$1.firstChild, [_el$15, _co$] = getNextMarker(_el$14.nextSibling), _el$11 = _el$15.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$12.nextSibling;
185
+ insert(_el$1, createComponent(Show, {
168
186
  get when() {
169
187
  return props.config.message;
170
188
  },
171
189
  get children() {
172
- var _el$16 = getNextElement(_tmpl$7);
173
- insert(_el$16, () => props.config.message);
174
- return _el$16;
190
+ var _el$10 = getNextElement(_tmpl$7);
191
+ insert(_el$10, () => props.config.message);
192
+ return _el$10;
175
193
  }
176
- }), _el$21, _co$4);
177
- addEventListener(_el$18, "click", props.onCancel, true);
178
- insert(_el$18, () => props.config.cancelLabel || "Cancel");
179
- addEventListener(_el$19, "click", props.onConfirm, true);
180
- insert(_el$19, () => props.config.confirmLabel || "Confirm");
181
- effect(() => className(_el$19, `px-4 py-2 text-sm font-medium rounded-lg text-white transition-colors ${isDanger() ? "bg-red-600 hover:bg-red-700" : "bg-blue-600 hover:bg-blue-700"}`));
194
+ }), _el$15, _co$);
195
+ addEventListener(_el$12, "click", props.onCancel, true);
196
+ insert(_el$12, () => props.config.cancelLabel || "Cancel");
197
+ addEventListener(_el$13, "click", props.onConfirm, true);
198
+ insert(_el$13, () => props.config.confirmLabel || "Confirm");
199
+ effect(() => className(_el$13, `px-4 py-2 text-sm font-medium rounded-lg text-white transition-colors ${isDanger() ? "bg-red-600 hover:bg-red-700" : "bg-blue-600 hover:bg-blue-700"}`));
182
200
  runHydrationEvents();
183
- return _el$15;
201
+ return _el$1;
184
202
  })();
185
203
  };
186
204
  const FormBody = (props) => {
@@ -287,9 +305,9 @@ const FormBody = (props) => {
287
305
  return field;
288
306
  };
289
307
  return (() => {
290
- var _el$22 = getNextElement(_tmpl$1), _el$27 = _el$22.firstChild, [_el$28, _co$5] = getNextMarker(_el$27.nextSibling), _el$29 = _el$28.nextSibling, [_el$30, _co$6] = getNextMarker(_el$29.nextSibling), _el$25 = _el$30.nextSibling, _el$26 = _el$25.firstChild;
291
- _el$22.addEventListener("submit", handleSubmit);
292
- insert(_el$22, createComponent(For, {
308
+ var _el$16 = getNextElement(_tmpl$1), _el$21 = _el$16.firstChild, [_el$22, _co$2] = getNextMarker(_el$21.nextSibling), _el$23 = _el$22.nextSibling, [_el$24, _co$3] = getNextMarker(_el$23.nextSibling), _el$19 = _el$24.nextSibling, _el$20 = _el$19.firstChild;
309
+ _el$16.addEventListener("submit", handleSubmit);
310
+ insert(_el$16, createComponent(For, {
293
311
  get each() {
294
312
  return props.config.fields;
295
313
  },
@@ -303,34 +321,34 @@ const FormBody = (props) => {
303
321
  onChange: (val) => updateField(field.name, val),
304
322
  formData
305
323
  })
306
- }), _el$28, _co$5);
307
- insert(_el$22, createComponent(Show, {
324
+ }), _el$22, _co$2);
325
+ insert(_el$16, createComponent(Show, {
308
326
  get when() {
309
327
  return previewText() || previewLoading();
310
328
  },
311
329
  get children() {
312
- var _el$23 = getNextElement(_tmpl$0);
313
- insert(_el$23, createComponent(Show, {
330
+ var _el$17 = getNextElement(_tmpl$0);
331
+ insert(_el$17, createComponent(Show, {
314
332
  get when() {
315
333
  return previewLoading();
316
334
  },
317
335
  get fallback() {
318
336
  return (() => {
319
- var _el$31 = getNextElement(_tmpl$10);
320
- insert(_el$31, previewText);
321
- return _el$31;
337
+ var _el$25 = getNextElement(_tmpl$10);
338
+ insert(_el$25, previewText);
339
+ return _el$25;
322
340
  })();
323
341
  },
324
342
  get children() {
325
343
  return getNextElement(_tmpl$9);
326
344
  }
327
345
  }));
328
- return _el$23;
346
+ return _el$17;
329
347
  }
330
- }), _el$30, _co$6);
331
- insert(_el$26, () => props.config.submitLabel || "Submit");
332
- effect(() => setProperty(_el$26, "disabled", !isValid()));
333
- return _el$22;
348
+ }), _el$24, _co$3);
349
+ insert(_el$20, () => props.config.submitLabel || "Submit");
350
+ effect(() => setProperty(_el$20, "disabled", !isValid()));
351
+ return _el$16;
334
352
  })();
335
353
  };
336
354
  delegateEvents(["click"]);
@@ -1 +1 @@
1
- {"version":3,"file":"ChatPrompt.js","sources":["../../src/components/ChatPrompt.tsx"],"sourcesContent":["/**\n * ChatPrompt — Ephemeral structured interaction above chat input\n * v2.4.0: choice, confirm, form subtypes\n *\n * @experimental — This component may change without major bump until v2.5.0.\n *\n * Renders above the chat input. User responds → Promise resolves → prompt disappears.\n * Supports AbortSignal for cleanup on navigation (C4).\n */\n\nimport { Component, Show, For, createSignal, createEffect, onCleanup, Switch, Match } from 'solid-js'\nimport type {\n ChatPromptConfig,\n ChatPromptResponse,\n ChoicePromptConfig,\n ConfirmPromptConfig,\n FormPromptConfig,\n} from '../types/chat-bus'\nimport { FormFieldRenderer } from './FormFieldRenderer'\nimport type { FormFieldParams } from '../types'\n\nexport interface ChatPromptProps {\n /** Prompt configuration */\n config: ChatPromptConfig\n /** Called when user responds */\n onSubmit: (response: ChatPromptResponse) => void\n /** Called when user dismisses (e.g. \"send as-is\") */\n onDismiss?: () => void\n /** Label for the dismiss button (replaces X icon). Default: shows X icon. */\n dismissLabel?: string\n}\n\n/**\n * @experimental\n * Ephemeral interaction component — choice buttons, confirmation dialog, or quick form.\n * Designed to sit between the chat messages and the input area.\n *\n * @example\n * <ChatPrompt\n * config={{ type: 'choice', title: 'Format?', config: { options: [...] } }}\n * onSubmit={(r) => bus.events.emit('onChatPromptResponse', { streamKey, response: r })}\n * onDismiss={() => setActivePrompt(null)}\n * />\n */\nexport const ChatPrompt: Component<ChatPromptProps> = (props) => {\n // F1: Guard against null/undefined config (e.g. after dismiss clears state)\n if (!props.config) return null\n\n return (\n <div\n class=\"w-full max-w-2xl mx-auto mb-2 bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-lg overflow-visible\"\n style={{ animation: 'chat-prompt-slide-up 0.2s ease-out' }}\n role=\"dialog\"\n aria-label={props.config.title}\n >\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-2.5 border-b border-gray-100 dark:border-gray-700\">\n <p class=\"text-sm font-medium text-gray-900 dark:text-white\">{props.config.title}</p>\n <button\n onClick={() => {\n props.onDismiss?.()\n props.onSubmit({ type: props.config.type, value: '', label: '', dismissed: true })\n }}\n class={props.dismissLabel\n ? 'px-3 py-1 text-xs font-medium text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-colors'\n : 'p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors'\n }\n aria-label={props.dismissLabel || 'Dismiss'}\n >\n <Show when={props.dismissLabel} fallback={\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n }>\n {props.dismissLabel}\n </Show>\n </button>\n </div>\n\n {/* Body — type-specific */}\n <div class=\"px-4 py-3\">\n <Switch>\n <Match when={props.config.type === 'choice'}>\n <ChoiceBody\n config={props.config.config as ChoicePromptConfig}\n onSelect={(value, label) => props.onSubmit({ type: 'choice', value, label })}\n />\n </Match>\n <Match when={props.config.type === 'confirm'}>\n <ConfirmBody\n config={props.config.config as ConfirmPromptConfig}\n onConfirm={() => props.onSubmit({ type: 'confirm', value: 'confirmed', label: (props.config.config as ConfirmPromptConfig).confirmLabel || 'Confirmed' })}\n onCancel={() => {\n props.onDismiss?.()\n props.onSubmit({ type: 'confirm', value: 'cancelled', label: (props.config.config as ConfirmPromptConfig).cancelLabel || 'Cancelled', dismissed: true })\n }}\n />\n </Match>\n <Match when={props.config.type === 'form'}>\n <FormBody\n config={props.config.config as FormPromptConfig}\n onSubmit={(data, label) => props.onSubmit({ type: 'form', value: data, label })}\n />\n </Match>\n </Switch>\n </div>\n\n <style>{`\n @keyframes chat-prompt-slide-up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `}</style>\n </div>\n )\n}\n\n// ─── Choice ──────────────────────────────────────────────────\n\nconst ChoiceBody: Component<{\n config: ChoicePromptConfig\n onSelect: (value: string, label: string) => void\n}> = (props) => {\n const layoutClass = () => {\n switch (props.config.layout) {\n case 'vertical': return 'flex flex-col gap-2'\n case 'grid': return 'grid grid-cols-2 gap-2'\n default: return 'flex flex-wrap gap-2'\n }\n }\n\n return (\n <div class={layoutClass()}>\n <For each={props.config.options}>\n {(option) => (\n <button\n onClick={() => props.onSelect(option.value, option.label)}\n class=\"px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white hover:bg-blue-50 hover:border-blue-300 dark:hover:bg-blue-900/30 dark:hover:border-blue-600 transition-colors text-left\"\n >\n <Show when={option.icon}>\n <span class=\"mr-2\">{option.icon}</span>\n </Show>\n {option.label}\n <Show when={option.description}>\n <span class=\"block text-xs text-gray-500 dark:text-gray-400 mt-0.5 font-normal\">{option.description}</span>\n </Show>\n </button>\n )}\n </For>\n </div>\n )\n}\n\n// ─── Confirm ─────────────────────────────────────────────────\n\nconst ConfirmBody: Component<{\n config: ConfirmPromptConfig\n onConfirm: () => void\n onCancel: () => void\n}> = (props) => {\n const isDanger = () => props.config.variant === 'danger'\n\n return (\n <div>\n <Show when={props.config.message}>\n <p class=\"text-sm text-gray-600 dark:text-gray-400 mb-3\">{props.config.message}</p>\n </Show>\n <div class=\"flex gap-2 justify-end\">\n <button\n onClick={props.onCancel}\n class=\"px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n >\n {props.config.cancelLabel || 'Cancel'}\n </button>\n <button\n onClick={props.onConfirm}\n class={`px-4 py-2 text-sm font-medium rounded-lg text-white transition-colors ${\n isDanger()\n ? 'bg-red-600 hover:bg-red-700'\n : 'bg-blue-600 hover:bg-blue-700'\n }`}\n >\n {props.config.confirmLabel || 'Confirm'}\n </button>\n </div>\n </div>\n )\n}\n\n// ─── Form (delegates to FormFieldRenderer for all field types) ───\n\nconst FormBody: Component<{\n config: FormPromptConfig\n onSubmit: (data: Record<string, unknown>, label: string) => void\n}> = (props) => {\n const [formData, setFormData] = createSignal<Record<string, any>>({})\n const [dynamicOptions, setDynamicOptions] = createSignal<Record<string, Array<{ label: string; value: string }>>>({})\n const [previewText, setPreviewText] = createSignal<string>('')\n const [previewLoading, setPreviewLoading] = createSignal(false)\n let previewTimer: ReturnType<typeof setTimeout> | null = null\n\n const updateField = (name: string, value: any) => {\n setFormData((prev) => ({ ...prev, [name]: value }))\n }\n\n // --- depends_on: fetch child options when parent changes ---\n createEffect(() => {\n const data = formData()\n for (const field of props.config.fields || []) {\n const dep = field.dependsOn || (field as any).depends_on\n if (!dep) continue\n const parentValue = data[dep.field]\n if (!parentValue) continue\n\n const apiUrl = (dep.apiUrl || dep.api_url || '').replace('{value}', encodeURIComponent(parentValue))\n if (!apiUrl) continue\n\n const params = new URLSearchParams(dep.extraParams || dep.extra_params || {})\n fetch(`${apiUrl}?${params}`)\n .then((r) => r.json())\n .then((items) => {\n const arr = Array.isArray(items) ? items : items.results || items.features || []\n const labelKey = dep.labelField || dep.label_field || 'label'\n const valueKey = dep.valueField || dep.value_field || 'value'\n setDynamicOptions((prev) => ({\n ...prev,\n [field.name]: arr.map((item: any) => ({\n label: item[labelKey] || String(item),\n value: String(item[valueKey] || item[labelKey] || item),\n })),\n }))\n })\n .catch(() => {})\n }\n })\n\n // --- preview: debounced live preview ---\n createEffect(() => {\n const preview = props.config.preview\n if (!preview) return\n\n const data = formData()\n // Check if any preview field has a value\n const hasValues = preview.fields.some((f) => {\n const v = data[f]\n return v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0)\n })\n if (!hasValues) { setPreviewText(''); return }\n\n if (previewTimer) clearTimeout(previewTimer)\n previewTimer = setTimeout(async () => {\n setPreviewLoading(true)\n try {\n const body: Record<string, any> = {}\n for (const f of preview.fields) {\n if (data[f] !== undefined) body[f] = data[f]\n }\n const res = await fetch(preview.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n credentials: 'include',\n body: JSON.stringify(body),\n })\n if (res.ok) {\n const result = await res.json()\n setPreviewText(result.summary_fr || result.summary || result.message || JSON.stringify(result))\n }\n } catch {\n setPreviewText('')\n }\n setPreviewLoading(false)\n }, preview.debounceMs || 500)\n })\n\n onCleanup(() => { if (previewTimer) clearTimeout(previewTimer) })\n\n const handleSubmit = (e: Event) => {\n e.preventDefault()\n const data = formData()\n const label = Object.entries(data)\n .filter(([, v]) => v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0))\n .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : v}`)\n .join(', ')\n props.onSubmit(data, label || 'Form submitted')\n }\n\n const isValid = () => {\n const data = formData()\n return (props.config.fields || [])\n .filter((f) => f.required)\n .every((f) => {\n const val = data[f.name]\n if (Array.isArray(val)) return val.length > 0\n if (typeof val === 'boolean') return true\n return val !== undefined && val !== ''\n })\n }\n\n // Build field with dynamic options override\n const getField = (field: any): FormFieldParams => {\n const dynOpts = dynamicOptions()[field.name]\n if (dynOpts) {\n return { ...field, options: dynOpts } as FormFieldParams\n }\n return field as FormFieldParams\n }\n\n return (\n <form onSubmit={handleSubmit} class=\"flex flex-col gap-3\">\n <For each={props.config.fields}>\n {(field) => (\n <FormFieldRenderer\n field={getField(field)}\n value={formData()[field.name]}\n onChange={(val) => updateField(field.name, val)}\n formData={formData}\n />\n )}\n </For>\n\n {/* Live preview */}\n <Show when={previewText() || previewLoading()}>\n <div class=\"px-3 py-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800 text-sm\">\n <Show when={previewLoading()} fallback={\n <p class=\"text-blue-700 dark:text-blue-300\">{previewText()}</p>\n }>\n <p class=\"text-blue-400 animate-pulse\">Loading preview...</p>\n </Show>\n </div>\n </Show>\n\n <div class=\"flex justify-end\">\n <button\n type=\"submit\"\n disabled={!isValid()}\n class=\"px-4 py-2 text-sm font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors\"\n >\n {props.config.submitLabel || 'Submit'}\n </button>\n </div>\n </form>\n )\n}\n"],"names":["ChatPrompt","props","config","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_$insert","title","$$click","onDismiss","onSubmit","type","value","label","dismissed","_$createComponent","Show","when","dismissLabel","fallback","_tmpl$2","children","Switch","Match","ChoiceBody","onSelect","ConfirmBody","onConfirm","confirmLabel","onCancel","cancelLabel","FormBody","data","_$effect","_p$","_v$","_v$2","_v$3","e","_$setAttribute","t","_$className","a","undefined","_$runHydrationEvents","layoutClass","layout","_el$7","_tmpl$3","For","each","options","option","_el$8","_tmpl$6","_el$1","_el$10","_co$","_$getNextMarker","_el$11","_el$12","_co$2","_el$13","_el$14","_co$3","icon","_el$9","_tmpl$4","description","_el$0","_tmpl$5","isDanger","variant","_el$15","_tmpl$8","_el$20","_el$21","_co$4","_el$17","_el$18","_el$19","message","_el$16","_tmpl$7","_$addEventListener","formData","setFormData","createSignal","dynamicOptions","setDynamicOptions","previewText","setPreviewText","previewLoading","setPreviewLoading","previewTimer","updateField","name","prev","createEffect","field","fields","dep","dependsOn","depends_on","parentValue","apiUrl","api_url","replace","encodeURIComponent","params","URLSearchParams","extraParams","extra_params","fetch","then","r","json","items","arr","Array","isArray","results","features","labelKey","labelField","label_field","valueKey","valueField","value_field","map","item","String","catch","preview","hasValues","some","f","v","length","setTimeout","body","res","endpoint","method","headers","credentials","JSON","stringify","ok","result","summary_fr","summary","debounceMs","onCleanup","handleSubmit","preventDefault","Object","entries","filter","k","join","isValid","required","every","val","getField","dynOpts","_el$22","_tmpl$1","_el$27","_el$28","_co$5","_el$29","_el$30","_co$6","_el$25","_el$26","addEventListener","FormFieldRenderer","onChange","_el$23","_tmpl$0","_el$31","_tmpl$10","_tmpl$9","submitLabel","_$setProperty","_$delegateEvents"],"mappings":";;;;;;;;;AA4CO,MAAMA,aAA0CC,CAAAA,UAAU;AAE/D,MAAI,CAACA,MAAMC,OAAQ,QAAO;AAE1B,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,MAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAC,YAAAE,QAAAD,MAAAE,aAAAC,QAAAL,MAAAI;AAAAE,WAAAJ,OAAA,MASoEP,MAAMC,OAAOW,KAAK;AAAAJ,UAAAK,UAErE,MAAM;;AACbb,kBAAMc,cAANd;AACAA,YAAMe,SAAS;AAAA,QAAEC,MAAMhB,MAAMC,OAAOe;AAAAA,QAAMC,OAAO;AAAA,QAAIC,OAAO;AAAA,QAAIC,WAAW;AAAA,MAAA,CAAM;AAAA,IACnF;AAACR,WAAAH,OAAAY,gBAOAC,MAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEtB,MAAMuB;AAAAA,MAAY;AAAA,MAAA,IAAEC,WAAQ;AAAA,eAAArB,eAAAsB,OAAA;AAAA,MAAA;AAAA,MAAA,IAAAC,WAAA;AAAA,eAKrC1B,MAAMuB;AAAAA,MAAY;AAAA,IAAA,CAAA,CAAA;AAAAZ,WAAAD,OAAAU,gBAOtBO,QAAM;AAAA,MAAA,IAAAD,WAAA;AAAA,eAAA,CAAAN,gBACJQ,OAAK;AAAA,UAAA,IAACN,OAAI;AAAA,mBAAEtB,MAAMC,OAAOe,SAAS;AAAA,UAAQ;AAAA,UAAA,IAAAU,WAAA;AAAA,mBAAAN,gBACxCS,YAAU;AAAA,cAAA,IACT5B,SAAM;AAAA,uBAAED,MAAMC,OAAOA;AAAAA,cAA4B;AAAA,cACjD6B,UAAUA,CAACb,OAAOC,UAAUlB,MAAMe,SAAS;AAAA,gBAAEC,MAAM;AAAA,gBAAUC;AAAAA,gBAAOC;AAAAA,cAAAA,CAAO;AAAA,YAAA,CAAC;AAAA,UAAA;AAAA,QAAA,CAAA,GAAAE,gBAG/EQ,OAAK;AAAA,UAAA,IAACN,OAAI;AAAA,mBAAEtB,MAAMC,OAAOe,SAAS;AAAA,UAAS;AAAA,UAAA,IAAAU,WAAA;AAAA,mBAAAN,gBACzCW,aAAW;AAAA,cAAA,IACV9B,SAAM;AAAA,uBAAED,MAAMC,OAAOA;AAAAA,cAA6B;AAAA,cAClD+B,WAAWA,MAAMhC,MAAMe,SAAS;AAAA,gBAAEC,MAAM;AAAA,gBAAWC,OAAO;AAAA,gBAAaC,OAAQlB,MAAMC,OAAOA,OAA+BgC,gBAAgB;AAAA,cAAA,CAAa;AAAA,cACxJC,UAAUA,MAAM;;AACdlC,4BAAMc,cAANd;AACAA,sBAAMe,SAAS;AAAA,kBAAEC,MAAM;AAAA,kBAAWC,OAAO;AAAA,kBAAaC,OAAQlB,MAAMC,OAAOA,OAA+BkC,eAAe;AAAA,kBAAahB,WAAW;AAAA,gBAAA,CAAM;AAAA,cACzJ;AAAA,YAAA,CAAC;AAAA,UAAA;AAAA,QAAA,CAAA,GAAAC,gBAGJQ,OAAK;AAAA,UAAA,IAACN,OAAI;AAAA,mBAAEtB,MAAMC,OAAOe,SAAS;AAAA,UAAM;AAAA,UAAA,IAAAU,WAAA;AAAA,mBAAAN,gBACtCgB,UAAQ;AAAA,cAAA,IACPnC,SAAM;AAAA,uBAAED,MAAMC,OAAOA;AAAAA,cAA0B;AAAA,cAC/Cc,UAAUA,CAACsB,MAAMnB,UAAUlB,MAAMe,SAAS;AAAA,gBAAEC,MAAM;AAAA,gBAAQC,OAAOoB;AAAAA,gBAAMnB;AAAAA,cAAAA,CAAO;AAAA,YAAA,CAAC;AAAA,UAAA;AAAA,QAAA,CAAA,CAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAoB,WAAAC,CAAAA,QAAA;AAAA,UAAAC,MAhD3ExC,MAAMC,OAAOW,OAAK6B,OAUnBzC,MAAMuB,eACT,2IACA,0IAAwImB,OAEhI1C,MAAMuB,gBAAgB;AAASiB,cAAAD,IAAAI,KAAAC,aAAA1C,MAAA,cAAAqC,IAAAI,IAAAH,GAAA;AAAAC,eAAAF,IAAAM,KAAAC,UAAAtC,OAAA+B,IAAAM,IAAAJ,IAAA;AAAAC,eAAAH,IAAAQ,KAAAH,aAAApC,OAAA,cAAA+B,IAAAQ,IAAAL,IAAA;AAAA,aAAAH;AAAAA,IAAA,GAAA;AAAA,MAAAI,GAAAK;AAAAA,MAAAH,GAAAG;AAAAA,MAAAD,GAAAC;AAAAA,IAAAA,CAAA;AAAAC,uBAAAA;AAAA,WAAA/C;AAAAA,EAAA,GAAA;AAgDrD;AAIA,MAAM2B,aAGA7B,CAAAA,UAAU;AACd,QAAMkD,cAAcA,MAAM;AACxB,YAAQlD,MAAMC,OAAOkD,QAAAA;AAAAA,MACnB,KAAK;AAAY,eAAO;AAAA,MACxB,KAAK;AAAQ,eAAO;AAAA,MACpB;AAAS,eAAO;AAAA,IAAA;AAAA,EAEpB;AAEA,UAAA,MAAA;AAAA,QAAAC,QAAAjD,eAAAkD,OAAA;AAAA1C,WAAAyC,OAAAhC,gBAEKkC,KAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEvD,MAAMC,OAAOuD;AAAAA,MAAO;AAAA,MAAA9B,UAC3B+B,aAAM,MAAA;AAAA,YAAAC,QAAAvD,eAAAwD,OAAA,GAAAC,QAAAF,MAAApD,YAAA,CAAAuD,QAAAC,IAAA,IAAAC,cAAAH,MAAAnD,WAAA,GAAAuD,SAAAH,OAAApD,aAAA,CAAAwD,QAAAC,KAAA,IAAAH,cAAAC,OAAAvD,WAAA,GAAA0D,SAAAF,OAAAxD,aAAA,CAAA2D,QAAAC,KAAA,IAAAN,cAAAI,OAAA1D,WAAA;AAAAiD,cAAA7C,UAEK,MAAMb,MAAM8B,SAAS2B,OAAOxC,OAAOwC,OAAOvC,KAAK;AAACP,eAAA+C,OAAAtC,gBAGxDC,MAAI;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAEmC,OAAOa;AAAAA,UAAI;AAAA,UAAA,IAAA5C,WAAA;AAAA,gBAAA6C,QAAApE,eAAAqE,OAAA;AAAA7D,mBAAA4D,OAAA,MACDd,OAAOa,IAAI;AAAA,mBAAAC;AAAAA,UAAA;AAAA,QAAA,CAAA,GAAAV,QAAAC,IAAA;AAAAnD,eAAA+C,OAAA,MAEhCD,OAAOvC,OAAK+C,QAAAC,KAAA;AAAAvD,eAAA+C,OAAAtC,gBACZC,MAAI;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAEmC,OAAOgB;AAAAA,UAAW;AAAA,UAAA,IAAA/C,WAAA;AAAA,gBAAAgD,QAAAvE,eAAAwE,OAAA;AAAAhE,mBAAA+D,OAAA,MACqDjB,OAAOgB,WAAW;AAAA,mBAAAC;AAAAA,UAAA;AAAA,QAAA,CAAA,GAAAN,QAAAC,KAAA;AAAApB,2BAAAA;AAAA,eAAAS;AAAAA,MAAA,GAAA;AAAA,IAAA,CAGxG,CAAA;AAAApB,iBAAAQ,UAAAM,OAfOF,YAAAA,CAAa,CAAA;AAAA,WAAAE;AAAAA,EAAA,GAAA;AAmB7B;AAIA,MAAMrB,cAIA/B,CAAAA,UAAU;AACd,QAAM4E,WAAWA,MAAM5E,MAAMC,OAAO4E,YAAY;AAEhD,UAAA,MAAA;AAAA,QAAAC,SAAA3E,eAAA4E,OAAA,GAAAC,SAAAF,OAAAxE,YAAA,CAAA2E,QAAAC,KAAA,IAAAnB,cAAAiB,OAAAvE,WAAA,GAAA0E,SAAAF,OAAAxE,aAAA2E,SAAAD,OAAA7E,YAAA+E,SAAAD,OAAA3E;AAAAE,WAAAmE,QAAA1D,gBAEKC,MAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEtB,MAAMC,OAAOqF;AAAAA,MAAO;AAAA,MAAA,IAAA5D,WAAA;AAAA,YAAA6D,SAAApF,eAAAqF,OAAA;AAAA7E,eAAA4E,QAAA,MAC4BvF,MAAMC,OAAOqF,OAAO;AAAA,eAAAC;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAN,QAAAC,KAAA;AAAAO,qBAAAL,QAAA,SAInEpF,MAAMkC,UAAQ,IAAA;AAAAvB,WAAAyE,QAAA,MAGtBpF,MAAMC,OAAOkC,eAAe,QAAQ;AAAAsD,qBAAAJ,QAAA,SAG5BrF,MAAMgC,WAAS,IAAA;AAAArB,WAAA0E,QAAA,MAOvBrF,MAAMC,OAAOgC,gBAAgB,SAAS;AAAAK,WAAA,MAAAQ,UAAAuC,QANhC,yEACLT,aACI,gCACA,+BAA+B,EACnC,CAAA;AAAA3B,uBAAAA;AAAA,WAAA6B;AAAAA,EAAA,GAAA;AAOZ;AAIA,MAAM1C,WAGApC,CAAAA,UAAU;AACd,QAAM,CAAC0F,UAAUC,WAAW,IAAIC,aAAkC,CAAA,CAAE;AACpE,QAAM,CAACC,gBAAgBC,iBAAiB,IAAIF,aAAsE,CAAA,CAAE;AACpH,QAAM,CAACG,aAAaC,cAAc,IAAIJ,aAAqB,EAAE;AAC7D,QAAM,CAACK,gBAAgBC,iBAAiB,IAAIN,aAAa,KAAK;AAC9D,MAAIO,eAAqD;AAEzD,QAAMC,cAAcA,CAACC,MAAcpF,UAAe;AAChD0E,gBAAaW,CAAAA,UAAU;AAAA,MAAE,GAAGA;AAAAA,MAAM,CAACD,IAAI,GAAGpF;AAAAA,IAAAA,EAAQ;AAAA,EACpD;AAGAsF,eAAa,MAAM;AACjB,UAAMlE,OAAOqD,SAAAA;AACb,eAAWc,SAASxG,MAAMC,OAAOwG,UAAU,CAAA,GAAI;AAC7C,YAAMC,MAAMF,MAAMG,aAAcH,MAAcI;AAC9C,UAAI,CAACF,IAAK;AACV,YAAMG,cAAcxE,KAAKqE,IAAIF,KAAK;AAClC,UAAI,CAACK,YAAa;AAElB,YAAMC,UAAUJ,IAAII,UAAUJ,IAAIK,WAAW,IAAIC,QAAQ,WAAWC,mBAAmBJ,WAAW,CAAC;AACnG,UAAI,CAACC,OAAQ;AAEb,YAAMI,SAAS,IAAIC,gBAAgBT,IAAIU,eAAeV,IAAIW,gBAAgB,EAAE;AAC5EC,YAAM,GAAGR,MAAM,IAAII,MAAM,EAAE,EACxBK,KAAMC,CAAAA,MAAMA,EAAEC,KAAAA,CAAM,EACpBF,KAAMG,CAAAA,UAAU;AACf,cAAMC,MAAMC,MAAMC,QAAQH,KAAK,IAAIA,QAAQA,MAAMI,WAAWJ,MAAMK,YAAY,CAAA;AAC9E,cAAMC,WAAWtB,IAAIuB,cAAcvB,IAAIwB,eAAe;AACtD,cAAMC,WAAWzB,IAAI0B,cAAc1B,IAAI2B,eAAe;AACtDvC,0BAAmBQ,CAAAA,UAAU;AAAA,UAC3B,GAAGA;AAAAA,UACH,CAACE,MAAMH,IAAI,GAAGsB,IAAIW,IAAI,CAACC,UAAe;AAAA,YACpCrH,OAAOqH,KAAKP,QAAQ,KAAKQ,OAAOD,IAAI;AAAA,YACpCtH,OAAOuH,OAAOD,KAAKJ,QAAQ,KAAKI,KAAKP,QAAQ,KAAKO,IAAI;AAAA,UAAA,EACtD;AAAA,QAAA,EACF;AAAA,MACJ,CAAC,EACAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB;AAAA,EACF,CAAC;AAGDlC,eAAa,MAAM;AACjB,UAAMmC,UAAU1I,MAAMC,OAAOyI;AAC7B,QAAI,CAACA,QAAS;AAEd,UAAMrG,OAAOqD,SAAAA;AAEb,UAAMiD,YAAYD,QAAQjC,OAAOmC,KAAMC,CAAAA,MAAM;AAC3C,YAAMC,IAAIzG,KAAKwG,CAAC;AAChB,aAAOC,MAAM9F,UAAa8F,MAAM,MAAM,EAAElB,MAAMC,QAAQiB,CAAC,KAAKA,EAAEC,WAAW;AAAA,IAC3E,CAAC;AACD,QAAI,CAACJ,WAAW;AAAE3C,qBAAe,EAAE;AAAG;AAAA,IAAO;AAE7C,QAAIG,2BAA2BA,YAAY;AAC3CA,mBAAe6C,WAAW,YAAY;AACpC9C,wBAAkB,IAAI;AACtB,UAAI;AACF,cAAM+C,OAA4B,CAAA;AAClC,mBAAWJ,KAAKH,QAAQjC,QAAQ;AAC9B,cAAIpE,KAAKwG,CAAC,MAAM7F,aAAgB6F,CAAC,IAAIxG,KAAKwG,CAAC;AAAA,QAC7C;AACA,cAAMK,MAAM,MAAM5B,MAAMoB,QAAQS,UAAU;AAAA,UACxCC,QAAQ;AAAA,UACRC,SAAS;AAAA,YAAE,gBAAgB;AAAA,UAAA;AAAA,UAC3BC,aAAa;AAAA,UACbL,MAAMM,KAAKC,UAAUP,IAAI;AAAA,QAAA,CAC1B;AACD,YAAIC,IAAIO,IAAI;AACV,gBAAMC,SAAS,MAAMR,IAAIzB,KAAAA;AACzBzB,yBAAe0D,OAAOC,cAAcD,OAAOE,WAAWF,OAAOpE,WAAWiE,KAAKC,UAAUE,MAAM,CAAC;AAAA,QAChG;AAAA,MACF,QAAQ;AACN1D,uBAAe,EAAE;AAAA,MACnB;AACAE,wBAAkB,KAAK;AAAA,IACzB,GAAGwC,QAAQmB,cAAc,GAAG;AAAA,EAC9B,CAAC;AAEDC,YAAU,MAAM;AAAE,QAAI3D,2BAA2BA,YAAY;AAAA,EAAE,CAAC;AAEhE,QAAM4D,eAAeA,CAACpH,MAAa;AACjCA,MAAEqH,eAAAA;AACF,UAAM3H,OAAOqD,SAAAA;AACb,UAAMxE,QAAQ+I,OAAOC,QAAQ7H,IAAI,EAC9B8H,OAAO,CAAC,CAAA,EAAGrB,CAAC,MAAMA,MAAM9F,UAAa8F,MAAM,MAAM,EAAElB,MAAMC,QAAQiB,CAAC,KAAKA,EAAEC,WAAW,EAAE,EACtFT,IAAI,CAAC,CAAC8B,GAAGtB,CAAC,MAAM,GAAGsB,CAAC,KAAKxC,MAAMC,QAAQiB,CAAC,IAAIA,EAAEuB,KAAK,IAAI,IAAIvB,CAAC,EAAE,EAC9DuB,KAAK,IAAI;AACZrK,UAAMe,SAASsB,MAAMnB,SAAS,gBAAgB;AAAA,EAChD;AAEA,QAAMoJ,UAAUA,MAAM;AACpB,UAAMjI,OAAOqD,SAAAA;AACb,YAAQ1F,MAAMC,OAAOwG,UAAU,CAAA,GAC5B0D,OAAQtB,CAAAA,MAAMA,EAAE0B,QAAQ,EACxBC,MAAO3B,CAAAA,MAAM;AACZ,YAAM4B,MAAMpI,KAAKwG,EAAExC,IAAI;AACvB,UAAIuB,MAAMC,QAAQ4C,GAAG,EAAG,QAAOA,IAAI1B,SAAS;AAC5C,UAAI,OAAO0B,QAAQ,UAAW,QAAO;AACrC,aAAOA,QAAQzH,UAAayH,QAAQ;AAAA,IACtC,CAAC;AAAA,EACL;AAGA,QAAMC,WAAWA,CAAClE,UAAgC;AAChD,UAAMmE,UAAU9E,iBAAiBW,MAAMH,IAAI;AAC3C,QAAIsE,SAAS;AACX,aAAO;AAAA,QAAE,GAAGnE;AAAAA,QAAOhD,SAASmH;AAAAA,MAAAA;AAAAA,IAC9B;AACA,WAAOnE;AAAAA,EACT;AAEA,UAAA,MAAA;AAAA,QAAAoE,SAAAzK,eAAA0K,OAAA,GAAAC,SAAAF,OAAAtK,YAAA,CAAAyK,QAAAC,KAAA,IAAAjH,cAAA+G,OAAArK,WAAA,GAAAwK,SAAAF,OAAAtK,aAAA,CAAAyK,QAAAC,KAAA,IAAApH,cAAAkH,OAAAxK,WAAA,GAAA2K,SAAAF,OAAAzK,aAAA4K,SAAAD,OAAA9K;AAAAsK,WAAAU,iBAAA,UACkBvB,YAAY;AAAApJ,WAAAiK,QAAAxJ,gBACzBkC,KAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEvD,MAAMC,OAAOwG;AAAAA,MAAM;AAAA,MAAA/E,UAC1B8E,CAAAA,UAAKpF,gBACJmK,mBAAiB;AAAA,QAAA,IAChB/E,QAAK;AAAA,iBAAEkE,SAASlE,KAAK;AAAA,QAAC;AAAA,QAAA,IACtBvF,QAAK;AAAA,iBAAEyE,SAAAA,EAAWc,MAAMH,IAAI;AAAA,QAAC;AAAA,QAC7BmF,UAAWf,CAAAA,QAAQrE,YAAYI,MAAMH,MAAMoE,GAAG;AAAA,QAC9C/E;AAAAA,MAAAA,CAAkB;AAAA,IAAA,CAErB,GAAAqF,QAAAC,KAAA;AAAArK,WAAAiK,QAAAxJ,gBAIFC,MAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEyE,YAAAA,KAAiBE,eAAAA;AAAAA,MAAgB;AAAA,MAAA,IAAAvE,WAAA;AAAA,YAAA+J,SAAAtL,eAAAuL,OAAA;AAAA/K,eAAA8K,QAAArK,gBAExCC,MAAI;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAE2E,eAAAA;AAAAA,UAAgB;AAAA,UAAA,IAAEzE,WAAQ;AAAA,oBAAA,MAAA;AAAA,kBAAAmK,SAAAxL,eAAAyL,QAAA;AAAAjL,qBAAAgL,QACS5F,WAAW;AAAA,qBAAA4F;AAAAA,YAAA,GAAA;AAAA,UAAA;AAAA,UAAA,IAAAjK,WAAA;AAAA,mBAAAvB,eAAA0L,OAAA;AAAA,UAAA;AAAA,QAAA,CAAA,CAAA;AAAA,eAAAJ;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAP,QAAAC,KAAA;AAAAxK,WAAA0K,QAAA,MAazDrL,MAAMC,OAAO6L,eAAe,QAAQ;AAAAxJ,WAAA,MAAAyJ,YAAAV,oBAH3B,CAACf,QAAAA,CAAS,CAAA;AAAA,WAAAM;AAAAA,EAAA,GAAA;AAQ9B;AAACoB,eAAA,CAAA,OAAA,CAAA;"}
1
+ {"version":3,"file":"ChatPrompt.js","sources":["../../src/components/ChatPrompt.tsx"],"sourcesContent":["/**\n * ChatPrompt — Ephemeral structured interaction above chat input\n * v2.4.0: choice, confirm, form subtypes\n *\n * @experimental — This component may change without major bump until v2.5.0.\n *\n * Renders above the chat input. User responds → consumer calls `onSubmit` →\n * prompt disappears.\n *\n * ## AbortSignal — known limitation (v5.1.0)\n *\n * **`ChatPrompt` itself does NOT listen to any `AbortSignal`.** It is a pure\n * presentation component: render a config, call `onSubmit` on user answer,\n * call `onDismiss` on X/Cancel. Lifecycle (including abort handling) is the\n * consumer's responsibility.\n *\n * `ChatCommands.showChatPrompt(config, signal?)` declares a `signal?` argument\n * in its type, but in v5.0.0/v5.1.0 mcp-ui ships **no default handler** for\n * this command — every consumer wires its own `bus.commands.handle('showChatPrompt', ...)`.\n * Each consumer's handler is responsible for:\n *\n * 1. Storing a `{ resolve, reject }` pair when the command fires.\n * 2. Calling `resolve(response)` from `onSubmit` / `resolve(dismissed)` from `onDismiss`.\n * 3. If a `signal` is provided: `signal.addEventListener('abort', () =>\n * reject(new DOMException('Prompt aborted', 'AbortError')))` and cleaning\n * up the listener on resolve/dismiss.\n *\n * The `DOMException('AbortError')` shape is the Web Platform convention\n * (matches `fetch()`, `Response.body.cancel()`, `WritableStream.abort()`).\n * Consumers can branch on `err.name === 'AbortError'` without importing any\n * mcp-ui type.\n *\n * A `createChatPromptController()` primitive centralising this wiring\n * (resolver lifecycle + re-entrance + abort) is planned for v5.2.0 — see\n * `docs/2026/r&d/mcpui-v5.1.0-consensus.md` for the design discussion.\n *\n * ## Re-entrance — known limitation (v5.1.0)\n *\n * Also handled by the consumer. If a new `showChatPrompt` arrives while a\n * previous one is active, the consumer's handler must decide whether to\n * auto-reject the previous Promise, queue, or throw. mcp-ui does not\n * currently enforce any policy. See the same design doc for the v5.2.0\n * direction (auto-reject with `PromptReplacedError`).\n */\n\nimport { Component, Show, For, createSignal, createEffect, onCleanup, Switch, Match } from 'solid-js'\nimport type {\n ChatPromptConfig,\n ChatPromptResponse,\n ChoicePromptConfig,\n ConfirmPromptConfig,\n FormPromptConfig,\n} from '../types/chat-bus'\nimport { FormFieldRenderer } from './FormFieldRenderer'\nimport type { FormFieldParams } from '../types'\n\nexport interface ChatPromptProps {\n /** Prompt configuration */\n config: ChatPromptConfig\n /** Called when user responds */\n onSubmit: (response: ChatPromptResponse) => void\n /** Called when user dismisses (e.g. \"send as-is\") */\n onDismiss?: () => void\n /** Label for the dismiss button (replaces X icon). Default: shows X icon. */\n dismissLabel?: string\n}\n\n/**\n * @experimental\n * Ephemeral interaction component — choice buttons, confirmation dialog, or quick form.\n * Designed to sit between the chat messages and the input area.\n *\n * @example\n * <ChatPrompt\n * config={{ type: 'choice', title: 'Format?', config: { options: [...] } }}\n * onSubmit={(r) => bus.events.emit('onChatPromptResponse', { streamKey, response: r })}\n * onDismiss={() => setActivePrompt(null)}\n * />\n */\nexport const ChatPrompt: Component<ChatPromptProps> = (props) => {\n // F1: Guard against null/undefined config (e.g. after dismiss clears state)\n if (!props.config) return null\n\n return (\n <div\n class=\"w-full max-w-2xl mx-auto mb-2 bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-lg overflow-visible\"\n style={{ animation: 'chat-prompt-slide-up 0.2s ease-out' }}\n role=\"dialog\"\n aria-label={props.config.title}\n >\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-2.5 border-b border-gray-100 dark:border-gray-700\">\n <p class=\"text-sm font-medium text-gray-900 dark:text-white\">{props.config.title}</p>\n <button\n onClick={() => {\n props.onDismiss?.()\n props.onSubmit({ type: props.config.type, value: '', label: '', dismissed: true })\n }}\n class={props.dismissLabel\n ? 'px-3 py-1 text-xs font-medium text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-colors'\n : 'p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors'\n }\n aria-label={props.dismissLabel || 'Dismiss'}\n >\n <Show when={props.dismissLabel} fallback={\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n }>\n {props.dismissLabel}\n </Show>\n </button>\n </div>\n\n {/* Body — type-specific */}\n <div class=\"px-4 py-3\">\n <Switch>\n <Match when={props.config.type === 'choice'}>\n <ChoiceBody\n config={props.config.config as ChoicePromptConfig}\n onSelect={(value, label) => props.onSubmit({ type: 'choice', value, label })}\n />\n </Match>\n <Match when={props.config.type === 'confirm'}>\n <ConfirmBody\n config={props.config.config as ConfirmPromptConfig}\n onConfirm={() => props.onSubmit({ type: 'confirm', value: 'confirmed', label: (props.config.config as ConfirmPromptConfig).confirmLabel || 'Confirmed' })}\n onCancel={() => {\n props.onDismiss?.()\n props.onSubmit({ type: 'confirm', value: 'cancelled', label: (props.config.config as ConfirmPromptConfig).cancelLabel || 'Cancelled', dismissed: true })\n }}\n />\n </Match>\n <Match when={props.config.type === 'form'}>\n <FormBody\n config={props.config.config as FormPromptConfig}\n onSubmit={(data, label) => props.onSubmit({ type: 'form', value: data, label })}\n />\n </Match>\n </Switch>\n </div>\n\n <style>{`\n @keyframes chat-prompt-slide-up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `}</style>\n </div>\n )\n}\n\n// ─── Choice ──────────────────────────────────────────────────\n\nconst ChoiceBody: Component<{\n config: ChoicePromptConfig\n onSelect: (value: string, label: string) => void\n}> = (props) => {\n const layoutClass = () => {\n const base = (() => {\n switch (props.config.layout) {\n case 'vertical': return 'flex flex-col gap-2'\n case 'grid': return 'grid grid-cols-2 gap-2'\n default: return 'flex flex-wrap gap-2'\n }\n })()\n const extra = props.config.containerClass\n return extra ? `${base} ${extra}` : base\n }\n\n const buttonClass = () => {\n const base = 'px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white hover:bg-blue-50 hover:border-blue-300 dark:hover:bg-blue-900/30 dark:hover:border-blue-600 transition-colors text-left'\n const extra = props.config.buttonClass\n return extra ? `${base} ${extra}` : base\n }\n\n return (\n <div class={layoutClass()}>\n <For each={props.config.options}>\n {(option, i) => (\n <button\n type=\"button\"\n onClick={() => props.onSelect(option.value, option.label)}\n class={buttonClass()}\n >\n <Show\n when={props.config.optionRenderer}\n fallback={\n <>\n <Show when={option.icon}>\n <span class=\"mr-2\">{option.icon}</span>\n </Show>\n {option.label}\n <Show when={option.description}>\n <span class=\"block text-xs text-gray-500 dark:text-gray-400 mt-0.5 font-normal\">{option.description}</span>\n </Show>\n </>\n }\n >\n {props.config.optionRenderer!(option, i())}\n </Show>\n </button>\n )}\n </For>\n </div>\n )\n}\n\n// ─── Confirm ─────────────────────────────────────────────────\n\nconst ConfirmBody: Component<{\n config: ConfirmPromptConfig\n onConfirm: () => void\n onCancel: () => void\n}> = (props) => {\n const isDanger = () => props.config.variant === 'danger'\n\n return (\n <div>\n <Show when={props.config.message}>\n <p class=\"text-sm text-gray-600 dark:text-gray-400 mb-3\">{props.config.message}</p>\n </Show>\n <div class=\"flex gap-2 justify-end\">\n <button\n onClick={props.onCancel}\n class=\"px-4 py-2 text-sm font-medium rounded-lg border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n >\n {props.config.cancelLabel || 'Cancel'}\n </button>\n <button\n onClick={props.onConfirm}\n class={`px-4 py-2 text-sm font-medium rounded-lg text-white transition-colors ${\n isDanger()\n ? 'bg-red-600 hover:bg-red-700'\n : 'bg-blue-600 hover:bg-blue-700'\n }`}\n >\n {props.config.confirmLabel || 'Confirm'}\n </button>\n </div>\n </div>\n )\n}\n\n// ─── Form (delegates to FormFieldRenderer for all field types) ───\n\nconst FormBody: Component<{\n config: FormPromptConfig\n onSubmit: (data: Record<string, unknown>, label: string) => void\n}> = (props) => {\n const [formData, setFormData] = createSignal<Record<string, any>>({})\n const [dynamicOptions, setDynamicOptions] = createSignal<Record<string, Array<{ label: string; value: string }>>>({})\n const [previewText, setPreviewText] = createSignal<string>('')\n const [previewLoading, setPreviewLoading] = createSignal(false)\n let previewTimer: ReturnType<typeof setTimeout> | null = null\n\n const updateField = (name: string, value: any) => {\n setFormData((prev) => ({ ...prev, [name]: value }))\n }\n\n // --- depends_on: fetch child options when parent changes ---\n createEffect(() => {\n const data = formData()\n for (const field of props.config.fields || []) {\n const dep = field.dependsOn || (field as any).depends_on\n if (!dep) continue\n const parentValue = data[dep.field]\n if (!parentValue) continue\n\n const apiUrl = (dep.apiUrl || dep.api_url || '').replace('{value}', encodeURIComponent(parentValue))\n if (!apiUrl) continue\n\n const params = new URLSearchParams(dep.extraParams || dep.extra_params || {})\n fetch(`${apiUrl}?${params}`)\n .then((r) => r.json())\n .then((items) => {\n const arr = Array.isArray(items) ? items : items.results || items.features || []\n const labelKey = dep.labelField || dep.label_field || 'label'\n const valueKey = dep.valueField || dep.value_field || 'value'\n setDynamicOptions((prev) => ({\n ...prev,\n [field.name]: arr.map((item: any) => ({\n label: item[labelKey] || String(item),\n value: String(item[valueKey] || item[labelKey] || item),\n })),\n }))\n })\n .catch(() => {})\n }\n })\n\n // --- preview: debounced live preview ---\n createEffect(() => {\n const preview = props.config.preview\n if (!preview) return\n\n const data = formData()\n // Check if any preview field has a value\n const hasValues = preview.fields.some((f) => {\n const v = data[f]\n return v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0)\n })\n if (!hasValues) { setPreviewText(''); return }\n\n if (previewTimer) clearTimeout(previewTimer)\n previewTimer = setTimeout(async () => {\n setPreviewLoading(true)\n try {\n const body: Record<string, any> = {}\n for (const f of preview.fields) {\n if (data[f] !== undefined) body[f] = data[f]\n }\n const res = await fetch(preview.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n credentials: 'include',\n body: JSON.stringify(body),\n })\n if (res.ok) {\n const result = await res.json()\n setPreviewText(result.summary_fr || result.summary || result.message || JSON.stringify(result))\n }\n } catch {\n setPreviewText('')\n }\n setPreviewLoading(false)\n }, preview.debounceMs || 500)\n })\n\n onCleanup(() => { if (previewTimer) clearTimeout(previewTimer) })\n\n const handleSubmit = (e: Event) => {\n e.preventDefault()\n const data = formData()\n const label = Object.entries(data)\n .filter(([, v]) => v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0))\n .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : v}`)\n .join(', ')\n props.onSubmit(data, label || 'Form submitted')\n }\n\n const isValid = () => {\n const data = formData()\n return (props.config.fields || [])\n .filter((f) => f.required)\n .every((f) => {\n const val = data[f.name]\n if (Array.isArray(val)) return val.length > 0\n if (typeof val === 'boolean') return true\n return val !== undefined && val !== ''\n })\n }\n\n // Build field with dynamic options override\n const getField = (field: any): FormFieldParams => {\n const dynOpts = dynamicOptions()[field.name]\n if (dynOpts) {\n return { ...field, options: dynOpts } as FormFieldParams\n }\n return field as FormFieldParams\n }\n\n return (\n <form onSubmit={handleSubmit} class=\"flex flex-col gap-3\">\n <For each={props.config.fields}>\n {(field) => (\n <FormFieldRenderer\n field={getField(field)}\n value={formData()[field.name]}\n onChange={(val) => updateField(field.name, val)}\n formData={formData}\n />\n )}\n </For>\n\n {/* Live preview */}\n <Show when={previewText() || previewLoading()}>\n <div class=\"px-3 py-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800 text-sm\">\n <Show when={previewLoading()} fallback={\n <p class=\"text-blue-700 dark:text-blue-300\">{previewText()}</p>\n }>\n <p class=\"text-blue-400 animate-pulse\">Loading preview...</p>\n </Show>\n </div>\n </Show>\n\n <div class=\"flex justify-end\">\n <button\n type=\"submit\"\n disabled={!isValid()}\n class=\"px-4 py-2 text-sm font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors\"\n >\n {props.config.submitLabel || 'Submit'}\n </button>\n </div>\n </form>\n )\n}\n"],"names":["ChatPrompt","props","config","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_$insert","title","$$click","onDismiss","onSubmit","type","value","label","dismissed","_$createComponent","Show","when","dismissLabel","fallback","_tmpl$2","children","Switch","Match","ChoiceBody","onSelect","ConfirmBody","onConfirm","confirmLabel","onCancel","cancelLabel","FormBody","data","_$effect","_p$","_v$","_v$2","_v$3","e","_$setAttribute","t","_$className","a","undefined","_$runHydrationEvents","layoutClass","base","layout","extra","containerClass","buttonClass","_el$7","_tmpl$3","For","each","options","option","i","_el$8","_tmpl$4","optionRenderer","icon","_el$9","_tmpl$5","_$memo","description","_el$0","_tmpl$6","isDanger","variant","_el$1","_tmpl$8","_el$14","_el$15","_co$","_$getNextMarker","_el$11","_el$12","_el$13","message","_el$10","_tmpl$7","_$addEventListener","formData","setFormData","createSignal","dynamicOptions","setDynamicOptions","previewText","setPreviewText","previewLoading","setPreviewLoading","previewTimer","updateField","name","prev","createEffect","field","fields","dep","dependsOn","depends_on","parentValue","apiUrl","api_url","replace","encodeURIComponent","params","URLSearchParams","extraParams","extra_params","fetch","then","r","json","items","arr","Array","isArray","results","features","labelKey","labelField","label_field","valueKey","valueField","value_field","map","item","String","catch","preview","hasValues","some","f","v","length","setTimeout","body","res","endpoint","method","headers","credentials","JSON","stringify","ok","result","summary_fr","summary","debounceMs","onCleanup","handleSubmit","preventDefault","Object","entries","filter","k","join","isValid","required","every","val","getField","dynOpts","_el$16","_tmpl$1","_el$21","_el$22","_co$2","_el$23","_el$24","_co$3","_el$19","_el$20","addEventListener","FormFieldRenderer","onChange","_el$17","_tmpl$0","_el$25","_tmpl$10","_tmpl$9","submitLabel","_$setProperty","_$delegateEvents"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -75,5 +75,5 @@ export { validateComponent, validateLayout, validateIframeDomain, getIframeSandb
75
75
  export { clarificationToPromptConfig } from './services/chat-bus';
76
76
  export { createMockChatBus } from './testing';
77
77
  export type { MockChatBusOptions } from './testing';
78
- export type { ChatEventBase, ChatEvents, ChatCommands, ChatBus, ChatEventEmitter, ChatCommandHandler, EventSubscribeOptions, ChatPromptConfig, ChatPromptResponse, ChoicePromptConfig, ConfirmPromptConfig, FormPromptConfig, SuggestionItem, AgentContext, BriefingEvent, BriefingSection, ScratchpadState, ScratchpadSection, ScratchpadEvent, StreamDoneMetadata, ChatError, Citation, ToolCallEvent, ClarificationEvent, DataValidation, LLMNumber, HallucinatedNumber, DataValidationOptions, VerifiedTextContent, DataPreviewColumn, DataPreviewContent, MapSectionContent, AgentCardContent, SplitStepperContent, AgentHandoffContent, BriefingDiffContent, } from './types/chat-bus';
78
+ export type { ChatEventBase, ChatEvents, ChatCommands, ChatBus, ChatEventEmitter, ChatCommandHandler, EventSubscribeOptions, ChatPromptConfig, ChatPromptResponse, ChoicePromptConfig, ChoiceOption, ConfirmPromptConfig, FormPromptConfig, SuggestionItem, AgentContext, BriefingEvent, BriefingSection, ScratchpadState, ScratchpadSection, ScratchpadEvent, StreamDoneMetadata, ChatError, Citation, ToolCallEvent, ClarificationEvent, DataValidation, LLMNumber, HallucinatedNumber, DataValidationOptions, VerifiedTextContent, DataPreviewColumn, DataPreviewContent, MapSectionContent, AgentCardContent, SplitStepperContent, AgentHandoffContent, BriefingDiffContent, } from './types/chat-bus';
79
79
  //# sourceMappingURL=index.d.ts.map
package/dist/index.d.ts CHANGED
@@ -75,5 +75,5 @@ export { validateComponent, validateLayout, validateIframeDomain, getIframeSandb
75
75
  export { clarificationToPromptConfig } from './services/chat-bus';
76
76
  export { createMockChatBus } from './testing';
77
77
  export type { MockChatBusOptions } from './testing';
78
- export type { ChatEventBase, ChatEvents, ChatCommands, ChatBus, ChatEventEmitter, ChatCommandHandler, EventSubscribeOptions, ChatPromptConfig, ChatPromptResponse, ChoicePromptConfig, ConfirmPromptConfig, FormPromptConfig, SuggestionItem, AgentContext, BriefingEvent, BriefingSection, ScratchpadState, ScratchpadSection, ScratchpadEvent, StreamDoneMetadata, ChatError, Citation, ToolCallEvent, ClarificationEvent, DataValidation, LLMNumber, HallucinatedNumber, DataValidationOptions, VerifiedTextContent, DataPreviewColumn, DataPreviewContent, MapSectionContent, AgentCardContent, SplitStepperContent, AgentHandoffContent, BriefingDiffContent, } from './types/chat-bus';
78
+ export type { ChatEventBase, ChatEvents, ChatCommands, ChatBus, ChatEventEmitter, ChatCommandHandler, EventSubscribeOptions, ChatPromptConfig, ChatPromptResponse, ChoicePromptConfig, ChoiceOption, ConfirmPromptConfig, FormPromptConfig, SuggestionItem, AgentContext, BriefingEvent, BriefingSection, ScratchpadState, ScratchpadSection, ScratchpadEvent, StreamDoneMetadata, ChatError, Citation, ToolCallEvent, ClarificationEvent, DataValidation, LLMNumber, HallucinatedNumber, DataValidationOptions, VerifiedTextContent, DataPreviewColumn, DataPreviewContent, MapSectionContent, AgentCardContent, SplitStepperContent, AgentHandoffContent, BriefingDiffContent, } from './types/chat-bus';
79
79
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  * @experimental — These types may change without major bump until stabilized in v2.5.0.
6
6
  * See CHANGELOG for breaking changes on experimental types.
7
7
  */
8
+ import type { JSX } from 'solid-js';
8
9
  import type { UIComponent, UILayout } from './index';
9
10
  /**
10
11
  * @experimental
@@ -103,15 +104,44 @@ export interface ChatCommands {
103
104
  /**
104
105
  * Show a ChatPrompt (choice, confirm, form) above the input (C4).
105
106
  *
106
- * **Known limitation (v4.3.9):** Not re-entrant. If called while another
107
- * prompt is already active, the previous prompt's Promise will never resolve
108
- * (memory leak). Host apps must queue prompts or dismiss the previous one
109
- * manually before showing a new one. Fix planned for v4.4.0 (auto-reject
110
- * previous prompt or FIFO queue).
107
+ * **No default handler in v5.0.0 / v5.1.0.** `showChatPrompt` is a command
108
+ * *name*, not a default implementation mcp-ui ships `ChatPrompt` (the
109
+ * presentation component) and the bus (event/command plumbing), but the
110
+ * handler that threads a Promise resolver through the SolidJS lifecycle is
111
+ * the consumer's responsibility. Every host app calls
112
+ * `bus.commands.handle('showChatPrompt', (config, signal?) => { ... })`.
111
113
  *
112
- * **AbortSignal limitation (v4.3.9):** The `signal` argument is currently
113
- * unused — `ChatPrompt` does not listen to aborts. Host apps must wire
114
- * abort Promise rejection themselves. Fix planned for v4.4.0.
114
+ * ### Implementer contract
115
+ *
116
+ * A conforming handler MUST:
117
+ *
118
+ * 1. Return a `Promise<ChatPromptResponse>`.
119
+ * 2. Resolve the Promise from the `ChatPrompt` component's `onSubmit`
120
+ * (explicit answer) or from `onDismiss` (dismissed flag true).
121
+ * 3. If a `signal` is provided:
122
+ * - If `signal.aborted` is already `true`, reject with
123
+ * `new DOMException('Prompt aborted', 'AbortError')` synchronously
124
+ * (or via `Promise.reject`) and do NOT show the UI.
125
+ * - Otherwise, register `signal.addEventListener('abort', () =>
126
+ * reject(new DOMException('Prompt aborted', 'AbortError')))` and
127
+ * clean up the listener on resolve/dismiss.
128
+ * 4. Enforce re-entrance policy — if a previous prompt is still active
129
+ * when a new one arrives, the recommended behavior is auto-reject the
130
+ * previous Promise with a custom error (e.g. `PromptReplacedError`).
131
+ * Alternatives: FIFO queue, or throw synchronously.
132
+ *
133
+ * The `DOMException('AbortError')` shape is the Web Platform convention
134
+ * (matches `fetch()`, `Response.body.cancel()`, `WritableStream.abort()`).
135
+ * Consumers branching on the error can do
136
+ * `catch (err) { if (err.name === 'AbortError') return; throw err }`.
137
+ *
138
+ * ### Planned primitive (v5.2.0)
139
+ *
140
+ * A `createChatPromptController(setActivePrompt)` helper will centralise
141
+ * the resolver lifecycle + abort + re-entrance logic once, so consumers
142
+ * can write `bus.commands.handle('showChatPrompt', ctrl.handle)` instead
143
+ * of threading a `let chatPromptResolver` closure by hand. Design doc:
144
+ * `docs/2026/r&d/mcpui-v5.1.0-consensus.md`.
115
145
  */
116
146
  showChatPrompt: (config: ChatPromptConfig, signal?: AbortSignal) => Promise<ChatPromptResponse>;
117
147
  /** Dismiss the active ChatPrompt */
@@ -184,21 +214,94 @@ export interface ChatPromptConfig {
184
214
  /** Type-specific configuration */
185
215
  config: ChoicePromptConfig | ConfirmPromptConfig | FormPromptConfig;
186
216
  }
187
- export interface ChoicePromptConfig {
188
- options: Array<{
189
- value: string;
190
- label: string;
191
- icon?: string;
192
- description?: string;
193
- /**
194
- * Free-form metadata (confidence, source, tags, ...).
195
- * Opaque to default renderer — use a custom ChoiceBody wrapper to display it.
196
- * Preserved through showChatPrompt → ChatPromptResponse roundtrip.
197
- * @since v4.3.9
198
- */
199
- metadata?: Record<string, unknown>;
200
- }>;
217
+ /**
218
+ * A single choice option. The generic `TMeta` parameter flows through the
219
+ * whole `ChoicePromptConfig<TMeta>` shape so consumers can strongly-type
220
+ * their metadata in `optionRenderer` without casting.
221
+ *
222
+ * @since v4.3.9 (metadata), v5.1.0 (generic TMeta + optionRenderer typing)
223
+ */
224
+ export interface ChoiceOption<TMeta = Record<string, unknown>> {
225
+ value: string;
226
+ label: string;
227
+ icon?: string;
228
+ description?: string;
229
+ /**
230
+ * Free-form metadata (confidence, source, tags, ...).
231
+ * Opaque to the default renderer — use `optionRenderer` to display it.
232
+ * Preserved through `showChatPrompt → ChatPromptResponse` roundtrip.
233
+ * @since v4.3.9
234
+ */
235
+ metadata?: TMeta;
236
+ }
237
+ export interface ChoicePromptConfig<TMeta = Record<string, unknown>> {
238
+ options: Array<ChoiceOption<TMeta>>;
201
239
  layout?: 'horizontal' | 'vertical' | 'grid';
240
+ /**
241
+ * Optional render prop for custom option bodies (badges, confidence
242
+ * indicators, rich layouts). Replaces the default `label + icon +
243
+ * description` body. mcp-ui still wraps the returned JSX in a `<button>`
244
+ * with the `onClick` handler, keyboard support, and focus styles — only
245
+ * the *content* of the button is yours.
246
+ *
247
+ * @param option The full `ChoiceOption` including strongly-typed `metadata`.
248
+ * @param index Zero-based position in the `options` array.
249
+ *
250
+ * @example
251
+ * ```tsx
252
+ * interface ConfBadgeMeta { confidence: number; source: string }
253
+ *
254
+ * bus.commands.exec('showChatPrompt', {
255
+ * type: 'choice',
256
+ * title: 'Pick an intent',
257
+ * config: {
258
+ * layout: 'vertical',
259
+ * options: [
260
+ * { value: 'a', label: 'Immobilier', metadata: { confidence: 0.9, source: 'llm' } },
261
+ * { value: 'b', label: 'Santé', metadata: { confidence: 0.4, source: 'llm' } },
262
+ * ],
263
+ * optionRenderer: (opt: ChoiceOption<ConfBadgeMeta>) => (
264
+ * <div>
265
+ * {opt.label}
266
+ * <span class="ml-2 text-xs">
267
+ * ({Math.round((opt.metadata?.confidence ?? 0) * 100)}%)
268
+ * </span>
269
+ * </div>
270
+ * ),
271
+ * },
272
+ * } as ChatPromptConfig)
273
+ * ```
274
+ *
275
+ * ### ⚠️ Accessibility
276
+ * Do NOT return `<button>`, `<a href>`, or other interactive elements from
277
+ * `optionRenderer`. mcp-ui already wraps the content in a `<button>`, and
278
+ * nested interactive elements break screen-reader semantics, keyboard
279
+ * focus order, and click-through behaviour.
280
+ *
281
+ * ### ⚠️ Stale closures
282
+ * `optionRenderer` is called once per option per render. If you capture
283
+ * SolidJS signals inside the closure, wrap the access in a thunk so the
284
+ * framework tracks the dependency correctly. Don't destructure signal
285
+ * values into locals outside reactive scopes.
286
+ *
287
+ * @since v5.1.0
288
+ */
289
+ optionRenderer?: (option: ChoiceOption<TMeta>, index: number) => JSX.Element;
290
+ /**
291
+ * Custom Tailwind classes appended to each option button (after mcp-ui's
292
+ * defaults). Escape hatch for colour/border/radius tweaks that don't
293
+ * warrant a full `optionRenderer`.
294
+ *
295
+ * @since v5.1.0
296
+ */
297
+ buttonClass?: string;
298
+ /**
299
+ * Custom Tailwind classes appended to the options container (the
300
+ * flex/grid wrapper that lays out the buttons).
301
+ *
302
+ * @since v5.1.0
303
+ */
304
+ containerClass?: string;
202
305
  }
203
306
  export interface ConfirmPromptConfig {
204
307
  message?: string;