@mulmochat-plugin/form 0.1.2 → 0.2.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/dist/vue.js ADDED
@@ -0,0 +1,582 @@
1
+ import { pluginCore as K } from "./core.js";
2
+ import { SAMPLES as We, TOOL_DEFINITION as Ge, TOOL_NAME as Ke, executeForm as Qe } from "./core.js";
3
+ import { defineComponent as P, ref as f, watch as N, computed as S, createElementBlock as i, openBlock as u, createCommentVNode as g, createElementVNode as l, toDisplayString as v, createTextVNode as B, Fragment as D, renderList as M, withModifiers as j, normalizeClass as b, withDirectives as $, vModelText as F, vModelRadio as Q, vModelSelect as X, vModelCheckbox as Y, normalizeStyle as Z } from "vue";
4
+ const ee = { class: "w-full h-full overflow-y-auto p-8" }, te = {
5
+ key: 0,
6
+ class: "max-w-3xl w-full mx-auto"
7
+ }, re = {
8
+ key: 0,
9
+ class: "text-gray-900 text-3xl font-bold mb-4 text-center"
10
+ }, ae = {
11
+ key: 1,
12
+ class: "text-gray-600 text-center mb-8 text-lg"
13
+ }, ne = {
14
+ key: 2,
15
+ class: "bg-red-50 border-2 border-red-500 rounded-lg p-4 mb-6",
16
+ role: "alert"
17
+ }, oe = { class: "text-red-700 space-y-1" }, se = ["href", "onClick"], ie = ["id"], ue = ["for"], le = {
18
+ key: 0,
19
+ class: "text-red-500 ml-1",
20
+ "aria-label": "required"
21
+ }, de = {
22
+ key: 0,
23
+ class: "text-gray-600 text-sm mb-2"
24
+ }, ce = ["id", "onUpdate:modelValue", "placeholder", "aria-invalid", "aria-describedby", "onBlur", "onInput"], ve = ["id", "onUpdate:modelValue", "placeholder", "rows", "aria-invalid", "aria-describedby", "onBlur", "onInput"], me = ["id", "onUpdate:modelValue", "min", "max", "step", "aria-invalid", "aria-describedby", "onBlur", "onInput"], he = ["id", "onUpdate:modelValue", "min", "max", "aria-invalid", "aria-describedby", "onBlur", "onChange"], pe = ["id", "onUpdate:modelValue", "aria-invalid", "aria-describedby", "onBlur", "onChange"], be = ["aria-invalid", "aria-describedby"], ge = ["name", "value", "onUpdate:modelValue", "onChange", "onBlur"], ye = { class: "text-gray-800" }, xe = ["id", "onUpdate:modelValue", "aria-invalid", "aria-describedby", "onBlur", "onChange"], _e = ["value"], $e = ["aria-invalid", "aria-describedby"], we = ["value", "onUpdate:modelValue", "onChange", "onBlur"], ke = { class: "text-gray-800" }, Ve = ["id"], fe = { key: 0 }, Se = { class: "mt-8 flex justify-center" }, Ce = ["disabled"], Le = { class: "mt-4 text-center text-gray-600 text-sm" }, Be = /* @__PURE__ */ P({
25
+ __name: "View",
26
+ props: {
27
+ selectedResult: {},
28
+ sendTextMessage: { type: Function }
29
+ },
30
+ emits: ["updateResult"],
31
+ setup(C, { emit: w }) {
32
+ const p = C, L = w, d = f(null), o = f({}), n = f(/* @__PURE__ */ new Set()), h = f(/* @__PURE__ */ new Map()), m = f(!1), U = f(!1), k = f(!1);
33
+ N(
34
+ () => p.selectedResult,
35
+ (t, a) => {
36
+ if (t?.toolName === "presentForm" && t.jsonData && (!a || !a.jsonData || a.uuid !== t.uuid || a.jsonData !== t.jsonData)) {
37
+ if (k.value = !0, d.value = t.jsonData, o.value = {}, d.value.fields.forEach((r) => {
38
+ o.value[r.id] = y(r);
39
+ }), t.viewState) {
40
+ const r = t.viewState;
41
+ r.userResponses && Object.assign(o.value, r.userResponses), r.touched && (n.value = new Set(r.touched), r.touched.forEach((c) => {
42
+ E(c);
43
+ })), r.submitted !== void 0 && (m.value = r.submitted);
44
+ }
45
+ k.value = !1;
46
+ }
47
+ },
48
+ { immediate: !0 }
49
+ ), N(
50
+ [o, n, m],
51
+ () => {
52
+ if (k.value || !p.selectedResult) return;
53
+ const t = {
54
+ ...p.selectedResult,
55
+ viewState: {
56
+ userResponses: { ...o.value },
57
+ touched: Array.from(n.value),
58
+ submitted: m.value
59
+ }
60
+ };
61
+ L("updateResult", t);
62
+ },
63
+ { deep: !0 }
64
+ );
65
+ function y(t) {
66
+ const a = t;
67
+ if (a.defaultValue !== void 0)
68
+ switch (t.type) {
69
+ case "radio":
70
+ case "dropdown": {
71
+ const e = t.choices.indexOf(
72
+ a.defaultValue
73
+ );
74
+ return e !== -1 ? e : null;
75
+ }
76
+ case "checkbox":
77
+ return Array.isArray(a.defaultValue) ? a.defaultValue.map((e) => t.choices.indexOf(e)).filter((e) => e !== -1) : [];
78
+ default:
79
+ return a.defaultValue;
80
+ }
81
+ switch (t.type) {
82
+ case "text":
83
+ case "textarea":
84
+ return "";
85
+ case "number":
86
+ return t.min !== void 0 ? t.min : 0;
87
+ case "date":
88
+ case "time":
89
+ return "";
90
+ case "radio":
91
+ case "dropdown":
92
+ return null;
93
+ case "checkbox":
94
+ return [];
95
+ default:
96
+ return null;
97
+ }
98
+ }
99
+ function R(t) {
100
+ return t == null ? !0 : typeof t == "string" ? t.trim() === "" : Array.isArray(t) ? t.length === 0 : !1;
101
+ }
102
+ function A(t) {
103
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t);
104
+ }
105
+ function O(t) {
106
+ try {
107
+ return new URL(t), !0;
108
+ } catch {
109
+ return !1;
110
+ }
111
+ }
112
+ function I(t) {
113
+ return /^[\d\s\-+()]+$/.test(t) && t.replace(/\D/g, "").length >= 10;
114
+ }
115
+ function T(t, a) {
116
+ if (t.required && R(a))
117
+ return `${t.label} is required`;
118
+ if (R(a))
119
+ return null;
120
+ switch (t.type) {
121
+ case "text": {
122
+ const e = t;
123
+ if (e.validation === "email" && !A(a))
124
+ return "Please enter a valid email address";
125
+ if (e.validation === "url" && !O(a))
126
+ return "Please enter a valid URL";
127
+ if (e.validation === "phone" && !I(a))
128
+ return "Please enter a valid phone number";
129
+ if (typeof e.validation == "string" && e.validation !== "email" && e.validation !== "url" && e.validation !== "phone")
130
+ try {
131
+ if (!new RegExp(e.validation).test(a))
132
+ return `${t.label} format is invalid`;
133
+ } catch {
134
+ console.warn(`Invalid regex pattern: ${e.validation}`);
135
+ }
136
+ break;
137
+ }
138
+ case "textarea": {
139
+ const e = t;
140
+ if (e.minLength && a.length < e.minLength)
141
+ return `Must be at least ${e.minLength} characters (currently ${a.length})`;
142
+ if (e.maxLength && a.length > e.maxLength)
143
+ return `Must be no more than ${e.maxLength} characters (currently ${a.length})`;
144
+ break;
145
+ }
146
+ case "number": {
147
+ const e = t;
148
+ if (e.min !== void 0 && a < e.min)
149
+ return `Must be at least ${e.min}`;
150
+ if (e.max !== void 0 && a > e.max)
151
+ return `Must be no more than ${e.max}`;
152
+ break;
153
+ }
154
+ case "date": {
155
+ const e = t;
156
+ if (e.minDate && a < e.minDate)
157
+ return `Date must be on or after ${e.minDate}`;
158
+ if (e.maxDate && a > e.maxDate)
159
+ return `Date must be on or before ${e.maxDate}`;
160
+ break;
161
+ }
162
+ case "checkbox": {
163
+ const e = t, r = a?.length || 0;
164
+ if (e.minSelections && r < e.minSelections)
165
+ return `Please select at least ${e.minSelections} option${e.minSelections > 1 ? "s" : ""}`;
166
+ if (e.maxSelections && r > e.maxSelections)
167
+ return `Please select no more than ${e.maxSelections} option${e.maxSelections > 1 ? "s" : ""}`;
168
+ break;
169
+ }
170
+ }
171
+ return null;
172
+ }
173
+ function E(t) {
174
+ const a = d.value?.fields.find((c) => c.id === t);
175
+ if (!a) return !0;
176
+ const e = o.value[t], r = T(a, e);
177
+ return r ? (h.value.set(t, {
178
+ fieldId: t,
179
+ message: r,
180
+ type: "custom"
181
+ }), !1) : (h.value.delete(t), !0);
182
+ }
183
+ function x(t) {
184
+ n.value.add(t), E(t);
185
+ }
186
+ function _(t) {
187
+ n.value.has(t) && E(t);
188
+ }
189
+ function s(t) {
190
+ return h.value.has(t);
191
+ }
192
+ function q(t) {
193
+ const a = document.getElementById(`input-${t}`);
194
+ a && (a.focus(), a.scrollIntoView({ behavior: "smooth", block: "center" }));
195
+ }
196
+ function H(t) {
197
+ return (t.type === "text" || t.type === "textarea") && t.maxLength !== void 0;
198
+ }
199
+ function z(t) {
200
+ if (t.type !== "text" && t.type !== "textarea") return !1;
201
+ const a = t.maxLength;
202
+ return a ? (o.value[t.id] || "").length / a > 0.9 : !1;
203
+ }
204
+ const J = S(() => d.value?.fields.filter((t) => t.required).length || 0), W = S(() => d.value ? d.value.fields.filter(
205
+ (t) => t.required && !R(o.value[t.id])
206
+ ).length : 0);
207
+ function G() {
208
+ if (m.value) return;
209
+ if (d.value?.fields.forEach((e) => {
210
+ n.value.add(e.id), E(e.id);
211
+ }), h.value.size > 0) {
212
+ U.value = !0;
213
+ const e = Array.from(h.value.keys())[0];
214
+ q(e);
215
+ return;
216
+ }
217
+ const t = {};
218
+ d.value?.fields.forEach((e) => {
219
+ const r = o.value[e.id];
220
+ e.type === "radio" || e.type === "dropdown" ? r != null ? t[e.id] = e.choices[r] : t[e.id] = null : e.type === "checkbox" ? t[e.id] = (r || []).map(
221
+ (c) => e.choices[c]
222
+ ) : t[e.id] = r;
223
+ });
224
+ const a = JSON.stringify(
225
+ {
226
+ formSubmission: {
227
+ formTitle: d.value?.title || "Form",
228
+ responses: t
229
+ }
230
+ },
231
+ null,
232
+ 2
233
+ );
234
+ m.value = !0, p.sendTextMessage(a);
235
+ }
236
+ return (t, a) => (u(), i("div", ee, [
237
+ d.value ? (u(), i("div", te, [
238
+ d.value.title ? (u(), i("h2", re, v(d.value.title), 1)) : g("", !0),
239
+ d.value.description ? (u(), i("p", ae, v(d.value.description), 1)) : g("", !0),
240
+ U.value && h.value.size > 0 ? (u(), i("div", ne, [
241
+ a[0] || (a[0] = l("h3", { class: "text-red-800 font-semibold mb-2 flex items-center gap-2" }, [
242
+ l("svg", {
243
+ class: "w-5 h-5",
244
+ fill: "currentColor",
245
+ viewBox: "0 0 20 20",
246
+ "aria-hidden": "true"
247
+ }, [
248
+ l("path", {
249
+ "fill-rule": "evenodd",
250
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",
251
+ "clip-rule": "evenodd"
252
+ })
253
+ ]),
254
+ B(" Please fix the following errors: ")
255
+ ], -1)),
256
+ l("ul", oe, [
257
+ (u(!0), i(D, null, M(h.value, ([e, r]) => (u(), i("li", { key: e }, [
258
+ l("a", {
259
+ href: `#${e}`,
260
+ onClick: j((c) => q(e), ["prevent"]),
261
+ class: "hover:underline cursor-pointer"
262
+ }, v(r.message), 9, se)
263
+ ]))), 128))
264
+ ])
265
+ ])) : g("", !0),
266
+ l("form", {
267
+ onSubmit: j(G, ["prevent"]),
268
+ class: "space-y-6"
269
+ }, [
270
+ (u(!0), i(D, null, M(d.value.fields, (e) => (u(), i("div", {
271
+ key: e.id,
272
+ id: e.id,
273
+ class: b(["form-field", { "has-error": s(e.id) && n.value.has(e.id) }])
274
+ }, [
275
+ l("label", {
276
+ for: `input-${e.id}`,
277
+ class: b(["block text-gray-800 font-semibold mb-2", {
278
+ "text-red-600": s(e.id) && n.value.has(e.id)
279
+ }])
280
+ }, [
281
+ B(v(e.label) + " ", 1),
282
+ e.required ? (u(), i("span", le, "*")) : g("", !0)
283
+ ], 10, ue),
284
+ e.description ? (u(), i("p", de, v(e.description), 1)) : g("", !0),
285
+ e.type === "text" ? $((u(), i("input", {
286
+ key: 1,
287
+ id: `input-${e.id}`,
288
+ "onUpdate:modelValue": (r) => o.value[e.id] = r,
289
+ type: "text",
290
+ placeholder: e.placeholder,
291
+ "aria-invalid": s(e.id) && n.value.has(e.id),
292
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0,
293
+ onBlur: (r) => x(e.id),
294
+ onInput: (r) => _(e.id),
295
+ class: b(["w-full px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors", {
296
+ "border-red-500 focus:ring-red-500": s(e.id) && n.value.has(e.id),
297
+ "border-gray-300": !s(e.id) || !n.value.has(e.id)
298
+ }])
299
+ }, null, 42, ce)), [
300
+ [F, o.value[e.id]]
301
+ ]) : e.type === "textarea" ? $((u(), i("textarea", {
302
+ key: 2,
303
+ id: `input-${e.id}`,
304
+ "onUpdate:modelValue": (r) => o.value[e.id] = r,
305
+ placeholder: e.placeholder,
306
+ rows: e.rows || 4,
307
+ "aria-invalid": s(e.id) && n.value.has(e.id),
308
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0,
309
+ onBlur: (r) => x(e.id),
310
+ onInput: (r) => _(e.id),
311
+ class: b(["w-full px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors resize-y", {
312
+ "border-red-500 focus:ring-red-500": s(e.id) && n.value.has(e.id),
313
+ "border-gray-300": !s(e.id) || !n.value.has(e.id)
314
+ }])
315
+ }, null, 42, ve)), [
316
+ [F, o.value[e.id]]
317
+ ]) : e.type === "number" ? $((u(), i("input", {
318
+ key: 3,
319
+ id: `input-${e.id}`,
320
+ "onUpdate:modelValue": (r) => o.value[e.id] = r,
321
+ type: "number",
322
+ min: e.min,
323
+ max: e.max,
324
+ step: e.step,
325
+ "aria-invalid": s(e.id) && n.value.has(e.id),
326
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0,
327
+ onBlur: (r) => x(e.id),
328
+ onInput: (r) => _(e.id),
329
+ class: b(["w-full px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors", {
330
+ "border-red-500 focus:ring-red-500": s(e.id) && n.value.has(e.id),
331
+ "border-gray-300": !s(e.id) || !n.value.has(e.id)
332
+ }])
333
+ }, null, 42, me)), [
334
+ [
335
+ F,
336
+ o.value[e.id],
337
+ void 0,
338
+ { number: !0 }
339
+ ]
340
+ ]) : e.type === "date" ? $((u(), i("input", {
341
+ key: 4,
342
+ id: `input-${e.id}`,
343
+ "onUpdate:modelValue": (r) => o.value[e.id] = r,
344
+ type: "date",
345
+ min: e.minDate,
346
+ max: e.maxDate,
347
+ "aria-invalid": s(e.id) && n.value.has(e.id),
348
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0,
349
+ onBlur: (r) => x(e.id),
350
+ onChange: (r) => _(e.id),
351
+ class: b(["w-full px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors", {
352
+ "border-red-500 focus:ring-red-500": s(e.id) && n.value.has(e.id),
353
+ "border-gray-300": !s(e.id) || !n.value.has(e.id)
354
+ }])
355
+ }, null, 42, he)), [
356
+ [F, o.value[e.id]]
357
+ ]) : e.type === "time" ? $((u(), i("input", {
358
+ key: 5,
359
+ id: `input-${e.id}`,
360
+ "onUpdate:modelValue": (r) => o.value[e.id] = r,
361
+ type: "time",
362
+ "aria-invalid": s(e.id) && n.value.has(e.id),
363
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0,
364
+ onBlur: (r) => x(e.id),
365
+ onChange: (r) => _(e.id),
366
+ class: b(["w-full px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors", {
367
+ "border-red-500 focus:ring-red-500": s(e.id) && n.value.has(e.id),
368
+ "border-gray-300": !s(e.id) || !n.value.has(e.id)
369
+ }])
370
+ }, null, 42, pe)), [
371
+ [F, o.value[e.id]]
372
+ ]) : e.type === "radio" ? (u(), i("div", {
373
+ key: 6,
374
+ class: "space-y-2",
375
+ role: "radiogroup",
376
+ "aria-invalid": s(e.id) && n.value.has(e.id),
377
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0
378
+ }, [
379
+ (u(!0), i(D, null, M(e.choices, (r, c) => (u(), i("label", {
380
+ key: c,
381
+ class: b(["flex items-center p-3 border-2 border-gray-300 rounded-lg cursor-pointer transition-all hover:bg-gray-50", {
382
+ "border-blue-500 bg-blue-50": o.value[e.id] === c,
383
+ "border-gray-300": o.value[e.id] !== c
384
+ }])
385
+ }, [
386
+ $(l("input", {
387
+ type: "radio",
388
+ name: e.id,
389
+ value: c,
390
+ "onUpdate:modelValue": (V) => o.value[e.id] = V,
391
+ onChange: (V) => _(e.id),
392
+ onBlur: (V) => x(e.id),
393
+ class: "mr-3 h-4 w-4 flex-shrink-0"
394
+ }, null, 40, ge), [
395
+ [Q, o.value[e.id]]
396
+ ]),
397
+ l("span", ye, v(r), 1)
398
+ ], 2))), 128))
399
+ ], 8, be)) : e.type === "dropdown" ? $((u(), i("select", {
400
+ key: 7,
401
+ id: `input-${e.id}`,
402
+ "onUpdate:modelValue": (r) => o.value[e.id] = r,
403
+ "aria-invalid": s(e.id) && n.value.has(e.id),
404
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0,
405
+ onBlur: (r) => x(e.id),
406
+ onChange: (r) => _(e.id),
407
+ class: b(["w-full px-4 py-2 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors bg-white", {
408
+ "border-red-500 focus:ring-red-500": s(e.id) && n.value.has(e.id),
409
+ "border-gray-300": !s(e.id) || !n.value.has(e.id)
410
+ }])
411
+ }, [
412
+ a[1] || (a[1] = l("option", {
413
+ value: null,
414
+ disabled: ""
415
+ }, "Select an option...", -1)),
416
+ (u(!0), i(D, null, M(e.choices, (r, c) => (u(), i("option", {
417
+ key: c,
418
+ value: c
419
+ }, v(r), 9, _e))), 128))
420
+ ], 42, xe)), [
421
+ [X, o.value[e.id]]
422
+ ]) : e.type === "checkbox" ? (u(), i("div", {
423
+ key: 8,
424
+ class: "space-y-2",
425
+ role: "group",
426
+ "aria-invalid": s(e.id) && n.value.has(e.id),
427
+ "aria-describedby": s(e.id) && n.value.has(e.id) ? `${e.id}-error` : void 0
428
+ }, [
429
+ (u(!0), i(D, null, M(e.choices, (r, c) => (u(), i("label", {
430
+ key: c,
431
+ class: b(["flex items-center p-3 border-2 border-gray-300 rounded-lg cursor-pointer transition-all hover:bg-gray-50", {
432
+ "border-blue-500 bg-blue-50": (o.value[e.id] || []).includes(c),
433
+ "border-gray-300": !(o.value[e.id] || []).includes(
434
+ c
435
+ )
436
+ }])
437
+ }, [
438
+ $(l("input", {
439
+ type: "checkbox",
440
+ value: c,
441
+ "onUpdate:modelValue": (V) => o.value[e.id] = V,
442
+ onChange: (V) => _(e.id),
443
+ onBlur: (V) => x(e.id),
444
+ class: "mr-3 h-4 w-4 flex-shrink-0"
445
+ }, null, 40, we), [
446
+ [Y, o.value[e.id]]
447
+ ]),
448
+ l("span", ke, v(r), 1)
449
+ ], 2))), 128))
450
+ ], 8, $e)) : g("", !0),
451
+ s(e.id) && n.value.has(e.id) ? (u(), i("div", {
452
+ key: 9,
453
+ id: `${e.id}-error`,
454
+ class: "flex items-center gap-2 mt-2 text-red-600 text-sm",
455
+ role: "alert"
456
+ }, [
457
+ a[2] || (a[2] = l("svg", {
458
+ class: "w-4 h-4 flex-shrink-0",
459
+ fill: "currentColor",
460
+ viewBox: "0 0 20 20",
461
+ "aria-hidden": "true"
462
+ }, [
463
+ l("path", {
464
+ "fill-rule": "evenodd",
465
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",
466
+ "clip-rule": "evenodd"
467
+ })
468
+ ], -1)),
469
+ B(" " + v(h.value.get(e.id)?.message), 1)
470
+ ], 8, Ve)) : g("", !0),
471
+ H(e) ? (u(), i("div", {
472
+ key: 10,
473
+ class: b(["text-sm mt-2", {
474
+ "text-amber-600 font-semibold": z(e),
475
+ "text-gray-500": !z(e)
476
+ }])
477
+ }, [
478
+ B(v((o.value[e.id] || "").length) + " ", 1),
479
+ e.maxLength ? (u(), i("span", fe, " / " + v(e.maxLength), 1)) : g("", !0),
480
+ a[3] || (a[3] = B(" characters ", -1))
481
+ ], 2)) : g("", !0)
482
+ ], 10, ie))), 128)),
483
+ l("div", Se, [
484
+ l("button", {
485
+ type: "submit",
486
+ disabled: m.value,
487
+ class: b([
488
+ m.value ? "bg-green-600 cursor-default" : "bg-blue-600 hover:bg-blue-700",
489
+ "px-8 py-3 rounded-lg text-white font-semibold text-lg transition-colors"
490
+ ])
491
+ }, v(m.value ? "Submitted" : "Submit Form"), 11, Ce)
492
+ ]),
493
+ l("div", Le, v(W.value) + " / " + v(J.value) + " required fields completed ", 1)
494
+ ], 32)
495
+ ])) : g("", !0)
496
+ ]));
497
+ }
498
+ }), De = (C, w) => {
499
+ const p = C.__vccOpts || C;
500
+ for (const [L, d] of w)
501
+ p[L] = d;
502
+ return p;
503
+ }, Me = /* @__PURE__ */ De(Be, [["__scopeId", "data-v-de00dace"]]), Fe = { class: "w-full h-full flex flex-col items-center justify-center p-4 bg-gradient-to-br from-blue-50 to-indigo-50 rounded-lg border-2 border-gray-200" }, Ue = { class: "text-center" }, Ee = { class: "text-gray-900 font-bold text-lg mb-1 line-clamp-2" }, Re = { class: "text-gray-600 text-sm mb-2" }, qe = {
504
+ key: 0,
505
+ class: "flex items-center justify-center gap-2"
506
+ }, ze = { class: "w-32 h-2 bg-gray-200 rounded-full overflow-hidden" }, Ne = { class: "text-xs text-gray-500" }, je = {
507
+ key: 1,
508
+ class: "inline-flex items-center gap-1 px-3 py-1 bg-green-100 text-green-700 rounded-full text-xs font-semibold"
509
+ }, Pe = /* @__PURE__ */ P({
510
+ __name: "Preview",
511
+ props: {
512
+ result: {}
513
+ },
514
+ setup(C) {
515
+ const w = C, p = S(() => w.result?.toolName === "presentForm" ? w.result.jsonData : null), L = S(() => w.result?.viewState || null), d = S(() => p.value?.fields.length || 0), o = S(() => L.value?.submitted || !1), n = S(() => {
516
+ if (!p.value || o.value) return 100;
517
+ const h = p.value.fields.filter((k) => k.required);
518
+ if (h.length === 0) return 0;
519
+ const m = L.value?.userResponses || {}, U = h.filter((k) => {
520
+ const y = m[k.id];
521
+ return y == null ? !1 : typeof y == "string" ? y.trim() !== "" : Array.isArray(y) ? y.length > 0 : !0;
522
+ }).length;
523
+ return Math.round(U / h.length * 100);
524
+ });
525
+ return (h, m) => (u(), i("div", Fe, [
526
+ l("div", Ue, [
527
+ m[1] || (m[1] = l("svg", {
528
+ class: "w-12 h-12 mx-auto mb-3 text-blue-600",
529
+ fill: "none",
530
+ stroke: "currentColor",
531
+ viewBox: "0 0 24 24"
532
+ }, [
533
+ l("path", {
534
+ "stroke-linecap": "round",
535
+ "stroke-linejoin": "round",
536
+ "stroke-width": "2",
537
+ d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
538
+ })
539
+ ], -1)),
540
+ l("h3", Ee, v(p.value?.title || "Form"), 1),
541
+ l("p", Re, v(d.value) + " field" + v(d.value !== 1 ? "s" : ""), 1),
542
+ o.value ? (u(), i("div", je, [...m[0] || (m[0] = [
543
+ l("svg", {
544
+ class: "w-3 h-3",
545
+ fill: "currentColor",
546
+ viewBox: "0 0 20 20"
547
+ }, [
548
+ l("path", {
549
+ "fill-rule": "evenodd",
550
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",
551
+ "clip-rule": "evenodd"
552
+ })
553
+ ], -1),
554
+ B(" Submitted ", -1)
555
+ ])])) : (u(), i("div", qe, [
556
+ l("div", ze, [
557
+ l("div", {
558
+ class: "h-full bg-blue-600 transition-all duration-300",
559
+ style: Z({ width: `${n.value}%` })
560
+ }, null, 4)
561
+ ]),
562
+ l("span", Ne, v(n.value) + "%", 1)
563
+ ]))
564
+ ])
565
+ ]));
566
+ }
567
+ }), Ae = {
568
+ ...K,
569
+ viewComponent: Me,
570
+ previewComponent: Pe
571
+ }, Te = { plugin: Ae };
572
+ export {
573
+ Pe as Preview,
574
+ We as SAMPLES,
575
+ Ge as TOOL_DEFINITION,
576
+ Ke as TOOL_NAME,
577
+ Me as View,
578
+ Te as default,
579
+ Qe as executeForm,
580
+ Ae as plugin,
581
+ K as pluginCore
582
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulmochat-plugin/form",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Form plugin for MulmoChat",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -12,6 +12,16 @@
12
12
  "import": "./dist/index.js",
13
13
  "require": "./dist/index.cjs"
14
14
  },
15
+ "./core": {
16
+ "types": "./dist/core/index.d.ts",
17
+ "import": "./dist/core.js",
18
+ "require": "./dist/core.cjs"
19
+ },
20
+ "./vue": {
21
+ "types": "./dist/vue/index.d.ts",
22
+ "import": "./dist/vue.js",
23
+ "require": "./dist/vue.cjs"
24
+ },
15
25
  "./style.css": "./dist/style.css"
16
26
  },
17
27
  "files": [
@@ -1,7 +0,0 @@
1
- /**
2
- * MulmoChat Plugin Common
3
- *
4
- * Shared types and utilities for building MulmoChat plugins.
5
- * Import from "@mulmochat-plugin/form/common" or copy to your plugin.
6
- */
7
- export type { ToolContext, ToolContextApp, ToolResult, ToolPlugin, ToolDefinition, JsonSchemaProperty, StartApiResponse, FileUploadConfig, ToolPluginConfig, ToolSample, } from "./types";