@blade-hq/agent-react 2612.0.0-beta.48 → 2612.0.0-beta.49

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.
@@ -0,0 +1,907 @@
1
+ import {
2
+ MarkdownContent
3
+ } from "./chunk-OQQCJD3L.js";
4
+ import {
5
+ Check,
6
+ LoaderCircle,
7
+ MessageSquareMore,
8
+ buttonVariants,
9
+ cn2 as cn
10
+ } from "./chunk-VUDRKCD4.js";
11
+ import "./chunk-PR4QN5HX.js";
12
+
13
+ // src/chat/QuestionnaireQuestionBlock.tsx
14
+ import { formatAskUserAnswer } from "@blade-hq/agent-client";
15
+ import { useEffect, useMemo as useMemo2, useState as useState2 } from "react";
16
+
17
+ // ../../node_modules/.pnpm/@shadcn+react@0.3.1_@types+react@19.2.14_react@19.2.4/node_modules/@shadcn/react/dist/chunk-HBS6WEDP.js
18
+ import * as i from "react";
19
+ function S({ defaultTagName: a, props: r, render: t, state: n = {}, stateAttributesMapping: e }) {
20
+ let o = d(R(n, e), r);
21
+ if (!t) return i.createElement(a, o);
22
+ if (typeof t == "function") return t(o, n);
23
+ if (!i.isValidElement(t)) return null;
24
+ let s = t.props, u = { ...d(o, s), ref: f(o.ref, s.ref) };
25
+ return i.cloneElement(t, u);
26
+ }
27
+ function d(...a) {
28
+ let r = {};
29
+ for (let t of a) {
30
+ if (!t) continue;
31
+ let n = t;
32
+ for (let e of Object.keys(n)) {
33
+ let o = n[e];
34
+ if (o === void 0) continue;
35
+ let s = r[e];
36
+ e === "className" ? r[e] = [s, o].filter(Boolean).join(" ") : e === "style" ? r[e] = { ...s, ...o } : e === "ref" ? r[e] = f(s, o) : l(e) && typeof s == "function" && typeof o == "function" ? r[e] = p(o, s) : r[e] = o;
37
+ }
38
+ }
39
+ return r;
40
+ }
41
+ function R(a, r) {
42
+ let t = {};
43
+ for (let n of Object.keys(a)) {
44
+ let e = a[n], o = r?.[n]?.(e);
45
+ if (o) {
46
+ Object.assign(t, o);
47
+ continue;
48
+ }
49
+ if (n === "slot") {
50
+ t["data-slot"] = e;
51
+ continue;
52
+ }
53
+ let s = `data-${String(n).replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)}`;
54
+ typeof e == "boolean" ? t[s] = e ? "" : void 0 : e != null && (t[s] = String(e));
55
+ }
56
+ return t;
57
+ }
58
+ function p(a, r) {
59
+ return function(n) {
60
+ a(n), n.defaultPrevented || r(n);
61
+ };
62
+ }
63
+ function l(a) {
64
+ return /^on[A-Z]/.test(a);
65
+ }
66
+ function f(...a) {
67
+ let r = a.filter(Boolean);
68
+ if (r.length !== 0) return (t) => {
69
+ for (let n of r) typeof n == "function" ? n(t) : n && (n.current = t);
70
+ };
71
+ }
72
+
73
+ // ../../node_modules/.pnpm/@shadcn+react@0.3.1_@types+react@19.2.14_react@19.2.4/node_modules/@shadcn/react/dist/questionnaire/index.js
74
+ import * as p2 from "react";
75
+ import { jsx } from "react/jsx-runtime";
76
+ var Pe = p2.createContext(null);
77
+ var ve = p2.createContext(null);
78
+ var Ee = p2.createContext(null);
79
+ function ne(e) {
80
+ let t = p2.useContext(ve);
81
+ if (!t) throw new Error(`${e} must be used within a Questionnaire.Root component.`);
82
+ return t;
83
+ }
84
+ function be(e) {
85
+ let t = p2.useContext(Pe);
86
+ if (!t) throw new Error(`${e} must be used within a Questionnaire.Choice component.`);
87
+ return t;
88
+ }
89
+ function Z(e) {
90
+ let t = p2.useContext(Ee);
91
+ if (!t) throw new Error(`${e} must be used within a Questionnaire.Item component.`);
92
+ return t;
93
+ }
94
+ function ce(e) {
95
+ return Array.isArray(e) ? e.some((t) => String(t).trim().length > 0) : e != null && String(e).trim().length > 0;
96
+ }
97
+ function me(e) {
98
+ return e === "letters" ? Array.from({ length: 26 }, (t, i2) => String.fromCharCode(65 + i2)) : e === "numbers" ? Array.from({ length: 9 }, (t, i2) => String(i2 + 1)) : [];
99
+ }
100
+ function He(e, t) {
101
+ let i2 = t === "letters" ? e.toUpperCase() : e;
102
+ return me(t).includes(i2) ? i2 : null;
103
+ }
104
+ function Ie(e, t) {
105
+ return [e, t ? "Enter" : null].filter(Boolean).join(" ") || void 0;
106
+ }
107
+ function pe(e) {
108
+ return e.type === "choice" ? e.element.checked : e.element.hasAttribute("name") && ce(e.element.value);
109
+ }
110
+ function $e(e) {
111
+ return e?.type === "input" && ["email", "password", "search", "tel", "text", "url"].includes(e.element.type) && !ce(e.element.value);
112
+ }
113
+ function he(e) {
114
+ return e instanceof HTMLTextAreaElement || e instanceof HTMLSelectElement ? true : e instanceof HTMLInputElement ? !["button", "checkbox", "radio", "reset", "submit"].includes(e.type) : e instanceof HTMLElement && e.isContentEditable;
115
+ }
116
+ function le(e) {
117
+ return e instanceof HTMLInputElement && e.type === "radio";
118
+ }
119
+ function Ke(e, t) {
120
+ if (e.element === t.element) return 0;
121
+ let i2 = e.element.compareDocumentPosition(t.element);
122
+ return i2 & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : i2 & Node.DOCUMENT_POSITION_PRECEDING ? 1 : 0;
123
+ }
124
+ function Ue(e, t) {
125
+ if (e.element === t.element) return 0;
126
+ let i2 = e.element.compareDocumentPosition(t.element);
127
+ return i2 & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : i2 & Node.DOCUMENT_POSITION_PRECEDING ? 1 : 0;
128
+ }
129
+ function qe({ checked: e, defaultChecked: t = false, disabled: i2 = false, onChange: a, value: s }) {
130
+ let { disabled: o, hasInputAnswer: u, invalid: f2, multiple: g, name: d2, registerAnswerControl: c, registerAnswerSelection: S2, required: B, resetVersion: Q, selectedAnswerIds: x, setAnswerDefault: U, setAnswerSelectionFromInteraction: P, shortcutByAnswerId: A, shortcutByChoiceValue: G, status: v, syncControlledAnswerSelection: C } = Z("Questionnaire.Choice"), E = p2.useId(), [O, V] = p2.useState(null), L = p2.useRef(t), N = e !== void 0, D = o || i2, M = x.includes(E), y = N ? v === "skipped" ? false : e : M, R2 = g ? "checkbox" : "radio", w = G?.get(s) ?? A.get(E) ?? null;
131
+ p2.useLayoutEffect(() => S2(E, L.current), [E, S2]), p2.useLayoutEffect(() => U(E, t), [E, t, U]), p2.useLayoutEffect(() => {
132
+ if (O) return c({ disabled: D, element: O, id: E, ownDisabled: i2, type: "choice", value: s });
133
+ }, [E, i2, D, O, c, s]), p2.useLayoutEffect(() => {
134
+ N && C(E, e);
135
+ }, [E, N, e, Q, C]), p2.useLayoutEffect(() => {
136
+ O && (O.defaultChecked = N ? e : t, Q > 0 && (O.checked = y));
137
+ }, [y, N, e, t, O, Q]);
138
+ function X(T) {
139
+ if (a?.(T), !T.defaultPrevented) {
140
+ if (!N) {
141
+ P(E, T.target.checked);
142
+ return;
143
+ }
144
+ v === "skipped" && e === T.target.checked && P(E, e);
145
+ }
146
+ }
147
+ let ie = { checked: y, disabled: D, invalid: f2, shortcut: w, type: R2 };
148
+ return { inputProps: { ref: V, "aria-invalid": f2 || void 0, "aria-keyshortcuts": Ie(w, !D && y), checked: y, disabled: D, id: E, name: v === "skipped" ? void 0 : d2, onChange: X, required: B && !g && !u, type: R2, value: s }, state: ie };
149
+ }
150
+ function _e({ defaultValue: e, disabled: t = false, onChange: i2, ref: a, type: s = "text", value: o }) {
151
+ let { disabled: u, invalid: f2, name: g, registerAnswerControl: d2, registerAnswerSelection: c$1, resetVersion: S2, selectedAnswerIds: B, setAnswerDefault: Q, setAnswerSelectionFromInteraction: x, syncControlledAnswerSelection: U } = Z("Questionnaire.Input"), P = p2.useId(), A = p2.useRef(null), G = p2.useRef(ce(e)), v = o !== void 0, C = ce(e), E = ce(o), [O, V] = p2.useState(C), L = u || t, N = v ? E : O, D = B.includes(P);
152
+ p2.useLayoutEffect(() => c$1(P, G.current), [P, c$1]), p2.useLayoutEffect(() => Q(P, C), [C, P, Q]), p2.useLayoutEffect(() => {
153
+ let w = A.current;
154
+ if (w) return d2({ disabled: L, element: w, id: P, type: "input" });
155
+ }, [L, P, d2]), p2.useLayoutEffect(() => {
156
+ if (v) {
157
+ U(P, E);
158
+ return;
159
+ }
160
+ S2 > 0 && V(C);
161
+ }, [v, E, o, C, P, S2, U]), p2.useLayoutEffect(() => {
162
+ let w = A.current;
163
+ !w || !v || (w.defaultValue = String(o));
164
+ }, [v, o]);
165
+ function M(w) {
166
+ if (i2?.(w), w.defaultPrevented) return;
167
+ let X = w.target.value.trim().length > 0;
168
+ v || (V(X), x(P, X));
169
+ }
170
+ let y = { disabled: L, filled: N, invalid: f2 }, R2 = p2.useCallback((w) => {
171
+ A.current = w, f(a)?.(w);
172
+ }, [a]);
173
+ return { inputProps: { "aria-invalid": f2 || void 0, "aria-keyshortcuts": Ie(null, !L && N && D), defaultValue: v ? void 0 : e, disabled: L, form: D ? void 0 : "", id: P, name: D ? g : void 0, onChange: M, ref: R2, type: s, value: v ? o : void 0 }, state: y };
174
+ }
175
+ function We(e) {
176
+ return e === void 0 ? null : { enabledItems: e.filter((t) => !t.disabled), itemByName: new Map(e.map((t) => [t.name, t])), items: e };
177
+ }
178
+ function we(e, t) {
179
+ if (!e) return t ?? null;
180
+ let i2 = t ? e.itemByName.get(t) : void 0;
181
+ return i2 && !i2.disabled ? i2.name : e.enabledItems[0]?.name ?? null;
182
+ }
183
+ function Ge(e, t) {
184
+ let i2 = /* @__PURE__ */ new Map();
185
+ if (!e || !t) return i2;
186
+ let a = me(t), s = 0;
187
+ for (let o of e.choices ?? []) {
188
+ if (o.disabled) continue;
189
+ let u = a[s];
190
+ if (!u) break;
191
+ i2.set(o.value, u), s += 1;
192
+ }
193
+ return i2;
194
+ }
195
+ function je(e, t) {
196
+ let i2 = [], a = /* @__PURE__ */ new Set();
197
+ for (let s of e.items) {
198
+ a.has(s.name) && i2.push(`Item name "${s.name}" is defined more than once.`), a.add(s.name);
199
+ let o = /* @__PURE__ */ new Set();
200
+ for (let u of s.choices ?? []) o.has(u.value) && i2.push(`Choice value "${u.value}" is defined more than once in item "${s.name}".`), o.add(u.value);
201
+ }
202
+ if (t) {
203
+ let s = e.itemByName.get(t);
204
+ (!s || s.disabled) && i2.push(`defaultItem "${t}" does not identify an enabled item. The first enabled item will be used instead.`);
205
+ }
206
+ return i2;
207
+ }
208
+ function ze(e, t, i2) {
209
+ let a = [], s = new Map(t.map((o) => [o.name, o]));
210
+ for (let o of e.items) {
211
+ let u = s.get(o.name);
212
+ if (!u) {
213
+ o.disabled || a.push(`Item "${o.name}" is defined but has no rendered Questionnaire.Item.`);
214
+ continue;
215
+ }
216
+ u.disabled !== !!o.disabled && a.push(`Item "${o.name}" has different disabled values in Root.items and Questionnaire.Item.`), u.required !== !!o.required && a.push(`Item "${o.name}" has different required values in Root.items and Questionnaire.Item.`);
217
+ let f2 = o.choices ?? [], g = new Map(f2.map((c) => [c.value, c])), d2 = new Map(u.choices.map((c) => [c.value, c]));
218
+ for (let c of f2) {
219
+ let S2 = d2.get(c.value);
220
+ if (!S2) {
221
+ a.push(`Choice "${c.value}" is defined for item "${o.name}" but has no rendered Questionnaire.Choice.`);
222
+ continue;
223
+ }
224
+ S2.disabled !== !!c.disabled && a.push(`Choice "${c.value}" in item "${o.name}" has different disabled values in Root.items and Questionnaire.Choice.`);
225
+ }
226
+ if (i2) {
227
+ for (let Q of u.choices) g.has(Q.value) || a.push(`Rendered choice "${Q.value}" in item "${o.name}" is missing from Root.items and will not receive a shortcut.`);
228
+ let c = f2.filter((Q) => !Q.disabled).map((Q) => Q.value), S2 = u.choices.filter((Q) => !Q.disabled).map((Q) => Q.value);
229
+ c.length > 0 && c.length === S2.length && c.every((Q) => S2.includes(Q)) && c.some((Q, x) => Q !== S2[x]) && a.push(`Choice order for item "${o.name}" differs between Root.items and the rendered Questionnaire.Choice elements.`);
230
+ }
231
+ }
232
+ for (let o of t) !o.disabled && !e.itemByName.has(o.name) && a.push(`Rendered item "${o.name}" is missing from Root.items and is excluded from the questionnaire collection.`);
233
+ return a;
234
+ }
235
+ function Je({ "aria-describedby": e, "aria-keyshortcuts": t, disabled: i2 = false, invalid: a = false, multiple: s = false, name: o, onStatusChange: u, ref: f2, required: g = false }) {
236
+ let { activeItemName: d2, domVersion: c$1, first: S2, itemDefinitionByName: B, last: Q, nativeValidation: x, registerItem: U, shortcuts: P } = ne("Questionnaire.Item"), [A, G] = p2.useState(null), [v, C] = p2.useState([]), [E, O] = p2.useState(false), [V, L] = p2.useState([]), [N, D] = p2.useState(false), [M, y] = p2.useState(0), [R2, w] = p2.useState([]), [X, ie] = p2.useState([]), T = p2.useRef([]), q = p2.useRef(s), de = p2.useRef(s);
237
+ q.current = s;
238
+ let _ = !i2 && d2 === o, j = p2.useMemo(() => [...v].sort(Ue), [v, c$1]), h = p2.useMemo(() => j.filter((r) => !r.disabled), [j]), ge = h.some((r) => V.includes(r.id)), F = N ? "skipped" : ge ? "answered" : "unanswered", re = F === "skipped" && !g, se = i2 || re || !a && F === "answered", ee = !i2 && !re && (a || E && !se), Re = h.some((r) => r.type === "input"), Qe = p2.useRef(F), Ce = B?.get(o), J = p2.useMemo(() => B ? Ge(Ce, P) : null, [Ce, B, P]), ae = p2.useMemo(() => {
239
+ if (J) return /* @__PURE__ */ new Map();
240
+ let r = me(P), m = h.filter((l2) => l2.type === "choice");
241
+ return new Map(m.slice(0, r.length).map((l2, $) => [l2.id, r[$]]));
242
+ }, [h, J, P]), ye = p2.useCallback((r) => (C((m) => [...m.filter((l2) => l2.element !== r.element && l2.id !== r.id), r]), () => {
243
+ C((m) => m.filter((l2) => l2 !== r));
244
+ }), []);
245
+ p2.useLayoutEffect(() => {
246
+ Qe.current !== F && (Qe.current = F, u?.(F));
247
+ }, [u, F]);
248
+ let n = p2.useCallback((r, m) => {
249
+ L((l2) => m ? s ? l2.includes(r) ? l2 : [...l2, r] : [r] : l2.filter(($) => $ !== r));
250
+ }, [s]), b = p2.useCallback((r, m) => {
251
+ D(false), n(r, m);
252
+ }, [n]), k = p2.useCallback((r, m) => {
253
+ m && D(false), n(r, m);
254
+ }, [n]), Y = p2.useCallback((r, m) => (m && (T.current = [...T.current.filter((l2) => l2 !== r), r], L((l2) => q.current ? l2.includes(r) ? l2 : [...l2, r] : l2.length ? l2 : [r])), () => {
255
+ T.current = T.current.filter((l2) => l2 !== r), L((l2) => l2.filter(($) => $ !== r));
256
+ }), []), xe = p2.useCallback((r, m) => {
257
+ if (m) {
258
+ T.current = T.current.includes(r) ? T.current : [...T.current, r];
259
+ return;
260
+ }
261
+ T.current = T.current.filter((l2) => l2 !== r);
262
+ }, []), Me = p2.useCallback((r) => (w((m) => m.includes(r) ? m : [...m, r]), () => {
263
+ w((m) => m.filter((l2) => l2 !== r));
264
+ }), []), Ae = p2.useCallback((r) => (ie((m) => m.includes(r) ? m : [...m, r]), () => {
265
+ ie((m) => m.filter((l2) => l2 !== r));
266
+ }), []), Ne = p2.useCallback(() => {
267
+ if (O(true), !se) return false;
268
+ if (!x) return true;
269
+ let r = h.find((m) => pe(m) && m.element.willValidate && !m.element.validity.valid);
270
+ return r ? (r.element.focus(), r.element.reportValidity(), false) : true;
271
+ }, [h, x, se]), Te = p2.useCallback(() => {
272
+ A?.focus();
273
+ }, [A]), Le = p2.useCallback(() => {
274
+ let r = A?.querySelector("input[data-filled][name]:not(:disabled)"), m = A?.querySelector("input:not([type=hidden]):not(:disabled), textarea:not(:disabled)");
275
+ (r ?? m ?? A)?.focus();
276
+ }, [A]), De = p2.useCallback(() => {
277
+ O(false), D(false), L(s ? [...T.current] : T.current.slice(0, 1)), y((r) => r + 1);
278
+ }, [s]), Be = p2.useCallback(() => {
279
+ g || (L([]), D(true));
280
+ }, [g]);
281
+ p2.useLayoutEffect(() => {
282
+ let r = de.current;
283
+ de.current = s, !(!r || s) && L((m) => {
284
+ let l2 = h.find(($) => m.includes($.id));
285
+ return l2 ? [l2.id] : [];
286
+ });
287
+ }, [h, s]);
288
+ let Fe = p2.useCallback((r) => h.find((m) => m.element === r) ?? null, [h]), Ve = p2.useCallback((r) => {
289
+ if (J) {
290
+ let l2 = Array.from(J.entries()).find(([, $]) => $ === r)?.[0];
291
+ return h.find(($) => $.type === "choice" && $.value === l2) ?? null;
292
+ }
293
+ let m = Array.from(ae.entries()).find(([, l2]) => l2 === r)?.[0];
294
+ return h.find((l2) => l2.id === m) ?? null;
295
+ }, [h, ae, J]), Oe = p2.useCallback((r, m) => {
296
+ let l2 = h.findIndex((Qt) => Qt.element === r), $ = l2 < 0 ? null : h[l2] ?? null;
297
+ if (!h.length || he(r) && !$e($) || l2 < 0 && r !== A) return false;
298
+ let oe = l2 < 0 ? h.find(pe) ?? (m === "next" ? h[0] : h[h.length - 1]) : h[(l2 + (m === "next" ? 1 : -1) + h.length) % h.length];
299
+ return !oe || oe.element === r || l2 >= 0 && le(r) && le(oe.element) ? false : (oe.element.focus(), oe.type === "choice" && le(oe.element) && oe.element.click(), true);
300
+ }, [h, A]);
301
+ p2.useLayoutEffect(() => {
302
+ if (A) return U({ choices: j.flatMap((r) => r.type === "choice" ? [{ disabled: r.ownDisabled, value: r.value }] : []), disabled: i2, element: A, focus: Te, focusInvalid: Le, getAnswerByElement: Fe, getAnswerByShortcut: Ve, moveAnswerFocus: Oe, name: o, required: g, reset: De, skip: Be, status: F, validate: Ne });
303
+ }, [j, i2, A, Te, Le, Fe, Ve, Oe, o, U, g, De, Be, F, Ne]);
304
+ let pt = p2.useMemo(() => ({ active: _, disabled: i2, hasInputAnswer: Re, invalid: ee, multiple: s, name: o, registerAnswerControl: ye, registerAnswerSelection: Y, registerDescription: Me, registerError: Ae, required: g, resetVersion: M, selectedAnswerIds: V, setAnswerDefault: xe, setAnswerSelectionFromInteraction: b, shortcutByAnswerId: ae, shortcutByChoiceValue: J, shortcuts: P, status: F, syncControlledAnswerSelection: k }), [_, i2, Re, ee, s, o, ye, Y, Me, Ae, g, M, V, xe, b, ae, J, P, F, k]), ht = p2.useCallback((r) => {
305
+ G(r), f(f2)?.(r);
306
+ }, [f2]), gt = [...R2, ...ee ? X : [], e].filter(Boolean).join(" ") || void 0, Rt = [t, _ ? "Meta+Enter Control+Enter" : void 0, _ && h.length ? "ArrowUp ArrowDown" : void 0, _ && !S2 ? "ArrowLeft" : void 0, _ && !Q && F !== "unanswered" ? "ArrowRight" : void 0].filter(Boolean).join(" ") || void 0;
307
+ return { context: pt, itemProps: { "aria-describedby": gt, "aria-invalid": ee || void 0, "aria-keyshortcuts": Rt, disabled: i2, hidden: !_, inert: !_, ref: ht, tabIndex: -1 }, state: { active: _, disabled: i2, invalid: ee, multiple: s, required: g, status: F } };
308
+ }
309
+ function Xe({ defaultItem: e, item: t, items: i2, noValidate: a, onItemChange: s, onReset: o, onSubmit: u, ref: f2, shortcuts: g }) {
310
+ let d2 = p2.useMemo(() => We(i2), [i2]), [c$1, S2] = p2.useState([]), [B, Q] = p2.useState(() => we(d2, e)), [x, U] = p2.useState(null), [P, A] = p2.useState(0), G = p2.useRef(null), v = t !== void 0, C = v ? t : B, E = p2.useRef(C), O = a === false, V = g ?? null, L = p2.useRef(/* @__PURE__ */ new Set());
311
+ p2.useLayoutEffect(() => {
312
+ if (false) return;
313
+ if (!d2 || !x) {
314
+ L.current.clear();
315
+ return;
316
+ }
317
+ let n = false;
318
+ return queueMicrotask(() => {
319
+ if (n) return;
320
+ let b = [...je(d2, e), ...ze(d2, c$1, V)], k = new Set(b);
321
+ k.forEach((Y) => {
322
+ L.current.has(Y) || console.warn(`[Questionnaire] ${Y}`);
323
+ }), L.current = k;
324
+ }), () => {
325
+ n = true;
326
+ };
327
+ }, [d2, e, c$1, x, V]), p2.useLayoutEffect(() => {
328
+ if (!x || typeof MutationObserver > "u") return;
329
+ let n = new MutationObserver(() => {
330
+ A((b) => b + 1);
331
+ });
332
+ return n.observe(x, { childList: true, subtree: true }), () => n.disconnect();
333
+ }, [x]);
334
+ let N = p2.useMemo(() => c$1.filter((n) => !n.disabled).sort(Ke), [P, c$1]), D = p2.useMemo(() => new Map(N.map((n) => [n.name, n])), [N]), M = d2?.enabledItems ?? N, y = M.findIndex((n) => n.name === C), R2 = y < 0 || !C ? null : D.get(C) ?? null, w = C ? d2?.itemByName.get(C) : void 0, X = y < 0 ? null : w ? !!w.required : R2?.required ?? false, ie = y < 0 ? null : R2?.status ?? (C ? "unanswered" : null), T = p2.useMemo(() => d2 ? d2.enabledItems.flatMap((n) => {
335
+ let b = D.get(n.name);
336
+ return b ? [b] : [];
337
+ }) : N, [d2, D, N]), q = M.length, de = y < 0 ? 0 : y + 1, _ = q > 0 && y === 0, j = q > 0 && y === q - 1, h = p2.useCallback((n, b = "item") => {
338
+ n !== C && (G.current = { name: n, target: b }, v || Q(n), s?.(n));
339
+ }, [C, v, s]);
340
+ p2.useLayoutEffect(() => {
341
+ if (q === 0) return;
342
+ if (y < 0) {
343
+ if (!v && C === null) {
344
+ Q(M[0].name);
345
+ return;
346
+ }
347
+ h(M[0].name);
348
+ return;
349
+ }
350
+ let n = G.current, b = E.current !== C;
351
+ if (E.current = C, !n || n.name !== C) {
352
+ v && b && (G.current = null, R2?.focus());
353
+ return;
354
+ }
355
+ n.target === "invalid" ? R2?.focusInvalid() : R2?.focus(), G.current = null;
356
+ }, [R2, C, v, y, M, h, q]);
357
+ let ge = p2.useCallback((n) => (S2((b) => [...b.filter((k) => k.element !== n.element && k.name !== n.name), n]), () => {
358
+ S2((b) => b.filter((k) => k !== n));
359
+ }), []), F = p2.useCallback(() => {
360
+ y <= 0 || h(M[y - 1].name);
361
+ }, [y, M, h]), re = p2.useCallback(() => {
362
+ if (!(!R2 || y >= q - 1)) {
363
+ if (!R2.validate()) {
364
+ R2.focusInvalid();
365
+ return;
366
+ }
367
+ h(M[y + 1].name);
368
+ }
369
+ }, [R2, y, M, h, q]), se = p2.useCallback(() => {
370
+ if (R2) {
371
+ if (!R2.validate()) {
372
+ R2.focusInvalid();
373
+ return;
374
+ }
375
+ if (j) {
376
+ x?.requestSubmit();
377
+ return;
378
+ }
379
+ h(M[y + 1].name);
380
+ }
381
+ }, [R2, y, j, M, x, h]), ee = p2.useCallback(() => {
382
+ if (!(!R2 || R2.required)) {
383
+ if (R2.skip(), !j) {
384
+ h(M[y + 1].name);
385
+ return;
386
+ }
387
+ queueMicrotask(() => {
388
+ x?.requestSubmit();
389
+ });
390
+ }
391
+ }, [R2, y, j, M, x, h]);
392
+ function Re(n) {
393
+ if (o?.(n), n.defaultPrevented) return;
394
+ for (let k of c$1) k.reset();
395
+ let b = d2 ? we(d2, e) : N.find((k) => k.name === e)?.name ?? N[0]?.name;
396
+ b && h(b);
397
+ }
398
+ function Qe(n) {
399
+ let b = T.find((k) => !k.validate());
400
+ if (b) {
401
+ n.preventDefault(), h(b.name, "invalid"), b.name === C && (b.focusInvalid(), G.current = null);
402
+ return;
403
+ }
404
+ u?.(n);
405
+ }
406
+ function Ce(n) {
407
+ if (n.defaultPrevented || n.nativeEvent.isComposing || n.keyCode === 229 || !R2 || !(n.target instanceof Element)) return;
408
+ if (n.key === "Enter" && (n.metaKey || n.ctrlKey) && !n.altKey && !n.shiftKey) {
409
+ n.preventDefault(), n.repeat || se();
410
+ return;
411
+ }
412
+ if (n.metaKey || n.ctrlKey || n.altKey) return;
413
+ if ((n.key === "ArrowUp" || n.key === "ArrowDown") && R2.moveAnswerFocus(n.target, n.key === "ArrowDown" ? "next" : "previous")) {
414
+ n.preventDefault();
415
+ return;
416
+ }
417
+ if ((n.key === "ArrowLeft" || n.key === "ArrowRight") && !he(n.target) && !le(n.target)) {
418
+ if (n.preventDefault(), n.repeat) return;
419
+ n.key === "ArrowLeft" ? F() : R2.status !== "unanswered" && re();
420
+ return;
421
+ }
422
+ if (n.key === "Enter") {
423
+ let Y = R2.getAnswerByElement(n.target);
424
+ if (!Y) return;
425
+ n.preventDefault(), !n.repeat && pe(Y) && se();
426
+ return;
427
+ }
428
+ if (!V || he(n.target)) return;
429
+ let b = He(n.key, V), k = b ? R2.getAnswerByShortcut(b) : null;
430
+ k && (n.preventDefault(), !n.repeat && (k.element.focus(), k.type === "choice" && k.element.click()));
431
+ }
432
+ let J = { current: de, first: _, last: j, total: q }, ae = p2.useMemo(() => ({ ...J, activeItem: R2, activeItemName: C, activeItemRequired: X, activeItemStatus: ie, domVersion: P, goNext: re, goPrevious: F, itemDefinitionByName: d2?.itemByName ?? null, nativeValidation: O, registerItem: ge, shortcuts: V, skipCurrent: ee }), [R2, C, X, ie, d2, de, P, _, re, F, j, O, ge, V, ee, q]), ye = p2.useCallback((n) => {
433
+ U(n), f(f2)?.(n);
434
+ }, [f2]);
435
+ return { context: ae, rootProps: { "data-shortcuts": V ?? void 0, onKeyDown: Ce, onReset: Re, onSubmit: Qe, ref: ye }, state: J };
436
+ }
437
+ function Ye({ defaultItem: e, item: t, items: i2, noValidate: a$1 = true, onItemChange: s, onReset: o, onSubmit: u, ref: f2, shortcuts: g, ...d2 }) {
438
+ let { context: c, rootProps: S2, state: B } = Xe({ defaultItem: e, item: t, items: i2, noValidate: a$1, onItemChange: s, onReset: o, onSubmit: u, ref: f2, shortcuts: g }), Q = S({ defaultTagName: "form", props: d({ ...S2, noValidate: a$1 }, d2), state: B });
439
+ return jsx(ve.Provider, { value: c, children: Q });
440
+ }
441
+ function Ze({ children: e, render: t, ...i2 }) {
442
+ let { current: a$1, first: s, last: o, total: u } = ne("Questionnaire.Progress"), f2 = u ? `Question ${a$1} of ${u}` : void 0;
443
+ return S({ defaultTagName: "div", props: d({ "aria-label": "Questionnaire progress", "aria-live": "polite", "aria-valuemax": u || void 0, "aria-valuemin": u ? 1 : void 0, "aria-valuenow": u ? a$1 : void 0, "aria-valuetext": f2, children: e ?? f2, role: "progressbar" }, i2), render: t, state: { current: a$1, first: s, last: o, total: u } });
444
+ }
445
+ function et({ "aria-describedby": e, "aria-keyshortcuts": t, children: i2, disabled: a$1 = false, invalid: s = false, multiple: o = false, name: u, onStatusChange: f2, ref: g, required: d2 = false, ...c }) {
446
+ let { context: S2, itemProps: B, state: Q } = Je({ "aria-describedby": e, "aria-keyshortcuts": t, disabled: a$1, invalid: s, multiple: o, name: u, onStatusChange: f2, ref: g, required: d2 }), x = S({ defaultTagName: "fieldset", props: d({ ...B, children: i2 }, c), state: Q, stateAttributesMapping: { active: (U) => ({ "data-active": U ? "" : void 0 }) } });
447
+ return jsx(Ee.Provider, { value: S2, children: x });
448
+ }
449
+ function tt({ render: e, ...t }) {
450
+ return Z("Questionnaire.Title"), S({ defaultTagName: "legend", props: t, render: e });
451
+ }
452
+ function nt({ id: e, render: t, ...i2 }) {
453
+ let { registerDescription: a$1 } = Z("Questionnaire.Description"), s = p2.useId(), o = e ?? s;
454
+ return p2.useLayoutEffect(() => a$1(o), [o, a$1]), S({ defaultTagName: "p", props: d({ id: o }, i2), render: t });
455
+ }
456
+ function it({ render: e, ...t }) {
457
+ let { shortcuts: i2 } = Z("Questionnaire.Choices");
458
+ return S({ defaultTagName: "div", props: t, render: e, state: { shortcuts: i2 } });
459
+ }
460
+ function ot({ checked: e, children: t, defaultChecked: i2 = false, disabled: a$1 = false, onChange: s, render: o, value: u, ...f2 }) {
461
+ let { inputProps: g, state: d2 } = qe({ checked: e, defaultChecked: i2, disabled: a$1, onChange: s, value: u }), c = S({ defaultTagName: "label", props: d({ children: t }, f2), render: o, state: d2, stateAttributesMapping: { checked: (S2) => ({ "data-checked": S2 ? "" : void 0, "data-unchecked": S2 ? void 0 : "" }) } });
462
+ return jsx(Pe.Provider, { value: { inputProps: g, state: d2 }, children: c });
463
+ }
464
+ function rt({ render: e, ...t }) {
465
+ let { inputProps: i2, state: a$1 } = be("Questionnaire.ChoiceInput");
466
+ return S({ defaultTagName: "input", props: d(i2, t), render: e, state: a$1, stateAttributesMapping: { checked: (s) => ({ "data-checked": s ? "" : void 0, "data-unchecked": s ? void 0 : "" }) } });
467
+ }
468
+ function st({ render: e, ...t }) {
469
+ return be("Questionnaire.ChoiceLabel"), S({ defaultTagName: "span", props: t, render: e });
470
+ }
471
+ function at({ children: e, render: t, ...i2 }) {
472
+ let { state: a$1 } = be("Questionnaire.ChoiceShortcut"), s = { shortcut: a$1.shortcut };
473
+ return S({ defaultTagName: "span", props: d({ "aria-hidden": true, children: e ?? a$1.shortcut, hidden: a$1.shortcut === null }, i2), render: t, state: s });
474
+ }
475
+ function ut({ defaultValue: e, disabled: t = false, onChange: i2, ref: a$1, render: s, type: o = "text", value: u, ...f2 }) {
476
+ let { inputProps: g, state: d2 } = _e({ defaultValue: e, disabled: t, onChange: i2, ref: a$1, type: o, value: u });
477
+ return S({ defaultTagName: "input", props: d(g, f2), render: s, state: d2, stateAttributesMapping: { filled: (c) => ({ "data-empty": c ? void 0 : "", "data-filled": c ? "" : void 0 }) } });
478
+ }
479
+ function ct({ children: e, id: t, render: i2, ...a$1 }) {
480
+ let { invalid: s, registerError: o, required: u } = Z("Questionnaire.Error"), f2 = p2.useId(), g = t ?? f2;
481
+ return p2.useLayoutEffect(() => o(g), [g, o]), S({ defaultTagName: "p", props: d({ children: e ?? (u ? "Choose an answer to continue." : "Choose an answer or skip this question."), hidden: !s, id: g, role: s ? "alert" : void 0 }, a$1), render: i2, state: { invalid: s } });
482
+ }
483
+ function lt({ children: e, disabled: t = false, onClick: i2, render: a, tabIndex: s, type: o = "button", ...u }) {
484
+ let f2 = ne("Questionnaire.Previous"), g = f2.total > 1 && !f2.first;
485
+ function d2(c) {
486
+ i2?.(c), c.defaultPrevented || f2.goPrevious();
487
+ }
488
+ return Se({ children: e ?? "Previous", disabled: t, onClick: d2, props: u, render: a, status: f2.activeItemStatus, tabIndex: s, type: o, visible: g });
489
+ }
490
+ function ft({ children: e, disabled: t = false, onClick: i2, render: a, tabIndex: s, type: o = "button", ...u }) {
491
+ let f2 = ne("Questionnaire.Skip"), g = f2.activeItemRequired === false;
492
+ function d2(c) {
493
+ i2?.(c), c.defaultPrevented || f2.skipCurrent();
494
+ }
495
+ return Se({ children: e ?? "Skip", disabled: t, onClick: d2, props: u, render: a, status: f2.activeItemStatus, tabIndex: s, type: o, visible: g });
496
+ }
497
+ function dt({ children: e, disabled: t = false, onClick: i2, render: a, tabIndex: s, type: o = "button", ...u }) {
498
+ let f2 = ne("Questionnaire.Next"), g = f2.total > 1 && !f2.last;
499
+ function d2(c) {
500
+ i2?.(c), c.defaultPrevented || f2.goNext();
501
+ }
502
+ return Se({ children: e ?? "Next", disabled: t, onClick: d2, props: u, render: a, shortcut: "Enter", status: f2.activeItemStatus, tabIndex: s, type: o, visible: g });
503
+ }
504
+ function mt({ children: e, disabled: t = false, render: i2, tabIndex: a, type: s = "submit", ...o }) {
505
+ let u = ne("Questionnaire.Submit"), f2 = u.total > 0 && u.last;
506
+ return Se({ children: e ?? "Submit", disabled: t, props: o, render: i2, shortcut: "Enter", status: u.activeItemStatus, tabIndex: a, type: s, visible: f2 });
507
+ }
508
+ function Se({ children: e, disabled: t, onClick: i2, props: a$1, render: s, shortcut: o, status: u, tabIndex: f2, type: g, visible: d2 }) {
509
+ let c = d2 && !t ? o ?? null : null, S2 = { disabled: t, shortcut: c, status: u, visible: d2 };
510
+ return S({ defaultTagName: "button", props: d({ "aria-hidden": !d2 || void 0, "aria-keyshortcuts": c ?? void 0, children: e, disabled: t, hidden: !d2, inert: !d2, onClick: i2, tabIndex: d2 ? f2 : -1, type: g }, a$1), render: s, state: S2, stateAttributesMapping: { visible: (B) => ({ "data-hidden": B ? void 0 : "", "data-visible": B ? "" : void 0 }) } });
511
+ }
512
+ var zt = { Root: Ye, Progress: Ze, Item: et, Title: tt, Description: nt, Choices: it, Choice: ot, ChoiceInput: rt, ChoiceLabel: st, ChoiceShortcut: at, Input: ut, Error: ct, Previous: lt, Skip: ft, Next: dt, Submit: mt };
513
+
514
+ // ../ui/src/components/questionnaire.tsx
515
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
516
+ function Questionnaire({
517
+ className,
518
+ ...props
519
+ }) {
520
+ return /* @__PURE__ */ jsx2(
521
+ zt.Root,
522
+ {
523
+ "data-slot": "questionnaire",
524
+ className: cn("flex w-full min-w-0 flex-col gap-4", className),
525
+ ...props
526
+ }
527
+ );
528
+ }
529
+ function QuestionnaireProgress({
530
+ className,
531
+ ...props
532
+ }) {
533
+ return /* @__PURE__ */ jsx2(
534
+ zt.Progress,
535
+ {
536
+ "data-slot": "questionnaire-progress",
537
+ className: cn(
538
+ "min-h-[1lh] w-fit min-w-[14ch] text-xs font-medium text-muted-foreground tabular-nums",
539
+ className
540
+ ),
541
+ ...props
542
+ }
543
+ );
544
+ }
545
+ function QuestionnaireItem({
546
+ className,
547
+ ...props
548
+ }) {
549
+ return /* @__PURE__ */ jsx2(
550
+ zt.Item,
551
+ {
552
+ "data-slot": "questionnaire-item",
553
+ className: cn(
554
+ "flex min-w-0 flex-col gap-4 border-0 p-0 outline-none",
555
+ className
556
+ ),
557
+ ...props
558
+ }
559
+ );
560
+ }
561
+ function QuestionnaireTitle({
562
+ className,
563
+ ...props
564
+ }) {
565
+ return /* @__PURE__ */ jsx2(
566
+ zt.Title,
567
+ {
568
+ "data-slot": "questionnaire-title",
569
+ className: cn(
570
+ "cn-font-heading text-base leading-snug font-medium text-pretty [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4",
571
+ className
572
+ ),
573
+ ...props
574
+ }
575
+ );
576
+ }
577
+ function QuestionnaireChoices({
578
+ className,
579
+ ...props
580
+ }) {
581
+ return /* @__PURE__ */ jsx2(
582
+ zt.Choices,
583
+ {
584
+ "data-slot": "questionnaire-choices",
585
+ className: cn(
586
+ "group/questionnaire-choices grid min-w-0 gap-2",
587
+ className
588
+ ),
589
+ ...props
590
+ }
591
+ );
592
+ }
593
+ function QuestionnaireChoice({
594
+ children,
595
+ className,
596
+ ...props
597
+ }) {
598
+ return /* @__PURE__ */ jsxs(
599
+ zt.Choice,
600
+ {
601
+ "data-slot": "questionnaire-choice",
602
+ className: cn(
603
+ "group/questionnaire-choice relative flex min-h-11 cursor-pointer items-start gap-2.5 rounded-lg border border-input bg-transparent px-3 py-2.5 text-start text-sm transition-colors outline-none select-none hover:bg-muted/50 has-[>input:focus-visible]:border-ring has-[>input:focus-visible]:ring-3 has-[>input:focus-visible]:ring-ring/50 data-invalid:border-destructive dark:bg-input/20 data-checked:border-primary/40 data-checked:bg-muted dark:data-checked:bg-muted",
604
+ "data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50",
605
+ className
606
+ ),
607
+ ...props,
608
+ children: [
609
+ /* @__PURE__ */ jsx2(
610
+ zt.ChoiceInput,
611
+ {
612
+ "data-slot": "questionnaire-choice-input",
613
+ className: "absolute inset-0 z-10 size-full cursor-pointer opacity-0"
614
+ }
615
+ ),
616
+ /* @__PURE__ */ jsxs(
617
+ "span",
618
+ {
619
+ "aria-hidden": "true",
620
+ "data-slot": "questionnaire-choice-indicator",
621
+ className: "pointer-events-none relative flex size-4 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-[4px] border border-input group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[type=radio]/questionnaire-choice:rounded-full group-data-checked/questionnaire-choice:border-primary group-data-checked/questionnaire-choice:bg-primary group-data-checked/questionnaire-choice:text-primary-foreground dark:bg-input/30 dark:group-data-checked/questionnaire-choice:bg-primary",
622
+ children: [
623
+ /* @__PURE__ */ jsx2(
624
+ "span",
625
+ {
626
+ "data-slot": "questionnaire-choice-indicator-dot",
627
+ className: "hidden size-2 rounded-full bg-primary-foreground group-data-[type=checkbox]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
628
+ }
629
+ ),
630
+ /* @__PURE__ */ jsx2(Check, { "data-slot": "questionnaire-choice-indicator-check", className: "hidden size-3.5 group-data-[type=radio]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block" })
631
+ ]
632
+ }
633
+ ),
634
+ /* @__PURE__ */ jsx2(
635
+ zt.ChoiceLabel,
636
+ {
637
+ "data-slot": "questionnaire-choice-label",
638
+ className: "flex min-w-0 flex-1 flex-col gap-0.5 leading-snug",
639
+ children
640
+ }
641
+ ),
642
+ /* @__PURE__ */ jsx2(
643
+ zt.ChoiceShortcut,
644
+ {
645
+ "data-slot": "questionnaire-choice-shortcut",
646
+ className: "pointer-events-none ms-auto hidden size-5 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-md border border-input bg-background font-mono text-[0.625rem] leading-none font-medium text-muted-foreground group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[shortcut]/questionnaire-choice:inline-flex"
647
+ }
648
+ )
649
+ ]
650
+ }
651
+ );
652
+ }
653
+ function QuestionnaireChoiceDescription({
654
+ className,
655
+ ...props
656
+ }) {
657
+ return /* @__PURE__ */ jsx2(
658
+ "span",
659
+ {
660
+ "data-slot": "questionnaire-choice-description",
661
+ className: cn("text-muted-foreground", className),
662
+ ...props
663
+ }
664
+ );
665
+ }
666
+ function QuestionnaireInput({
667
+ className,
668
+ ...props
669
+ }) {
670
+ return /* @__PURE__ */ jsx2(
671
+ "div",
672
+ {
673
+ "data-slot": "questionnaire-input-wrapper",
674
+ className: "group/questionnaire-input relative w-full min-w-0",
675
+ children: /* @__PURE__ */ jsx2(
676
+ zt.Input,
677
+ {
678
+ "data-slot": "questionnaire-input",
679
+ className: cn(
680
+ "h-8 min-h-11 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-[color,box-shadow,background-color] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 sm:min-h-0 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
681
+ "selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground",
682
+ className
683
+ ),
684
+ ...props
685
+ }
686
+ )
687
+ }
688
+ );
689
+ }
690
+ function QuestionnaireError({
691
+ className,
692
+ ...props
693
+ }) {
694
+ return /* @__PURE__ */ jsx2(
695
+ zt.Error,
696
+ {
697
+ "data-slot": "questionnaire-error",
698
+ className: cn("mt-2 text-sm text-destructive", className),
699
+ ...props
700
+ }
701
+ );
702
+ }
703
+ function QuestionnaireActions({
704
+ className,
705
+ ...props
706
+ }) {
707
+ return /* @__PURE__ */ jsx2(
708
+ "div",
709
+ {
710
+ "data-slot": "questionnaire-actions",
711
+ className: cn(
712
+ "grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-2 sm:min-h-8",
713
+ className
714
+ ),
715
+ ...props
716
+ }
717
+ );
718
+ }
719
+ function QuestionnairePrevious({
720
+ children,
721
+ className,
722
+ size = "default",
723
+ variant = "outline",
724
+ ...props
725
+ }) {
726
+ return /* @__PURE__ */ jsx2(
727
+ zt.Previous,
728
+ {
729
+ "data-slot": "questionnaire-previous",
730
+ "data-size": size,
731
+ "data-variant": variant,
732
+ className: cn(
733
+ buttonVariants({ size, variant }),
734
+ "col-start-1 row-start-1 min-h-11 justify-self-start sm:min-h-0",
735
+ className
736
+ ),
737
+ ...props,
738
+ children: children ?? "Previous"
739
+ }
740
+ );
741
+ }
742
+ function QuestionnaireNext({
743
+ children,
744
+ className,
745
+ size = "default",
746
+ variant = "default",
747
+ ...props
748
+ }) {
749
+ return /* @__PURE__ */ jsx2(
750
+ zt.Next,
751
+ {
752
+ "data-slot": "questionnaire-next",
753
+ "data-size": size,
754
+ "data-variant": variant,
755
+ className: cn(
756
+ buttonVariants({ size, variant }),
757
+ "col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
758
+ className
759
+ ),
760
+ ...props,
761
+ children: children ?? "Next"
762
+ }
763
+ );
764
+ }
765
+ function QuestionnaireSubmit({
766
+ children,
767
+ className,
768
+ size = "default",
769
+ variant = "default",
770
+ ...props
771
+ }) {
772
+ return /* @__PURE__ */ jsx2(
773
+ zt.Submit,
774
+ {
775
+ "data-slot": "questionnaire-submit",
776
+ "data-size": size,
777
+ "data-variant": variant,
778
+ className: cn(
779
+ buttonVariants({ size, variant }),
780
+ "col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
781
+ className
782
+ ),
783
+ ...props,
784
+ children: children ?? "Submit"
785
+ }
786
+ );
787
+ }
788
+
789
+ // src/chat/QuestionnaireQuestionBlock.tsx
790
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
791
+ function QuestionnaireQuestionBlock({ data, answered, toolCallId, sessionStatus, answerData, onAnswer }) {
792
+ const [submitted, setSubmitted] = useState2(false);
793
+ const [draftAnswer, setDraftAnswer] = useState2();
794
+ const [note, setNote] = useState2("");
795
+ const [item, setItem] = useState2("0");
796
+ const items = useMemo2(() => data.questions.map((question, index) => ({
797
+ name: String(index),
798
+ required: true,
799
+ choices: question.options.map((_, optionIndex) => ({ value: String(optionIndex) }))
800
+ })), [data.questions]);
801
+ useEffect(() => {
802
+ if (sessionStatus === "failed" || sessionStatus === "interrupted") setSubmitted(false);
803
+ }, [sessionStatus]);
804
+ function handleSubmit(event) {
805
+ event.preventDefault();
806
+ if (answered || submitted || !onAnswer) return;
807
+ const form = event.currentTarget;
808
+ const next = { selections: {}, custom: {}, ...note.trim() ? { note: note.trim() } : {} };
809
+ for (const [index] of data.questions.entries()) {
810
+ const fieldset = form.querySelector(`[data-question-index="${index}"]`);
811
+ const custom = fieldset?.querySelector('[data-slot="questionnaire-input"]');
812
+ if (custom?.name && custom.value.trim()) next.custom[index] = custom.value.trim();
813
+ else {
814
+ const selected = [...fieldset?.querySelectorAll('input[data-slot="questionnaire-choice-input"]:checked') ?? []].map((input) => Number(input.value)).sort((a, b) => a - b);
815
+ if (selected.length) next.selections[index] = selected;
816
+ }
817
+ }
818
+ setDraftAnswer(next);
819
+ setSubmitted(true);
820
+ onAnswer(formatAskUserAnswer(data, next), toolCallId, next);
821
+ }
822
+ if (answered) {
823
+ const saved = answerData ?? draftAnswer;
824
+ return /* @__PURE__ */ jsxs2("div", { part: "ask-card", className: "ask-user-question blade-chat-ask-card ask-user-question-summary ml-4 max-w-2xl rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-sm", children: [
825
+ /* @__PURE__ */ jsx3("dl", { className: "space-y-3", children: data.questions.map((question, index) => {
826
+ const selected = saved?.custom[index] ?? saved?.selections[index]?.map((option) => question.options[option]?.label).filter(Boolean).join("\u3001");
827
+ return /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
828
+ /* @__PURE__ */ jsx3("dt", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: question.question }),
829
+ /* @__PURE__ */ jsx3("dd", { className: "m-0 whitespace-pre-wrap font-medium text-[hsl(var(--foreground))]", children: selected || "\u672A\u4F5C\u7B54" })
830
+ ] }, `${toolCallId}:${index}`);
831
+ }) }),
832
+ saved?.note && /* @__PURE__ */ jsx3("p", { "aria-label": "\u8865\u5145\u8BF4\u660E", className: "mt-3 whitespace-pre-wrap border-t border-[hsl(var(--border))] pt-3 text-xs text-[hsl(var(--muted-foreground))]", children: saved.note })
833
+ ] });
834
+ }
835
+ return /* @__PURE__ */ jsxs2("div", { part: "ask-card", className: "ask-user-question blade-chat-ask-card ml-4 max-w-lg rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-sm", children: [
836
+ data.source_loop?.description && /* @__PURE__ */ jsxs2("p", { className: "mb-4 text-xs text-[hsl(var(--muted-foreground))]", children: [
837
+ data.source_loop.description,
838
+ " \u60F3\u548C\u4F60\u786E\u8BA4\u4E00\u4EF6\u4E8B"
839
+ ] }),
840
+ /* @__PURE__ */ jsx3("fieldset", { disabled: submitted || !onAnswer, className: "m-0 min-w-0 border-0 p-0", children: /* @__PURE__ */ jsxs2(Questionnaire, { items, item, onItemChange: setItem, onSubmit: handleSubmit, children: [
841
+ /* @__PURE__ */ jsx3(QuestionnaireProgress, { "aria-label": "\u95EE\u9898\u8FDB\u5EA6", render: (props, state) => /* @__PURE__ */ jsxs2("div", { ...props, "aria-valuetext": `\u7B2C ${state.current} \u9898\uFF0C\u5171 ${state.total} \u9898`, children: [
842
+ "\u7B2C ",
843
+ state.current,
844
+ " / ",
845
+ state.total,
846
+ " \u9898"
847
+ ] }) }),
848
+ data.questions.map((question, index) => /* @__PURE__ */ jsxs2(QuestionnaireItem, { "data-question-index": index, name: String(index), multiple: question.multiSelect, required: true, children: [
849
+ /* @__PURE__ */ jsxs2(QuestionnaireTitle, { className: "mb-0 flex items-start gap-2 text-[hsl(var(--foreground))]", children: [
850
+ /* @__PURE__ */ jsx3(MessageSquareMore, { size: 16, className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]", "aria-hidden": "true" }),
851
+ /* @__PURE__ */ jsx3(MarkdownContent, { className: "min-w-0 flex-1 [&_p]:my-0", controls: { code: true }, children: question.question })
852
+ ] }),
853
+ /* @__PURE__ */ jsxs2(QuestionnaireChoices, { children: [
854
+ question.options.map((option, optionIndex) => /* @__PURE__ */ jsxs2(QuestionnaireChoice, { value: String(optionIndex), className: "blade-chat-ask-option", children: [
855
+ /* @__PURE__ */ jsx3("span", { className: "font-medium", children: option.label }),
856
+ option.description && /* @__PURE__ */ jsx3(QuestionnaireChoiceDescription, { children: option.description })
857
+ ] }, optionIndex)),
858
+ /* @__PURE__ */ jsx3(QuestionnaireInput, { "aria-label": "\u81EA\u5B9A\u4E49\u56DE\u7B54", placeholder: "\u5176\u4ED6\u60F3\u6CD5\uFF1F\u5728\u8FD9\u91CC\u8865\u5145", render: /* @__PURE__ */ jsx3("textarea", { rows: 2 }), className: "h-auto min-h-16 resize-y py-2.5 leading-6" })
859
+ ] }),
860
+ /* @__PURE__ */ jsx3(QuestionnaireError, { children: "\u8BF7\u9009\u62E9\u4E00\u4E2A\u9009\u9879\uFF0C\u6216\u586B\u5199\u81EA\u5DF1\u7684\u56DE\u7B54\u3002" })
861
+ ] }, `${toolCallId}:${index}`)),
862
+ /* @__PURE__ */ jsxs2("label", { hidden: item !== String(data.questions.length - 1), className: "block space-y-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
863
+ /* @__PURE__ */ jsx3("span", { children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
864
+ /* @__PURE__ */ jsx3("textarea", { "aria-label": "\u8865\u5145\u8BF4\u660E", rows: 2, value: note, onChange: (event) => setNote(event.target.value), placeholder: "\u8FD8\u6709\u9700\u8981\u52A9\u624B\u6CE8\u610F\u7684\u5417\uFF1F", className: "w-full resize-y rounded-lg border border-[hsl(var(--border))] bg-transparent px-3 py-2 text-sm text-[hsl(var(--foreground))] outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring)/0.35)]" })
865
+ ] }),
866
+ /* @__PURE__ */ jsxs2(QuestionnaireActions, { children: [
867
+ /* @__PURE__ */ jsx3(QuestionnairePrevious, { children: "\u4E0A\u4E00\u9898" }),
868
+ /* @__PURE__ */ jsx3(QuestionnaireNext, { render: (props, state) => /* @__PURE__ */ jsx3("button", { ...props, disabled: state.status !== "answered", children: "\u4E0B\u4E00\u9898" }) }),
869
+ /* @__PURE__ */ jsx3(QuestionnaireSubmit, { render: (props, state) => /* @__PURE__ */ jsx3("button", { ...props, disabled: submitted || state.status !== "answered", children: submitted ? /* @__PURE__ */ jsxs2(Fragment, { children: [
870
+ /* @__PURE__ */ jsx3(LoaderCircle, { size: 14, className: "animate-spin", "aria-hidden": "true" }),
871
+ "\u6B63\u5728\u63D0\u4EA4\u2026"
872
+ ] }) : "\u786E\u8BA4\u63D0\u4EA4" }) })
873
+ ] })
874
+ ] }) })
875
+ ] });
876
+ }
877
+ export {
878
+ QuestionnaireQuestionBlock as AskUserQuestionBlock,
879
+ QuestionnaireQuestionBlock
880
+ };
881
+ /*!
882
+ * Adapted from shadcn/ui Questionnaire (radix-nova).
883
+ * Source: https://ui.shadcn.com/r/styles/radix-nova/questionnaire.json
884
+ *
885
+ * MIT License
886
+ *
887
+ * Copyright (c) 2023 shadcn
888
+ *
889
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
890
+ * of this software and associated documentation files (the "Software"), to deal
891
+ * in the Software without restriction, including without limitation the rights
892
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
893
+ * copies of the Software, and to permit persons to whom the Software is
894
+ * furnished to do so, subject to the following conditions:
895
+ *
896
+ * The above copyright notice and this permission notice shall be included in all
897
+ * copies or substantial portions of the Software.
898
+ *
899
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
900
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
901
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
902
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
903
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
904
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
905
+ * SOFTWARE.
906
+ */
907
+ //# sourceMappingURL=questions.js.map