@nucleux/structured-input 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +167 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +166 -9
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -165,6 +165,12 @@ var StructuredInput = React__namespace.forwardRef(
|
|
|
165
165
|
}
|
|
166
166
|
);
|
|
167
167
|
StructuredInput.displayName = "StructuredInput";
|
|
168
|
+
function splitStructuredTags(value) {
|
|
169
|
+
return (value ?? "").split(",").map((t) => t.trim()).filter(Boolean);
|
|
170
|
+
}
|
|
171
|
+
function structuredSlotType(slot) {
|
|
172
|
+
return slot.type ?? (slot.options ? "select" : "text");
|
|
173
|
+
}
|
|
168
174
|
var StructuredInputSlots = React__namespace.forwardRef(
|
|
169
175
|
({
|
|
170
176
|
slots,
|
|
@@ -175,6 +181,12 @@ var StructuredInputSlots = React__namespace.forwardRef(
|
|
|
175
181
|
onSubmit,
|
|
176
182
|
submitLabel = "Generate",
|
|
177
183
|
label = "Structured prompt builder",
|
|
184
|
+
title,
|
|
185
|
+
icon,
|
|
186
|
+
aside,
|
|
187
|
+
showProgress = false,
|
|
188
|
+
onCancel,
|
|
189
|
+
cancelLabel = "Cancel",
|
|
178
190
|
className,
|
|
179
191
|
...props
|
|
180
192
|
}, ref) => {
|
|
@@ -189,41 +201,120 @@ var StructuredInputSlots = React__namespace.forwardRef(
|
|
|
189
201
|
setEdited((e) => ({ ...e, [name]: true }));
|
|
190
202
|
onValuesChange?.(next);
|
|
191
203
|
};
|
|
204
|
+
const filled = (name) => !!values[name]?.trim();
|
|
205
|
+
const filledCount = slots.filter((slot) => filled(slot.name)).length;
|
|
206
|
+
const requiredMet = slots.every((slot) => !slot.required || filled(slot.name));
|
|
192
207
|
const hasAny = Object.values(values).some((v) => v && v.trim()) || extra.trim().length > 0;
|
|
208
|
+
const canSubmit = hasAny && requiredMet;
|
|
193
209
|
const freeformLabel = typeof freeform === "string" ? freeform : "Anything else?";
|
|
210
|
+
const titleId = `${baseId}-title`;
|
|
194
211
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
195
212
|
"form",
|
|
196
213
|
{
|
|
197
214
|
ref,
|
|
198
|
-
"aria-label": label,
|
|
215
|
+
"aria-label": title == null ? label : void 0,
|
|
216
|
+
"aria-labelledby": title == null ? void 0 : titleId,
|
|
199
217
|
className: utils.cn("grid grid-cols-1 gap-3 sm:grid-cols-2", className),
|
|
200
218
|
onSubmit: (e) => {
|
|
201
219
|
e.preventDefault();
|
|
202
|
-
if (
|
|
220
|
+
if (canSubmit) onSubmit?.(values, extra);
|
|
203
221
|
},
|
|
204
222
|
...props,
|
|
205
223
|
children: [
|
|
224
|
+
(title != null || aside != null) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex items-center gap-3 border-b border-border pb-4 sm:col-span-2", children: [
|
|
225
|
+
icon != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
226
|
+
"span",
|
|
227
|
+
{
|
|
228
|
+
"aria-hidden": "true",
|
|
229
|
+
className: "inline-flex size-[1.625rem] shrink-0 items-center justify-center rounded-md bg-foreground text-background [&_svg]:size-3.5",
|
|
230
|
+
children: icon
|
|
231
|
+
}
|
|
232
|
+
),
|
|
233
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { id: titleId, className: "flex-1 text-base font-semibold text-foreground", children: title }),
|
|
234
|
+
aside
|
|
235
|
+
] }),
|
|
206
236
|
slots.map((slot) => {
|
|
207
237
|
const id = `${baseId}-${slot.name}`;
|
|
208
238
|
const helperId = `${id}-helper`;
|
|
209
239
|
const mark = slot.suggested ? edited[slot.name] ? { text: "Edited by you", variant: "secondary" } : { text: "Suggested", variant: "info" } : null;
|
|
210
240
|
const describedBy = slot.helper || mark && !edited[slot.name] ? helperId : void 0;
|
|
241
|
+
const type = structuredSlotType(slot);
|
|
211
242
|
return /* @__PURE__ */ jsxRuntime.jsxs(field.Field, { className: utils.cn("gap-1.5", slot.wide && "sm:col-span-2"), children: [
|
|
212
243
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
213
|
-
/* @__PURE__ */ jsxRuntime.
|
|
244
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
245
|
+
field.FieldLabel,
|
|
246
|
+
{
|
|
247
|
+
id: `${id}-label`,
|
|
248
|
+
htmlFor: id,
|
|
249
|
+
className: "text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground",
|
|
250
|
+
children: [
|
|
251
|
+
slot.label,
|
|
252
|
+
slot.required && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: " *" })
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
),
|
|
214
256
|
mark && /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: mark.variant, children: mark.text })
|
|
215
257
|
] }),
|
|
216
|
-
slot.options ? /* @__PURE__ */ jsxRuntime.jsxs(select.Select, { value: values[slot.name] || void 0, onValueChange: (v) => setValue(slot.name, v), children: [
|
|
217
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
258
|
+
type === "select" && slot.options ? /* @__PURE__ */ jsxRuntime.jsxs(select.Select, { value: values[slot.name] || void 0, onValueChange: (v) => setValue(slot.name, v), children: [
|
|
259
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
260
|
+
select.SelectTrigger,
|
|
261
|
+
{
|
|
262
|
+
id,
|
|
263
|
+
"aria-labelledby": `${id}-label ${id}`,
|
|
264
|
+
"aria-describedby": describedBy,
|
|
265
|
+
"aria-required": slot.required || void 0,
|
|
266
|
+
className: "h-11 rounded-lg px-3.5",
|
|
267
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: slot.placeholder ?? "Choose\u2026" })
|
|
268
|
+
}
|
|
269
|
+
),
|
|
218
270
|
/* @__PURE__ */ jsxRuntime.jsx(select.SelectContent, { children: slot.options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: o.value, children: o.label }, o.value)) })
|
|
219
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
271
|
+
] }) : type === "segmented" && slot.options ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
272
|
+
"div",
|
|
273
|
+
{
|
|
274
|
+
id,
|
|
275
|
+
role: "group",
|
|
276
|
+
"aria-labelledby": `${id}-label`,
|
|
277
|
+
"aria-describedby": describedBy,
|
|
278
|
+
className: "inline-flex w-fit overflow-hidden rounded-lg border border-input",
|
|
279
|
+
children: slot.options.map((o, i) => {
|
|
280
|
+
const on = values[slot.name] === o.value;
|
|
281
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
282
|
+
"button",
|
|
283
|
+
{
|
|
284
|
+
type: "button",
|
|
285
|
+
"aria-pressed": on,
|
|
286
|
+
onClick: () => setValue(slot.name, o.value),
|
|
287
|
+
className: utils.cn(
|
|
288
|
+
"h-11 px-4 text-sm font-medium transition-colors focus-visible:relative focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
|
|
289
|
+
i > 0 && "border-l border-input",
|
|
290
|
+
on ? "bg-accent text-accent-foreground" : "bg-background text-foreground hover:bg-accent/50"
|
|
291
|
+
),
|
|
292
|
+
children: o.label
|
|
293
|
+
},
|
|
294
|
+
o.value
|
|
295
|
+
);
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
) : type === "tags" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
299
|
+
StructuredTagsField,
|
|
300
|
+
{
|
|
301
|
+
id,
|
|
302
|
+
value: values[slot.name],
|
|
303
|
+
placeholder: slot.placeholder,
|
|
304
|
+
describedBy,
|
|
305
|
+
onChange: (v) => setValue(slot.name, v)
|
|
306
|
+
}
|
|
307
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
220
308
|
input.Input,
|
|
221
309
|
{
|
|
222
310
|
id,
|
|
311
|
+
type: type === "date" ? "date" : "text",
|
|
223
312
|
value: values[slot.name] ?? "",
|
|
224
313
|
placeholder: slot.placeholder,
|
|
225
314
|
"aria-describedby": describedBy,
|
|
226
|
-
|
|
315
|
+
"aria-required": slot.required || void 0,
|
|
316
|
+
onChange: (e) => setValue(slot.name, e.target.value),
|
|
317
|
+
className: "h-11 rounded-lg px-3.5 text-base shadow-none"
|
|
227
318
|
}
|
|
228
319
|
),
|
|
229
320
|
describedBy && /* @__PURE__ */ jsxRuntime.jsxs(field.FieldDescription, { id: helperId, className: "text-xs", children: [
|
|
@@ -245,13 +336,79 @@ var StructuredInputSlots = React__namespace.forwardRef(
|
|
|
245
336
|
}
|
|
246
337
|
)
|
|
247
338
|
] }),
|
|
248
|
-
onSubmit && /* @__PURE__ */ jsxRuntime.
|
|
339
|
+
(onSubmit || onCancel || showProgress) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:col-span-2", children: [
|
|
340
|
+
showProgress && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", "aria-live": "polite", children: [
|
|
341
|
+
filledCount,
|
|
342
|
+
" of ",
|
|
343
|
+
slots.length,
|
|
344
|
+
" filled"
|
|
345
|
+
] }),
|
|
346
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
347
|
+
onCancel && /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", variant: "ghost", onClick: onCancel, children: cancelLabel }),
|
|
348
|
+
onSubmit && /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "submit", variant: "primary", disabled: !canSubmit, className: "h-10 rounded-lg px-5 text-base", children: submitLabel })
|
|
349
|
+
] })
|
|
249
350
|
]
|
|
250
351
|
}
|
|
251
352
|
);
|
|
252
353
|
}
|
|
253
354
|
);
|
|
254
355
|
StructuredInputSlots.displayName = "StructuredInputSlots";
|
|
356
|
+
var SLOT_TAG_TONES = ["bg-destructive/10 text-destructive", "bg-info/10 text-info", "bg-success/10 text-success", "bg-warning/10 text-warning"];
|
|
357
|
+
function StructuredTagsField({
|
|
358
|
+
id,
|
|
359
|
+
value,
|
|
360
|
+
placeholder,
|
|
361
|
+
describedBy,
|
|
362
|
+
onChange
|
|
363
|
+
}) {
|
|
364
|
+
const tags = splitStructuredTags(value);
|
|
365
|
+
const [draft, setDraft] = React__namespace.useState("");
|
|
366
|
+
const add = (text = draft) => {
|
|
367
|
+
const t = text.trim();
|
|
368
|
+
if (t && !tags.includes(t)) onChange([...tags, t].join(", "));
|
|
369
|
+
setDraft("");
|
|
370
|
+
};
|
|
371
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-11 flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-2.5 py-1.5 focus-within:ring-2 focus-within:ring-ring", children: [
|
|
372
|
+
tags.map((t, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
373
|
+
"button",
|
|
374
|
+
{
|
|
375
|
+
type: "button",
|
|
376
|
+
"aria-label": `Remove ${t}`,
|
|
377
|
+
onClick: () => onChange(tags.filter((x) => x !== t).join(", ")),
|
|
378
|
+
className: utils.cn(
|
|
379
|
+
"rounded-md px-2 py-0.5 text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
380
|
+
SLOT_TAG_TONES[i % SLOT_TAG_TONES.length]
|
|
381
|
+
),
|
|
382
|
+
children: t
|
|
383
|
+
},
|
|
384
|
+
t
|
|
385
|
+
)),
|
|
386
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
387
|
+
"input",
|
|
388
|
+
{
|
|
389
|
+
id,
|
|
390
|
+
value: draft,
|
|
391
|
+
placeholder: placeholder ?? "+",
|
|
392
|
+
"aria-describedby": describedBy,
|
|
393
|
+
onChange: (e) => {
|
|
394
|
+
const next = e.target.value;
|
|
395
|
+
if (next.endsWith(",")) add(next.slice(0, -1));
|
|
396
|
+
else setDraft(next);
|
|
397
|
+
},
|
|
398
|
+
onKeyDown: (e) => {
|
|
399
|
+
if (e.key === "Enter") {
|
|
400
|
+
e.preventDefault();
|
|
401
|
+
add();
|
|
402
|
+
} else if (e.key === "Backspace" && !draft && tags.length) {
|
|
403
|
+
onChange(tags.slice(0, -1).join(", "));
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
onBlur: () => add(),
|
|
407
|
+
className: "min-w-16 flex-1 bg-transparent px-1 text-sm text-foreground outline-none placeholder:text-muted-foreground"
|
|
408
|
+
}
|
|
409
|
+
)
|
|
410
|
+
] });
|
|
411
|
+
}
|
|
255
412
|
var DEFAULT_TRIGGERS = [
|
|
256
413
|
{ trigger: "@", label: "Person" },
|
|
257
414
|
{ trigger: "p:", label: "Project" },
|
|
@@ -491,6 +648,8 @@ exports.StructuredInput = StructuredInput;
|
|
|
491
648
|
exports.StructuredInputSlots = StructuredInputSlots;
|
|
492
649
|
exports.StructuredInputTags = StructuredInputTags;
|
|
493
650
|
exports.StructuredInputWizard = StructuredInputWizard;
|
|
651
|
+
exports.splitStructuredTags = splitStructuredTags;
|
|
494
652
|
exports.structuredPartsToText = structuredPartsToText;
|
|
653
|
+
exports.structuredSlotType = structuredSlotType;
|
|
495
654
|
//# sourceMappingURL=index.cjs.map
|
|
496
655
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"names":["React","jsxs","cn","jsx","Check","Field","FieldLabel","Badge","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","FieldDescription","Textarea","Button","X"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Check, X } from \"lucide-react\";\nimport { Badge, type BadgeVariant } from \"@nucleux/badge\";\nimport { Button } from \"@nucleux/button\";\nimport { Field, FieldDescription, FieldLabel } from \"@nucleux/field\";\nimport { Input } from \"@nucleux/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@nucleux/select\";\nimport { Textarea } from \"@nucleux/textarea\";\n\nexport interface StructuredOption {\n /** Stable value. */\n value: string;\n /** Display label. */\n label: React.ReactNode;\n}\n\nexport interface StructuredInputProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\" | \"onSubmit\"> {\n /** The clarifying question the agent is asking. */\n question: React.ReactNode;\n /** The selectable answers. */\n options: StructuredOption[];\n /** Allow selecting more than one option. */\n multiple?: boolean;\n /** Selected values (controlled). */\n value?: string[];\n /** Initial selection (uncontrolled). */\n defaultValue?: string[];\n /** Called when the selection changes. */\n onValueChange?: (values: string[]) => void;\n /** Show a free-text \"something else\" escape. */\n allowOther?: boolean;\n /** Label for the other escape. Defaults to `\"Something else…\"`. */\n otherPlaceholder?: string;\n /** Called when the answer is submitted. */\n onSubmit?: (values: string[], other?: string) => void;\n /** Called when the user skips the question. Renders the skip control when set. */\n onSkip?: () => void;\n /** Label for the submit button. */\n submitLabel?: React.ReactNode;\n /** Label for the skip button. */\n skipLabel?: React.ReactNode;\n}\n\n/**\n * An agent-generated clarifying question rendered as a structured choice —\n * single or multi-select options, a free-text escape, and a skip. The other\n * structured-input variants are composable siblings: {@link StructuredInputSlots}\n * (named slots), {@link StructuredInputTags} (tagged input) and\n * {@link StructuredInputWizard} (wizard step).\n * Source: Figma \"Expressive Input / Structured Input\".\n */\nexport const StructuredInput = React.forwardRef<HTMLDivElement, StructuredInputProps>(\n (\n {\n question,\n options,\n multiple = false,\n value,\n defaultValue = [],\n onValueChange,\n allowOther = false,\n otherPlaceholder = \"Something else…\",\n onSubmit,\n onSkip,\n submitLabel = \"Continue\",\n skipLabel = \"Skip\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<string[]>(defaultValue);\n const [other, setOther] = React.useState(\"\");\n const questionId = React.useId();\n const groupRef = React.useRef<HTMLDivElement>(null);\n const selected = value !== undefined ? value : internal;\n\n const setSelected = (next: string[]) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n };\n const toggle = (val: string) => {\n if (multiple) {\n setSelected(selected.includes(val) ? selected.filter((v) => v !== val) : [...selected, val]);\n } else {\n setSelected([val]);\n }\n };\n\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col gap-4 rounded-xl border border-border bg-background p-5\", className)}\n {...props}\n >\n <p id={questionId} className=\"text-base font-medium text-foreground\">\n {question}\n </p>\n <div\n ref={groupRef}\n role={multiple ? \"group\" : \"radiogroup\"}\n aria-labelledby={questionId}\n className=\"flex flex-col gap-2\"\n onKeyDown={(e) => {\n // Radio-group keyboard pattern: arrows move and select.\n if (multiple || ![\"ArrowDown\", \"ArrowUp\", \"ArrowRight\", \"ArrowLeft\"].includes(e.key)) return;\n const radios = Array.from(groupRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"radio\"]') ?? []);\n const i = radios.indexOf(document.activeElement as HTMLButtonElement);\n if (i < 0) return;\n e.preventDefault();\n const step = e.key === \"ArrowDown\" || e.key === \"ArrowRight\" ? 1 : -1;\n const next = (i + step + radios.length) % radios.length;\n radios[next].focus();\n setSelected([options[next].value]);\n }}\n >\n {options.map((option, index) => {\n const active = selected.includes(option.value);\n const tabbable = multiple || index === Math.max(0, options.findIndex((o) => selected.includes(o.value)));\n return (\n <button\n key={option.value}\n type=\"button\"\n role={multiple ? \"checkbox\" : \"radio\"}\n aria-checked={active}\n tabIndex={tabbable ? 0 : -1}\n onClick={() => toggle(option.value)}\n className={cn(\n \"flex items-center gap-3 rounded-lg border px-3 py-2.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-brand bg-brand-muted/50 text-foreground\"\n : \"border-border bg-background text-foreground hover:bg-accent\",\n )}\n >\n <span\n className={cn(\n \"inline-flex size-5 shrink-0 items-center justify-center border transition-colors [&_svg]:size-3.5\",\n multiple ? \"rounded-md\" : \"rounded-full\",\n active ? \"border-brand bg-brand text-brand-foreground\" : \"border-border\",\n )}\n >\n {active && <Check aria-hidden=\"true\" />}\n </span>\n <span className=\"flex-1\">{option.label}</span>\n </button>\n );\n })}\n </div>\n {allowOther && (\n <input\n type=\"text\"\n value={other}\n onChange={(e) => setOther(e.target.value)}\n placeholder={otherPlaceholder}\n aria-label={otherPlaceholder}\n className=\"rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n )}\n <div className=\"flex items-center justify-end gap-2\">\n {onSkip && (\n <button\n type=\"button\"\n onClick={onSkip}\n className=\"inline-flex items-center rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {skipLabel}\n </button>\n )}\n {onSubmit && (\n <button\n type=\"button\"\n onClick={() => onSubmit(selected, allowOther ? other : undefined)}\n disabled={selected.length === 0 && !(allowOther && other.trim())}\n className=\"inline-flex items-center rounded-lg bg-info px-3 py-2 text-sm font-medium text-info-foreground transition-colors hover:bg-info/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\"\n >\n {submitLabel}\n </button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInput.displayName = \"StructuredInput\";\n\n/* -------------------------------------------------------------------------- */\n/* Named slots */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputSlot {\n /** Key in the values object. */\n name: string;\n /** Plain-language label, e.g. `\"Audience\"`. */\n label: string;\n /** Placeholder / example value. */\n placeholder?: string;\n /** Choices — renders a select instead of a text field. */\n options?: StructuredOption[];\n /** Helper text under the field. */\n helper?: string;\n /**\n * Marks the initial value as the agent's suggestion, with the reason, e.g.\n * `\"from the meeting invite\"`. Once the person changes it, it reads “Edited by you”.\n */\n suggested?: string;\n /** Span the full row. */\n wide?: boolean;\n}\n\nexport type StructuredInputValues = Record<string, string>;\n\nexport interface StructuredInputSlotsProps\n extends Omit<React.HTMLAttributes<HTMLFormElement>, \"onSubmit\" | \"defaultValue\"> {\n /** The 2–4 slots the prompt template needs. */\n slots: StructuredInputSlot[];\n /** Values (controlled). */\n values?: StructuredInputValues;\n /** Initial values (uncontrolled). */\n defaultValues?: StructuredInputValues;\n /** Called on every change. */\n onValuesChange?: (values: StructuredInputValues) => void;\n /** Show a freeform override field. `true` uses the label `\"Anything else?\"`; a string sets the label. */\n freeform?: boolean | string;\n /** Called on submit. Never requires every slot — any value (or the freeform text) is enough. */\n onSubmit?: (values: StructuredInputValues, freeform: string) => void;\n /** Label of the submit button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Accessible name of the form. Defaults to `\"Structured prompt builder\"`. */\n label?: string;\n}\n\n/**\n * Named slots: a short set of plain-language fields (2–4) that fill a prompt\n * template — text fields or selects, an optional freeform override, and a\n * submit that never requires every field. Agent-suggested values are marked\n * “Suggested” with their reason and become “Edited by you” once changed; the\n * component never changes a value the person set.\n */\nexport const StructuredInputSlots = React.forwardRef<HTMLFormElement, StructuredInputSlotsProps>(\n (\n {\n slots,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n freeform = false,\n onSubmit,\n submitLabel = \"Generate\",\n label = \"Structured prompt builder\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputValues>(defaultValues ?? {});\n const values = valuesProp ?? internal;\n const [edited, setEdited] = React.useState<Record<string, boolean>>({});\n const [extra, setExtra] = React.useState(\"\");\n const baseId = React.useId();\n\n const setValue = (name: string, value: string) => {\n const next = { ...values, [name]: value };\n if (valuesProp === undefined) setInternal(next);\n setEdited((e) => ({ ...e, [name]: true }));\n onValuesChange?.(next);\n };\n\n const hasAny = Object.values(values).some((v) => v && v.trim()) || extra.trim().length > 0;\n const freeformLabel = typeof freeform === \"string\" ? freeform : \"Anything else?\";\n\n return (\n <form\n ref={ref}\n aria-label={label}\n className={cn(\"grid grid-cols-1 gap-3 sm:grid-cols-2\", className)}\n onSubmit={(e) => {\n e.preventDefault();\n if (hasAny) onSubmit?.(values, extra);\n }}\n {...props}\n >\n {slots.map((slot) => {\n const id = `${baseId}-${slot.name}`;\n const helperId = `${id}-helper`;\n const mark = slot.suggested\n ? edited[slot.name]\n ? { text: \"Edited by you\", variant: \"secondary\" as const }\n : { text: \"Suggested\", variant: \"info\" as const }\n : null;\n const describedBy = slot.helper || (mark && !edited[slot.name]) ? helperId : undefined;\n return (\n <Field key={slot.name} className={cn(\"gap-1.5\", slot.wide && \"sm:col-span-2\")}>\n <div className=\"flex items-center gap-2\">\n <FieldLabel id={`${id}-label`} htmlFor={id} className=\"text-xs font-semibold text-muted-foreground\">\n {slot.label}\n </FieldLabel>\n {mark && <Badge variant={mark.variant}>{mark.text}</Badge>}\n </div>\n {slot.options ? (\n <Select value={values[slot.name] || undefined} onValueChange={(v) => setValue(slot.name, v)}>\n <SelectTrigger id={id} aria-labelledby={`${id}-label ${id}`} aria-describedby={describedBy}>\n <SelectValue placeholder={slot.placeholder ?? \"Choose…\"} />\n </SelectTrigger>\n <SelectContent>\n {slot.options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input\n id={id}\n value={values[slot.name] ?? \"\"}\n placeholder={slot.placeholder}\n aria-describedby={describedBy}\n onChange={(e) => setValue(slot.name, e.target.value)}\n />\n )}\n {describedBy && (\n <FieldDescription id={helperId} className=\"text-xs\">\n {mark && !edited[slot.name] ? `Suggested ${slot.suggested}. ` : \"\"}\n {slot.helper}\n </FieldDescription>\n )}\n </Field>\n );\n })}\n {freeform && (\n <Field className=\"gap-1.5 sm:col-span-2\">\n <FieldLabel htmlFor={`${baseId}-freeform`} className=\"text-xs font-semibold text-muted-foreground\">\n {freeformLabel}\n </FieldLabel>\n <Textarea\n id={`${baseId}-freeform`}\n rows={2}\n value={extra}\n placeholder=\"Say it in your own words — this overrides the fields above\"\n onChange={(e) => setExtra(e.target.value)}\n />\n </Field>\n )}\n {onSubmit && (\n <div className=\"flex justify-end sm:col-span-2\">\n <Button type=\"submit\" variant=\"cta\" size=\"sm\" disabled={!hasAny}>\n {submitLabel}\n </Button>\n </div>\n )}\n </form>\n );\n },\n);\nStructuredInputSlots.displayName = \"StructuredInputSlots\";\n\n/* -------------------------------------------------------------------------- */\n/* Tagged input */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputTagTrigger {\n /** The prefix that starts a tag, e.g. `\"@\"`, `\"p:\"`, `\"/\"`. */\n trigger: string;\n /** What the tag refers to, e.g. `\"Person\"`. */\n label: string;\n /** Values offered while typing after the trigger. */\n suggestions?: string[];\n}\n\nexport type StructuredInputPart =\n | { type: \"text\"; text: string }\n | { type: \"tag\"; trigger: string; value: string };\n\nexport interface StructuredInputTagsProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"defaultValue\" | \"onChange\"> {\n /** Recognised tag prefixes. Defaults to `@` person, `p:` project, `/` file. */\n triggers?: StructuredInputTagTrigger[];\n /** Committed parts (controlled). */\n value?: StructuredInputPart[];\n /** Initial parts (uncontrolled). */\n defaultValue?: StructuredInputPart[];\n /** Called when parts are added or removed. */\n onValueChange?: (parts: StructuredInputPart[]) => void;\n /** Called on Enter or the send button with the parts and their plain-text form. */\n onSubmit?: (parts: StructuredInputPart[], text: string) => void;\n /** Accessible name and placeholder of the text field. */\n placeholder?: string;\n /** Label of the send button. Defaults to `\"Send\"`. */\n submitLabel?: React.ReactNode;\n}\n\nconst DEFAULT_TRIGGERS: StructuredInputTagTrigger[] = [\n { trigger: \"@\", label: \"Person\" },\n { trigger: \"p:\", label: \"Project\" },\n { trigger: \"/\", label: \"File\" },\n];\n\nconst TAG_TONES: { variant: BadgeVariant; className?: string }[] = [\n { variant: \"secondary\", className: \"bg-brand-muted text-brand\" },\n { variant: \"info\" },\n { variant: \"success\" },\n { variant: \"outline\" },\n];\n\n/** Serialise parts into the plain prompt text, e.g. `\"Update @sam on p:Apollo\"`. */\nexport function structuredPartsToText(parts: StructuredInputPart[]): string {\n return parts\n .map((p) => (p.type === \"text\" ? p.text : `${p.trigger}${p.value}`))\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Tagged input: a prompt field where typed prefixes (`@` person, `p:` project,\n * `/` file — configurable) become removable tag chips, with optional\n * type-ahead suggestions shown as buttons. Backspace on an empty field removes\n * the last tag; Enter sends. Tags are optional — plain text always works.\n */\nexport const StructuredInputTags = React.forwardRef<HTMLDivElement, StructuredInputTagsProps>(\n (\n {\n triggers = DEFAULT_TRIGGERS,\n value: valueProp,\n defaultValue,\n onValueChange,\n onSubmit,\n placeholder = \"Type @ for people, p: for projects, / for files\",\n submitLabel = \"Send\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputPart[]>(defaultValue ?? []);\n const parts = valueProp ?? internal;\n const [draft, setDraft] = React.useState(\"\");\n const inputRef = React.useRef<HTMLInputElement>(null);\n const hintId = React.useId();\n\n const commit = (next: StructuredInputPart[]) => {\n if (valueProp === undefined) setInternal(next);\n onValueChange?.(next);\n };\n\n // Longest trigger first so \"p:\" wins over \"p\".\n const ordered = [...triggers].sort((a, b) => b.trigger.length - a.trigger.length);\n const matchTag = (word: string) => {\n const t = ordered.find((tr) => word.startsWith(tr.trigger) && word.length > tr.trigger.length);\n return t ? { trigger: t.trigger, value: word.slice(t.trigger.length) } : null;\n };\n\n const lastWord = draft.split(\" \").pop() ?? \"\";\n const activeTrigger = ordered.find((tr) => lastWord.startsWith(tr.trigger));\n const query = activeTrigger ? lastWord.slice(activeTrigger.trigger.length).toLowerCase() : \"\";\n const suggestions =\n activeTrigger?.suggestions?.filter((s) => s.toLowerCase().startsWith(query)).slice(0, 5) ?? [];\n\n /** Split the draft into text + a trailing tag (if any) and commit them. */\n const flush = (source = draft, forceTag?: { trigger: string; value: string }): StructuredInputPart[] => {\n const words = source.split(\" \");\n const last = words.pop() ?? \"\";\n const tag = forceTag ?? matchTag(last);\n const textBefore = (tag ? words.join(\" \") : source).trim();\n const next = [...parts];\n if (textBefore) next.push({ type: \"text\", text: textBefore });\n if (tag) next.push({ type: \"tag\", ...tag });\n if (next.length !== parts.length) commit(next);\n setDraft(\"\");\n return next;\n };\n\n const toneFor = (trigger: string) => {\n const i = triggers.findIndex((t) => t.trigger === trigger);\n return TAG_TONES[(i < 0 ? 0 : i) % TAG_TONES.length];\n };\n const labelFor = (trigger: string) => triggers.find((t) => t.trigger === trigger)?.label ?? \"Tag\";\n\n const submit = () => {\n const next = flush();\n const text = structuredPartsToText(next);\n if (text) onSubmit?.(next, text);\n };\n\n return (\n <div ref={ref} className={cn(\"flex flex-col gap-2\", className)} {...props}>\n <div\n className=\"flex flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground focus-within:ring-2 focus-within:ring-ring\"\n onClick={() => inputRef.current?.focus()}\n >\n {parts.map((part, i) =>\n part.type === \"text\" ? (\n <span key={i}>{part.text}</span>\n ) : (\n <Badge\n key={i}\n variant={toneFor(part.trigger).variant}\n className={cn(\"gap-0.5 rounded-md pr-0.5 font-semibold\", toneFor(part.trigger).className)}\n >\n {part.trigger}\n {part.value}\n <button\n type=\"button\"\n aria-label={`Remove ${labelFor(part.trigger).toLowerCase()} ${part.trigger}${part.value}`}\n onClick={(e) => {\n e.stopPropagation();\n commit(parts.filter((_, j) => j !== i));\n inputRef.current?.focus();\n }}\n className=\"inline-flex size-4 items-center justify-center rounded-sm opacity-70 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-3\"\n >\n <X aria-hidden=\"true\" />\n </button>\n </Badge>\n ),\n )}\n <Input\n ref={inputRef}\n value={draft}\n aria-label={placeholder}\n aria-describedby={hintId}\n placeholder={parts.length ? undefined : placeholder}\n onChange={(e) => {\n const v = e.target.value;\n // A space after a tag word (incl. mobile keyboards that skip keydown) makes it a chip.\n if (v.endsWith(\" \") && matchTag(v.trimEnd().split(\" \").pop() ?? \"\")) flush(v.trimEnd());\n else setDraft(v);\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" && matchTag(lastWord)) {\n e.preventDefault();\n flush();\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n submit();\n } else if (e.key === \"Backspace\" && draft === \"\" && parts.length) {\n e.preventDefault();\n const last = parts[parts.length - 1];\n commit(parts.slice(0, -1));\n if (last.type === \"text\") setDraft(last.text);\n }\n }}\n className=\"h-7 min-w-[8rem] flex-1 border-0 px-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n <p id={hintId} className=\"sr-only\">\n {triggers.map((t) => `${t.trigger} for ${t.label.toLowerCase()}`).join(\", \")}. Space turns a tag into a\n chip; Backspace removes the last one; Enter sends.\n </p>\n {activeTrigger && suggestions.length > 0 && (\n <div role=\"group\" aria-label={`${activeTrigger.label} suggestions`} className=\"flex flex-wrap gap-1\">\n {suggestions.map((s) => (\n <Button\n key={s}\n variant=\"secondary\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={() => {\n flush(draft, { trigger: activeTrigger.trigger, value: s });\n inputRef.current?.focus();\n }}\n >\n {activeTrigger.trigger}\n {s}\n </Button>\n ))}\n </div>\n )}\n {onSubmit && (\n <div className=\"flex justify-end\">\n <Button\n variant=\"cta\"\n size=\"sm\"\n onClick={submit}\n disabled={parts.length === 0 && draft.trim() === \"\"}\n >\n {submitLabel}\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\nStructuredInputTags.displayName = \"StructuredInputTags\";\n\n/* -------------------------------------------------------------------------- */\n/* Wizard step */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputWizardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"title\"> {\n /** Step titles, e.g. `[\"Intent\", \"Audience\", \"Tone\"]`. */\n steps: string[];\n /** Current step, 0-based (controlled). */\n step?: number;\n /** Initial step (uncontrolled). */\n defaultStep?: number;\n /** Called when Back / Next move. */\n onStepChange?: (step: number) => void;\n /** The current step's question, e.g. `\"Who is the brief for?\"`. */\n description?: React.ReactNode;\n /** Called from the last step (or from “Generate now” when `allowEarlySubmit`). */\n onSubmit?: () => void;\n /** Label of the final button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Offer “Generate now” before the last step — fields are never all required. Defaults to `true`. */\n allowEarlySubmit?: boolean;\n /** The current step's fields. */\n children?: React.ReactNode;\n}\n\n/**\n * Wizard step: a multi-step frame for high-stakes prompts (legal, HR, medical) —\n * a progress bar, “Step 2 of 3 · Audience”, the step's question and fields\n * (children), and Back / Next / Generate. Focus moves to the step heading when\n * the step changes; nothing forces every step to be filled before generating.\n */\nexport const StructuredInputWizard = React.forwardRef<HTMLDivElement, StructuredInputWizardProps>(\n (\n {\n steps,\n step: stepProp,\n defaultStep = 0,\n onStepChange,\n description,\n onSubmit,\n submitLabel = \"Generate\",\n allowEarlySubmit = true,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState(defaultStep);\n const step = Math.min(Math.max(stepProp ?? internal, 0), Math.max(steps.length - 1, 0));\n const headingRef = React.useRef<HTMLParagraphElement>(null);\n const headingId = React.useId();\n const moved = React.useRef(false);\n\n React.useEffect(() => {\n if (moved.current) headingRef.current?.focus();\n }, [step]);\n\n const go = (next: number) => {\n moved.current = true;\n if (stepProp === undefined) setInternal(next);\n onStepChange?.(next);\n };\n\n const last = step === steps.length - 1;\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={headingId}\n className={cn(\"flex flex-col gap-3 rounded-xl border border-border bg-background p-4\", className)}\n {...props}\n >\n <div className=\"flex gap-1\" aria-hidden=\"true\">\n {steps.map((_, i) => (\n <span key={i} className={cn(\"h-1 flex-1 rounded-full\", i <= step ? \"bg-brand\" : \"bg-muted\")} />\n ))}\n </div>\n <div className=\"flex flex-col gap-1\">\n <p ref={headingRef} id={headingId} tabIndex={-1} className=\"text-sm font-semibold text-foreground outline-none\">\n Step {step + 1} of {steps.length} · {steps[step]}\n </p>\n {description && <p className=\"text-sm text-muted-foreground\">{description}</p>}\n </div>\n {children}\n <div className=\"flex items-center gap-2\">\n {step > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => go(step - 1)}>\n Back\n </Button>\n )}\n <span className=\"flex-1\" />\n {!last && allowEarlySubmit && onSubmit && (\n <Button variant=\"link\" size=\"sm\" onClick={onSubmit}>\n {submitLabel} now\n </Button>\n )}\n {last ? (\n onSubmit && (\n <Button variant=\"cta\" size=\"sm\" onClick={onSubmit}>\n {submitLabel}\n </Button>\n )\n ) : (\n <Button variant=\"cta\" size=\"sm\" onClick={() => go(step + 1)}>\n Next\n </Button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInputWizard.displayName = \"StructuredInputWizard\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["React","jsxs","cn","jsx","Check","Field","FieldLabel","Badge","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","FieldDescription","Textarea","Button","X"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Check, X } from \"lucide-react\";\nimport { Badge, type BadgeVariant } from \"@nucleux/badge\";\nimport { Button } from \"@nucleux/button\";\nimport { Field, FieldDescription, FieldLabel } from \"@nucleux/field\";\nimport { Input } from \"@nucleux/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@nucleux/select\";\nimport { Textarea } from \"@nucleux/textarea\";\n\nexport interface StructuredOption {\n /** Stable value. */\n value: string;\n /** Display label. */\n label: React.ReactNode;\n}\n\nexport interface StructuredInputProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\" | \"onSubmit\"> {\n /** The clarifying question the agent is asking. */\n question: React.ReactNode;\n /** The selectable answers. */\n options: StructuredOption[];\n /** Allow selecting more than one option. */\n multiple?: boolean;\n /** Selected values (controlled). */\n value?: string[];\n /** Initial selection (uncontrolled). */\n defaultValue?: string[];\n /** Called when the selection changes. */\n onValueChange?: (values: string[]) => void;\n /** Show a free-text \"something else\" escape. */\n allowOther?: boolean;\n /** Label for the other escape. Defaults to `\"Something else…\"`. */\n otherPlaceholder?: string;\n /** Called when the answer is submitted. */\n onSubmit?: (values: string[], other?: string) => void;\n /** Called when the user skips the question. Renders the skip control when set. */\n onSkip?: () => void;\n /** Label for the submit button. */\n submitLabel?: React.ReactNode;\n /** Label for the skip button. */\n skipLabel?: React.ReactNode;\n}\n\n/**\n * An agent-generated clarifying question rendered as a structured choice —\n * single or multi-select options, a free-text escape, and a skip. The other\n * structured-input variants are composable siblings: {@link StructuredInputSlots}\n * (named slots), {@link StructuredInputTags} (tagged input) and\n * {@link StructuredInputWizard} (wizard step).\n * Source: Figma \"Expressive Input / Structured Input\".\n */\nexport const StructuredInput = React.forwardRef<HTMLDivElement, StructuredInputProps>(\n (\n {\n question,\n options,\n multiple = false,\n value,\n defaultValue = [],\n onValueChange,\n allowOther = false,\n otherPlaceholder = \"Something else…\",\n onSubmit,\n onSkip,\n submitLabel = \"Continue\",\n skipLabel = \"Skip\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<string[]>(defaultValue);\n const [other, setOther] = React.useState(\"\");\n const questionId = React.useId();\n const groupRef = React.useRef<HTMLDivElement>(null);\n const selected = value !== undefined ? value : internal;\n\n const setSelected = (next: string[]) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n };\n const toggle = (val: string) => {\n if (multiple) {\n setSelected(selected.includes(val) ? selected.filter((v) => v !== val) : [...selected, val]);\n } else {\n setSelected([val]);\n }\n };\n\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col gap-4 rounded-xl border border-border bg-background p-5\", className)}\n {...props}\n >\n <p id={questionId} className=\"text-base font-medium text-foreground\">\n {question}\n </p>\n <div\n ref={groupRef}\n role={multiple ? \"group\" : \"radiogroup\"}\n aria-labelledby={questionId}\n className=\"flex flex-col gap-2\"\n onKeyDown={(e) => {\n // Radio-group keyboard pattern: arrows move and select.\n if (multiple || ![\"ArrowDown\", \"ArrowUp\", \"ArrowRight\", \"ArrowLeft\"].includes(e.key)) return;\n const radios = Array.from(groupRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"radio\"]') ?? []);\n const i = radios.indexOf(document.activeElement as HTMLButtonElement);\n if (i < 0) return;\n e.preventDefault();\n const step = e.key === \"ArrowDown\" || e.key === \"ArrowRight\" ? 1 : -1;\n const next = (i + step + radios.length) % radios.length;\n radios[next].focus();\n setSelected([options[next].value]);\n }}\n >\n {options.map((option, index) => {\n const active = selected.includes(option.value);\n const tabbable = multiple || index === Math.max(0, options.findIndex((o) => selected.includes(o.value)));\n return (\n <button\n key={option.value}\n type=\"button\"\n role={multiple ? \"checkbox\" : \"radio\"}\n aria-checked={active}\n tabIndex={tabbable ? 0 : -1}\n onClick={() => toggle(option.value)}\n className={cn(\n \"flex items-center gap-3 rounded-lg border px-3 py-2.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-brand bg-brand-muted/50 text-foreground\"\n : \"border-border bg-background text-foreground hover:bg-accent\",\n )}\n >\n <span\n className={cn(\n \"inline-flex size-5 shrink-0 items-center justify-center border transition-colors [&_svg]:size-3.5\",\n multiple ? \"rounded-md\" : \"rounded-full\",\n active ? \"border-brand bg-brand text-brand-foreground\" : \"border-border\",\n )}\n >\n {active && <Check aria-hidden=\"true\" />}\n </span>\n <span className=\"flex-1\">{option.label}</span>\n </button>\n );\n })}\n </div>\n {allowOther && (\n <input\n type=\"text\"\n value={other}\n onChange={(e) => setOther(e.target.value)}\n placeholder={otherPlaceholder}\n aria-label={otherPlaceholder}\n className=\"rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n )}\n <div className=\"flex items-center justify-end gap-2\">\n {onSkip && (\n <button\n type=\"button\"\n onClick={onSkip}\n className=\"inline-flex items-center rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {skipLabel}\n </button>\n )}\n {onSubmit && (\n <button\n type=\"button\"\n onClick={() => onSubmit(selected, allowOther ? other : undefined)}\n disabled={selected.length === 0 && !(allowOther && other.trim())}\n className=\"inline-flex items-center rounded-lg bg-info px-3 py-2 text-sm font-medium text-info-foreground transition-colors hover:bg-info/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\"\n >\n {submitLabel}\n </button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInput.displayName = \"StructuredInput\";\n\n/* -------------------------------------------------------------------------- */\n/* Named slots */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputSlot {\n /** Key in the values object. */\n name: string;\n /** Plain-language label, e.g. `\"Audience\"`. */\n label: string;\n /** Placeholder / example value. */\n placeholder?: string;\n /** Choices — renders a select instead of a text field. */\n options?: StructuredOption[];\n /** Helper text under the field. */\n helper?: string;\n /**\n * Marks the initial value as the agent's suggestion, with the reason, e.g.\n * `\"from the meeting invite\"`. Once the person changes it, it reads “Edited by you”.\n */\n suggested?: string;\n /** Span the full row. */\n wide?: boolean;\n /**\n * The control. Defaults to `\"select\"` when `options` are given, else `\"text\"`.\n * `\"segmented\"` shows `options` as a row of buttons; `\"date\"` a date field;\n * `\"tags\"` a tag field whose value is a comma-separated list.\n */\n type?: StructuredInputSlotType;\n /** The slot must be filled before submitting; its label carries “*”. */\n required?: boolean;\n}\n\n/** Control used for a slot. */\nexport type StructuredInputSlotType = \"text\" | \"select\" | \"segmented\" | \"date\" | \"tags\";\n\n/** Splits a `\"tags\"` slot's value into its tags. */\nexport function splitStructuredTags(value: string | undefined): string[] {\n return (value ?? \"\")\n .split(\",\")\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\n/** The control a slot uses, from its `type` and `options`. */\nexport function structuredSlotType(slot: StructuredInputSlot): StructuredInputSlotType {\n return slot.type ?? (slot.options ? \"select\" : \"text\");\n}\n\nexport type StructuredInputValues = Record<string, string>;\n\nexport interface StructuredInputSlotsProps\n extends Omit<React.HTMLAttributes<HTMLFormElement>, \"onSubmit\" | \"defaultValue\" | \"title\"> {\n /** The 2–4 slots the prompt template needs. */\n slots: StructuredInputSlot[];\n /** Values (controlled). */\n values?: StructuredInputValues;\n /** Initial values (uncontrolled). */\n defaultValues?: StructuredInputValues;\n /** Called on every change. */\n onValuesChange?: (values: StructuredInputValues) => void;\n /** Show a freeform override field. `true` uses the label `\"Anything else?\"`; a string sets the label. */\n freeform?: boolean | string;\n /** Called on submit. Never requires every slot — any value (or the freeform text) is enough. */\n onSubmit?: (values: StructuredInputValues, freeform: string) => void;\n /** Label of the submit button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Accessible name of the form. Defaults to `\"Structured prompt builder\"`. */\n label?: string;\n /** Heading over the fields, e.g. `\"Structured prompt\"`; it also names the form. */\n title?: React.ReactNode;\n /** Icon beside the title. */\n icon?: React.ReactNode;\n /** Right side of the title row, e.g. a \"Template\" badge or what the form is for. */\n aside?: React.ReactNode;\n /** Shows “3 of 4 filled” beside the buttons. */\n showProgress?: boolean;\n /** Shows a Cancel button beside submit. */\n onCancel?: () => void;\n /** Label of the cancel button. Defaults to `\"Cancel\"`. */\n cancelLabel?: React.ReactNode;\n}\n\n/**\n * Named slots: a short set of plain-language fields (2–4) that fill a prompt\n * template — text fields or selects, an optional freeform override, and a\n * submit that never requires every field. Agent-suggested values are marked\n * “Suggested” with their reason and become “Edited by you” once changed; the\n * component never changes a value the person set.\n */\nexport const StructuredInputSlots = React.forwardRef<HTMLFormElement, StructuredInputSlotsProps>(\n (\n {\n slots,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n freeform = false,\n onSubmit,\n submitLabel = \"Generate\",\n label = \"Structured prompt builder\",\n title,\n icon,\n aside,\n showProgress = false,\n onCancel,\n cancelLabel = \"Cancel\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputValues>(defaultValues ?? {});\n const values = valuesProp ?? internal;\n const [edited, setEdited] = React.useState<Record<string, boolean>>({});\n const [extra, setExtra] = React.useState(\"\");\n const baseId = React.useId();\n\n const setValue = (name: string, value: string) => {\n const next = { ...values, [name]: value };\n if (valuesProp === undefined) setInternal(next);\n setEdited((e) => ({ ...e, [name]: true }));\n onValuesChange?.(next);\n };\n\n const filled = (name: string) => !!values[name]?.trim();\n const filledCount = slots.filter((slot) => filled(slot.name)).length;\n const requiredMet = slots.every((slot) => !slot.required || filled(slot.name));\n const hasAny = Object.values(values).some((v) => v && v.trim()) || extra.trim().length > 0;\n const canSubmit = hasAny && requiredMet;\n const freeformLabel = typeof freeform === \"string\" ? freeform : \"Anything else?\";\n const titleId = `${baseId}-title`;\n\n return (\n <form\n ref={ref}\n aria-label={title == null ? label : undefined}\n aria-labelledby={title == null ? undefined : titleId}\n className={cn(\"grid grid-cols-1 gap-3 sm:grid-cols-2\", className)}\n onSubmit={(e) => {\n e.preventDefault();\n if (canSubmit) onSubmit?.(values, extra);\n }}\n {...props}\n >\n {(title != null || aside != null) && (\n <div className=\"mb-1 flex items-center gap-3 border-b border-border pb-4 sm:col-span-2\">\n {icon != null && (\n <span\n aria-hidden=\"true\"\n className=\"inline-flex size-[1.625rem] shrink-0 items-center justify-center rounded-md bg-foreground text-background [&_svg]:size-3.5\"\n >\n {icon}\n </span>\n )}\n <h3 id={titleId} className=\"flex-1 text-base font-semibold text-foreground\">\n {title}\n </h3>\n {aside}\n </div>\n )}\n {slots.map((slot) => {\n const id = `${baseId}-${slot.name}`;\n const helperId = `${id}-helper`;\n const mark = slot.suggested\n ? edited[slot.name]\n ? { text: \"Edited by you\", variant: \"secondary\" as const }\n : { text: \"Suggested\", variant: \"info\" as const }\n : null;\n const describedBy = slot.helper || (mark && !edited[slot.name]) ? helperId : undefined;\n const type = structuredSlotType(slot);\n return (\n <Field key={slot.name} className={cn(\"gap-1.5\", slot.wide && \"sm:col-span-2\")}>\n <div className=\"flex items-center gap-2\">\n <FieldLabel\n id={`${id}-label`}\n htmlFor={id}\n className=\"text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground\"\n >\n {slot.label}\n {slot.required && <span aria-hidden=\"true\"> *</span>}\n </FieldLabel>\n {mark && <Badge variant={mark.variant}>{mark.text}</Badge>}\n </div>\n {type === \"select\" && slot.options ? (\n <Select value={values[slot.name] || undefined} onValueChange={(v) => setValue(slot.name, v)}>\n <SelectTrigger\n id={id}\n aria-labelledby={`${id}-label ${id}`}\n aria-describedby={describedBy}\n aria-required={slot.required || undefined}\n className=\"h-11 rounded-lg px-3.5\"\n >\n <SelectValue placeholder={slot.placeholder ?? \"Choose…\"} />\n </SelectTrigger>\n <SelectContent>\n {slot.options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : type === \"segmented\" && slot.options ? (\n <div\n id={id}\n role=\"group\"\n aria-labelledby={`${id}-label`}\n aria-describedby={describedBy}\n className=\"inline-flex w-fit overflow-hidden rounded-lg border border-input\"\n >\n {slot.options.map((o, i) => {\n const on = values[slot.name] === o.value;\n return (\n <button\n key={o.value}\n type=\"button\"\n aria-pressed={on}\n onClick={() => setValue(slot.name, o.value)}\n className={cn(\n \"h-11 px-4 text-sm font-medium transition-colors focus-visible:relative focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n i > 0 && \"border-l border-input\",\n on ? \"bg-accent text-accent-foreground\" : \"bg-background text-foreground hover:bg-accent/50\",\n )}\n >\n {o.label}\n </button>\n );\n })}\n </div>\n ) : type === \"tags\" ? (\n <StructuredTagsField\n id={id}\n value={values[slot.name]}\n placeholder={slot.placeholder}\n describedBy={describedBy}\n onChange={(v) => setValue(slot.name, v)}\n />\n ) : (\n <Input\n id={id}\n type={type === \"date\" ? \"date\" : \"text\"}\n value={values[slot.name] ?? \"\"}\n placeholder={slot.placeholder}\n aria-describedby={describedBy}\n aria-required={slot.required || undefined}\n onChange={(e) => setValue(slot.name, e.target.value)}\n className=\"h-11 rounded-lg px-3.5 text-base shadow-none\"\n />\n )}\n {describedBy && (\n <FieldDescription id={helperId} className=\"text-xs\">\n {mark && !edited[slot.name] ? `Suggested ${slot.suggested}. ` : \"\"}\n {slot.helper}\n </FieldDescription>\n )}\n </Field>\n );\n })}\n {freeform && (\n <Field className=\"gap-1.5 sm:col-span-2\">\n <FieldLabel htmlFor={`${baseId}-freeform`} className=\"text-xs font-semibold text-muted-foreground\">\n {freeformLabel}\n </FieldLabel>\n <Textarea\n id={`${baseId}-freeform`}\n rows={2}\n value={extra}\n placeholder=\"Say it in your own words — this overrides the fields above\"\n onChange={(e) => setExtra(e.target.value)}\n />\n </Field>\n )}\n {(onSubmit || onCancel || showProgress) && (\n <div className=\"flex items-center gap-2 sm:col-span-2\">\n {showProgress && (\n <span className=\"text-xs text-muted-foreground\" aria-live=\"polite\">\n {filledCount} of {slots.length} filled\n </span>\n )}\n <span className=\"flex-1\" />\n {onCancel && (\n <Button type=\"button\" variant=\"ghost\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n )}\n {onSubmit && (\n <Button type=\"submit\" variant=\"primary\" disabled={!canSubmit} className=\"h-10 rounded-lg px-5 text-base\">\n {submitLabel}\n </Button>\n )}\n </div>\n )}\n </form>\n );\n },\n);\nStructuredInputSlots.displayName = \"StructuredInputSlots\";\n\nconst SLOT_TAG_TONES = [\"bg-destructive/10 text-destructive\", \"bg-info/10 text-info\", \"bg-success/10 text-success\", \"bg-warning/10 text-warning\"];\n\n/** The `\"tags\"` slot: tinted tags (press one to remove it) and a field that adds on Enter or comma. */\nfunction StructuredTagsField({\n id,\n value,\n placeholder,\n describedBy,\n onChange,\n}: {\n id: string;\n value?: string;\n placeholder?: string;\n describedBy?: string;\n onChange: (value: string) => void;\n}) {\n const tags = splitStructuredTags(value);\n const [draft, setDraft] = React.useState(\"\");\n const add = (text = draft) => {\n const t = text.trim();\n if (t && !tags.includes(t)) onChange([...tags, t].join(\", \"));\n setDraft(\"\");\n };\n return (\n <div className=\"flex min-h-11 flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-2.5 py-1.5 focus-within:ring-2 focus-within:ring-ring\">\n {tags.map((t, i) => (\n <button\n key={t}\n type=\"button\"\n aria-label={`Remove ${t}`}\n onClick={() => onChange(tags.filter((x) => x !== t).join(\", \"))}\n className={cn(\n \"rounded-md px-2 py-0.5 text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n SLOT_TAG_TONES[i % SLOT_TAG_TONES.length],\n )}\n >\n {t}\n </button>\n ))}\n <input\n id={id}\n value={draft}\n placeholder={placeholder ?? \"+\"}\n aria-describedby={describedBy}\n onChange={(e) => {\n const next = e.target.value;\n if (next.endsWith(\",\")) add(next.slice(0, -1));\n else setDraft(next);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n add();\n } else if (e.key === \"Backspace\" && !draft && tags.length) {\n onChange(tags.slice(0, -1).join(\", \"));\n }\n }}\n onBlur={() => add()}\n className=\"min-w-16 flex-1 bg-transparent px-1 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Tagged input */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputTagTrigger {\n /** The prefix that starts a tag, e.g. `\"@\"`, `\"p:\"`, `\"/\"`. */\n trigger: string;\n /** What the tag refers to, e.g. `\"Person\"`. */\n label: string;\n /** Values offered while typing after the trigger. */\n suggestions?: string[];\n}\n\nexport type StructuredInputPart =\n | { type: \"text\"; text: string }\n | { type: \"tag\"; trigger: string; value: string };\n\nexport interface StructuredInputTagsProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"defaultValue\" | \"onChange\"> {\n /** Recognised tag prefixes. Defaults to `@` person, `p:` project, `/` file. */\n triggers?: StructuredInputTagTrigger[];\n /** Committed parts (controlled). */\n value?: StructuredInputPart[];\n /** Initial parts (uncontrolled). */\n defaultValue?: StructuredInputPart[];\n /** Called when parts are added or removed. */\n onValueChange?: (parts: StructuredInputPart[]) => void;\n /** Called on Enter or the send button with the parts and their plain-text form. */\n onSubmit?: (parts: StructuredInputPart[], text: string) => void;\n /** Accessible name and placeholder of the text field. */\n placeholder?: string;\n /** Label of the send button. Defaults to `\"Send\"`. */\n submitLabel?: React.ReactNode;\n}\n\nconst DEFAULT_TRIGGERS: StructuredInputTagTrigger[] = [\n { trigger: \"@\", label: \"Person\" },\n { trigger: \"p:\", label: \"Project\" },\n { trigger: \"/\", label: \"File\" },\n];\n\nconst TAG_TONES: { variant: BadgeVariant; className?: string }[] = [\n { variant: \"secondary\", className: \"bg-brand-muted text-brand\" },\n { variant: \"info\" },\n { variant: \"success\" },\n { variant: \"outline\" },\n];\n\n/** Serialise parts into the plain prompt text, e.g. `\"Update @sam on p:Apollo\"`. */\nexport function structuredPartsToText(parts: StructuredInputPart[]): string {\n return parts\n .map((p) => (p.type === \"text\" ? p.text : `${p.trigger}${p.value}`))\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Tagged input: a prompt field where typed prefixes (`@` person, `p:` project,\n * `/` file — configurable) become removable tag chips, with optional\n * type-ahead suggestions shown as buttons. Backspace on an empty field removes\n * the last tag; Enter sends. Tags are optional — plain text always works.\n */\nexport const StructuredInputTags = React.forwardRef<HTMLDivElement, StructuredInputTagsProps>(\n (\n {\n triggers = DEFAULT_TRIGGERS,\n value: valueProp,\n defaultValue,\n onValueChange,\n onSubmit,\n placeholder = \"Type @ for people, p: for projects, / for files\",\n submitLabel = \"Send\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputPart[]>(defaultValue ?? []);\n const parts = valueProp ?? internal;\n const [draft, setDraft] = React.useState(\"\");\n const inputRef = React.useRef<HTMLInputElement>(null);\n const hintId = React.useId();\n\n const commit = (next: StructuredInputPart[]) => {\n if (valueProp === undefined) setInternal(next);\n onValueChange?.(next);\n };\n\n // Longest trigger first so \"p:\" wins over \"p\".\n const ordered = [...triggers].sort((a, b) => b.trigger.length - a.trigger.length);\n const matchTag = (word: string) => {\n const t = ordered.find((tr) => word.startsWith(tr.trigger) && word.length > tr.trigger.length);\n return t ? { trigger: t.trigger, value: word.slice(t.trigger.length) } : null;\n };\n\n const lastWord = draft.split(\" \").pop() ?? \"\";\n const activeTrigger = ordered.find((tr) => lastWord.startsWith(tr.trigger));\n const query = activeTrigger ? lastWord.slice(activeTrigger.trigger.length).toLowerCase() : \"\";\n const suggestions =\n activeTrigger?.suggestions?.filter((s) => s.toLowerCase().startsWith(query)).slice(0, 5) ?? [];\n\n /** Split the draft into text + a trailing tag (if any) and commit them. */\n const flush = (source = draft, forceTag?: { trigger: string; value: string }): StructuredInputPart[] => {\n const words = source.split(\" \");\n const last = words.pop() ?? \"\";\n const tag = forceTag ?? matchTag(last);\n const textBefore = (tag ? words.join(\" \") : source).trim();\n const next = [...parts];\n if (textBefore) next.push({ type: \"text\", text: textBefore });\n if (tag) next.push({ type: \"tag\", ...tag });\n if (next.length !== parts.length) commit(next);\n setDraft(\"\");\n return next;\n };\n\n const toneFor = (trigger: string) => {\n const i = triggers.findIndex((t) => t.trigger === trigger);\n return TAG_TONES[(i < 0 ? 0 : i) % TAG_TONES.length];\n };\n const labelFor = (trigger: string) => triggers.find((t) => t.trigger === trigger)?.label ?? \"Tag\";\n\n const submit = () => {\n const next = flush();\n const text = structuredPartsToText(next);\n if (text) onSubmit?.(next, text);\n };\n\n return (\n <div ref={ref} className={cn(\"flex flex-col gap-2\", className)} {...props}>\n <div\n className=\"flex flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground focus-within:ring-2 focus-within:ring-ring\"\n onClick={() => inputRef.current?.focus()}\n >\n {parts.map((part, i) =>\n part.type === \"text\" ? (\n <span key={i}>{part.text}</span>\n ) : (\n <Badge\n key={i}\n variant={toneFor(part.trigger).variant}\n className={cn(\"gap-0.5 rounded-md pr-0.5 font-semibold\", toneFor(part.trigger).className)}\n >\n {part.trigger}\n {part.value}\n <button\n type=\"button\"\n aria-label={`Remove ${labelFor(part.trigger).toLowerCase()} ${part.trigger}${part.value}`}\n onClick={(e) => {\n e.stopPropagation();\n commit(parts.filter((_, j) => j !== i));\n inputRef.current?.focus();\n }}\n className=\"inline-flex size-4 items-center justify-center rounded-sm opacity-70 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-3\"\n >\n <X aria-hidden=\"true\" />\n </button>\n </Badge>\n ),\n )}\n <Input\n ref={inputRef}\n value={draft}\n aria-label={placeholder}\n aria-describedby={hintId}\n placeholder={parts.length ? undefined : placeholder}\n onChange={(e) => {\n const v = e.target.value;\n // A space after a tag word (incl. mobile keyboards that skip keydown) makes it a chip.\n if (v.endsWith(\" \") && matchTag(v.trimEnd().split(\" \").pop() ?? \"\")) flush(v.trimEnd());\n else setDraft(v);\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" && matchTag(lastWord)) {\n e.preventDefault();\n flush();\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n submit();\n } else if (e.key === \"Backspace\" && draft === \"\" && parts.length) {\n e.preventDefault();\n const last = parts[parts.length - 1];\n commit(parts.slice(0, -1));\n if (last.type === \"text\") setDraft(last.text);\n }\n }}\n className=\"h-7 min-w-[8rem] flex-1 border-0 px-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n <p id={hintId} className=\"sr-only\">\n {triggers.map((t) => `${t.trigger} for ${t.label.toLowerCase()}`).join(\", \")}. Space turns a tag into a\n chip; Backspace removes the last one; Enter sends.\n </p>\n {activeTrigger && suggestions.length > 0 && (\n <div role=\"group\" aria-label={`${activeTrigger.label} suggestions`} className=\"flex flex-wrap gap-1\">\n {suggestions.map((s) => (\n <Button\n key={s}\n variant=\"secondary\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={() => {\n flush(draft, { trigger: activeTrigger.trigger, value: s });\n inputRef.current?.focus();\n }}\n >\n {activeTrigger.trigger}\n {s}\n </Button>\n ))}\n </div>\n )}\n {onSubmit && (\n <div className=\"flex justify-end\">\n <Button\n variant=\"cta\"\n size=\"sm\"\n onClick={submit}\n disabled={parts.length === 0 && draft.trim() === \"\"}\n >\n {submitLabel}\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\nStructuredInputTags.displayName = \"StructuredInputTags\";\n\n/* -------------------------------------------------------------------------- */\n/* Wizard step */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputWizardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"title\"> {\n /** Step titles, e.g. `[\"Intent\", \"Audience\", \"Tone\"]`. */\n steps: string[];\n /** Current step, 0-based (controlled). */\n step?: number;\n /** Initial step (uncontrolled). */\n defaultStep?: number;\n /** Called when Back / Next move. */\n onStepChange?: (step: number) => void;\n /** The current step's question, e.g. `\"Who is the brief for?\"`. */\n description?: React.ReactNode;\n /** Called from the last step (or from “Generate now” when `allowEarlySubmit`). */\n onSubmit?: () => void;\n /** Label of the final button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Offer “Generate now” before the last step — fields are never all required. Defaults to `true`. */\n allowEarlySubmit?: boolean;\n /** The current step's fields. */\n children?: React.ReactNode;\n}\n\n/**\n * Wizard step: a multi-step frame for high-stakes prompts (legal, HR, medical) —\n * a progress bar, “Step 2 of 3 · Audience”, the step's question and fields\n * (children), and Back / Next / Generate. Focus moves to the step heading when\n * the step changes; nothing forces every step to be filled before generating.\n */\nexport const StructuredInputWizard = React.forwardRef<HTMLDivElement, StructuredInputWizardProps>(\n (\n {\n steps,\n step: stepProp,\n defaultStep = 0,\n onStepChange,\n description,\n onSubmit,\n submitLabel = \"Generate\",\n allowEarlySubmit = true,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState(defaultStep);\n const step = Math.min(Math.max(stepProp ?? internal, 0), Math.max(steps.length - 1, 0));\n const headingRef = React.useRef<HTMLParagraphElement>(null);\n const headingId = React.useId();\n const moved = React.useRef(false);\n\n React.useEffect(() => {\n if (moved.current) headingRef.current?.focus();\n }, [step]);\n\n const go = (next: number) => {\n moved.current = true;\n if (stepProp === undefined) setInternal(next);\n onStepChange?.(next);\n };\n\n const last = step === steps.length - 1;\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={headingId}\n className={cn(\"flex flex-col gap-3 rounded-xl border border-border bg-background p-4\", className)}\n {...props}\n >\n <div className=\"flex gap-1\" aria-hidden=\"true\">\n {steps.map((_, i) => (\n <span key={i} className={cn(\"h-1 flex-1 rounded-full\", i <= step ? \"bg-brand\" : \"bg-muted\")} />\n ))}\n </div>\n <div className=\"flex flex-col gap-1\">\n <p ref={headingRef} id={headingId} tabIndex={-1} className=\"text-sm font-semibold text-foreground outline-none\">\n Step {step + 1} of {steps.length} · {steps[step]}\n </p>\n {description && <p className=\"text-sm text-muted-foreground\">{description}</p>}\n </div>\n {children}\n <div className=\"flex items-center gap-2\">\n {step > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => go(step - 1)}>\n Back\n </Button>\n )}\n <span className=\"flex-1\" />\n {!last && allowEarlySubmit && onSubmit && (\n <Button variant=\"link\" size=\"sm\" onClick={onSubmit}>\n {submitLabel} now\n </Button>\n )}\n {last ? (\n onSubmit && (\n <Button variant=\"cta\" size=\"sm\" onClick={onSubmit}>\n {submitLabel}\n </Button>\n )\n ) : (\n <Button variant=\"cta\" size=\"sm\" onClick={() => go(step + 1)}>\n Next\n </Button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInputWizard.displayName = \"StructuredInputWizard\";\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -59,9 +59,23 @@ interface StructuredInputSlot {
|
|
|
59
59
|
suggested?: string;
|
|
60
60
|
/** Span the full row. */
|
|
61
61
|
wide?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The control. Defaults to `"select"` when `options` are given, else `"text"`.
|
|
64
|
+
* `"segmented"` shows `options` as a row of buttons; `"date"` a date field;
|
|
65
|
+
* `"tags"` a tag field whose value is a comma-separated list.
|
|
66
|
+
*/
|
|
67
|
+
type?: StructuredInputSlotType;
|
|
68
|
+
/** The slot must be filled before submitting; its label carries “*”. */
|
|
69
|
+
required?: boolean;
|
|
62
70
|
}
|
|
71
|
+
/** Control used for a slot. */
|
|
72
|
+
type StructuredInputSlotType = "text" | "select" | "segmented" | "date" | "tags";
|
|
73
|
+
/** Splits a `"tags"` slot's value into its tags. */
|
|
74
|
+
declare function splitStructuredTags(value: string | undefined): string[];
|
|
75
|
+
/** The control a slot uses, from its `type` and `options`. */
|
|
76
|
+
declare function structuredSlotType(slot: StructuredInputSlot): StructuredInputSlotType;
|
|
63
77
|
type StructuredInputValues = Record<string, string>;
|
|
64
|
-
interface StructuredInputSlotsProps extends Omit<React.HTMLAttributes<HTMLFormElement>, "onSubmit" | "defaultValue"> {
|
|
78
|
+
interface StructuredInputSlotsProps extends Omit<React.HTMLAttributes<HTMLFormElement>, "onSubmit" | "defaultValue" | "title"> {
|
|
65
79
|
/** The 2–4 slots the prompt template needs. */
|
|
66
80
|
slots: StructuredInputSlot[];
|
|
67
81
|
/** Values (controlled). */
|
|
@@ -78,6 +92,18 @@ interface StructuredInputSlotsProps extends Omit<React.HTMLAttributes<HTMLFormEl
|
|
|
78
92
|
submitLabel?: React.ReactNode;
|
|
79
93
|
/** Accessible name of the form. Defaults to `"Structured prompt builder"`. */
|
|
80
94
|
label?: string;
|
|
95
|
+
/** Heading over the fields, e.g. `"Structured prompt"`; it also names the form. */
|
|
96
|
+
title?: React.ReactNode;
|
|
97
|
+
/** Icon beside the title. */
|
|
98
|
+
icon?: React.ReactNode;
|
|
99
|
+
/** Right side of the title row, e.g. a "Template" badge or what the form is for. */
|
|
100
|
+
aside?: React.ReactNode;
|
|
101
|
+
/** Shows “3 of 4 filled” beside the buttons. */
|
|
102
|
+
showProgress?: boolean;
|
|
103
|
+
/** Shows a Cancel button beside submit. */
|
|
104
|
+
onCancel?: () => void;
|
|
105
|
+
/** Label of the cancel button. Defaults to `"Cancel"`. */
|
|
106
|
+
cancelLabel?: React.ReactNode;
|
|
81
107
|
}
|
|
82
108
|
/**
|
|
83
109
|
* Named slots: a short set of plain-language fields (2–4) that fill a prompt
|
|
@@ -156,4 +182,4 @@ interface StructuredInputWizardProps extends Omit<React.HTMLAttributes<HTMLDivEl
|
|
|
156
182
|
*/
|
|
157
183
|
declare const StructuredInputWizard: React.ForwardRefExoticComponent<StructuredInputWizardProps & React.RefAttributes<HTMLDivElement>>;
|
|
158
184
|
|
|
159
|
-
export { StructuredInput, type StructuredInputPart, type StructuredInputProps, type StructuredInputSlot, StructuredInputSlots, type StructuredInputSlotsProps, type StructuredInputTagTrigger, StructuredInputTags, type StructuredInputTagsProps, type StructuredInputValues, StructuredInputWizard, type StructuredInputWizardProps, type StructuredOption, structuredPartsToText };
|
|
185
|
+
export { StructuredInput, type StructuredInputPart, type StructuredInputProps, type StructuredInputSlot, type StructuredInputSlotType, StructuredInputSlots, type StructuredInputSlotsProps, type StructuredInputTagTrigger, StructuredInputTags, type StructuredInputTagsProps, type StructuredInputValues, StructuredInputWizard, type StructuredInputWizardProps, type StructuredOption, splitStructuredTags, structuredPartsToText, structuredSlotType };
|
package/dist/index.d.ts
CHANGED
|
@@ -59,9 +59,23 @@ interface StructuredInputSlot {
|
|
|
59
59
|
suggested?: string;
|
|
60
60
|
/** Span the full row. */
|
|
61
61
|
wide?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The control. Defaults to `"select"` when `options` are given, else `"text"`.
|
|
64
|
+
* `"segmented"` shows `options` as a row of buttons; `"date"` a date field;
|
|
65
|
+
* `"tags"` a tag field whose value is a comma-separated list.
|
|
66
|
+
*/
|
|
67
|
+
type?: StructuredInputSlotType;
|
|
68
|
+
/** The slot must be filled before submitting; its label carries “*”. */
|
|
69
|
+
required?: boolean;
|
|
62
70
|
}
|
|
71
|
+
/** Control used for a slot. */
|
|
72
|
+
type StructuredInputSlotType = "text" | "select" | "segmented" | "date" | "tags";
|
|
73
|
+
/** Splits a `"tags"` slot's value into its tags. */
|
|
74
|
+
declare function splitStructuredTags(value: string | undefined): string[];
|
|
75
|
+
/** The control a slot uses, from its `type` and `options`. */
|
|
76
|
+
declare function structuredSlotType(slot: StructuredInputSlot): StructuredInputSlotType;
|
|
63
77
|
type StructuredInputValues = Record<string, string>;
|
|
64
|
-
interface StructuredInputSlotsProps extends Omit<React.HTMLAttributes<HTMLFormElement>, "onSubmit" | "defaultValue"> {
|
|
78
|
+
interface StructuredInputSlotsProps extends Omit<React.HTMLAttributes<HTMLFormElement>, "onSubmit" | "defaultValue" | "title"> {
|
|
65
79
|
/** The 2–4 slots the prompt template needs. */
|
|
66
80
|
slots: StructuredInputSlot[];
|
|
67
81
|
/** Values (controlled). */
|
|
@@ -78,6 +92,18 @@ interface StructuredInputSlotsProps extends Omit<React.HTMLAttributes<HTMLFormEl
|
|
|
78
92
|
submitLabel?: React.ReactNode;
|
|
79
93
|
/** Accessible name of the form. Defaults to `"Structured prompt builder"`. */
|
|
80
94
|
label?: string;
|
|
95
|
+
/** Heading over the fields, e.g. `"Structured prompt"`; it also names the form. */
|
|
96
|
+
title?: React.ReactNode;
|
|
97
|
+
/** Icon beside the title. */
|
|
98
|
+
icon?: React.ReactNode;
|
|
99
|
+
/** Right side of the title row, e.g. a "Template" badge or what the form is for. */
|
|
100
|
+
aside?: React.ReactNode;
|
|
101
|
+
/** Shows “3 of 4 filled” beside the buttons. */
|
|
102
|
+
showProgress?: boolean;
|
|
103
|
+
/** Shows a Cancel button beside submit. */
|
|
104
|
+
onCancel?: () => void;
|
|
105
|
+
/** Label of the cancel button. Defaults to `"Cancel"`. */
|
|
106
|
+
cancelLabel?: React.ReactNode;
|
|
81
107
|
}
|
|
82
108
|
/**
|
|
83
109
|
* Named slots: a short set of plain-language fields (2–4) that fill a prompt
|
|
@@ -156,4 +182,4 @@ interface StructuredInputWizardProps extends Omit<React.HTMLAttributes<HTMLDivEl
|
|
|
156
182
|
*/
|
|
157
183
|
declare const StructuredInputWizard: React.ForwardRefExoticComponent<StructuredInputWizardProps & React.RefAttributes<HTMLDivElement>>;
|
|
158
184
|
|
|
159
|
-
export { StructuredInput, type StructuredInputPart, type StructuredInputProps, type StructuredInputSlot, StructuredInputSlots, type StructuredInputSlotsProps, type StructuredInputTagTrigger, StructuredInputTags, type StructuredInputTagsProps, type StructuredInputValues, StructuredInputWizard, type StructuredInputWizardProps, type StructuredOption, structuredPartsToText };
|
|
185
|
+
export { StructuredInput, type StructuredInputPart, type StructuredInputProps, type StructuredInputSlot, type StructuredInputSlotType, StructuredInputSlots, type StructuredInputSlotsProps, type StructuredInputTagTrigger, StructuredInputTags, type StructuredInputTagsProps, type StructuredInputValues, StructuredInputWizard, type StructuredInputWizardProps, type StructuredOption, splitStructuredTags, structuredPartsToText, structuredSlotType };
|
package/dist/index.js
CHANGED
|
@@ -143,6 +143,12 @@ var StructuredInput = React.forwardRef(
|
|
|
143
143
|
}
|
|
144
144
|
);
|
|
145
145
|
StructuredInput.displayName = "StructuredInput";
|
|
146
|
+
function splitStructuredTags(value) {
|
|
147
|
+
return (value ?? "").split(",").map((t) => t.trim()).filter(Boolean);
|
|
148
|
+
}
|
|
149
|
+
function structuredSlotType(slot) {
|
|
150
|
+
return slot.type ?? (slot.options ? "select" : "text");
|
|
151
|
+
}
|
|
146
152
|
var StructuredInputSlots = React.forwardRef(
|
|
147
153
|
({
|
|
148
154
|
slots,
|
|
@@ -153,6 +159,12 @@ var StructuredInputSlots = React.forwardRef(
|
|
|
153
159
|
onSubmit,
|
|
154
160
|
submitLabel = "Generate",
|
|
155
161
|
label = "Structured prompt builder",
|
|
162
|
+
title,
|
|
163
|
+
icon,
|
|
164
|
+
aside,
|
|
165
|
+
showProgress = false,
|
|
166
|
+
onCancel,
|
|
167
|
+
cancelLabel = "Cancel",
|
|
156
168
|
className,
|
|
157
169
|
...props
|
|
158
170
|
}, ref) => {
|
|
@@ -167,41 +179,120 @@ var StructuredInputSlots = React.forwardRef(
|
|
|
167
179
|
setEdited((e) => ({ ...e, [name]: true }));
|
|
168
180
|
onValuesChange?.(next);
|
|
169
181
|
};
|
|
182
|
+
const filled = (name) => !!values[name]?.trim();
|
|
183
|
+
const filledCount = slots.filter((slot) => filled(slot.name)).length;
|
|
184
|
+
const requiredMet = slots.every((slot) => !slot.required || filled(slot.name));
|
|
170
185
|
const hasAny = Object.values(values).some((v) => v && v.trim()) || extra.trim().length > 0;
|
|
186
|
+
const canSubmit = hasAny && requiredMet;
|
|
171
187
|
const freeformLabel = typeof freeform === "string" ? freeform : "Anything else?";
|
|
188
|
+
const titleId = `${baseId}-title`;
|
|
172
189
|
return /* @__PURE__ */ jsxs(
|
|
173
190
|
"form",
|
|
174
191
|
{
|
|
175
192
|
ref,
|
|
176
|
-
"aria-label": label,
|
|
193
|
+
"aria-label": title == null ? label : void 0,
|
|
194
|
+
"aria-labelledby": title == null ? void 0 : titleId,
|
|
177
195
|
className: cn("grid grid-cols-1 gap-3 sm:grid-cols-2", className),
|
|
178
196
|
onSubmit: (e) => {
|
|
179
197
|
e.preventDefault();
|
|
180
|
-
if (
|
|
198
|
+
if (canSubmit) onSubmit?.(values, extra);
|
|
181
199
|
},
|
|
182
200
|
...props,
|
|
183
201
|
children: [
|
|
202
|
+
(title != null || aside != null) && /* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center gap-3 border-b border-border pb-4 sm:col-span-2", children: [
|
|
203
|
+
icon != null && /* @__PURE__ */ jsx(
|
|
204
|
+
"span",
|
|
205
|
+
{
|
|
206
|
+
"aria-hidden": "true",
|
|
207
|
+
className: "inline-flex size-[1.625rem] shrink-0 items-center justify-center rounded-md bg-foreground text-background [&_svg]:size-3.5",
|
|
208
|
+
children: icon
|
|
209
|
+
}
|
|
210
|
+
),
|
|
211
|
+
/* @__PURE__ */ jsx("h3", { id: titleId, className: "flex-1 text-base font-semibold text-foreground", children: title }),
|
|
212
|
+
aside
|
|
213
|
+
] }),
|
|
184
214
|
slots.map((slot) => {
|
|
185
215
|
const id = `${baseId}-${slot.name}`;
|
|
186
216
|
const helperId = `${id}-helper`;
|
|
187
217
|
const mark = slot.suggested ? edited[slot.name] ? { text: "Edited by you", variant: "secondary" } : { text: "Suggested", variant: "info" } : null;
|
|
188
218
|
const describedBy = slot.helper || mark && !edited[slot.name] ? helperId : void 0;
|
|
219
|
+
const type = structuredSlotType(slot);
|
|
189
220
|
return /* @__PURE__ */ jsxs(Field, { className: cn("gap-1.5", slot.wide && "sm:col-span-2"), children: [
|
|
190
221
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
191
|
-
/* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ jsxs(
|
|
223
|
+
FieldLabel,
|
|
224
|
+
{
|
|
225
|
+
id: `${id}-label`,
|
|
226
|
+
htmlFor: id,
|
|
227
|
+
className: "text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground",
|
|
228
|
+
children: [
|
|
229
|
+
slot.label,
|
|
230
|
+
slot.required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " *" })
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
),
|
|
192
234
|
mark && /* @__PURE__ */ jsx(Badge, { variant: mark.variant, children: mark.text })
|
|
193
235
|
] }),
|
|
194
|
-
slot.options ? /* @__PURE__ */ jsxs(Select, { value: values[slot.name] || void 0, onValueChange: (v) => setValue(slot.name, v), children: [
|
|
195
|
-
/* @__PURE__ */ jsx(
|
|
236
|
+
type === "select" && slot.options ? /* @__PURE__ */ jsxs(Select, { value: values[slot.name] || void 0, onValueChange: (v) => setValue(slot.name, v), children: [
|
|
237
|
+
/* @__PURE__ */ jsx(
|
|
238
|
+
SelectTrigger,
|
|
239
|
+
{
|
|
240
|
+
id,
|
|
241
|
+
"aria-labelledby": `${id}-label ${id}`,
|
|
242
|
+
"aria-describedby": describedBy,
|
|
243
|
+
"aria-required": slot.required || void 0,
|
|
244
|
+
className: "h-11 rounded-lg px-3.5",
|
|
245
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: slot.placeholder ?? "Choose\u2026" })
|
|
246
|
+
}
|
|
247
|
+
),
|
|
196
248
|
/* @__PURE__ */ jsx(SelectContent, { children: slot.options.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })
|
|
197
|
-
] }) : /* @__PURE__ */ jsx(
|
|
249
|
+
] }) : type === "segmented" && slot.options ? /* @__PURE__ */ jsx(
|
|
250
|
+
"div",
|
|
251
|
+
{
|
|
252
|
+
id,
|
|
253
|
+
role: "group",
|
|
254
|
+
"aria-labelledby": `${id}-label`,
|
|
255
|
+
"aria-describedby": describedBy,
|
|
256
|
+
className: "inline-flex w-fit overflow-hidden rounded-lg border border-input",
|
|
257
|
+
children: slot.options.map((o, i) => {
|
|
258
|
+
const on = values[slot.name] === o.value;
|
|
259
|
+
return /* @__PURE__ */ jsx(
|
|
260
|
+
"button",
|
|
261
|
+
{
|
|
262
|
+
type: "button",
|
|
263
|
+
"aria-pressed": on,
|
|
264
|
+
onClick: () => setValue(slot.name, o.value),
|
|
265
|
+
className: cn(
|
|
266
|
+
"h-11 px-4 text-sm font-medium transition-colors focus-visible:relative focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
|
|
267
|
+
i > 0 && "border-l border-input",
|
|
268
|
+
on ? "bg-accent text-accent-foreground" : "bg-background text-foreground hover:bg-accent/50"
|
|
269
|
+
),
|
|
270
|
+
children: o.label
|
|
271
|
+
},
|
|
272
|
+
o.value
|
|
273
|
+
);
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
) : type === "tags" ? /* @__PURE__ */ jsx(
|
|
277
|
+
StructuredTagsField,
|
|
278
|
+
{
|
|
279
|
+
id,
|
|
280
|
+
value: values[slot.name],
|
|
281
|
+
placeholder: slot.placeholder,
|
|
282
|
+
describedBy,
|
|
283
|
+
onChange: (v) => setValue(slot.name, v)
|
|
284
|
+
}
|
|
285
|
+
) : /* @__PURE__ */ jsx(
|
|
198
286
|
Input,
|
|
199
287
|
{
|
|
200
288
|
id,
|
|
289
|
+
type: type === "date" ? "date" : "text",
|
|
201
290
|
value: values[slot.name] ?? "",
|
|
202
291
|
placeholder: slot.placeholder,
|
|
203
292
|
"aria-describedby": describedBy,
|
|
204
|
-
|
|
293
|
+
"aria-required": slot.required || void 0,
|
|
294
|
+
onChange: (e) => setValue(slot.name, e.target.value),
|
|
295
|
+
className: "h-11 rounded-lg px-3.5 text-base shadow-none"
|
|
205
296
|
}
|
|
206
297
|
),
|
|
207
298
|
describedBy && /* @__PURE__ */ jsxs(FieldDescription, { id: helperId, className: "text-xs", children: [
|
|
@@ -223,13 +314,79 @@ var StructuredInputSlots = React.forwardRef(
|
|
|
223
314
|
}
|
|
224
315
|
)
|
|
225
316
|
] }),
|
|
226
|
-
onSubmit && /* @__PURE__ */
|
|
317
|
+
(onSubmit || onCancel || showProgress) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:col-span-2", children: [
|
|
318
|
+
showProgress && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", "aria-live": "polite", children: [
|
|
319
|
+
filledCount,
|
|
320
|
+
" of ",
|
|
321
|
+
slots.length,
|
|
322
|
+
" filled"
|
|
323
|
+
] }),
|
|
324
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
325
|
+
onCancel && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", onClick: onCancel, children: cancelLabel }),
|
|
326
|
+
onSubmit && /* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", disabled: !canSubmit, className: "h-10 rounded-lg px-5 text-base", children: submitLabel })
|
|
327
|
+
] })
|
|
227
328
|
]
|
|
228
329
|
}
|
|
229
330
|
);
|
|
230
331
|
}
|
|
231
332
|
);
|
|
232
333
|
StructuredInputSlots.displayName = "StructuredInputSlots";
|
|
334
|
+
var SLOT_TAG_TONES = ["bg-destructive/10 text-destructive", "bg-info/10 text-info", "bg-success/10 text-success", "bg-warning/10 text-warning"];
|
|
335
|
+
function StructuredTagsField({
|
|
336
|
+
id,
|
|
337
|
+
value,
|
|
338
|
+
placeholder,
|
|
339
|
+
describedBy,
|
|
340
|
+
onChange
|
|
341
|
+
}) {
|
|
342
|
+
const tags = splitStructuredTags(value);
|
|
343
|
+
const [draft, setDraft] = React.useState("");
|
|
344
|
+
const add = (text = draft) => {
|
|
345
|
+
const t = text.trim();
|
|
346
|
+
if (t && !tags.includes(t)) onChange([...tags, t].join(", "));
|
|
347
|
+
setDraft("");
|
|
348
|
+
};
|
|
349
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-11 flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-2.5 py-1.5 focus-within:ring-2 focus-within:ring-ring", children: [
|
|
350
|
+
tags.map((t, i) => /* @__PURE__ */ jsx(
|
|
351
|
+
"button",
|
|
352
|
+
{
|
|
353
|
+
type: "button",
|
|
354
|
+
"aria-label": `Remove ${t}`,
|
|
355
|
+
onClick: () => onChange(tags.filter((x) => x !== t).join(", ")),
|
|
356
|
+
className: cn(
|
|
357
|
+
"rounded-md px-2 py-0.5 text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
358
|
+
SLOT_TAG_TONES[i % SLOT_TAG_TONES.length]
|
|
359
|
+
),
|
|
360
|
+
children: t
|
|
361
|
+
},
|
|
362
|
+
t
|
|
363
|
+
)),
|
|
364
|
+
/* @__PURE__ */ jsx(
|
|
365
|
+
"input",
|
|
366
|
+
{
|
|
367
|
+
id,
|
|
368
|
+
value: draft,
|
|
369
|
+
placeholder: placeholder ?? "+",
|
|
370
|
+
"aria-describedby": describedBy,
|
|
371
|
+
onChange: (e) => {
|
|
372
|
+
const next = e.target.value;
|
|
373
|
+
if (next.endsWith(",")) add(next.slice(0, -1));
|
|
374
|
+
else setDraft(next);
|
|
375
|
+
},
|
|
376
|
+
onKeyDown: (e) => {
|
|
377
|
+
if (e.key === "Enter") {
|
|
378
|
+
e.preventDefault();
|
|
379
|
+
add();
|
|
380
|
+
} else if (e.key === "Backspace" && !draft && tags.length) {
|
|
381
|
+
onChange(tags.slice(0, -1).join(", "));
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
onBlur: () => add(),
|
|
385
|
+
className: "min-w-16 flex-1 bg-transparent px-1 text-sm text-foreground outline-none placeholder:text-muted-foreground"
|
|
386
|
+
}
|
|
387
|
+
)
|
|
388
|
+
] });
|
|
389
|
+
}
|
|
233
390
|
var DEFAULT_TRIGGERS = [
|
|
234
391
|
{ trigger: "@", label: "Person" },
|
|
235
392
|
{ trigger: "p:", label: "Project" },
|
|
@@ -465,6 +622,6 @@ var StructuredInputWizard = React.forwardRef(
|
|
|
465
622
|
);
|
|
466
623
|
StructuredInputWizard.displayName = "StructuredInputWizard";
|
|
467
624
|
|
|
468
|
-
export { StructuredInput, StructuredInputSlots, StructuredInputTags, StructuredInputWizard, structuredPartsToText };
|
|
625
|
+
export { StructuredInput, StructuredInputSlots, StructuredInputTags, StructuredInputWizard, splitStructuredTags, structuredPartsToText, structuredSlotType };
|
|
469
626
|
//# sourceMappingURL=index.js.map
|
|
470
627
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAqDO,IAAM,eAAA,GAAwB,KAAA,CAAA,UAAA;AAAA,EACnC,CACE;AAAA,IACE,QAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,GAAW,KAAA;AAAA,IACX,KAAA;AAAA,IACA,eAAe,EAAC;AAAA,IAChB,aAAA;AAAA,IACA,UAAA,GAAa,KAAA;AAAA,IACb,gBAAA,GAAmB,sBAAA;AAAA,IACnB,QAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA,GAAc,UAAA;AAAA,IACd,SAAA,GAAY,MAAA;AAAA,IACZ,SAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAmB,YAAY,CAAA;AACrE,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,aAAmB,KAAA,CAAA,KAAA,EAAM;AAC/B,IAAA,MAAM,QAAA,GAAiB,aAAuB,IAAI,CAAA;AAClD,IAAA,MAAM,QAAA,GAAW,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,QAAA;AAE/C,IAAA,MAAM,WAAA,GAAc,CAAC,IAAA,KAAmB;AACtC,MAAA,IAAI,KAAA,KAAU,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AACzC,MAAA,aAAA,GAAgB,IAAI,CAAA;AAAA,IACtB,CAAA;AACA,IAAA,MAAM,MAAA,GAAS,CAAC,GAAA,KAAgB;AAC9B,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,WAAA,CAAY,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,GAAI,SAAS,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,GAAG,CAAA,GAAI,CAAC,GAAG,QAAA,EAAU,GAAG,CAAC,CAAA;AAAA,MAC7F,CAAA,MAAO;AACL,QAAA,WAAA,CAAY,CAAC,GAAG,CAAC,CAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA,CAAG,uEAAA,EAAyE,SAAS,CAAA;AAAA,QAC/F,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,GAAA,EAAA,EAAE,EAAA,EAAI,UAAA,EAAY,SAAA,EAAU,yCAC1B,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,0BACA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAM,WAAW,OAAA,GAAU,YAAA;AAAA,cAC3B,iBAAA,EAAiB,UAAA;AAAA,cACjB,SAAA,EAAU,qBAAA;AAAA,cACV,SAAA,EAAW,CAAC,CAAA,KAAM;AAEhB,gBAAA,IAAI,QAAA,IAAY,CAAC,CAAC,WAAA,EAAa,SAAA,EAAW,YAAA,EAAc,WAAW,CAAA,CAAE,QAAA,CAAS,CAAA,CAAE,GAAG,CAAA,EAAG;AACtF,gBAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,QAAA,CAAS,SAAS,gBAAA,CAAoC,gBAAgB,CAAA,IAAK,EAAE,CAAA;AACvG,gBAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,aAAkC,CAAA;AACpE,gBAAA,IAAI,IAAI,CAAA,EAAG;AACX,gBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,gBAAA,MAAM,OAAO,CAAA,CAAE,GAAA,KAAQ,eAAe,CAAA,CAAE,GAAA,KAAQ,eAAe,CAAA,GAAI,EAAA;AACnE,gBAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,GAAI,IAAA,GAAO,MAAA,CAAO,UAAU,MAAA,CAAO,MAAA;AACjD,gBAAA,MAAA,CAAO,IAAI,EAAE,KAAA,EAAM;AACnB,gBAAA,WAAA,CAAY,CAAC,OAAA,CAAQ,IAAI,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,cACnC,CAAA;AAAA,cAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAA,KAAU;AAC9B,gBAAA,MAAM,MAAA,GAAS,QAAA,CAAS,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA;AAC7C,gBAAA,MAAM,QAAA,GAAW,QAAA,IAAY,KAAA,KAAU,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,CAAQ,SAAA,CAAU,CAAC,MAAM,QAAA,CAAS,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA;AACvG,gBAAA,uBACE,IAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBAEC,IAAA,EAAK,QAAA;AAAA,oBACL,IAAA,EAAM,WAAW,UAAA,GAAa,OAAA;AAAA,oBAC9B,cAAA,EAAc,MAAA;AAAA,oBACd,QAAA,EAAU,WAAW,CAAA,GAAI,EAAA;AAAA,oBACzB,OAAA,EAAS,MAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,oBAClC,SAAA,EAAW,EAAA;AAAA,sBACT,mKAAA;AAAA,sBACA,SACI,gDAAA,GACA;AAAA,qBACN;AAAA,oBAEA,QAAA,EAAA;AAAA,sCAAA,GAAA;AAAA,wBAAC,MAAA;AAAA,wBAAA;AAAA,0BACC,SAAA,EAAW,EAAA;AAAA,4BACT,mGAAA;AAAA,4BACA,WAAW,YAAA,GAAe,cAAA;AAAA,4BAC1B,SAAS,6CAAA,GAAgD;AAAA,2BAC3D;AAAA,0BAEC,QAAA,EAAA,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAM,aAAA,EAAY,MAAA,EAAO;AAAA;AAAA,uBACvC;AAAA,sCACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAU,iBAAO,KAAA,EAAM;AAAA;AAAA,mBAAA;AAAA,kBAtBlC,MAAA,CAAO;AAAA,iBAuBd;AAAA,cAEJ,CAAC;AAAA;AAAA,WACH;AAAA,UACC,UAAA,oBACC,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,MAAA;AAAA,cACL,KAAA,EAAO,KAAA;AAAA,cACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cACxC,WAAA,EAAa,gBAAA;AAAA,cACb,YAAA,EAAY,gBAAA;AAAA,cACZ,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,0BAEF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qCAAA,EACZ,QAAA,EAAA;AAAA,YAAA,MAAA,oBACC,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,OAAA,EAAS,MAAA;AAAA,gBACT,SAAA,EAAU,yNAAA;AAAA,gBAET,QAAA,EAAA;AAAA;AAAA,aACH;AAAA,YAED,QAAA,oBACC,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,SAAS,MAAM,QAAA,CAAS,QAAA,EAAU,UAAA,GAAa,QAAQ,MAAS,CAAA;AAAA,gBAChE,UAAU,QAAA,CAAS,MAAA,KAAW,KAAK,EAAE,UAAA,IAAc,MAAM,IAAA,EAAK,CAAA;AAAA,gBAC9D,SAAA,EAAU,4PAAA;AAAA,gBAET,QAAA,EAAA;AAAA;AAAA;AACH,WAAA,EAEJ;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAuDvB,IAAM,oBAAA,GAA6B,KAAA,CAAA,UAAA;AAAA,EACxC,CACE;AAAA,IACE,KAAA;AAAA,IACA,MAAA,EAAQ,UAAA;AAAA,IACR,aAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA,GAAW,KAAA;AAAA,IACX,QAAA;AAAA,IACA,WAAA,GAAc,UAAA;AAAA,IACd,KAAA,GAAQ,2BAAA;AAAA,IACR,SAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,IAAU,KAAA,CAAA,QAAA,CAAgC,aAAA,IAAiB,EAAE,CAAA;AACzF,IAAA,MAAM,SAAS,UAAA,IAAc,QAAA;AAC7B,IAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAU,KAAA,CAAA,QAAA,CAAkC,EAAE,CAAA;AACtE,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,SAAe,KAAA,CAAA,KAAA,EAAM;AAE3B,IAAA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAc,KAAA,KAAkB;AAChD,MAAA,MAAM,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,GAAG,KAAA,EAAM;AACxC,MAAA,IAAI,UAAA,KAAe,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAC9C,MAAA,SAAA,CAAU,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,GAAG,IAAA,EAAK,CAAE,CAAA;AACzC,MAAA,cAAA,GAAiB,IAAI,CAAA;AAAA,IACvB,CAAA;AAEA,IAAA,MAAM,SAAS,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,MAAM,CAAA,IAAK,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,CAAA;AACzF,IAAA,MAAM,aAAA,GAAgB,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,gBAAA;AAEhE,IAAA,uBACE,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,YAAA,EAAY,KAAA;AAAA,QACZ,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,QAChE,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,IAAI,MAAA,EAAQ,QAAA,GAAW,MAAA,EAAQ,KAAK,CAAA;AAAA,QACtC,CAAA;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACnB,YAAA,MAAM,EAAA,GAAK,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,CAAA;AACjC,YAAA,MAAM,QAAA,GAAW,GAAG,EAAE,CAAA,OAAA,CAAA;AACtB,YAAA,MAAM,OAAO,IAAA,CAAK,SAAA,GACd,OAAO,IAAA,CAAK,IAAI,IACd,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,aAAqB,GACvD,EAAE,MAAM,WAAA,EAAa,OAAA,EAAS,QAAgB,GAChD,IAAA;AACJ,YAAA,MAAM,WAAA,GAAc,KAAK,MAAA,IAAW,IAAA,IAAQ,CAAC,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,GAAK,QAAA,GAAW,MAAA;AAC7E,YAAA,uBACE,IAAA,CAAC,SAAsB,SAAA,EAAW,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,IAAQ,eAAe,CAAA,EAC1E,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,UAAA,EAAA,EAAW,EAAA,EAAI,CAAA,EAAG,EAAE,CAAA,MAAA,CAAA,EAAU,SAAS,EAAA,EAAI,SAAA,EAAU,6CAAA,EACnD,QAAA,EAAA,IAAA,CAAK,KAAA,EACR,CAAA;AAAA,gBACC,wBAAQ,GAAA,CAAC,KAAA,EAAA,EAAM,SAAS,IAAA,CAAK,OAAA,EAAU,eAAK,IAAA,EAAK;AAAA,eAAA,EACpD,CAAA;AAAA,cACC,KAAK,OAAA,mBACJ,IAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAO,OAAO,IAAA,CAAK,IAAI,CAAA,IAAK,MAAA,EAAW,eAAe,CAAC,CAAA,KAAM,SAAS,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA,EACxF,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,iBAAc,EAAA,EAAQ,iBAAA,EAAiB,CAAA,EAAG,EAAE,UAAU,EAAE,CAAA,CAAA,EAAI,kBAAA,EAAkB,WAAA,EAC7E,8BAAC,WAAA,EAAA,EAAY,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,gBAAW,CAAA,EAC3D,CAAA;AAAA,oCACC,aAAA,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,qBACjB,GAAA,CAAC,UAAA,EAAA,EAAyB,KAAA,EAAO,EAAE,KAAA,EAChC,QAAA,EAAA,CAAA,CAAE,SADY,CAAA,CAAE,KAEnB,CACD,CAAA,EACH;AAAA,eAAA,EACF,CAAA,mBAEA,GAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,EAAA;AAAA,kBACA,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,IAAK,EAAA;AAAA,kBAC5B,aAAa,IAAA,CAAK,WAAA;AAAA,kBAClB,kBAAA,EAAkB,WAAA;AAAA,kBAClB,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,CAAS,KAAK,IAAA,EAAM,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA,eACrD;AAAA,cAED,+BACC,IAAA,CAAC,gBAAA,EAAA,EAAiB,EAAA,EAAI,QAAA,EAAU,WAAU,SAAA,EACvC,QAAA,EAAA;AAAA,gBAAA,IAAA,IAAQ,CAAC,OAAO,IAAA,CAAK,IAAI,IAAI,CAAA,UAAA,EAAa,IAAA,CAAK,SAAS,CAAA,EAAA,CAAA,GAAO,EAAA;AAAA,gBAC/D,IAAA,CAAK;AAAA,eAAA,EACR;AAAA,aAAA,EAAA,EAjCQ,KAAK,IAmCjB,CAAA;AAAA,UAEJ,CAAC,CAAA;AAAA,UACA,QAAA,oBACC,IAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,uBAAA,EACf,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,cAAW,OAAA,EAAS,CAAA,EAAG,MAAM,CAAA,SAAA,CAAA,EAAa,SAAA,EAAU,+CAClD,QAAA,EAAA,aAAA,EACH,CAAA;AAAA,4BACA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,EAAA,EAAI,GAAG,MAAM,CAAA,SAAA,CAAA;AAAA,gBACb,IAAA,EAAM,CAAA;AAAA,gBACN,KAAA,EAAO,KAAA;AAAA,gBACP,WAAA,EAAY,iEAAA;AAAA,gBACZ,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA;AAC1C,WAAA,EACF,CAAA;AAAA,UAED,4BACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,8BAAC,MAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAQ,OAAM,IAAA,EAAK,IAAA,EAAK,UAAU,CAAC,MAAA,EACtD,uBACH,CAAA,EACF;AAAA;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AACA,oBAAA,CAAqB,WAAA,GAAc,sBAAA;AAqCnC,IAAM,gBAAA,GAAgD;AAAA,EACpD,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,QAAA,EAAS;AAAA,EAChC,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,SAAA,EAAU;AAAA,EAClC,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,MAAA;AACzB,CAAA;AAEA,IAAM,SAAA,GAA6D;AAAA,EACjE,EAAE,OAAA,EAAS,WAAA,EAAa,SAAA,EAAW,2BAAA,EAA4B;AAAA,EAC/D,EAAE,SAAS,MAAA,EAAO;AAAA,EAClB,EAAE,SAAS,SAAA,EAAU;AAAA,EACrB,EAAE,SAAS,SAAA;AACb,CAAA;AAGO,SAAS,sBAAsB,KAAA,EAAsC;AAC1E,EAAA,OAAO,KAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAO,CAAA,CAAE,SAAS,MAAA,GAAS,CAAA,CAAE,IAAA,GAAO,CAAA,EAAG,CAAA,CAAE,OAAO,GAAG,CAAA,CAAE,KAAK,CAAA,CAAG,CAAA,CAClE,IAAA,CAAK,GAAG,EACR,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,IAAA,EAAK;AACV;AAQO,IAAM,mBAAA,GAA4B,KAAA,CAAA,UAAA;AAAA,EACvC,CACE;AAAA,IACE,QAAA,GAAW,gBAAA;AAAA,IACX,KAAA,EAAO,SAAA;AAAA,IACP,YAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,iDAAA;AAAA,IACd,WAAA,GAAc,MAAA;AAAA,IACd,SAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,IAAU,KAAA,CAAA,QAAA,CAAgC,YAAA,IAAgB,EAAE,CAAA;AACxF,IAAA,MAAM,QAAQ,SAAA,IAAa,QAAA;AAC3B,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAiB,aAAyB,IAAI,CAAA;AACpD,IAAA,MAAM,SAAe,KAAA,CAAA,KAAA,EAAM;AAE3B,IAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAgC;AAC9C,MAAA,IAAI,SAAA,KAAc,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAC7C,MAAA,aAAA,GAAgB,IAAI,CAAA;AAAA,IACtB,CAAA;AAGA,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,QAAQ,EAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,CAAA,CAAE,QAAQ,MAAM,CAAA;AAChF,IAAA,MAAM,QAAA,GAAW,CAAC,IAAA,KAAiB;AACjC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,IAAA,CAAK,CAAC,OAAO,IAAA,CAAK,UAAA,CAAW,EAAA,CAAG,OAAO,CAAA,IAAK,IAAA,CAAK,MAAA,GAAS,EAAA,CAAG,QAAQ,MAAM,CAAA;AAC7F,MAAA,OAAO,CAAA,GAAI,EAAE,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA,EAAE,GAAI,IAAA;AAAA,IAC3E,CAAA;AAEA,IAAA,MAAM,WAAW,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,EAAA;AAC3C,IAAA,MAAM,aAAA,GAAgB,QAAQ,IAAA,CAAK,CAAC,OAAO,QAAA,CAAS,UAAA,CAAW,EAAA,CAAG,OAAO,CAAC,CAAA;AAC1E,IAAA,MAAM,KAAA,GAAQ,gBAAgB,QAAA,CAAS,KAAA,CAAM,cAAc,OAAA,CAAQ,MAAM,CAAA,CAAE,WAAA,EAAY,GAAI,EAAA;AAC3F,IAAA,MAAM,cACJ,aAAA,EAAe,WAAA,EAAa,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,WAAA,EAAY,CAAE,UAAA,CAAW,KAAK,CAAC,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,KAAK,EAAC;AAG/F,IAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,GAAS,KAAA,EAAO,QAAA,KAAyE;AACtG,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAC9B,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,EAAI,IAAK,EAAA;AAC5B,MAAA,MAAM,GAAA,GAAM,QAAA,IAAY,QAAA,CAAS,IAAI,CAAA;AACrC,MAAA,MAAM,cAAc,GAAA,GAAM,KAAA,CAAM,KAAK,GAAG,CAAA,GAAI,QAAQ,IAAA,EAAK;AACzD,MAAA,MAAM,IAAA,GAAO,CAAC,GAAG,KAAK,CAAA;AACtB,MAAA,IAAI,UAAA,OAAiB,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,YAAY,CAAA;AAC5D,MAAA,IAAI,GAAA,OAAU,IAAA,CAAK,EAAE,MAAM,KAAA,EAAO,GAAG,KAAK,CAAA;AAC1C,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,KAAA,CAAM,MAAA,SAAe,IAAI,CAAA;AAC7C,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,OAAA,KAAoB;AACnC,MAAA,MAAM,IAAI,QAAA,CAAS,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,OAAO,CAAA;AACzD,MAAA,OAAO,WAAW,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA,IAAK,UAAU,MAAM,CAAA;AAAA,IACrD,CAAA;AACA,IAAA,MAAM,QAAA,GAAW,CAAC,OAAA,KAAoB,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,KAAY,OAAO,CAAA,EAAG,KAAA,IAAS,KAAA;AAE5F,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,OAAO,KAAA,EAAM;AACnB,MAAA,MAAM,IAAA,GAAO,sBAAsB,IAAI,CAAA;AACvC,MAAA,IAAI,IAAA,EAAM,QAAA,GAAW,IAAA,EAAM,IAAI,CAAA;AAAA,IACjC,CAAA;AAEA,IAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,qBAAA,EAAuB,SAAS,CAAA,EAAI,GAAG,KAAA,EAClE,QAAA,EAAA;AAAA,sBAAA,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,+JAAA;AAAA,UACV,OAAA,EAAS,MAAM,QAAA,CAAS,OAAA,EAAS,KAAA,EAAM;AAAA,UAEtC,QAAA,EAAA;AAAA,YAAA,KAAA,CAAM,GAAA;AAAA,cAAI,CAAC,IAAA,EAAM,CAAA,KAChB,IAAA,CAAK,IAAA,KAAS,MAAA,mBACZ,GAAA,CAAC,MAAA,EAAA,EAAc,QAAA,EAAA,IAAA,CAAK,IAAA,EAAA,EAAT,CAAc,CAAA,mBAEzB,IAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBAEC,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,CAAE,OAAA;AAAA,kBAC/B,WAAW,EAAA,CAAG,yCAAA,EAA2C,QAAQ,IAAA,CAAK,OAAO,EAAE,SAAS,CAAA;AAAA,kBAEvF,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAK,OAAA;AAAA,oBACL,IAAA,CAAK,KAAA;AAAA,oCACN,GAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,QAAA;AAAA,wBACL,YAAA,EAAY,CAAA,OAAA,EAAU,QAAA,CAAS,IAAA,CAAK,OAAO,CAAA,CAAE,WAAA,EAAa,CAAA,CAAA,EAAI,IAAA,CAAK,OAAO,CAAA,EAAG,KAAK,KAAK,CAAA,CAAA;AAAA,wBACvF,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,0BAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,0BAAA,MAAA,CAAO,MAAM,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,KAAM,CAAC,CAAC,CAAA;AACtC,0BAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,wBAC1B,CAAA;AAAA,wBACA,SAAA,EAAU,+KAAA;AAAA,wBAEV,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,aAAA,EAAY,MAAA,EAAO;AAAA;AAAA;AACxB;AAAA,iBAAA;AAAA,gBAjBK;AAAA;AAkBP,aAEJ;AAAA,4BACA,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,QAAA;AAAA,gBACL,KAAA,EAAO,KAAA;AAAA,gBACP,YAAA,EAAY,WAAA;AAAA,gBACZ,kBAAA,EAAkB,MAAA;AAAA,gBAClB,WAAA,EAAa,KAAA,CAAM,MAAA,GAAS,MAAA,GAAY,WAAA;AAAA,gBACxC,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,kBAAA,MAAM,CAAA,GAAI,EAAE,MAAA,CAAO,KAAA;AAEnB,kBAAA,IAAI,EAAE,QAAA,CAAS,GAAG,KAAK,QAAA,CAAS,CAAA,CAAE,SAAQ,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,EAAE,GAAG,KAAA,CAAM,CAAA,CAAE,SAAS,CAAA;AAAA,gCACxE,CAAC,CAAA;AAAA,gBACjB,CAAA;AAAA,gBACA,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,kBAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,QAAA,CAAS,QAAQ,CAAA,EAAG;AACvC,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,KAAA,EAAM;AAAA,kBACR,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,EAAS;AAC5B,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,MAAA,EAAO;AAAA,kBACT,WAAW,CAAA,CAAE,GAAA,KAAQ,eAAe,KAAA,KAAU,EAAA,IAAM,MAAM,MAAA,EAAQ;AAChE,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACnC,oBAAA,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AACzB,oBAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,EAAQ,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,kBAC9C;AAAA,gBACF,CAAA;AAAA,gBACA,SAAA,EAAU;AAAA;AAAA;AACZ;AAAA;AAAA,OACF;AAAA,sBACA,IAAA,CAAC,GAAA,EAAA,EAAE,EAAA,EAAI,MAAA,EAAQ,WAAU,SAAA,EACtB,QAAA,EAAA;AAAA,QAAA,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,EAAE,OAAO,CAAA,KAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,WAAA,EAAa,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,QAAE;AAAA,OAAA,EAE/E,CAAA;AAAA,MACC,iBAAiB,WAAA,CAAY,MAAA,GAAS,qBACrC,GAAA,CAAC,KAAA,EAAA,EAAI,MAAK,OAAA,EAAQ,YAAA,EAAY,CAAA,EAAG,aAAA,CAAc,KAAK,CAAA,YAAA,CAAA,EAAgB,SAAA,EAAU,wBAC3E,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,qBAChB,IAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAEC,OAAA,EAAQ,WAAA;AAAA,UACR,IAAA,EAAK,IAAA;AAAA,UACL,SAAA,EAAU,UAAA;AAAA,UACV,SAAS,MAAM;AACb,YAAA,KAAA,CAAM,OAAO,EAAE,OAAA,EAAS,cAAc,OAAA,EAAS,KAAA,EAAO,GAAG,CAAA;AACzD,YAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,UAC1B,CAAA;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,aAAA,CAAc,OAAA;AAAA,YACd;AAAA;AAAA,SAAA;AAAA,QAVI;AAAA,OAYR,CAAA,EACH,CAAA;AAAA,MAED,QAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,KAAA;AAAA,UACR,IAAA,EAAK,IAAA;AAAA,UACL,OAAA,EAAS,MAAA;AAAA,UACT,UAAU,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,MAAK,KAAM,EAAA;AAAA,UAEhD,QAAA,EAAA;AAAA;AAAA,OACH,EACF;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AACA,mBAAA,CAAoB,WAAA,GAAc,qBAAA;AAkC3B,IAAM,qBAAA,GAA8B,KAAA,CAAA,UAAA;AAAA,EACzC,CACE;AAAA,IACE,KAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,GAAc,CAAA;AAAA,IACd,YAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,UAAA;AAAA,IACd,gBAAA,GAAmB,IAAA;AAAA,IACnB,SAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAS,WAAW,CAAA;AAC1D,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,IAAI,QAAA,IAAY,QAAA,EAAU,CAAC,CAAA,EAAG,KAAK,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAC,CAAC,CAAA;AACtF,IAAA,MAAM,UAAA,GAAmB,aAA6B,IAAI,CAAA;AAC1D,IAAA,MAAM,YAAkB,KAAA,CAAA,KAAA,EAAM;AAC9B,IAAA,MAAM,KAAA,GAAc,aAAO,KAAK,CAAA;AAEhC,IAAM,gBAAU,MAAM;AACpB,MAAA,IAAI,KAAA,CAAM,OAAA,EAAS,UAAA,CAAW,OAAA,EAAS,KAAA,EAAM;AAAA,IAC/C,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,IAAA,MAAM,EAAA,GAAK,CAAC,IAAA,KAAiB;AAC3B,MAAA,KAAA,CAAM,OAAA,GAAU,IAAA;AAChB,MAAA,IAAI,QAAA,KAAa,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAC5C,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA;AAEA,IAAA,MAAM,IAAA,GAAO,IAAA,KAAS,KAAA,CAAM,MAAA,GAAS,CAAA;AAErC,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA,EAAK,OAAA;AAAA,QACL,iBAAA,EAAiB,SAAA;AAAA,QACjB,SAAA,EAAW,EAAA,CAAG,uEAAA,EAAyE,SAAS,CAAA;AAAA,QAC/F,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,YAAA,EAAa,aAAA,EAAY,QACrC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACb,GAAA,CAAC,UAAa,SAAA,EAAW,EAAA,CAAG,2BAA2B,CAAA,IAAK,IAAA,GAAO,aAAa,UAAU,CAAA,EAAA,EAA/E,CAAkF,CAC9F,CAAA,EACH,CAAA;AAAA,0BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,GAAA,EAAA,EAAE,KAAK,UAAA,EAAY,EAAA,EAAI,WAAW,QAAA,EAAU,EAAA,EAAI,WAAU,oDAAA,EAAqD,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,cACxG,IAAA,GAAO,CAAA;AAAA,cAAE,MAAA;AAAA,cAAK,KAAA,CAAM,MAAA;AAAA,cAAO,QAAA;AAAA,cAAI,MAAM,IAAI;AAAA,aAAA,EACjD,CAAA;AAAA,YACC,WAAA,oBAAe,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iCAAiC,QAAA,EAAA,WAAA,EAAY;AAAA,WAAA,EAC5E,CAAA;AAAA,UACC,QAAA;AAAA,0BACD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACZ,QAAA,EAAA;AAAA,YAAA,IAAA,GAAO,CAAA,oBACN,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,MAAM,EAAA,CAAG,IAAA,GAAO,CAAC,GAAG,QAAA,EAAA,MAAA,EAE/D,CAAA;AAAA,4BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,YACxB,CAAC,IAAA,IAAQ,gBAAA,IAAoB,QAAA,oBAC5B,IAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,MAAA,EAAO,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,QAAA,EACvC,QAAA,EAAA;AAAA,cAAA,WAAA;AAAA,cAAY;AAAA,aAAA,EACf,CAAA;AAAA,YAED,IAAA,GACC,QAAA,oBACE,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAM,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,QAAA,EACtC,QAAA,EAAA,WAAA,EACH,CAAA,uBAGD,MAAA,EAAA,EAAO,OAAA,EAAQ,KAAA,EAAM,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,MAAM,EAAA,CAAG,IAAA,GAAO,CAAC,CAAA,EAAG,QAAA,EAAA,MAAA,EAE7D;AAAA,WAAA,EAEJ;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,qBAAA,CAAsB,WAAA,GAAc,uBAAA","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Check, X } from \"lucide-react\";\nimport { Badge, type BadgeVariant } from \"@nucleux/badge\";\nimport { Button } from \"@nucleux/button\";\nimport { Field, FieldDescription, FieldLabel } from \"@nucleux/field\";\nimport { Input } from \"@nucleux/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@nucleux/select\";\nimport { Textarea } from \"@nucleux/textarea\";\n\nexport interface StructuredOption {\n /** Stable value. */\n value: string;\n /** Display label. */\n label: React.ReactNode;\n}\n\nexport interface StructuredInputProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\" | \"onSubmit\"> {\n /** The clarifying question the agent is asking. */\n question: React.ReactNode;\n /** The selectable answers. */\n options: StructuredOption[];\n /** Allow selecting more than one option. */\n multiple?: boolean;\n /** Selected values (controlled). */\n value?: string[];\n /** Initial selection (uncontrolled). */\n defaultValue?: string[];\n /** Called when the selection changes. */\n onValueChange?: (values: string[]) => void;\n /** Show a free-text \"something else\" escape. */\n allowOther?: boolean;\n /** Label for the other escape. Defaults to `\"Something else…\"`. */\n otherPlaceholder?: string;\n /** Called when the answer is submitted. */\n onSubmit?: (values: string[], other?: string) => void;\n /** Called when the user skips the question. Renders the skip control when set. */\n onSkip?: () => void;\n /** Label for the submit button. */\n submitLabel?: React.ReactNode;\n /** Label for the skip button. */\n skipLabel?: React.ReactNode;\n}\n\n/**\n * An agent-generated clarifying question rendered as a structured choice —\n * single or multi-select options, a free-text escape, and a skip. The other\n * structured-input variants are composable siblings: {@link StructuredInputSlots}\n * (named slots), {@link StructuredInputTags} (tagged input) and\n * {@link StructuredInputWizard} (wizard step).\n * Source: Figma \"Expressive Input / Structured Input\".\n */\nexport const StructuredInput = React.forwardRef<HTMLDivElement, StructuredInputProps>(\n (\n {\n question,\n options,\n multiple = false,\n value,\n defaultValue = [],\n onValueChange,\n allowOther = false,\n otherPlaceholder = \"Something else…\",\n onSubmit,\n onSkip,\n submitLabel = \"Continue\",\n skipLabel = \"Skip\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<string[]>(defaultValue);\n const [other, setOther] = React.useState(\"\");\n const questionId = React.useId();\n const groupRef = React.useRef<HTMLDivElement>(null);\n const selected = value !== undefined ? value : internal;\n\n const setSelected = (next: string[]) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n };\n const toggle = (val: string) => {\n if (multiple) {\n setSelected(selected.includes(val) ? selected.filter((v) => v !== val) : [...selected, val]);\n } else {\n setSelected([val]);\n }\n };\n\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col gap-4 rounded-xl border border-border bg-background p-5\", className)}\n {...props}\n >\n <p id={questionId} className=\"text-base font-medium text-foreground\">\n {question}\n </p>\n <div\n ref={groupRef}\n role={multiple ? \"group\" : \"radiogroup\"}\n aria-labelledby={questionId}\n className=\"flex flex-col gap-2\"\n onKeyDown={(e) => {\n // Radio-group keyboard pattern: arrows move and select.\n if (multiple || ![\"ArrowDown\", \"ArrowUp\", \"ArrowRight\", \"ArrowLeft\"].includes(e.key)) return;\n const radios = Array.from(groupRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"radio\"]') ?? []);\n const i = radios.indexOf(document.activeElement as HTMLButtonElement);\n if (i < 0) return;\n e.preventDefault();\n const step = e.key === \"ArrowDown\" || e.key === \"ArrowRight\" ? 1 : -1;\n const next = (i + step + radios.length) % radios.length;\n radios[next].focus();\n setSelected([options[next].value]);\n }}\n >\n {options.map((option, index) => {\n const active = selected.includes(option.value);\n const tabbable = multiple || index === Math.max(0, options.findIndex((o) => selected.includes(o.value)));\n return (\n <button\n key={option.value}\n type=\"button\"\n role={multiple ? \"checkbox\" : \"radio\"}\n aria-checked={active}\n tabIndex={tabbable ? 0 : -1}\n onClick={() => toggle(option.value)}\n className={cn(\n \"flex items-center gap-3 rounded-lg border px-3 py-2.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-brand bg-brand-muted/50 text-foreground\"\n : \"border-border bg-background text-foreground hover:bg-accent\",\n )}\n >\n <span\n className={cn(\n \"inline-flex size-5 shrink-0 items-center justify-center border transition-colors [&_svg]:size-3.5\",\n multiple ? \"rounded-md\" : \"rounded-full\",\n active ? \"border-brand bg-brand text-brand-foreground\" : \"border-border\",\n )}\n >\n {active && <Check aria-hidden=\"true\" />}\n </span>\n <span className=\"flex-1\">{option.label}</span>\n </button>\n );\n })}\n </div>\n {allowOther && (\n <input\n type=\"text\"\n value={other}\n onChange={(e) => setOther(e.target.value)}\n placeholder={otherPlaceholder}\n aria-label={otherPlaceholder}\n className=\"rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n )}\n <div className=\"flex items-center justify-end gap-2\">\n {onSkip && (\n <button\n type=\"button\"\n onClick={onSkip}\n className=\"inline-flex items-center rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {skipLabel}\n </button>\n )}\n {onSubmit && (\n <button\n type=\"button\"\n onClick={() => onSubmit(selected, allowOther ? other : undefined)}\n disabled={selected.length === 0 && !(allowOther && other.trim())}\n className=\"inline-flex items-center rounded-lg bg-info px-3 py-2 text-sm font-medium text-info-foreground transition-colors hover:bg-info/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\"\n >\n {submitLabel}\n </button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInput.displayName = \"StructuredInput\";\n\n/* -------------------------------------------------------------------------- */\n/* Named slots */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputSlot {\n /** Key in the values object. */\n name: string;\n /** Plain-language label, e.g. `\"Audience\"`. */\n label: string;\n /** Placeholder / example value. */\n placeholder?: string;\n /** Choices — renders a select instead of a text field. */\n options?: StructuredOption[];\n /** Helper text under the field. */\n helper?: string;\n /**\n * Marks the initial value as the agent's suggestion, with the reason, e.g.\n * `\"from the meeting invite\"`. Once the person changes it, it reads “Edited by you”.\n */\n suggested?: string;\n /** Span the full row. */\n wide?: boolean;\n}\n\nexport type StructuredInputValues = Record<string, string>;\n\nexport interface StructuredInputSlotsProps\n extends Omit<React.HTMLAttributes<HTMLFormElement>, \"onSubmit\" | \"defaultValue\"> {\n /** The 2–4 slots the prompt template needs. */\n slots: StructuredInputSlot[];\n /** Values (controlled). */\n values?: StructuredInputValues;\n /** Initial values (uncontrolled). */\n defaultValues?: StructuredInputValues;\n /** Called on every change. */\n onValuesChange?: (values: StructuredInputValues) => void;\n /** Show a freeform override field. `true` uses the label `\"Anything else?\"`; a string sets the label. */\n freeform?: boolean | string;\n /** Called on submit. Never requires every slot — any value (or the freeform text) is enough. */\n onSubmit?: (values: StructuredInputValues, freeform: string) => void;\n /** Label of the submit button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Accessible name of the form. Defaults to `\"Structured prompt builder\"`. */\n label?: string;\n}\n\n/**\n * Named slots: a short set of plain-language fields (2–4) that fill a prompt\n * template — text fields or selects, an optional freeform override, and a\n * submit that never requires every field. Agent-suggested values are marked\n * “Suggested” with their reason and become “Edited by you” once changed; the\n * component never changes a value the person set.\n */\nexport const StructuredInputSlots = React.forwardRef<HTMLFormElement, StructuredInputSlotsProps>(\n (\n {\n slots,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n freeform = false,\n onSubmit,\n submitLabel = \"Generate\",\n label = \"Structured prompt builder\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputValues>(defaultValues ?? {});\n const values = valuesProp ?? internal;\n const [edited, setEdited] = React.useState<Record<string, boolean>>({});\n const [extra, setExtra] = React.useState(\"\");\n const baseId = React.useId();\n\n const setValue = (name: string, value: string) => {\n const next = { ...values, [name]: value };\n if (valuesProp === undefined) setInternal(next);\n setEdited((e) => ({ ...e, [name]: true }));\n onValuesChange?.(next);\n };\n\n const hasAny = Object.values(values).some((v) => v && v.trim()) || extra.trim().length > 0;\n const freeformLabel = typeof freeform === \"string\" ? freeform : \"Anything else?\";\n\n return (\n <form\n ref={ref}\n aria-label={label}\n className={cn(\"grid grid-cols-1 gap-3 sm:grid-cols-2\", className)}\n onSubmit={(e) => {\n e.preventDefault();\n if (hasAny) onSubmit?.(values, extra);\n }}\n {...props}\n >\n {slots.map((slot) => {\n const id = `${baseId}-${slot.name}`;\n const helperId = `${id}-helper`;\n const mark = slot.suggested\n ? edited[slot.name]\n ? { text: \"Edited by you\", variant: \"secondary\" as const }\n : { text: \"Suggested\", variant: \"info\" as const }\n : null;\n const describedBy = slot.helper || (mark && !edited[slot.name]) ? helperId : undefined;\n return (\n <Field key={slot.name} className={cn(\"gap-1.5\", slot.wide && \"sm:col-span-2\")}>\n <div className=\"flex items-center gap-2\">\n <FieldLabel id={`${id}-label`} htmlFor={id} className=\"text-xs font-semibold text-muted-foreground\">\n {slot.label}\n </FieldLabel>\n {mark && <Badge variant={mark.variant}>{mark.text}</Badge>}\n </div>\n {slot.options ? (\n <Select value={values[slot.name] || undefined} onValueChange={(v) => setValue(slot.name, v)}>\n <SelectTrigger id={id} aria-labelledby={`${id}-label ${id}`} aria-describedby={describedBy}>\n <SelectValue placeholder={slot.placeholder ?? \"Choose…\"} />\n </SelectTrigger>\n <SelectContent>\n {slot.options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input\n id={id}\n value={values[slot.name] ?? \"\"}\n placeholder={slot.placeholder}\n aria-describedby={describedBy}\n onChange={(e) => setValue(slot.name, e.target.value)}\n />\n )}\n {describedBy && (\n <FieldDescription id={helperId} className=\"text-xs\">\n {mark && !edited[slot.name] ? `Suggested ${slot.suggested}. ` : \"\"}\n {slot.helper}\n </FieldDescription>\n )}\n </Field>\n );\n })}\n {freeform && (\n <Field className=\"gap-1.5 sm:col-span-2\">\n <FieldLabel htmlFor={`${baseId}-freeform`} className=\"text-xs font-semibold text-muted-foreground\">\n {freeformLabel}\n </FieldLabel>\n <Textarea\n id={`${baseId}-freeform`}\n rows={2}\n value={extra}\n placeholder=\"Say it in your own words — this overrides the fields above\"\n onChange={(e) => setExtra(e.target.value)}\n />\n </Field>\n )}\n {onSubmit && (\n <div className=\"flex justify-end sm:col-span-2\">\n <Button type=\"submit\" variant=\"cta\" size=\"sm\" disabled={!hasAny}>\n {submitLabel}\n </Button>\n </div>\n )}\n </form>\n );\n },\n);\nStructuredInputSlots.displayName = \"StructuredInputSlots\";\n\n/* -------------------------------------------------------------------------- */\n/* Tagged input */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputTagTrigger {\n /** The prefix that starts a tag, e.g. `\"@\"`, `\"p:\"`, `\"/\"`. */\n trigger: string;\n /** What the tag refers to, e.g. `\"Person\"`. */\n label: string;\n /** Values offered while typing after the trigger. */\n suggestions?: string[];\n}\n\nexport type StructuredInputPart =\n | { type: \"text\"; text: string }\n | { type: \"tag\"; trigger: string; value: string };\n\nexport interface StructuredInputTagsProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"defaultValue\" | \"onChange\"> {\n /** Recognised tag prefixes. Defaults to `@` person, `p:` project, `/` file. */\n triggers?: StructuredInputTagTrigger[];\n /** Committed parts (controlled). */\n value?: StructuredInputPart[];\n /** Initial parts (uncontrolled). */\n defaultValue?: StructuredInputPart[];\n /** Called when parts are added or removed. */\n onValueChange?: (parts: StructuredInputPart[]) => void;\n /** Called on Enter or the send button with the parts and their plain-text form. */\n onSubmit?: (parts: StructuredInputPart[], text: string) => void;\n /** Accessible name and placeholder of the text field. */\n placeholder?: string;\n /** Label of the send button. Defaults to `\"Send\"`. */\n submitLabel?: React.ReactNode;\n}\n\nconst DEFAULT_TRIGGERS: StructuredInputTagTrigger[] = [\n { trigger: \"@\", label: \"Person\" },\n { trigger: \"p:\", label: \"Project\" },\n { trigger: \"/\", label: \"File\" },\n];\n\nconst TAG_TONES: { variant: BadgeVariant; className?: string }[] = [\n { variant: \"secondary\", className: \"bg-brand-muted text-brand\" },\n { variant: \"info\" },\n { variant: \"success\" },\n { variant: \"outline\" },\n];\n\n/** Serialise parts into the plain prompt text, e.g. `\"Update @sam on p:Apollo\"`. */\nexport function structuredPartsToText(parts: StructuredInputPart[]): string {\n return parts\n .map((p) => (p.type === \"text\" ? p.text : `${p.trigger}${p.value}`))\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Tagged input: a prompt field where typed prefixes (`@` person, `p:` project,\n * `/` file — configurable) become removable tag chips, with optional\n * type-ahead suggestions shown as buttons. Backspace on an empty field removes\n * the last tag; Enter sends. Tags are optional — plain text always works.\n */\nexport const StructuredInputTags = React.forwardRef<HTMLDivElement, StructuredInputTagsProps>(\n (\n {\n triggers = DEFAULT_TRIGGERS,\n value: valueProp,\n defaultValue,\n onValueChange,\n onSubmit,\n placeholder = \"Type @ for people, p: for projects, / for files\",\n submitLabel = \"Send\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputPart[]>(defaultValue ?? []);\n const parts = valueProp ?? internal;\n const [draft, setDraft] = React.useState(\"\");\n const inputRef = React.useRef<HTMLInputElement>(null);\n const hintId = React.useId();\n\n const commit = (next: StructuredInputPart[]) => {\n if (valueProp === undefined) setInternal(next);\n onValueChange?.(next);\n };\n\n // Longest trigger first so \"p:\" wins over \"p\".\n const ordered = [...triggers].sort((a, b) => b.trigger.length - a.trigger.length);\n const matchTag = (word: string) => {\n const t = ordered.find((tr) => word.startsWith(tr.trigger) && word.length > tr.trigger.length);\n return t ? { trigger: t.trigger, value: word.slice(t.trigger.length) } : null;\n };\n\n const lastWord = draft.split(\" \").pop() ?? \"\";\n const activeTrigger = ordered.find((tr) => lastWord.startsWith(tr.trigger));\n const query = activeTrigger ? lastWord.slice(activeTrigger.trigger.length).toLowerCase() : \"\";\n const suggestions =\n activeTrigger?.suggestions?.filter((s) => s.toLowerCase().startsWith(query)).slice(0, 5) ?? [];\n\n /** Split the draft into text + a trailing tag (if any) and commit them. */\n const flush = (source = draft, forceTag?: { trigger: string; value: string }): StructuredInputPart[] => {\n const words = source.split(\" \");\n const last = words.pop() ?? \"\";\n const tag = forceTag ?? matchTag(last);\n const textBefore = (tag ? words.join(\" \") : source).trim();\n const next = [...parts];\n if (textBefore) next.push({ type: \"text\", text: textBefore });\n if (tag) next.push({ type: \"tag\", ...tag });\n if (next.length !== parts.length) commit(next);\n setDraft(\"\");\n return next;\n };\n\n const toneFor = (trigger: string) => {\n const i = triggers.findIndex((t) => t.trigger === trigger);\n return TAG_TONES[(i < 0 ? 0 : i) % TAG_TONES.length];\n };\n const labelFor = (trigger: string) => triggers.find((t) => t.trigger === trigger)?.label ?? \"Tag\";\n\n const submit = () => {\n const next = flush();\n const text = structuredPartsToText(next);\n if (text) onSubmit?.(next, text);\n };\n\n return (\n <div ref={ref} className={cn(\"flex flex-col gap-2\", className)} {...props}>\n <div\n className=\"flex flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground focus-within:ring-2 focus-within:ring-ring\"\n onClick={() => inputRef.current?.focus()}\n >\n {parts.map((part, i) =>\n part.type === \"text\" ? (\n <span key={i}>{part.text}</span>\n ) : (\n <Badge\n key={i}\n variant={toneFor(part.trigger).variant}\n className={cn(\"gap-0.5 rounded-md pr-0.5 font-semibold\", toneFor(part.trigger).className)}\n >\n {part.trigger}\n {part.value}\n <button\n type=\"button\"\n aria-label={`Remove ${labelFor(part.trigger).toLowerCase()} ${part.trigger}${part.value}`}\n onClick={(e) => {\n e.stopPropagation();\n commit(parts.filter((_, j) => j !== i));\n inputRef.current?.focus();\n }}\n className=\"inline-flex size-4 items-center justify-center rounded-sm opacity-70 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-3\"\n >\n <X aria-hidden=\"true\" />\n </button>\n </Badge>\n ),\n )}\n <Input\n ref={inputRef}\n value={draft}\n aria-label={placeholder}\n aria-describedby={hintId}\n placeholder={parts.length ? undefined : placeholder}\n onChange={(e) => {\n const v = e.target.value;\n // A space after a tag word (incl. mobile keyboards that skip keydown) makes it a chip.\n if (v.endsWith(\" \") && matchTag(v.trimEnd().split(\" \").pop() ?? \"\")) flush(v.trimEnd());\n else setDraft(v);\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" && matchTag(lastWord)) {\n e.preventDefault();\n flush();\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n submit();\n } else if (e.key === \"Backspace\" && draft === \"\" && parts.length) {\n e.preventDefault();\n const last = parts[parts.length - 1];\n commit(parts.slice(0, -1));\n if (last.type === \"text\") setDraft(last.text);\n }\n }}\n className=\"h-7 min-w-[8rem] flex-1 border-0 px-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n <p id={hintId} className=\"sr-only\">\n {triggers.map((t) => `${t.trigger} for ${t.label.toLowerCase()}`).join(\", \")}. Space turns a tag into a\n chip; Backspace removes the last one; Enter sends.\n </p>\n {activeTrigger && suggestions.length > 0 && (\n <div role=\"group\" aria-label={`${activeTrigger.label} suggestions`} className=\"flex flex-wrap gap-1\">\n {suggestions.map((s) => (\n <Button\n key={s}\n variant=\"secondary\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={() => {\n flush(draft, { trigger: activeTrigger.trigger, value: s });\n inputRef.current?.focus();\n }}\n >\n {activeTrigger.trigger}\n {s}\n </Button>\n ))}\n </div>\n )}\n {onSubmit && (\n <div className=\"flex justify-end\">\n <Button\n variant=\"cta\"\n size=\"sm\"\n onClick={submit}\n disabled={parts.length === 0 && draft.trim() === \"\"}\n >\n {submitLabel}\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\nStructuredInputTags.displayName = \"StructuredInputTags\";\n\n/* -------------------------------------------------------------------------- */\n/* Wizard step */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputWizardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"title\"> {\n /** Step titles, e.g. `[\"Intent\", \"Audience\", \"Tone\"]`. */\n steps: string[];\n /** Current step, 0-based (controlled). */\n step?: number;\n /** Initial step (uncontrolled). */\n defaultStep?: number;\n /** Called when Back / Next move. */\n onStepChange?: (step: number) => void;\n /** The current step's question, e.g. `\"Who is the brief for?\"`. */\n description?: React.ReactNode;\n /** Called from the last step (or from “Generate now” when `allowEarlySubmit`). */\n onSubmit?: () => void;\n /** Label of the final button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Offer “Generate now” before the last step — fields are never all required. Defaults to `true`. */\n allowEarlySubmit?: boolean;\n /** The current step's fields. */\n children?: React.ReactNode;\n}\n\n/**\n * Wizard step: a multi-step frame for high-stakes prompts (legal, HR, medical) —\n * a progress bar, “Step 2 of 3 · Audience”, the step's question and fields\n * (children), and Back / Next / Generate. Focus moves to the step heading when\n * the step changes; nothing forces every step to be filled before generating.\n */\nexport const StructuredInputWizard = React.forwardRef<HTMLDivElement, StructuredInputWizardProps>(\n (\n {\n steps,\n step: stepProp,\n defaultStep = 0,\n onStepChange,\n description,\n onSubmit,\n submitLabel = \"Generate\",\n allowEarlySubmit = true,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState(defaultStep);\n const step = Math.min(Math.max(stepProp ?? internal, 0), Math.max(steps.length - 1, 0));\n const headingRef = React.useRef<HTMLParagraphElement>(null);\n const headingId = React.useId();\n const moved = React.useRef(false);\n\n React.useEffect(() => {\n if (moved.current) headingRef.current?.focus();\n }, [step]);\n\n const go = (next: number) => {\n moved.current = true;\n if (stepProp === undefined) setInternal(next);\n onStepChange?.(next);\n };\n\n const last = step === steps.length - 1;\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={headingId}\n className={cn(\"flex flex-col gap-3 rounded-xl border border-border bg-background p-4\", className)}\n {...props}\n >\n <div className=\"flex gap-1\" aria-hidden=\"true\">\n {steps.map((_, i) => (\n <span key={i} className={cn(\"h-1 flex-1 rounded-full\", i <= step ? \"bg-brand\" : \"bg-muted\")} />\n ))}\n </div>\n <div className=\"flex flex-col gap-1\">\n <p ref={headingRef} id={headingId} tabIndex={-1} className=\"text-sm font-semibold text-foreground outline-none\">\n Step {step + 1} of {steps.length} · {steps[step]}\n </p>\n {description && <p className=\"text-sm text-muted-foreground\">{description}</p>}\n </div>\n {children}\n <div className=\"flex items-center gap-2\">\n {step > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => go(step - 1)}>\n Back\n </Button>\n )}\n <span className=\"flex-1\" />\n {!last && allowEarlySubmit && onSubmit && (\n <Button variant=\"link\" size=\"sm\" onClick={onSubmit}>\n {submitLabel} now\n </Button>\n )}\n {last ? (\n onSubmit && (\n <Button variant=\"cta\" size=\"sm\" onClick={onSubmit}>\n {submitLabel}\n </Button>\n )\n ) : (\n <Button variant=\"cta\" size=\"sm\" onClick={() => go(step + 1)}>\n Next\n </Button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInputWizard.displayName = \"StructuredInputWizard\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAqDO,IAAM,eAAA,GAAwB,KAAA,CAAA,UAAA;AAAA,EACnC,CACE;AAAA,IACE,QAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,GAAW,KAAA;AAAA,IACX,KAAA;AAAA,IACA,eAAe,EAAC;AAAA,IAChB,aAAA;AAAA,IACA,UAAA,GAAa,KAAA;AAAA,IACb,gBAAA,GAAmB,sBAAA;AAAA,IACnB,QAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA,GAAc,UAAA;AAAA,IACd,SAAA,GAAY,MAAA;AAAA,IACZ,SAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAmB,YAAY,CAAA;AACrE,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,aAAmB,KAAA,CAAA,KAAA,EAAM;AAC/B,IAAA,MAAM,QAAA,GAAiB,aAAuB,IAAI,CAAA;AAClD,IAAA,MAAM,QAAA,GAAW,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,QAAA;AAE/C,IAAA,MAAM,WAAA,GAAc,CAAC,IAAA,KAAmB;AACtC,MAAA,IAAI,KAAA,KAAU,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AACzC,MAAA,aAAA,GAAgB,IAAI,CAAA;AAAA,IACtB,CAAA;AACA,IAAA,MAAM,MAAA,GAAS,CAAC,GAAA,KAAgB;AAC9B,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,WAAA,CAAY,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,GAAI,SAAS,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,GAAG,CAAA,GAAI,CAAC,GAAG,QAAA,EAAU,GAAG,CAAC,CAAA;AAAA,MAC7F,CAAA,MAAO;AACL,QAAA,WAAA,CAAY,CAAC,GAAG,CAAC,CAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA,CAAG,uEAAA,EAAyE,SAAS,CAAA;AAAA,QAC/F,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,GAAA,EAAA,EAAE,EAAA,EAAI,UAAA,EAAY,SAAA,EAAU,yCAC1B,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,0BACA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAM,WAAW,OAAA,GAAU,YAAA;AAAA,cAC3B,iBAAA,EAAiB,UAAA;AAAA,cACjB,SAAA,EAAU,qBAAA;AAAA,cACV,SAAA,EAAW,CAAC,CAAA,KAAM;AAEhB,gBAAA,IAAI,QAAA,IAAY,CAAC,CAAC,WAAA,EAAa,SAAA,EAAW,YAAA,EAAc,WAAW,CAAA,CAAE,QAAA,CAAS,CAAA,CAAE,GAAG,CAAA,EAAG;AACtF,gBAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,QAAA,CAAS,SAAS,gBAAA,CAAoC,gBAAgB,CAAA,IAAK,EAAE,CAAA;AACvG,gBAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,aAAkC,CAAA;AACpE,gBAAA,IAAI,IAAI,CAAA,EAAG;AACX,gBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,gBAAA,MAAM,OAAO,CAAA,CAAE,GAAA,KAAQ,eAAe,CAAA,CAAE,GAAA,KAAQ,eAAe,CAAA,GAAI,EAAA;AACnE,gBAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,GAAI,IAAA,GAAO,MAAA,CAAO,UAAU,MAAA,CAAO,MAAA;AACjD,gBAAA,MAAA,CAAO,IAAI,EAAE,KAAA,EAAM;AACnB,gBAAA,WAAA,CAAY,CAAC,OAAA,CAAQ,IAAI,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,cACnC,CAAA;AAAA,cAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAA,KAAU;AAC9B,gBAAA,MAAM,MAAA,GAAS,QAAA,CAAS,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA;AAC7C,gBAAA,MAAM,QAAA,GAAW,QAAA,IAAY,KAAA,KAAU,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,CAAQ,SAAA,CAAU,CAAC,MAAM,QAAA,CAAS,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC,CAAC,CAAA;AACvG,gBAAA,uBACE,IAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBAEC,IAAA,EAAK,QAAA;AAAA,oBACL,IAAA,EAAM,WAAW,UAAA,GAAa,OAAA;AAAA,oBAC9B,cAAA,EAAc,MAAA;AAAA,oBACd,QAAA,EAAU,WAAW,CAAA,GAAI,EAAA;AAAA,oBACzB,OAAA,EAAS,MAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,oBAClC,SAAA,EAAW,EAAA;AAAA,sBACT,mKAAA;AAAA,sBACA,SACI,gDAAA,GACA;AAAA,qBACN;AAAA,oBAEA,QAAA,EAAA;AAAA,sCAAA,GAAA;AAAA,wBAAC,MAAA;AAAA,wBAAA;AAAA,0BACC,SAAA,EAAW,EAAA;AAAA,4BACT,mGAAA;AAAA,4BACA,WAAW,YAAA,GAAe,cAAA;AAAA,4BAC1B,SAAS,6CAAA,GAAgD;AAAA,2BAC3D;AAAA,0BAEC,QAAA,EAAA,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAM,aAAA,EAAY,MAAA,EAAO;AAAA;AAAA,uBACvC;AAAA,sCACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAU,iBAAO,KAAA,EAAM;AAAA;AAAA,mBAAA;AAAA,kBAtBlC,MAAA,CAAO;AAAA,iBAuBd;AAAA,cAEJ,CAAC;AAAA;AAAA,WACH;AAAA,UACC,UAAA,oBACC,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,MAAA;AAAA,cACL,KAAA,EAAO,KAAA;AAAA,cACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cACxC,WAAA,EAAa,gBAAA;AAAA,cACb,YAAA,EAAY,gBAAA;AAAA,cACZ,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,0BAEF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qCAAA,EACZ,QAAA,EAAA;AAAA,YAAA,MAAA,oBACC,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,OAAA,EAAS,MAAA;AAAA,gBACT,SAAA,EAAU,yNAAA;AAAA,gBAET,QAAA,EAAA;AAAA;AAAA,aACH;AAAA,YAED,QAAA,oBACC,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,SAAS,MAAM,QAAA,CAAS,QAAA,EAAU,UAAA,GAAa,QAAQ,MAAS,CAAA;AAAA,gBAChE,UAAU,QAAA,CAAS,MAAA,KAAW,KAAK,EAAE,UAAA,IAAc,MAAM,IAAA,EAAK,CAAA;AAAA,gBAC9D,SAAA,EAAU,4PAAA;AAAA,gBAET,QAAA,EAAA;AAAA;AAAA;AACH,WAAA,EAEJ;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAsCvB,SAAS,oBAAoB,KAAA,EAAqC;AACvE,EAAA,OAAA,CAAQ,KAAA,IAAS,EAAA,EACd,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,OAAO,OAAO,CAAA;AACnB;AAGO,SAAS,mBAAmB,IAAA,EAAoD;AACrF,EAAA,OAAO,IAAA,CAAK,IAAA,KAAS,IAAA,CAAK,OAAA,GAAU,QAAA,GAAW,MAAA,CAAA;AACjD;AA2CO,IAAM,oBAAA,GAA6B,KAAA,CAAA,UAAA;AAAA,EACxC,CACE;AAAA,IACE,KAAA;AAAA,IACA,MAAA,EAAQ,UAAA;AAAA,IACR,aAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA,GAAW,KAAA;AAAA,IACX,QAAA;AAAA,IACA,WAAA,GAAc,UAAA;AAAA,IACd,KAAA,GAAQ,2BAAA;AAAA,IACR,KAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,YAAA,GAAe,KAAA;AAAA,IACf,QAAA;AAAA,IACA,WAAA,GAAc,QAAA;AAAA,IACd,SAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,IAAU,KAAA,CAAA,QAAA,CAAgC,aAAA,IAAiB,EAAE,CAAA;AACzF,IAAA,MAAM,SAAS,UAAA,IAAc,QAAA;AAC7B,IAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAU,KAAA,CAAA,QAAA,CAAkC,EAAE,CAAA;AACtE,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,SAAe,KAAA,CAAA,KAAA,EAAM;AAE3B,IAAA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAc,KAAA,KAAkB;AAChD,MAAA,MAAM,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,GAAG,KAAA,EAAM;AACxC,MAAA,IAAI,UAAA,KAAe,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAC9C,MAAA,SAAA,CAAU,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,GAAG,IAAA,EAAK,CAAE,CAAA;AACzC,MAAA,cAAA,GAAiB,IAAI,CAAA;AAAA,IACvB,CAAA;AAEA,IAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAiB,CAAC,CAAC,MAAA,CAAO,IAAI,GAAG,IAAA,EAAK;AACtD,IAAA,MAAM,WAAA,GAAc,MAAM,MAAA,CAAO,CAAC,SAAS,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,MAAA;AAC9D,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,CAAM,CAAC,IAAA,KAAS,CAAC,IAAA,CAAK,QAAA,IAAY,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA;AAC7E,IAAA,MAAM,SAAS,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,MAAM,CAAA,IAAK,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,CAAA;AACzF,IAAA,MAAM,YAAY,MAAA,IAAU,WAAA;AAC5B,IAAA,MAAM,aAAA,GAAgB,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,gBAAA;AAChE,IAAA,MAAM,OAAA,GAAU,GAAG,MAAM,CAAA,MAAA,CAAA;AAEzB,IAAA,uBACE,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,YAAA,EAAY,KAAA,IAAS,IAAA,GAAO,KAAA,GAAQ,MAAA;AAAA,QACpC,iBAAA,EAAiB,KAAA,IAAS,IAAA,GAAO,MAAA,GAAY,OAAA;AAAA,QAC7C,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,QAChE,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,IAAI,SAAA,EAAW,QAAA,GAAW,MAAA,EAAQ,KAAK,CAAA;AAAA,QACzC,CAAA;AAAA,QACC,GAAG,KAAA;AAAA,QAEF,QAAA,EAAA;AAAA,UAAA,CAAA,KAAA,IAAS,QAAQ,KAAA,IAAS,IAAA,qBAC1B,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wEAAA,EACZ,QAAA,EAAA;AAAA,YAAA,IAAA,IAAQ,IAAA,oBACP,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAY,MAAA;AAAA,gBACZ,SAAA,EAAU,4HAAA;AAAA,gBAET,QAAA,EAAA;AAAA;AAAA,aACH;AAAA,gCAED,IAAA,EAAA,EAAG,EAAA,EAAI,OAAA,EAAS,SAAA,EAAU,kDACxB,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,YACC;AAAA,WAAA,EACH,CAAA;AAAA,UAED,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACnB,YAAA,MAAM,EAAA,GAAK,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,CAAA;AACjC,YAAA,MAAM,QAAA,GAAW,GAAG,EAAE,CAAA,OAAA,CAAA;AACtB,YAAA,MAAM,OAAO,IAAA,CAAK,SAAA,GACd,OAAO,IAAA,CAAK,IAAI,IACd,EAAE,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,aAAqB,GACvD,EAAE,MAAM,WAAA,EAAa,OAAA,EAAS,QAAgB,GAChD,IAAA;AACJ,YAAA,MAAM,WAAA,GAAc,KAAK,MAAA,IAAW,IAAA,IAAQ,CAAC,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,GAAK,QAAA,GAAW,MAAA;AAC7E,YAAA,MAAM,IAAA,GAAO,mBAAmB,IAAI,CAAA;AACpC,YAAA,uBACE,IAAA,CAAC,SAAsB,SAAA,EAAW,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,IAAQ,eAAe,CAAA,EAC1E,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,gCAAA,IAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,EAAA,EAAI,GAAG,EAAE,CAAA,MAAA,CAAA;AAAA,oBACT,OAAA,EAAS,EAAA;AAAA,oBACT,SAAA,EAAU,yEAAA;AAAA,oBAET,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAK,KAAA;AAAA,sBACL,KAAK,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,QAAO,QAAA,EAAA,IAAA,EAAE;AAAA;AAAA;AAAA,iBAC/C;AAAA,gBACC,wBAAQ,GAAA,CAAC,KAAA,EAAA,EAAM,SAAS,IAAA,CAAK,OAAA,EAAU,eAAK,IAAA,EAAK;AAAA,eAAA,EACpD,CAAA;AAAA,cACC,SAAS,QAAA,IAAY,IAAA,CAAK,0BACzB,IAAA,CAAC,MAAA,EAAA,EAAO,OAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,IAAK,MAAA,EAAW,eAAe,CAAC,CAAA,KAAM,SAAS,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA,EACxF,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,aAAA;AAAA,kBAAA;AAAA,oBACC,EAAA;AAAA,oBACA,iBAAA,EAAiB,CAAA,EAAG,EAAE,CAAA,OAAA,EAAU,EAAE,CAAA,CAAA;AAAA,oBAClC,kBAAA,EAAkB,WAAA;AAAA,oBAClB,eAAA,EAAe,KAAK,QAAA,IAAY,MAAA;AAAA,oBAChC,SAAA,EAAU,wBAAA;AAAA,oBAEV,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,WAAA,EAAa,IAAA,CAAK,eAAe,cAAA,EAAW;AAAA;AAAA,iBAC3D;AAAA,oCACC,aAAA,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,qBACjB,GAAA,CAAC,UAAA,EAAA,EAAyB,KAAA,EAAO,EAAE,KAAA,EAChC,QAAA,EAAA,CAAA,CAAE,SADY,CAAA,CAAE,KAEnB,CACD,CAAA,EACH;AAAA,eAAA,EACF,CAAA,GACE,IAAA,KAAS,WAAA,IAAe,IAAA,CAAK,OAAA,mBAC/B,GAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,EAAA;AAAA,kBACA,IAAA,EAAK,OAAA;AAAA,kBACL,iBAAA,EAAiB,GAAG,EAAE,CAAA,MAAA,CAAA;AAAA,kBACtB,kBAAA,EAAkB,WAAA;AAAA,kBAClB,SAAA,EAAU,kEAAA;AAAA,kBAET,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AAC1B,oBAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,IAAI,MAAM,CAAA,CAAE,KAAA;AACnC,oBAAA,uBACE,GAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBAEC,IAAA,EAAK,QAAA;AAAA,wBACL,cAAA,EAAc,EAAA;AAAA,wBACd,SAAS,MAAM,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,EAAE,KAAK,CAAA;AAAA,wBAC1C,SAAA,EAAW,EAAA;AAAA,0BACT,yKAAA;AAAA,0BACA,IAAI,CAAA,IAAK,uBAAA;AAAA,0BACT,KAAK,kCAAA,GAAqC;AAAA,yBAC5C;AAAA,wBAEC,QAAA,EAAA,CAAA,CAAE;AAAA,uBAAA;AAAA,sBAVE,CAAA,CAAE;AAAA,qBAWT;AAAA,kBAEJ,CAAC;AAAA;AAAA,eACH,GACE,SAAS,MAAA,mBACX,GAAA;AAAA,gBAAC,mBAAA;AAAA,gBAAA;AAAA,kBACC,EAAA;AAAA,kBACA,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AAAA,kBACvB,aAAa,IAAA,CAAK,WAAA;AAAA,kBAClB,WAAA;AAAA,kBACA,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,IAAA,CAAK,MAAM,CAAC;AAAA;AAAA,eACxC,mBAEA,GAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,EAAA;AAAA,kBACA,IAAA,EAAM,IAAA,KAAS,MAAA,GAAS,MAAA,GAAS,MAAA;AAAA,kBACjC,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,IAAK,EAAA;AAAA,kBAC5B,aAAa,IAAA,CAAK,WAAA;AAAA,kBAClB,kBAAA,EAAkB,WAAA;AAAA,kBAClB,eAAA,EAAe,KAAK,QAAA,IAAY,MAAA;AAAA,kBAChC,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,CAAS,KAAK,IAAA,EAAM,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,kBACnD,SAAA,EAAU;AAAA;AAAA,eACZ;AAAA,cAED,+BACC,IAAA,CAAC,gBAAA,EAAA,EAAiB,EAAA,EAAI,QAAA,EAAU,WAAU,SAAA,EACvC,QAAA,EAAA;AAAA,gBAAA,IAAA,IAAQ,CAAC,OAAO,IAAA,CAAK,IAAI,IAAI,CAAA,UAAA,EAAa,IAAA,CAAK,SAAS,CAAA,EAAA,CAAA,GAAO,EAAA;AAAA,gBAC/D,IAAA,CAAK;AAAA,eAAA,EACR;AAAA,aAAA,EAAA,EAlFQ,KAAK,IAoFjB,CAAA;AAAA,UAEJ,CAAC,CAAA;AAAA,UACA,QAAA,oBACC,IAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,uBAAA,EACf,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,cAAW,OAAA,EAAS,CAAA,EAAG,MAAM,CAAA,SAAA,CAAA,EAAa,SAAA,EAAU,+CAClD,QAAA,EAAA,aAAA,EACH,CAAA;AAAA,4BACA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,EAAA,EAAI,GAAG,MAAM,CAAA,SAAA,CAAA;AAAA,gBACb,IAAA,EAAM,CAAA;AAAA,gBACN,KAAA,EAAO,KAAA;AAAA,gBACP,WAAA,EAAY,iEAAA;AAAA,gBACZ,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA;AAC1C,WAAA,EACF,CAAA;AAAA,UAAA,CAEA,YAAY,QAAA,IAAY,YAAA,qBACxB,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uCAAA,EACZ,QAAA,EAAA;AAAA,YAAA,YAAA,oBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+BAAA,EAAgC,aAAU,QAAA,EACvD,QAAA,EAAA;AAAA,cAAA,WAAA;AAAA,cAAY,MAAA;AAAA,cAAK,KAAA,CAAM,MAAA;AAAA,cAAO;AAAA,aAAA,EACjC,CAAA;AAAA,4BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,YACxB,QAAA,wBACE,MAAA,EAAA,EAAO,IAAA,EAAK,UAAS,OAAA,EAAQ,OAAA,EAAQ,OAAA,EAAS,QAAA,EAC5C,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,YAED,QAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAQ,SAAA,EAAU,QAAA,EAAU,CAAC,SAAA,EAAW,SAAA,EAAU,gCAAA,EACrE,QAAA,EAAA,WAAA,EACH;AAAA,WAAA,EAEJ;AAAA;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AACA,oBAAA,CAAqB,WAAA,GAAc,sBAAA;AAEnC,IAAM,cAAA,GAAiB,CAAC,oCAAA,EAAsC,sBAAA,EAAwB,8BAA8B,4BAA4B,CAAA;AAGhJ,SAAS,mBAAA,CAAoB;AAAA,EAC3B,EAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,MAAM,IAAA,GAAO,oBAAoB,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAM,CAAC,IAAA,GAAO,KAAA,KAAU;AAC5B,IAAA,MAAM,CAAA,GAAI,KAAK,IAAA,EAAK;AACpB,IAAA,IAAI,CAAA,IAAK,CAAC,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,GAAG,IAAA,EAAM,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAC5D,IAAA,QAAA,CAAS,EAAE,CAAA;AAAA,EACb,CAAA;AACA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oJAAA,EACZ,QAAA,EAAA;AAAA,IAAA,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACZ,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAY,UAAU,CAAC,CAAA,CAAA;AAAA,QACvB,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,QAC9D,SAAA,EAAW,EAAA;AAAA,UACT,oHAAA;AAAA,UACA,cAAA,CAAe,CAAA,GAAI,cAAA,CAAe,MAAM;AAAA,SAC1C;AAAA,QAEC,QAAA,EAAA;AAAA,OAAA;AAAA,MATI;AAAA,KAWR,CAAA;AAAA,oBACD,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,KAAA,EAAO,KAAA;AAAA,QACP,aAAa,WAAA,IAAe,GAAA;AAAA,QAC5B,kBAAA,EAAkB,WAAA;AAAA,QAClB,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,MAAM,IAAA,GAAO,EAAE,MAAA,CAAO,KAAA;AACtB,UAAA,IAAI,IAAA,CAAK,SAAS,GAAG,CAAA,MAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,wBAC/B,IAAI,CAAA;AAAA,QACpB,CAAA;AAAA,QACA,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,UAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AACrB,YAAA,CAAA,CAAE,cAAA,EAAe;AACjB,YAAA,GAAA,EAAI;AAAA,UACN,WAAW,CAAA,CAAE,GAAA,KAAQ,eAAe,CAAC,KAAA,IAAS,KAAK,MAAA,EAAQ;AACzD,YAAA,QAAA,CAAS,KAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,UACvC;AAAA,QACF,CAAA;AAAA,QACA,MAAA,EAAQ,MAAM,GAAA,EAAI;AAAA,QAClB,SAAA,EAAU;AAAA;AAAA;AACZ,GAAA,EACF,CAAA;AAEJ;AAqCA,IAAM,gBAAA,GAAgD;AAAA,EACpD,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,QAAA,EAAS;AAAA,EAChC,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,SAAA,EAAU;AAAA,EAClC,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,MAAA;AACzB,CAAA;AAEA,IAAM,SAAA,GAA6D;AAAA,EACjE,EAAE,OAAA,EAAS,WAAA,EAAa,SAAA,EAAW,2BAAA,EAA4B;AAAA,EAC/D,EAAE,SAAS,MAAA,EAAO;AAAA,EAClB,EAAE,SAAS,SAAA,EAAU;AAAA,EACrB,EAAE,SAAS,SAAA;AACb,CAAA;AAGO,SAAS,sBAAsB,KAAA,EAAsC;AAC1E,EAAA,OAAO,KAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAO,CAAA,CAAE,SAAS,MAAA,GAAS,CAAA,CAAE,IAAA,GAAO,CAAA,EAAG,CAAA,CAAE,OAAO,GAAG,CAAA,CAAE,KAAK,CAAA,CAAG,CAAA,CAClE,IAAA,CAAK,GAAG,EACR,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,IAAA,EAAK;AACV;AAQO,IAAM,mBAAA,GAA4B,KAAA,CAAA,UAAA;AAAA,EACvC,CACE;AAAA,IACE,QAAA,GAAW,gBAAA;AAAA,IACX,KAAA,EAAO,SAAA;AAAA,IACP,YAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,iDAAA;AAAA,IACd,WAAA,GAAc,MAAA;AAAA,IACd,SAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,IAAU,KAAA,CAAA,QAAA,CAAgC,YAAA,IAAgB,EAAE,CAAA;AACxF,IAAA,MAAM,QAAQ,SAAA,IAAa,QAAA;AAC3B,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAiB,aAAyB,IAAI,CAAA;AACpD,IAAA,MAAM,SAAe,KAAA,CAAA,KAAA,EAAM;AAE3B,IAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAgC;AAC9C,MAAA,IAAI,SAAA,KAAc,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAC7C,MAAA,aAAA,GAAgB,IAAI,CAAA;AAAA,IACtB,CAAA;AAGA,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,QAAQ,EAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,CAAA,CAAE,QAAQ,MAAM,CAAA;AAChF,IAAA,MAAM,QAAA,GAAW,CAAC,IAAA,KAAiB;AACjC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,IAAA,CAAK,CAAC,OAAO,IAAA,CAAK,UAAA,CAAW,EAAA,CAAG,OAAO,CAAA,IAAK,IAAA,CAAK,MAAA,GAAS,EAAA,CAAG,QAAQ,MAAM,CAAA;AAC7F,MAAA,OAAO,CAAA,GAAI,EAAE,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA,EAAE,GAAI,IAAA;AAAA,IAC3E,CAAA;AAEA,IAAA,MAAM,WAAW,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,EAAA;AAC3C,IAAA,MAAM,aAAA,GAAgB,QAAQ,IAAA,CAAK,CAAC,OAAO,QAAA,CAAS,UAAA,CAAW,EAAA,CAAG,OAAO,CAAC,CAAA;AAC1E,IAAA,MAAM,KAAA,GAAQ,gBAAgB,QAAA,CAAS,KAAA,CAAM,cAAc,OAAA,CAAQ,MAAM,CAAA,CAAE,WAAA,EAAY,GAAI,EAAA;AAC3F,IAAA,MAAM,cACJ,aAAA,EAAe,WAAA,EAAa,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,WAAA,EAAY,CAAE,UAAA,CAAW,KAAK,CAAC,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,KAAK,EAAC;AAG/F,IAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,GAAS,KAAA,EAAO,QAAA,KAAyE;AACtG,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAC9B,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,EAAI,IAAK,EAAA;AAC5B,MAAA,MAAM,GAAA,GAAM,QAAA,IAAY,QAAA,CAAS,IAAI,CAAA;AACrC,MAAA,MAAM,cAAc,GAAA,GAAM,KAAA,CAAM,KAAK,GAAG,CAAA,GAAI,QAAQ,IAAA,EAAK;AACzD,MAAA,MAAM,IAAA,GAAO,CAAC,GAAG,KAAK,CAAA;AACtB,MAAA,IAAI,UAAA,OAAiB,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,YAAY,CAAA;AAC5D,MAAA,IAAI,GAAA,OAAU,IAAA,CAAK,EAAE,MAAM,KAAA,EAAO,GAAG,KAAK,CAAA;AAC1C,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,KAAA,CAAM,MAAA,SAAe,IAAI,CAAA;AAC7C,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,OAAA,KAAoB;AACnC,MAAA,MAAM,IAAI,QAAA,CAAS,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,OAAO,CAAA;AACzD,MAAA,OAAO,WAAW,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA,IAAK,UAAU,MAAM,CAAA;AAAA,IACrD,CAAA;AACA,IAAA,MAAM,QAAA,GAAW,CAAC,OAAA,KAAoB,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,KAAY,OAAO,CAAA,EAAG,KAAA,IAAS,KAAA;AAE5F,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,OAAO,KAAA,EAAM;AACnB,MAAA,MAAM,IAAA,GAAO,sBAAsB,IAAI,CAAA;AACvC,MAAA,IAAI,IAAA,EAAM,QAAA,GAAW,IAAA,EAAM,IAAI,CAAA;AAAA,IACjC,CAAA;AAEA,IAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,qBAAA,EAAuB,SAAS,CAAA,EAAI,GAAG,KAAA,EAClE,QAAA,EAAA;AAAA,sBAAA,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,+JAAA;AAAA,UACV,OAAA,EAAS,MAAM,QAAA,CAAS,OAAA,EAAS,KAAA,EAAM;AAAA,UAEtC,QAAA,EAAA;AAAA,YAAA,KAAA,CAAM,GAAA;AAAA,cAAI,CAAC,IAAA,EAAM,CAAA,KAChB,IAAA,CAAK,IAAA,KAAS,MAAA,mBACZ,GAAA,CAAC,MAAA,EAAA,EAAc,QAAA,EAAA,IAAA,CAAK,IAAA,EAAA,EAAT,CAAc,CAAA,mBAEzB,IAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBAEC,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,CAAE,OAAA;AAAA,kBAC/B,WAAW,EAAA,CAAG,yCAAA,EAA2C,QAAQ,IAAA,CAAK,OAAO,EAAE,SAAS,CAAA;AAAA,kBAEvF,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAK,OAAA;AAAA,oBACL,IAAA,CAAK,KAAA;AAAA,oCACN,GAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,QAAA;AAAA,wBACL,YAAA,EAAY,CAAA,OAAA,EAAU,QAAA,CAAS,IAAA,CAAK,OAAO,CAAA,CAAE,WAAA,EAAa,CAAA,CAAA,EAAI,IAAA,CAAK,OAAO,CAAA,EAAG,KAAK,KAAK,CAAA,CAAA;AAAA,wBACvF,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,0BAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,0BAAA,MAAA,CAAO,MAAM,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,KAAM,CAAC,CAAC,CAAA;AACtC,0BAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,wBAC1B,CAAA;AAAA,wBACA,SAAA,EAAU,+KAAA;AAAA,wBAEV,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,aAAA,EAAY,MAAA,EAAO;AAAA;AAAA;AACxB;AAAA,iBAAA;AAAA,gBAjBK;AAAA;AAkBP,aAEJ;AAAA,4BACA,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,QAAA;AAAA,gBACL,KAAA,EAAO,KAAA;AAAA,gBACP,YAAA,EAAY,WAAA;AAAA,gBACZ,kBAAA,EAAkB,MAAA;AAAA,gBAClB,WAAA,EAAa,KAAA,CAAM,MAAA,GAAS,MAAA,GAAY,WAAA;AAAA,gBACxC,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,kBAAA,MAAM,CAAA,GAAI,EAAE,MAAA,CAAO,KAAA;AAEnB,kBAAA,IAAI,EAAE,QAAA,CAAS,GAAG,KAAK,QAAA,CAAS,CAAA,CAAE,SAAQ,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,EAAE,GAAG,KAAA,CAAM,CAAA,CAAE,SAAS,CAAA;AAAA,gCACxE,CAAC,CAAA;AAAA,gBACjB,CAAA;AAAA,gBACA,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,kBAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,QAAA,CAAS,QAAQ,CAAA,EAAG;AACvC,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,KAAA,EAAM;AAAA,kBACR,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,EAAS;AAC5B,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,MAAA,EAAO;AAAA,kBACT,WAAW,CAAA,CAAE,GAAA,KAAQ,eAAe,KAAA,KAAU,EAAA,IAAM,MAAM,MAAA,EAAQ;AAChE,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACnC,oBAAA,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AACzB,oBAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,EAAQ,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,kBAC9C;AAAA,gBACF,CAAA;AAAA,gBACA,SAAA,EAAU;AAAA;AAAA;AACZ;AAAA;AAAA,OACF;AAAA,sBACA,IAAA,CAAC,GAAA,EAAA,EAAE,EAAA,EAAI,MAAA,EAAQ,WAAU,SAAA,EACtB,QAAA,EAAA;AAAA,QAAA,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,EAAE,OAAO,CAAA,KAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,WAAA,EAAa,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,QAAE;AAAA,OAAA,EAE/E,CAAA;AAAA,MACC,iBAAiB,WAAA,CAAY,MAAA,GAAS,qBACrC,GAAA,CAAC,KAAA,EAAA,EAAI,MAAK,OAAA,EAAQ,YAAA,EAAY,CAAA,EAAG,aAAA,CAAc,KAAK,CAAA,YAAA,CAAA,EAAgB,SAAA,EAAU,wBAC3E,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,qBAChB,IAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAEC,OAAA,EAAQ,WAAA;AAAA,UACR,IAAA,EAAK,IAAA;AAAA,UACL,SAAA,EAAU,UAAA;AAAA,UACV,SAAS,MAAM;AACb,YAAA,KAAA,CAAM,OAAO,EAAE,OAAA,EAAS,cAAc,OAAA,EAAS,KAAA,EAAO,GAAG,CAAA;AACzD,YAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,UAC1B,CAAA;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,aAAA,CAAc,OAAA;AAAA,YACd;AAAA;AAAA,SAAA;AAAA,QAVI;AAAA,OAYR,CAAA,EACH,CAAA;AAAA,MAED,QAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,KAAA;AAAA,UACR,IAAA,EAAK,IAAA;AAAA,UACL,OAAA,EAAS,MAAA;AAAA,UACT,UAAU,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,MAAK,KAAM,EAAA;AAAA,UAEhD,QAAA,EAAA;AAAA;AAAA,OACH,EACF;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AACA,mBAAA,CAAoB,WAAA,GAAc,qBAAA;AAkC3B,IAAM,qBAAA,GAA8B,KAAA,CAAA,UAAA;AAAA,EACzC,CACE;AAAA,IACE,KAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,GAAc,CAAA;AAAA,IACd,YAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,UAAA;AAAA,IACd,gBAAA,GAAmB,IAAA;AAAA,IACnB,SAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAS,WAAW,CAAA;AAC1D,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,IAAI,QAAA,IAAY,QAAA,EAAU,CAAC,CAAA,EAAG,KAAK,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAC,CAAC,CAAA;AACtF,IAAA,MAAM,UAAA,GAAmB,aAA6B,IAAI,CAAA;AAC1D,IAAA,MAAM,YAAkB,KAAA,CAAA,KAAA,EAAM;AAC9B,IAAA,MAAM,KAAA,GAAc,aAAO,KAAK,CAAA;AAEhC,IAAM,gBAAU,MAAM;AACpB,MAAA,IAAI,KAAA,CAAM,OAAA,EAAS,UAAA,CAAW,OAAA,EAAS,KAAA,EAAM;AAAA,IAC/C,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,IAAA,MAAM,EAAA,GAAK,CAAC,IAAA,KAAiB;AAC3B,MAAA,KAAA,CAAM,OAAA,GAAU,IAAA;AAChB,MAAA,IAAI,QAAA,KAAa,MAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAC5C,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA;AAEA,IAAA,MAAM,IAAA,GAAO,IAAA,KAAS,KAAA,CAAM,MAAA,GAAS,CAAA;AAErC,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA,EAAK,OAAA;AAAA,QACL,iBAAA,EAAiB,SAAA;AAAA,QACjB,SAAA,EAAW,EAAA,CAAG,uEAAA,EAAyE,SAAS,CAAA;AAAA,QAC/F,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,YAAA,EAAa,aAAA,EAAY,QACrC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACb,GAAA,CAAC,UAAa,SAAA,EAAW,EAAA,CAAG,2BAA2B,CAAA,IAAK,IAAA,GAAO,aAAa,UAAU,CAAA,EAAA,EAA/E,CAAkF,CAC9F,CAAA,EACH,CAAA;AAAA,0BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,GAAA,EAAA,EAAE,KAAK,UAAA,EAAY,EAAA,EAAI,WAAW,QAAA,EAAU,EAAA,EAAI,WAAU,oDAAA,EAAqD,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,cACxG,IAAA,GAAO,CAAA;AAAA,cAAE,MAAA;AAAA,cAAK,KAAA,CAAM,MAAA;AAAA,cAAO,QAAA;AAAA,cAAI,MAAM,IAAI;AAAA,aAAA,EACjD,CAAA;AAAA,YACC,WAAA,oBAAe,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iCAAiC,QAAA,EAAA,WAAA,EAAY;AAAA,WAAA,EAC5E,CAAA;AAAA,UACC,QAAA;AAAA,0BACD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACZ,QAAA,EAAA;AAAA,YAAA,IAAA,GAAO,CAAA,oBACN,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,MAAM,EAAA,CAAG,IAAA,GAAO,CAAC,GAAG,QAAA,EAAA,MAAA,EAE/D,CAAA;AAAA,4BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,YACxB,CAAC,IAAA,IAAQ,gBAAA,IAAoB,QAAA,oBAC5B,IAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,MAAA,EAAO,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,QAAA,EACvC,QAAA,EAAA;AAAA,cAAA,WAAA;AAAA,cAAY;AAAA,aAAA,EACf,CAAA;AAAA,YAED,IAAA,GACC,QAAA,oBACE,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,OAAM,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,QAAA,EACtC,QAAA,EAAA,WAAA,EACH,CAAA,uBAGD,MAAA,EAAA,EAAO,OAAA,EAAQ,KAAA,EAAM,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,MAAM,EAAA,CAAG,IAAA,GAAO,CAAC,CAAA,EAAG,QAAA,EAAA,MAAA,EAE7D;AAAA,WAAA,EAEJ;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,qBAAA,CAAsB,WAAA,GAAc,uBAAA","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Check, X } from \"lucide-react\";\nimport { Badge, type BadgeVariant } from \"@nucleux/badge\";\nimport { Button } from \"@nucleux/button\";\nimport { Field, FieldDescription, FieldLabel } from \"@nucleux/field\";\nimport { Input } from \"@nucleux/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@nucleux/select\";\nimport { Textarea } from \"@nucleux/textarea\";\n\nexport interface StructuredOption {\n /** Stable value. */\n value: string;\n /** Display label. */\n label: React.ReactNode;\n}\n\nexport interface StructuredInputProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\" | \"onSubmit\"> {\n /** The clarifying question the agent is asking. */\n question: React.ReactNode;\n /** The selectable answers. */\n options: StructuredOption[];\n /** Allow selecting more than one option. */\n multiple?: boolean;\n /** Selected values (controlled). */\n value?: string[];\n /** Initial selection (uncontrolled). */\n defaultValue?: string[];\n /** Called when the selection changes. */\n onValueChange?: (values: string[]) => void;\n /** Show a free-text \"something else\" escape. */\n allowOther?: boolean;\n /** Label for the other escape. Defaults to `\"Something else…\"`. */\n otherPlaceholder?: string;\n /** Called when the answer is submitted. */\n onSubmit?: (values: string[], other?: string) => void;\n /** Called when the user skips the question. Renders the skip control when set. */\n onSkip?: () => void;\n /** Label for the submit button. */\n submitLabel?: React.ReactNode;\n /** Label for the skip button. */\n skipLabel?: React.ReactNode;\n}\n\n/**\n * An agent-generated clarifying question rendered as a structured choice —\n * single or multi-select options, a free-text escape, and a skip. The other\n * structured-input variants are composable siblings: {@link StructuredInputSlots}\n * (named slots), {@link StructuredInputTags} (tagged input) and\n * {@link StructuredInputWizard} (wizard step).\n * Source: Figma \"Expressive Input / Structured Input\".\n */\nexport const StructuredInput = React.forwardRef<HTMLDivElement, StructuredInputProps>(\n (\n {\n question,\n options,\n multiple = false,\n value,\n defaultValue = [],\n onValueChange,\n allowOther = false,\n otherPlaceholder = \"Something else…\",\n onSubmit,\n onSkip,\n submitLabel = \"Continue\",\n skipLabel = \"Skip\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<string[]>(defaultValue);\n const [other, setOther] = React.useState(\"\");\n const questionId = React.useId();\n const groupRef = React.useRef<HTMLDivElement>(null);\n const selected = value !== undefined ? value : internal;\n\n const setSelected = (next: string[]) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n };\n const toggle = (val: string) => {\n if (multiple) {\n setSelected(selected.includes(val) ? selected.filter((v) => v !== val) : [...selected, val]);\n } else {\n setSelected([val]);\n }\n };\n\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col gap-4 rounded-xl border border-border bg-background p-5\", className)}\n {...props}\n >\n <p id={questionId} className=\"text-base font-medium text-foreground\">\n {question}\n </p>\n <div\n ref={groupRef}\n role={multiple ? \"group\" : \"radiogroup\"}\n aria-labelledby={questionId}\n className=\"flex flex-col gap-2\"\n onKeyDown={(e) => {\n // Radio-group keyboard pattern: arrows move and select.\n if (multiple || ![\"ArrowDown\", \"ArrowUp\", \"ArrowRight\", \"ArrowLeft\"].includes(e.key)) return;\n const radios = Array.from(groupRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"radio\"]') ?? []);\n const i = radios.indexOf(document.activeElement as HTMLButtonElement);\n if (i < 0) return;\n e.preventDefault();\n const step = e.key === \"ArrowDown\" || e.key === \"ArrowRight\" ? 1 : -1;\n const next = (i + step + radios.length) % radios.length;\n radios[next].focus();\n setSelected([options[next].value]);\n }}\n >\n {options.map((option, index) => {\n const active = selected.includes(option.value);\n const tabbable = multiple || index === Math.max(0, options.findIndex((o) => selected.includes(o.value)));\n return (\n <button\n key={option.value}\n type=\"button\"\n role={multiple ? \"checkbox\" : \"radio\"}\n aria-checked={active}\n tabIndex={tabbable ? 0 : -1}\n onClick={() => toggle(option.value)}\n className={cn(\n \"flex items-center gap-3 rounded-lg border px-3 py-2.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-brand bg-brand-muted/50 text-foreground\"\n : \"border-border bg-background text-foreground hover:bg-accent\",\n )}\n >\n <span\n className={cn(\n \"inline-flex size-5 shrink-0 items-center justify-center border transition-colors [&_svg]:size-3.5\",\n multiple ? \"rounded-md\" : \"rounded-full\",\n active ? \"border-brand bg-brand text-brand-foreground\" : \"border-border\",\n )}\n >\n {active && <Check aria-hidden=\"true\" />}\n </span>\n <span className=\"flex-1\">{option.label}</span>\n </button>\n );\n })}\n </div>\n {allowOther && (\n <input\n type=\"text\"\n value={other}\n onChange={(e) => setOther(e.target.value)}\n placeholder={otherPlaceholder}\n aria-label={otherPlaceholder}\n className=\"rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n )}\n <div className=\"flex items-center justify-end gap-2\">\n {onSkip && (\n <button\n type=\"button\"\n onClick={onSkip}\n className=\"inline-flex items-center rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {skipLabel}\n </button>\n )}\n {onSubmit && (\n <button\n type=\"button\"\n onClick={() => onSubmit(selected, allowOther ? other : undefined)}\n disabled={selected.length === 0 && !(allowOther && other.trim())}\n className=\"inline-flex items-center rounded-lg bg-info px-3 py-2 text-sm font-medium text-info-foreground transition-colors hover:bg-info/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\"\n >\n {submitLabel}\n </button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInput.displayName = \"StructuredInput\";\n\n/* -------------------------------------------------------------------------- */\n/* Named slots */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputSlot {\n /** Key in the values object. */\n name: string;\n /** Plain-language label, e.g. `\"Audience\"`. */\n label: string;\n /** Placeholder / example value. */\n placeholder?: string;\n /** Choices — renders a select instead of a text field. */\n options?: StructuredOption[];\n /** Helper text under the field. */\n helper?: string;\n /**\n * Marks the initial value as the agent's suggestion, with the reason, e.g.\n * `\"from the meeting invite\"`. Once the person changes it, it reads “Edited by you”.\n */\n suggested?: string;\n /** Span the full row. */\n wide?: boolean;\n /**\n * The control. Defaults to `\"select\"` when `options` are given, else `\"text\"`.\n * `\"segmented\"` shows `options` as a row of buttons; `\"date\"` a date field;\n * `\"tags\"` a tag field whose value is a comma-separated list.\n */\n type?: StructuredInputSlotType;\n /** The slot must be filled before submitting; its label carries “*”. */\n required?: boolean;\n}\n\n/** Control used for a slot. */\nexport type StructuredInputSlotType = \"text\" | \"select\" | \"segmented\" | \"date\" | \"tags\";\n\n/** Splits a `\"tags\"` slot's value into its tags. */\nexport function splitStructuredTags(value: string | undefined): string[] {\n return (value ?? \"\")\n .split(\",\")\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\n/** The control a slot uses, from its `type` and `options`. */\nexport function structuredSlotType(slot: StructuredInputSlot): StructuredInputSlotType {\n return slot.type ?? (slot.options ? \"select\" : \"text\");\n}\n\nexport type StructuredInputValues = Record<string, string>;\n\nexport interface StructuredInputSlotsProps\n extends Omit<React.HTMLAttributes<HTMLFormElement>, \"onSubmit\" | \"defaultValue\" | \"title\"> {\n /** The 2–4 slots the prompt template needs. */\n slots: StructuredInputSlot[];\n /** Values (controlled). */\n values?: StructuredInputValues;\n /** Initial values (uncontrolled). */\n defaultValues?: StructuredInputValues;\n /** Called on every change. */\n onValuesChange?: (values: StructuredInputValues) => void;\n /** Show a freeform override field. `true` uses the label `\"Anything else?\"`; a string sets the label. */\n freeform?: boolean | string;\n /** Called on submit. Never requires every slot — any value (or the freeform text) is enough. */\n onSubmit?: (values: StructuredInputValues, freeform: string) => void;\n /** Label of the submit button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Accessible name of the form. Defaults to `\"Structured prompt builder\"`. */\n label?: string;\n /** Heading over the fields, e.g. `\"Structured prompt\"`; it also names the form. */\n title?: React.ReactNode;\n /** Icon beside the title. */\n icon?: React.ReactNode;\n /** Right side of the title row, e.g. a \"Template\" badge or what the form is for. */\n aside?: React.ReactNode;\n /** Shows “3 of 4 filled” beside the buttons. */\n showProgress?: boolean;\n /** Shows a Cancel button beside submit. */\n onCancel?: () => void;\n /** Label of the cancel button. Defaults to `\"Cancel\"`. */\n cancelLabel?: React.ReactNode;\n}\n\n/**\n * Named slots: a short set of plain-language fields (2–4) that fill a prompt\n * template — text fields or selects, an optional freeform override, and a\n * submit that never requires every field. Agent-suggested values are marked\n * “Suggested” with their reason and become “Edited by you” once changed; the\n * component never changes a value the person set.\n */\nexport const StructuredInputSlots = React.forwardRef<HTMLFormElement, StructuredInputSlotsProps>(\n (\n {\n slots,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n freeform = false,\n onSubmit,\n submitLabel = \"Generate\",\n label = \"Structured prompt builder\",\n title,\n icon,\n aside,\n showProgress = false,\n onCancel,\n cancelLabel = \"Cancel\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputValues>(defaultValues ?? {});\n const values = valuesProp ?? internal;\n const [edited, setEdited] = React.useState<Record<string, boolean>>({});\n const [extra, setExtra] = React.useState(\"\");\n const baseId = React.useId();\n\n const setValue = (name: string, value: string) => {\n const next = { ...values, [name]: value };\n if (valuesProp === undefined) setInternal(next);\n setEdited((e) => ({ ...e, [name]: true }));\n onValuesChange?.(next);\n };\n\n const filled = (name: string) => !!values[name]?.trim();\n const filledCount = slots.filter((slot) => filled(slot.name)).length;\n const requiredMet = slots.every((slot) => !slot.required || filled(slot.name));\n const hasAny = Object.values(values).some((v) => v && v.trim()) || extra.trim().length > 0;\n const canSubmit = hasAny && requiredMet;\n const freeformLabel = typeof freeform === \"string\" ? freeform : \"Anything else?\";\n const titleId = `${baseId}-title`;\n\n return (\n <form\n ref={ref}\n aria-label={title == null ? label : undefined}\n aria-labelledby={title == null ? undefined : titleId}\n className={cn(\"grid grid-cols-1 gap-3 sm:grid-cols-2\", className)}\n onSubmit={(e) => {\n e.preventDefault();\n if (canSubmit) onSubmit?.(values, extra);\n }}\n {...props}\n >\n {(title != null || aside != null) && (\n <div className=\"mb-1 flex items-center gap-3 border-b border-border pb-4 sm:col-span-2\">\n {icon != null && (\n <span\n aria-hidden=\"true\"\n className=\"inline-flex size-[1.625rem] shrink-0 items-center justify-center rounded-md bg-foreground text-background [&_svg]:size-3.5\"\n >\n {icon}\n </span>\n )}\n <h3 id={titleId} className=\"flex-1 text-base font-semibold text-foreground\">\n {title}\n </h3>\n {aside}\n </div>\n )}\n {slots.map((slot) => {\n const id = `${baseId}-${slot.name}`;\n const helperId = `${id}-helper`;\n const mark = slot.suggested\n ? edited[slot.name]\n ? { text: \"Edited by you\", variant: \"secondary\" as const }\n : { text: \"Suggested\", variant: \"info\" as const }\n : null;\n const describedBy = slot.helper || (mark && !edited[slot.name]) ? helperId : undefined;\n const type = structuredSlotType(slot);\n return (\n <Field key={slot.name} className={cn(\"gap-1.5\", slot.wide && \"sm:col-span-2\")}>\n <div className=\"flex items-center gap-2\">\n <FieldLabel\n id={`${id}-label`}\n htmlFor={id}\n className=\"text-xs font-semibold uppercase tracking-[0.08em] text-muted-foreground\"\n >\n {slot.label}\n {slot.required && <span aria-hidden=\"true\"> *</span>}\n </FieldLabel>\n {mark && <Badge variant={mark.variant}>{mark.text}</Badge>}\n </div>\n {type === \"select\" && slot.options ? (\n <Select value={values[slot.name] || undefined} onValueChange={(v) => setValue(slot.name, v)}>\n <SelectTrigger\n id={id}\n aria-labelledby={`${id}-label ${id}`}\n aria-describedby={describedBy}\n aria-required={slot.required || undefined}\n className=\"h-11 rounded-lg px-3.5\"\n >\n <SelectValue placeholder={slot.placeholder ?? \"Choose…\"} />\n </SelectTrigger>\n <SelectContent>\n {slot.options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : type === \"segmented\" && slot.options ? (\n <div\n id={id}\n role=\"group\"\n aria-labelledby={`${id}-label`}\n aria-describedby={describedBy}\n className=\"inline-flex w-fit overflow-hidden rounded-lg border border-input\"\n >\n {slot.options.map((o, i) => {\n const on = values[slot.name] === o.value;\n return (\n <button\n key={o.value}\n type=\"button\"\n aria-pressed={on}\n onClick={() => setValue(slot.name, o.value)}\n className={cn(\n \"h-11 px-4 text-sm font-medium transition-colors focus-visible:relative focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n i > 0 && \"border-l border-input\",\n on ? \"bg-accent text-accent-foreground\" : \"bg-background text-foreground hover:bg-accent/50\",\n )}\n >\n {o.label}\n </button>\n );\n })}\n </div>\n ) : type === \"tags\" ? (\n <StructuredTagsField\n id={id}\n value={values[slot.name]}\n placeholder={slot.placeholder}\n describedBy={describedBy}\n onChange={(v) => setValue(slot.name, v)}\n />\n ) : (\n <Input\n id={id}\n type={type === \"date\" ? \"date\" : \"text\"}\n value={values[slot.name] ?? \"\"}\n placeholder={slot.placeholder}\n aria-describedby={describedBy}\n aria-required={slot.required || undefined}\n onChange={(e) => setValue(slot.name, e.target.value)}\n className=\"h-11 rounded-lg px-3.5 text-base shadow-none\"\n />\n )}\n {describedBy && (\n <FieldDescription id={helperId} className=\"text-xs\">\n {mark && !edited[slot.name] ? `Suggested ${slot.suggested}. ` : \"\"}\n {slot.helper}\n </FieldDescription>\n )}\n </Field>\n );\n })}\n {freeform && (\n <Field className=\"gap-1.5 sm:col-span-2\">\n <FieldLabel htmlFor={`${baseId}-freeform`} className=\"text-xs font-semibold text-muted-foreground\">\n {freeformLabel}\n </FieldLabel>\n <Textarea\n id={`${baseId}-freeform`}\n rows={2}\n value={extra}\n placeholder=\"Say it in your own words — this overrides the fields above\"\n onChange={(e) => setExtra(e.target.value)}\n />\n </Field>\n )}\n {(onSubmit || onCancel || showProgress) && (\n <div className=\"flex items-center gap-2 sm:col-span-2\">\n {showProgress && (\n <span className=\"text-xs text-muted-foreground\" aria-live=\"polite\">\n {filledCount} of {slots.length} filled\n </span>\n )}\n <span className=\"flex-1\" />\n {onCancel && (\n <Button type=\"button\" variant=\"ghost\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n )}\n {onSubmit && (\n <Button type=\"submit\" variant=\"primary\" disabled={!canSubmit} className=\"h-10 rounded-lg px-5 text-base\">\n {submitLabel}\n </Button>\n )}\n </div>\n )}\n </form>\n );\n },\n);\nStructuredInputSlots.displayName = \"StructuredInputSlots\";\n\nconst SLOT_TAG_TONES = [\"bg-destructive/10 text-destructive\", \"bg-info/10 text-info\", \"bg-success/10 text-success\", \"bg-warning/10 text-warning\"];\n\n/** The `\"tags\"` slot: tinted tags (press one to remove it) and a field that adds on Enter or comma. */\nfunction StructuredTagsField({\n id,\n value,\n placeholder,\n describedBy,\n onChange,\n}: {\n id: string;\n value?: string;\n placeholder?: string;\n describedBy?: string;\n onChange: (value: string) => void;\n}) {\n const tags = splitStructuredTags(value);\n const [draft, setDraft] = React.useState(\"\");\n const add = (text = draft) => {\n const t = text.trim();\n if (t && !tags.includes(t)) onChange([...tags, t].join(\", \"));\n setDraft(\"\");\n };\n return (\n <div className=\"flex min-h-11 flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-2.5 py-1.5 focus-within:ring-2 focus-within:ring-ring\">\n {tags.map((t, i) => (\n <button\n key={t}\n type=\"button\"\n aria-label={`Remove ${t}`}\n onClick={() => onChange(tags.filter((x) => x !== t).join(\", \"))}\n className={cn(\n \"rounded-md px-2 py-0.5 text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n SLOT_TAG_TONES[i % SLOT_TAG_TONES.length],\n )}\n >\n {t}\n </button>\n ))}\n <input\n id={id}\n value={draft}\n placeholder={placeholder ?? \"+\"}\n aria-describedby={describedBy}\n onChange={(e) => {\n const next = e.target.value;\n if (next.endsWith(\",\")) add(next.slice(0, -1));\n else setDraft(next);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n add();\n } else if (e.key === \"Backspace\" && !draft && tags.length) {\n onChange(tags.slice(0, -1).join(\", \"));\n }\n }}\n onBlur={() => add()}\n className=\"min-w-16 flex-1 bg-transparent px-1 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Tagged input */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputTagTrigger {\n /** The prefix that starts a tag, e.g. `\"@\"`, `\"p:\"`, `\"/\"`. */\n trigger: string;\n /** What the tag refers to, e.g. `\"Person\"`. */\n label: string;\n /** Values offered while typing after the trigger. */\n suggestions?: string[];\n}\n\nexport type StructuredInputPart =\n | { type: \"text\"; text: string }\n | { type: \"tag\"; trigger: string; value: string };\n\nexport interface StructuredInputTagsProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"defaultValue\" | \"onChange\"> {\n /** Recognised tag prefixes. Defaults to `@` person, `p:` project, `/` file. */\n triggers?: StructuredInputTagTrigger[];\n /** Committed parts (controlled). */\n value?: StructuredInputPart[];\n /** Initial parts (uncontrolled). */\n defaultValue?: StructuredInputPart[];\n /** Called when parts are added or removed. */\n onValueChange?: (parts: StructuredInputPart[]) => void;\n /** Called on Enter or the send button with the parts and their plain-text form. */\n onSubmit?: (parts: StructuredInputPart[], text: string) => void;\n /** Accessible name and placeholder of the text field. */\n placeholder?: string;\n /** Label of the send button. Defaults to `\"Send\"`. */\n submitLabel?: React.ReactNode;\n}\n\nconst DEFAULT_TRIGGERS: StructuredInputTagTrigger[] = [\n { trigger: \"@\", label: \"Person\" },\n { trigger: \"p:\", label: \"Project\" },\n { trigger: \"/\", label: \"File\" },\n];\n\nconst TAG_TONES: { variant: BadgeVariant; className?: string }[] = [\n { variant: \"secondary\", className: \"bg-brand-muted text-brand\" },\n { variant: \"info\" },\n { variant: \"success\" },\n { variant: \"outline\" },\n];\n\n/** Serialise parts into the plain prompt text, e.g. `\"Update @sam on p:Apollo\"`. */\nexport function structuredPartsToText(parts: StructuredInputPart[]): string {\n return parts\n .map((p) => (p.type === \"text\" ? p.text : `${p.trigger}${p.value}`))\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Tagged input: a prompt field where typed prefixes (`@` person, `p:` project,\n * `/` file — configurable) become removable tag chips, with optional\n * type-ahead suggestions shown as buttons. Backspace on an empty field removes\n * the last tag; Enter sends. Tags are optional — plain text always works.\n */\nexport const StructuredInputTags = React.forwardRef<HTMLDivElement, StructuredInputTagsProps>(\n (\n {\n triggers = DEFAULT_TRIGGERS,\n value: valueProp,\n defaultValue,\n onValueChange,\n onSubmit,\n placeholder = \"Type @ for people, p: for projects, / for files\",\n submitLabel = \"Send\",\n className,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState<StructuredInputPart[]>(defaultValue ?? []);\n const parts = valueProp ?? internal;\n const [draft, setDraft] = React.useState(\"\");\n const inputRef = React.useRef<HTMLInputElement>(null);\n const hintId = React.useId();\n\n const commit = (next: StructuredInputPart[]) => {\n if (valueProp === undefined) setInternal(next);\n onValueChange?.(next);\n };\n\n // Longest trigger first so \"p:\" wins over \"p\".\n const ordered = [...triggers].sort((a, b) => b.trigger.length - a.trigger.length);\n const matchTag = (word: string) => {\n const t = ordered.find((tr) => word.startsWith(tr.trigger) && word.length > tr.trigger.length);\n return t ? { trigger: t.trigger, value: word.slice(t.trigger.length) } : null;\n };\n\n const lastWord = draft.split(\" \").pop() ?? \"\";\n const activeTrigger = ordered.find((tr) => lastWord.startsWith(tr.trigger));\n const query = activeTrigger ? lastWord.slice(activeTrigger.trigger.length).toLowerCase() : \"\";\n const suggestions =\n activeTrigger?.suggestions?.filter((s) => s.toLowerCase().startsWith(query)).slice(0, 5) ?? [];\n\n /** Split the draft into text + a trailing tag (if any) and commit them. */\n const flush = (source = draft, forceTag?: { trigger: string; value: string }): StructuredInputPart[] => {\n const words = source.split(\" \");\n const last = words.pop() ?? \"\";\n const tag = forceTag ?? matchTag(last);\n const textBefore = (tag ? words.join(\" \") : source).trim();\n const next = [...parts];\n if (textBefore) next.push({ type: \"text\", text: textBefore });\n if (tag) next.push({ type: \"tag\", ...tag });\n if (next.length !== parts.length) commit(next);\n setDraft(\"\");\n return next;\n };\n\n const toneFor = (trigger: string) => {\n const i = triggers.findIndex((t) => t.trigger === trigger);\n return TAG_TONES[(i < 0 ? 0 : i) % TAG_TONES.length];\n };\n const labelFor = (trigger: string) => triggers.find((t) => t.trigger === trigger)?.label ?? \"Tag\";\n\n const submit = () => {\n const next = flush();\n const text = structuredPartsToText(next);\n if (text) onSubmit?.(next, text);\n };\n\n return (\n <div ref={ref} className={cn(\"flex flex-col gap-2\", className)} {...props}>\n <div\n className=\"flex flex-wrap items-center gap-1.5 rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground focus-within:ring-2 focus-within:ring-ring\"\n onClick={() => inputRef.current?.focus()}\n >\n {parts.map((part, i) =>\n part.type === \"text\" ? (\n <span key={i}>{part.text}</span>\n ) : (\n <Badge\n key={i}\n variant={toneFor(part.trigger).variant}\n className={cn(\"gap-0.5 rounded-md pr-0.5 font-semibold\", toneFor(part.trigger).className)}\n >\n {part.trigger}\n {part.value}\n <button\n type=\"button\"\n aria-label={`Remove ${labelFor(part.trigger).toLowerCase()} ${part.trigger}${part.value}`}\n onClick={(e) => {\n e.stopPropagation();\n commit(parts.filter((_, j) => j !== i));\n inputRef.current?.focus();\n }}\n className=\"inline-flex size-4 items-center justify-center rounded-sm opacity-70 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:size-3\"\n >\n <X aria-hidden=\"true\" />\n </button>\n </Badge>\n ),\n )}\n <Input\n ref={inputRef}\n value={draft}\n aria-label={placeholder}\n aria-describedby={hintId}\n placeholder={parts.length ? undefined : placeholder}\n onChange={(e) => {\n const v = e.target.value;\n // A space after a tag word (incl. mobile keyboards that skip keydown) makes it a chip.\n if (v.endsWith(\" \") && matchTag(v.trimEnd().split(\" \").pop() ?? \"\")) flush(v.trimEnd());\n else setDraft(v);\n }}\n onKeyDown={(e) => {\n if (e.key === \" \" && matchTag(lastWord)) {\n e.preventDefault();\n flush();\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n submit();\n } else if (e.key === \"Backspace\" && draft === \"\" && parts.length) {\n e.preventDefault();\n const last = parts[parts.length - 1];\n commit(parts.slice(0, -1));\n if (last.type === \"text\") setDraft(last.text);\n }\n }}\n className=\"h-7 min-w-[8rem] flex-1 border-0 px-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n <p id={hintId} className=\"sr-only\">\n {triggers.map((t) => `${t.trigger} for ${t.label.toLowerCase()}`).join(\", \")}. Space turns a tag into a\n chip; Backspace removes the last one; Enter sends.\n </p>\n {activeTrigger && suggestions.length > 0 && (\n <div role=\"group\" aria-label={`${activeTrigger.label} suggestions`} className=\"flex flex-wrap gap-1\">\n {suggestions.map((s) => (\n <Button\n key={s}\n variant=\"secondary\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={() => {\n flush(draft, { trigger: activeTrigger.trigger, value: s });\n inputRef.current?.focus();\n }}\n >\n {activeTrigger.trigger}\n {s}\n </Button>\n ))}\n </div>\n )}\n {onSubmit && (\n <div className=\"flex justify-end\">\n <Button\n variant=\"cta\"\n size=\"sm\"\n onClick={submit}\n disabled={parts.length === 0 && draft.trim() === \"\"}\n >\n {submitLabel}\n </Button>\n </div>\n )}\n </div>\n );\n },\n);\nStructuredInputTags.displayName = \"StructuredInputTags\";\n\n/* -------------------------------------------------------------------------- */\n/* Wizard step */\n/* -------------------------------------------------------------------------- */\n\nexport interface StructuredInputWizardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"title\"> {\n /** Step titles, e.g. `[\"Intent\", \"Audience\", \"Tone\"]`. */\n steps: string[];\n /** Current step, 0-based (controlled). */\n step?: number;\n /** Initial step (uncontrolled). */\n defaultStep?: number;\n /** Called when Back / Next move. */\n onStepChange?: (step: number) => void;\n /** The current step's question, e.g. `\"Who is the brief for?\"`. */\n description?: React.ReactNode;\n /** Called from the last step (or from “Generate now” when `allowEarlySubmit`). */\n onSubmit?: () => void;\n /** Label of the final button. Defaults to `\"Generate\"`. */\n submitLabel?: React.ReactNode;\n /** Offer “Generate now” before the last step — fields are never all required. Defaults to `true`. */\n allowEarlySubmit?: boolean;\n /** The current step's fields. */\n children?: React.ReactNode;\n}\n\n/**\n * Wizard step: a multi-step frame for high-stakes prompts (legal, HR, medical) —\n * a progress bar, “Step 2 of 3 · Audience”, the step's question and fields\n * (children), and Back / Next / Generate. Focus moves to the step heading when\n * the step changes; nothing forces every step to be filled before generating.\n */\nexport const StructuredInputWizard = React.forwardRef<HTMLDivElement, StructuredInputWizardProps>(\n (\n {\n steps,\n step: stepProp,\n defaultStep = 0,\n onStepChange,\n description,\n onSubmit,\n submitLabel = \"Generate\",\n allowEarlySubmit = true,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const [internal, setInternal] = React.useState(defaultStep);\n const step = Math.min(Math.max(stepProp ?? internal, 0), Math.max(steps.length - 1, 0));\n const headingRef = React.useRef<HTMLParagraphElement>(null);\n const headingId = React.useId();\n const moved = React.useRef(false);\n\n React.useEffect(() => {\n if (moved.current) headingRef.current?.focus();\n }, [step]);\n\n const go = (next: number) => {\n moved.current = true;\n if (stepProp === undefined) setInternal(next);\n onStepChange?.(next);\n };\n\n const last = step === steps.length - 1;\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={headingId}\n className={cn(\"flex flex-col gap-3 rounded-xl border border-border bg-background p-4\", className)}\n {...props}\n >\n <div className=\"flex gap-1\" aria-hidden=\"true\">\n {steps.map((_, i) => (\n <span key={i} className={cn(\"h-1 flex-1 rounded-full\", i <= step ? \"bg-brand\" : \"bg-muted\")} />\n ))}\n </div>\n <div className=\"flex flex-col gap-1\">\n <p ref={headingRef} id={headingId} tabIndex={-1} className=\"text-sm font-semibold text-foreground outline-none\">\n Step {step + 1} of {steps.length} · {steps[step]}\n </p>\n {description && <p className=\"text-sm text-muted-foreground\">{description}</p>}\n </div>\n {children}\n <div className=\"flex items-center gap-2\">\n {step > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => go(step - 1)}>\n Back\n </Button>\n )}\n <span className=\"flex-1\" />\n {!last && allowEarlySubmit && onSubmit && (\n <Button variant=\"link\" size=\"sm\" onClick={onSubmit}>\n {submitLabel} now\n </Button>\n )}\n {last ? (\n onSubmit && (\n <Button variant=\"cta\" size=\"sm\" onClick={onSubmit}>\n {submitLabel}\n </Button>\n )\n ) : (\n <Button variant=\"cta\" size=\"sm\" onClick={() => go(step + 1)}>\n Next\n </Button>\n )}\n </div>\n </div>\n );\n },\n);\nStructuredInputWizard.displayName = \"StructuredInputWizard\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nucleux/structured-input",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "StructuredInput — an agent's structured clarifying question — Nucleux agentic UI for React.",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"react-dom": ">=18"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@nucleux/badge": "0.
|
|
37
|
-
"@nucleux/button": "0.
|
|
38
|
-
"@nucleux/field": "0.
|
|
39
|
-
"@nucleux/input": "0.
|
|
40
|
-
"@nucleux/select": "0.
|
|
41
|
-
"@nucleux/textarea": "0.
|
|
42
|
-
"@nucleux/utils": "0.
|
|
36
|
+
"@nucleux/badge": "0.10.0",
|
|
37
|
+
"@nucleux/button": "0.10.0",
|
|
38
|
+
"@nucleux/field": "0.10.0",
|
|
39
|
+
"@nucleux/input": "0.10.0",
|
|
40
|
+
"@nucleux/select": "0.10.0",
|
|
41
|
+
"@nucleux/textarea": "0.10.0",
|
|
42
|
+
"@nucleux/utils": "0.10.0",
|
|
43
43
|
"lucide-react": "^0.469.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|