@nucleux/structured-input 0.9.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 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 (hasAny) onSubmit?.(values, extra);
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.jsx(field.FieldLabel, { id: `${id}-label`, htmlFor: id, className: "text-xs font-semibold text-muted-foreground", children: slot.label }),
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(select.SelectTrigger, { id, "aria-labelledby": `${id}-label ${id}`, "aria-describedby": describedBy, children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: slot.placeholder ?? "Choose\u2026" }) }),
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
- onChange: (e) => setValue(slot.name, e.target.value)
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.jsx("div", { className: "flex justify-end sm:col-span-2", children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "submit", variant: "cta", size: "sm", disabled: !hasAny, children: submitLabel }) })
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
@@ -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 (hasAny) onSubmit?.(values, extra);
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__ */ jsx(FieldLabel, { id: `${id}-label`, htmlFor: id, className: "text-xs font-semibold text-muted-foreground", children: slot.label }),
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(SelectTrigger, { id, "aria-labelledby": `${id}-label ${id}`, "aria-describedby": describedBy, children: /* @__PURE__ */ jsx(SelectValue, { placeholder: slot.placeholder ?? "Choose\u2026" }) }),
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
- onChange: (e) => setValue(slot.name, e.target.value)
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__ */ jsx("div", { className: "flex justify-end sm:col-span-2", children: /* @__PURE__ */ jsx(Button, { type: "submit", variant: "cta", size: "sm", disabled: !hasAny, children: submitLabel }) })
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":"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","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":"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","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.9.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.9.0",
37
- "@nucleux/button": "0.9.0",
38
- "@nucleux/field": "0.9.0",
39
- "@nucleux/input": "0.9.0",
40
- "@nucleux/select": "0.9.0",
41
- "@nucleux/textarea": "0.9.0",
42
- "@nucleux/utils": "0.9.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": {