@blade-hq/agent-react 2612.0.0-beta.6 → 2612.0.0-beta.61

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