@assistant-ui/react-generative-ui 0.0.22 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/a2ui/convert.d.ts.map +1 -1
  2. package/dist/a2ui/convert.js +21 -4
  3. package/dist/a2ui/convert.js.map +1 -1
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +2 -1
  7. package/dist/constants.js.map +1 -1
  8. package/dist/slack/decodeBlockAction.d.ts.map +1 -1
  9. package/dist/slack/decodeBlockAction.js +64 -26
  10. package/dist/slack/decodeBlockAction.js.map +1 -1
  11. package/dist/slack/fromSlackBlocks.d.ts.map +1 -1
  12. package/dist/slack/fromSlackBlocks.js +23 -0
  13. package/dist/slack/fromSlackBlocks.js.map +1 -1
  14. package/dist/slack/toSlackBlocks.d.ts.map +1 -1
  15. package/dist/slack/toSlackBlocks.js +74 -18
  16. package/dist/slack/toSlackBlocks.js.map +1 -1
  17. package/dist/slack/types.d.ts +20 -1
  18. package/dist/slack/types.d.ts.map +1 -1
  19. package/dist/slack.d.ts +1 -1
  20. package/dist/slack.d.ts.map +1 -1
  21. package/dist/teams/decodeSubmitData.d.ts.map +1 -1
  22. package/dist/teams/decodeSubmitData.js +24 -3
  23. package/dist/teams/decodeSubmitData.js.map +1 -1
  24. package/dist/teams/temporalId.d.ts +5 -0
  25. package/dist/teams/temporalId.d.ts.map +1 -0
  26. package/dist/teams/temporalId.js +28 -0
  27. package/dist/teams/temporalId.js.map +1 -0
  28. package/dist/teams/toAdaptiveCard.d.ts.map +1 -1
  29. package/dist/teams/toAdaptiveCard.js +80 -1
  30. package/dist/teams/toAdaptiveCard.js.map +1 -1
  31. package/dist/teams/toTeamsAttachments.d.ts.map +1 -1
  32. package/dist/teams/toTeamsAttachments.js.map +1 -1
  33. package/dist/teams/types.d.ts +19 -1
  34. package/dist/teams/types.d.ts.map +1 -1
  35. package/dist/teams.d.ts +1 -1
  36. package/dist/teams.d.ts.map +1 -1
  37. package/dist/temporal.d.ts +33 -0
  38. package/dist/temporal.d.ts.map +1 -0
  39. package/dist/temporal.js +153 -0
  40. package/dist/temporal.js.map +1 -0
  41. package/dist/vocabulary/collectFormValues.d.ts +1 -1
  42. package/dist/vocabulary/collectFormValues.d.ts.map +1 -1
  43. package/dist/vocabulary/collectFormValues.js +7 -3
  44. package/dist/vocabulary/collectFormValues.js.map +1 -1
  45. package/dist/vocabulary/data.d.ts +1 -1
  46. package/dist/vocabulary/interactive.d.ts +7 -1
  47. package/dist/vocabulary/interactive.d.ts.map +1 -1
  48. package/dist/vocabulary/interactive.js +116 -12
  49. package/dist/vocabulary/interactive.js.map +1 -1
  50. package/package.json +6 -5
  51. package/src/a2ui/convert.test.ts +223 -14
  52. package/src/a2ui/convert.ts +41 -7
  53. package/src/constants.ts +1 -0
  54. package/src/slack/datePicker.test.ts +612 -0
  55. package/src/slack/decodeBlockAction.ts +114 -41
  56. package/src/slack/fromSlackBlocks.ts +29 -0
  57. package/src/slack/toSlackBlocks.ts +123 -36
  58. package/src/slack/types.ts +24 -0
  59. package/src/slack.ts +2 -0
  60. package/src/teams/decodeSubmitData.test.ts +216 -0
  61. package/src/teams/decodeSubmitData.ts +49 -4
  62. package/src/teams/temporal.test.ts +766 -0
  63. package/src/teams/temporalId.ts +56 -0
  64. package/src/teams/toAdaptiveCard.ts +166 -2
  65. package/src/teams/toTeamsAttachments.ts +4 -1
  66. package/src/teams/types.ts +17 -0
  67. package/src/teams.ts +1 -0
  68. package/src/temporal.test.ts +337 -0
  69. package/src/temporal.ts +263 -0
  70. package/src/vocabulary/collectFormValues.test.ts +198 -1
  71. package/src/vocabulary/collectFormValues.ts +31 -2
  72. package/src/vocabulary/datepicker.dom.test.tsx +1457 -0
  73. package/src/vocabulary/interactive.dom.test.tsx +59 -11
  74. package/src/vocabulary/interactive.tsx +212 -15
@@ -1 +1 @@
1
- {"version":3,"file":"interactive.js","names":[],"sources":["../../src/vocabulary/interactive.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { z } from \"zod\";\nimport {\n CHECKBOX_GROUP_ATTR,\n FIELD_NAME_ATTR,\n GENERATED_NAME_ATTR,\n} from \"../constants\";\nimport type { Action } from \"../ir\";\nimport { BUTTON_STYLES } from \"../ir\";\nimport type {\n GenerativeUIDispatch,\n GenerativeUILibrary,\n GenerativeUIStatus,\n} from \"../types\";\nimport { A2uiBindingContext, useA2uiBinding } from \"../a2ui/BindingContext\";\nimport { useAnsweredValue } from \"../answeredValues\";\nimport { actionAttr, fire } from \"./dispatch\";\nimport { toTextContent } from \"./toTextContent\";\nimport { useRadioGroupName } from \"../RadioGroupScope\";\n\nconst optionSchema = z.object({\n label: z.string(),\n value: z.string(),\n});\n\nconst describedOptionSchema = optionSchema.extend({\n description: z.string().optional(),\n});\n\ntype Option = { label: string; description?: string; value: string };\n\nconst isOption = (option: unknown): option is Option =>\n option !== null &&\n typeof option === \"object\" &&\n \"label\" in option &&\n typeof option.label === \"string\" &&\n (!(\"description\" in option) || typeof option.description === \"string\") &&\n \"value\" in option &&\n typeof option.value === \"string\";\n\nconst mapOptions = (\n options: unknown,\n render: (option: Option, key: string) => React.ReactNode,\n) => {\n const occurrences = new Map<string, number>();\n return (Array.isArray(options) ? options : []).map((option) => {\n if (!isOption(option)) return null;\n const occurrence = occurrences.get(option.value) ?? 0;\n occurrences.set(option.value, occurrence + 1);\n return render(option, JSON.stringify([option.value, occurrence]));\n });\n};\n\ntype RadioGroupRenderProps = {\n value?: string;\n options: Option[];\n name?: string;\n label?: string;\n defaultValue?: string;\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction RadioGroupRender({\n value,\n options,\n name,\n label,\n defaultValue,\n children,\n $action,\n $dispatch,\n}: RadioGroupRenderProps) {\n const groupName = useRadioGroupName(name);\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialValue =\n typeof answeredValue === \"string\" ? answeredValue : defaultValue;\n return (\n <fieldset\n key={initialValue}\n data-aui=\"radiogroup\"\n data-aui-action={actionAttr($action)}\n aria-label={label}\n >\n {mapOptions(options, (option, key) => (\n <label key={key} data-aui=\"radiogroup-option\">\n <input\n type=\"radio\"\n name={groupName}\n {...{ [FIELD_NAME_ATTR]: name }}\n {...(name == null ? { [GENERATED_NAME_ATTR]: \"\" } : {})}\n value={option.value}\n {...(isBound\n ? { checked: (answeredValue ?? value) === option.value }\n : { defaultChecked: initialValue === option.value })}\n onChange={(e) => {\n updateBinding?.(option.value);\n fire($action, $dispatch, option.value, e.currentTarget);\n }}\n />\n {option.description ? (\n <span data-aui=\"option-content\">\n <span data-aui=\"option-label\">{option.label}</span>\n <span data-aui=\"option-description\">{option.description}</span>\n </span>\n ) : (\n option.label\n )}\n </label>\n ))}\n {children}\n </fieldset>\n );\n}\n\ntype CheckboxGroupRenderProps = {\n value?: string[];\n options: Option[];\n name?: string;\n label?: string;\n defaultValue?: string[];\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nconst checkedGroupValues = (input: HTMLInputElement): string[] =>\n Array.from(\n input\n .closest(\"fieldset\")\n ?.querySelectorAll<HTMLInputElement>(\n `:scope > label > input[${CHECKBOX_GROUP_ATTR}]:checked`,\n ) ?? [],\n (checkbox) => checkbox.value,\n );\n\nfunction CheckboxGroupRender({\n value,\n options,\n name,\n label,\n defaultValue,\n children,\n $action,\n $dispatch,\n}: CheckboxGroupRenderProps) {\n const generatedName = React.useId();\n const fieldName = name ?? generatedName;\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const checkedValues =\n Array.isArray(answeredValue) &&\n answeredValue.every((value): value is string => typeof value === \"string\")\n ? answeredValue\n : Array.isArray(defaultValue)\n ? defaultValue\n : [];\n return (\n <fieldset\n key={JSON.stringify(checkedValues)}\n data-aui=\"checkboxgroup\"\n data-aui-action={actionAttr($action)}\n aria-label={label}\n >\n {mapOptions(options, (option, key) => (\n <label key={key} data-aui=\"checkboxgroup-option\">\n <input\n type=\"checkbox\"\n name={fieldName}\n {...{ [CHECKBOX_GROUP_ATTR]: \"\" }}\n {...(name == null ? { [GENERATED_NAME_ATTR]: \"\" } : {})}\n value={option.value}\n {...(isBound\n ? {\n checked: (Array.isArray(answeredValue)\n ? checkedValues\n : (value ?? [])\n ).includes(option.value),\n }\n : { defaultChecked: checkedValues.includes(option.value) })}\n onChange={(e) => {\n const selected = checkedGroupValues(e.currentTarget);\n updateBinding?.(selected);\n fire($action, $dispatch, selected, e.currentTarget);\n }}\n />\n {option.description ? (\n <span data-aui=\"option-content\">\n <span data-aui=\"option-label\">{option.label}</span>\n <span data-aui=\"option-description\">{option.description}</span>\n </span>\n ) : (\n option.label\n )}\n </label>\n ))}\n {children}\n </fieldset>\n );\n}\n\ntype SelectRenderProps = {\n value?: string;\n options: Option[];\n placeholder?: string;\n label?: string;\n name?: string;\n defaultValue?: string;\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction SelectRender({\n value,\n options,\n placeholder,\n label,\n name,\n defaultValue,\n $action,\n $dispatch,\n children,\n}: SelectRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const placeholderText = toTextContent(placeholder);\n const initialValue =\n typeof answeredValue === \"string\"\n ? answeredValue\n : typeof defaultValue === \"string\"\n ? defaultValue\n : \"\";\n return (\n <select\n key={initialValue}\n data-aui=\"select\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n onChange={(e) => {\n updateBinding?.(e.currentTarget.value);\n fire($action, $dispatch, e.currentTarget.value, e.currentTarget);\n }}\n >\n {placeholderText ? (\n <option value=\"\" disabled>\n {placeholderText}\n </option>\n ) : null}\n {mapOptions(options, (option, key) => (\n <option key={key} value={option.value}>\n {option.label}\n </option>\n ))}\n {children}\n </select>\n );\n}\n\ntype InputRenderProps = {\n value?: string;\n inputType?: \"text\" | \"password\" | \"number\";\n placeholder?: string;\n multiline?: boolean;\n label?: string;\n name?: string;\n defaultValue?: string;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction InputRender({\n value,\n inputType,\n placeholder,\n multiline,\n label,\n name,\n defaultValue,\n $action,\n $dispatch,\n}: InputRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialValue =\n typeof answeredValue === \"string\" ? answeredValue : defaultValue;\n const submit = (control: HTMLInputElement | HTMLTextAreaElement) =>\n fire($action, $dispatch, control.value, control);\n return multiline && (inputType === undefined || inputType === \"text\") ? (\n <textarea\n key={initialValue}\n data-aui=\"input\"\n data-aui-multiline\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n placeholder={placeholder}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n onChange={\n updateBinding ? (e) => updateBinding(e.currentTarget.value) : undefined\n }\n onKeyDown={(e) => {\n if (\n e.key !== \"Enter\" ||\n !(e.ctrlKey || e.metaKey) ||\n e.nativeEvent.isComposing\n )\n return;\n if (e.currentTarget.form) {\n e.preventDefault();\n HTMLFormElement.prototype.requestSubmit.call(e.currentTarget.form);\n } else {\n submit(e.currentTarget);\n }\n }}\n />\n ) : (\n <input\n key={initialValue}\n type={inputType}\n step={inputType === \"number\" ? \"any\" : undefined}\n data-aui=\"input\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n placeholder={placeholder}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n onChange={\n updateBinding ? (e) => updateBinding(e.currentTarget.value) : undefined\n }\n onKeyDown={(e) => {\n if (\n e.key === \"Enter\" &&\n !e.nativeEvent.isComposing &&\n !e.currentTarget.form\n )\n submit(e.currentTarget);\n }}\n />\n );\n}\n\ntype DatePickerRenderProps = {\n value?: string;\n min?: string;\n max?: string;\n label?: string;\n name?: string;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction DatePickerRender({\n value,\n min,\n max,\n label,\n name,\n $action,\n $dispatch,\n}: DatePickerRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialValue =\n typeof answeredValue === \"string\" ? answeredValue : value;\n return (\n <input\n key={isBound ? undefined : initialValue}\n type=\"date\"\n data-aui=\"datepicker\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n min={min}\n max={max}\n onChange={(e) => {\n updateBinding?.(e.currentTarget.value);\n fire($action, $dispatch, e.currentTarget.value, e.currentTarget);\n }}\n />\n );\n}\n\ntype CheckboxRenderProps = {\n checked?: boolean;\n label: string;\n name?: string;\n defaultChecked?: boolean;\n variant?: \"checkbox\" | \"switch\";\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction CheckboxRender({\n checked,\n label,\n name,\n defaultChecked,\n variant = \"checkbox\",\n $action,\n $dispatch,\n}: CheckboxRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialChecked =\n typeof answeredValue === \"boolean\" ? answeredValue : defaultChecked;\n return (\n <label\n data-aui=\"checkbox\"\n data-aui-variant={variant === \"switch\" ? variant : undefined}\n >\n <input\n key={String(initialChecked)}\n type=\"checkbox\"\n role={variant === \"switch\" ? \"switch\" : undefined}\n data-aui-action={actionAttr($action)}\n name={name}\n {...(isBound\n ? {\n checked:\n typeof answeredValue === \"boolean\"\n ? answeredValue\n : checked === true,\n }\n : { defaultChecked: initialChecked })}\n onChange={(e) => {\n updateBinding?.(e.currentTarget.checked);\n fire($action, $dispatch, e.currentTarget.checked, e.currentTarget);\n }}\n />\n <span data-aui=\"checkbox-label\">{toTextContent(label)}</span>\n </label>\n );\n}\n\nconst finiteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.min(Math.max(value, min), max);\n\ntype SliderRenderProps = {\n value?: number;\n name?: string;\n label?: string;\n min: number;\n max: number;\n step?: number;\n defaultValue?: number;\n unit?: string;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\ntype SliderControlProps = {\n controlledValue?: number;\n name?: string;\n label?: string;\n min: number;\n max: number;\n step: number;\n initialValue: number;\n unit?: string;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction SliderControl({\n controlledValue,\n name,\n label,\n min,\n max,\n step,\n initialValue,\n unit,\n $action,\n $dispatch,\n}: SliderControlProps) {\n const updateBinding = useA2uiBinding(name);\n const [localValue, setValue] = React.useState(initialValue);\n const value = controlledValue ?? localValue;\n const pointerActive = React.useRef(false);\n const keyboardActive = React.useRef(false);\n const lastCommitted = React.useRef(initialValue);\n const currentValue = (input: HTMLInputElement) =>\n clamp(Number(input.value), min, max);\n const commit = (input: HTMLInputElement) => {\n if (controlledValue !== undefined) return;\n const nextValue = currentValue(input);\n setValue(nextValue);\n if (lastCommitted.current === nextValue) return;\n lastCommitted.current = nextValue;\n fire($action, $dispatch, nextValue, input);\n };\n\n return (\n <label data-aui=\"slider-field\">\n {label ? <span data-aui=\"slider-label\">{label}</span> : null}\n <input\n type=\"range\"\n data-aui=\"slider\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n aria-valuetext={unit ? `${value} ${unit}` : String(value)}\n min={min}\n max={max}\n step={step}\n {...(controlledValue !== undefined\n ? { value }\n : { defaultValue: initialValue })}\n onInput={(e) => {\n const nextValue = currentValue(e.currentTarget);\n if (controlledValue !== undefined) updateBinding?.(nextValue);\n else setValue(nextValue);\n }}\n onPointerDown={() => {\n pointerActive.current = true;\n }}\n onPointerUp={(e) => {\n pointerActive.current = false;\n commit(e.currentTarget);\n }}\n onKeyDown={(e) => {\n keyboardActive.current = [\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"End\",\n \"Home\",\n \"PageDown\",\n \"PageUp\",\n ].includes(e.key);\n }}\n onKeyUp={(e) => {\n if (!keyboardActive.current) return;\n keyboardActive.current = false;\n commit(e.currentTarget);\n }}\n onChange={(e) => {\n if (!pointerActive.current && !keyboardActive.current)\n commit(e.currentTarget);\n }}\n />\n <output data-aui=\"slider-value\">\n {value}\n {unit ? ` ${unit}` : \"\"}\n </output>\n </label>\n );\n}\n\nfunction SliderRender({\n value,\n name,\n label,\n min,\n max,\n step,\n defaultValue,\n unit,\n $action,\n $dispatch,\n}: SliderRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const safeMin = finiteNumber(min) ? min : 0;\n const safeMax = finiteNumber(max) ? Math.max(max, safeMin) : safeMin + 100;\n const safeStep = finiteNumber(step) && step > 0 ? step : 1;\n const defaultNumber = finiteNumber(isBound ? value : defaultValue)\n ? isBound\n ? value!\n : defaultValue!\n : safeMin;\n const initialValue = clamp(\n finiteNumber(answeredValue) ? answeredValue : defaultNumber,\n safeMin,\n safeMax,\n );\n return (\n <SliderControl\n key={`${safeMin}:${safeMax}:${safeStep}:${isBound ? \"bound\" : initialValue}`}\n {...(isBound ? { controlledValue: initialValue } : {})}\n min={safeMin}\n max={safeMax}\n step={safeStep}\n initialValue={initialValue}\n {...(name !== undefined ? { name } : {})}\n {...(label !== undefined ? { label } : {})}\n {...(unit !== undefined ? { unit } : {})}\n {...($action !== undefined ? { $action } : {})}\n {...($dispatch !== undefined ? { $dispatch } : {})}\n />\n );\n}\n\nconst UNDO_WINDOW_SECONDS = 5;\n\ntype ButtonRenderProps = {\n label: string;\n buttonStyle?: (typeof BUTTON_STYLES)[number];\n block?: boolean;\n submit?: boolean;\n undoable?: boolean;\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction ButtonRender({\n label,\n buttonStyle,\n block,\n submit,\n undoable,\n children,\n $action,\n $dispatch,\n}: ButtonRenderProps) {\n const bindings = React.useContext(A2uiBindingContext!)?.fields;\n const bindingsRef = React.useRef(bindings);\n bindingsRef.current = bindings;\n const [remaining, setRemaining] = React.useState<number | undefined>(\n undefined,\n );\n const labelText = String(toTextContent(label) ?? \"\");\n const undoLabel = labelText.trim();\n const pendingAction = React.useRef<\n | {\n $action: Action;\n $dispatch: GenerativeUIDispatch;\n source: HTMLButtonElement;\n }\n | undefined\n >(undefined);\n const canUndo =\n undoable && !submit && $action !== undefined && $dispatch !== undefined;\n\n React.useEffect(() => {\n if (remaining === undefined) return;\n const timer = setTimeout(() => {\n if (remaining > 1) {\n setRemaining(remaining - 1);\n return;\n }\n const action = pendingAction.current;\n pendingAction.current = undefined;\n setRemaining(undefined);\n if (action)\n fire(\n action.$action,\n action.$dispatch,\n undefined,\n action.source,\n bindingsRef.current,\n );\n }, 1_000);\n return () => clearTimeout(timer);\n }, [remaining]);\n\n const cancelUndo = () => {\n pendingAction.current = undefined;\n setRemaining(undefined);\n };\n\n return (\n <button\n type={submit ? \"submit\" : \"button\"}\n data-aui=\"button\"\n data-aui-style={buttonStyle}\n data-aui-block={block || undefined}\n data-aui-submit={submit || undefined}\n data-aui-state={remaining === undefined ? undefined : \"pending\"}\n data-aui-action={actionAttr($action)}\n aria-label={\n remaining === undefined\n ? undefined\n : undoLabel\n ? `Undo ${undoLabel}`\n : \"Undo\"\n }\n onClick={\n submit\n ? undefined\n : canUndo\n ? (e) => {\n if (remaining !== undefined) {\n cancelUndo();\n return;\n }\n pendingAction.current = {\n $action,\n $dispatch,\n source: e.currentTarget,\n };\n setRemaining(UNDO_WINDOW_SECONDS);\n }\n : (e) =>\n fire($action, $dispatch, undefined, e.currentTarget, bindings)\n }\n onKeyDown={\n canUndo\n ? (e) => {\n if (e.key !== \"Escape\" || remaining === undefined) return;\n e.preventDefault();\n cancelUndo();\n }\n : undefined\n }\n >\n {remaining === undefined ? (\n <>\n {labelText}\n {children}\n </>\n ) : (\n <>\n Undo <span data-aui=\"button-countdown\">{remaining}</span>\n <span data-aui=\"button-undo-status\" role=\"status\">\n {labelText} in {UNDO_WINDOW_SECONDS} seconds\n </span>\n </>\n )}\n </button>\n );\n}\n\nexport const interactiveVocabulary = {\n Button: {\n description:\n \"A clickable button. Carries `$action` describing the side effect or resume value. Set `submit` to submit an ancestor Form/Card instead of firing `$action` on click.\",\n properties: z.object({\n label: z.string().describe(\"Button label.\"),\n buttonStyle: z.enum(BUTTON_STYLES).optional().describe(\"Visual style.\"),\n block: z\n .boolean()\n .optional()\n .describe(\"Whether the button spans the full width.\"),\n submit: z\n .boolean()\n .optional()\n .describe(\n \"Render as a submit button for an ancestor Form/Card instead of a click button.\",\n ),\n undoable: z\n .boolean()\n .optional()\n .describe(\n \"Delay the action with an undo control, for sends and other hard-to-reverse actions.\",\n ),\n }),\n render: ButtonRender,\n },\n Select: {\n description:\n \"A dropdown selector. Carries `$action` describing the on-select behavior.\",\n properties: z.object({\n options: z.array(optionSchema).describe(\"Selectable options.\"),\n placeholder: z\n .string()\n .optional()\n .describe(\"Placeholder shown when nothing is selected.\"),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n defaultValue: z.string().optional().describe(\"Initially selected value.\"),\n }),\n render: SelectRender,\n },\n Input: {\n description:\n \"A text input. Carries `$action` describing the on-submit behavior.\",\n properties: z.object({\n inputType: z\n .enum([\"text\", \"password\", \"number\"])\n .optional()\n .describe(\"Single-line input type. Values remain strings.\"),\n placeholder: z.string().optional().describe(\"Placeholder text.\"),\n multiline: z\n .boolean()\n .optional()\n .describe(\n 'Render a textarea instead of a single-line input; ignored when `inputType` is `\"password\"` or `\"number\"`.',\n ),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n defaultValue: z.string().optional().describe(\"Initial text.\"),\n }),\n render: InputRender,\n },\n DatePicker: {\n description:\n \"A date input. Carries `$action` describing the on-select behavior.\",\n properties: z.object({\n value: z.string().optional().describe(\"Initial date (YYYY-MM-DD).\"),\n min: z.string().optional().describe(\"Minimum date (YYYY-MM-DD).\"),\n max: z.string().optional().describe(\"Maximum date (YYYY-MM-DD).\"),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n }),\n render: DatePickerRender,\n },\n Checkbox: {\n description:\n \"A checkbox with a label. Carries `$action` describing the on-change behavior.\",\n properties: z.object({\n label: z.string().describe(\"Label text next to the checkbox.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n defaultChecked: z\n .boolean()\n .optional()\n .describe(\"Whether the checkbox starts checked.\"),\n variant: z\n .enum([\"checkbox\", \"switch\"])\n .optional()\n .describe(\"Whether to render a checkbox or switch.\"),\n }),\n render: CheckboxRender,\n },\n Slider: {\n description:\n \"A numeric range control. Carries `$action` describing the committed value.\",\n properties: z.object({\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n min: z.number().describe(\"Minimum value.\"),\n max: z.number().describe(\"Maximum value.\"),\n step: z.number().optional().describe(\"Value increment. Defaults to 1.\"),\n defaultValue: z.number().optional().describe(\"Initial value.\"),\n unit: z.string().optional().describe(\"Unit shown with the value.\"),\n }),\n render: SliderRender,\n },\n RadioGroup: {\n description:\n \"A group of mutually exclusive radio options. Carries `$action` describing the on-change behavior.\",\n properties: z.object({\n options: z.array(describedOptionSchema).describe(\"Selectable options.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n label: z.string().optional().describe(\"Accessible name for the group.\"),\n defaultValue: z.string().optional().describe(\"Initially selected value.\"),\n }),\n render: RadioGroupRender,\n },\n CheckboxGroup: {\n description:\n \"A group of checkbox options where any number can be checked. Carries `$action` describing the on-change behavior.\",\n properties: z.object({\n options: z.array(describedOptionSchema).describe(\"Selectable options.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n label: z.string().optional().describe(\"Accessible name for the group.\"),\n defaultValue: z\n .array(z.string())\n .optional()\n .describe(\"Initially checked values.\"),\n }),\n render: CheckboxGroupRender,\n },\n} satisfies GenerativeUILibrary;\n"],"mappings":"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"}
1
+ {"version":3,"file":"interactive.js","names":[],"sources":["../../src/vocabulary/interactive.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { z } from \"zod\";\nimport {\n CHECKBOX_GROUP_ATTR,\n FIELD_NAME_ATTR,\n FIELD_VALUE_ATTR,\n GENERATED_NAME_ATTR,\n} from \"../constants\";\nimport type { Action } from \"../ir\";\nimport { BUTTON_STYLES } from \"../ir\";\nimport type {\n GenerativeUIDispatch,\n GenerativeUILibrary,\n GenerativeUIStatus,\n} from \"../types\";\nimport { A2uiBindingContext, useA2uiBinding } from \"../a2ui/BindingContext\";\nimport { useAnsweredValue } from \"../answeredValues\";\nimport { actionAttr, fire } from \"./dispatch\";\nimport { toTextContent } from \"./toTextContent\";\nimport { useRadioGroupName } from \"../RadioGroupScope\";\nimport {\n classifyTemporal,\n fromLocalDateTime,\n getTemporalInputStep,\n normalizeTemporalInputValue,\n toLocalDateTime,\n toPickerLocalDateTime,\n} from \"../temporal\";\n\nconst optionSchema = z.object({\n label: z.string(),\n value: z.string(),\n});\n\nconst describedOptionSchema = optionSchema.extend({\n description: z.string().optional(),\n});\n\ntype Option = { label: string; description?: string; value: string };\n\nconst isOption = (option: unknown): option is Option =>\n option !== null &&\n typeof option === \"object\" &&\n \"label\" in option &&\n typeof option.label === \"string\" &&\n (!(\"description\" in option) || typeof option.description === \"string\") &&\n \"value\" in option &&\n typeof option.value === \"string\";\n\nconst mapOptions = (\n options: unknown,\n render: (option: Option, key: string) => React.ReactNode,\n) => {\n const occurrences = new Map<string, number>();\n return (Array.isArray(options) ? options : []).map((option) => {\n if (!isOption(option)) return null;\n const occurrence = occurrences.get(option.value) ?? 0;\n occurrences.set(option.value, occurrence + 1);\n return render(option, JSON.stringify([option.value, occurrence]));\n });\n};\n\ntype RadioGroupRenderProps = {\n value?: string;\n options: Option[];\n name?: string;\n label?: string;\n defaultValue?: string;\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction RadioGroupRender({\n value,\n options,\n name,\n label,\n defaultValue,\n children,\n $action,\n $dispatch,\n}: RadioGroupRenderProps) {\n const groupName = useRadioGroupName(name);\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialValue =\n typeof answeredValue === \"string\" ? answeredValue : defaultValue;\n return (\n <fieldset\n key={initialValue}\n data-aui=\"radiogroup\"\n data-aui-action={actionAttr($action)}\n aria-label={label}\n >\n {mapOptions(options, (option, key) => (\n <label key={key} data-aui=\"radiogroup-option\">\n <input\n type=\"radio\"\n name={groupName}\n {...{ [FIELD_NAME_ATTR]: name }}\n {...(name == null ? { [GENERATED_NAME_ATTR]: \"\" } : {})}\n value={option.value}\n {...(isBound\n ? { checked: (answeredValue ?? value) === option.value }\n : { defaultChecked: initialValue === option.value })}\n onChange={(e) => {\n updateBinding?.(option.value);\n fire($action, $dispatch, option.value, e.currentTarget);\n }}\n />\n {option.description ? (\n <span data-aui=\"option-content\">\n <span data-aui=\"option-label\">{option.label}</span>\n <span data-aui=\"option-description\">{option.description}</span>\n </span>\n ) : (\n option.label\n )}\n </label>\n ))}\n {children}\n </fieldset>\n );\n}\n\ntype CheckboxGroupRenderProps = {\n value?: string[];\n options: Option[];\n name?: string;\n label?: string;\n defaultValue?: string[];\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nconst checkedGroupValues = (input: HTMLInputElement): string[] =>\n Array.from(\n input\n .closest(\"fieldset\")\n ?.querySelectorAll<HTMLInputElement>(\n `:scope > label > input[${CHECKBOX_GROUP_ATTR}]:checked`,\n ) ?? [],\n (checkbox) => checkbox.value,\n );\n\nfunction CheckboxGroupRender({\n value,\n options,\n name,\n label,\n defaultValue,\n children,\n $action,\n $dispatch,\n}: CheckboxGroupRenderProps) {\n const generatedName = React.useId();\n const fieldName = name ?? generatedName;\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const checkedValues =\n Array.isArray(answeredValue) &&\n answeredValue.every((value): value is string => typeof value === \"string\")\n ? answeredValue\n : Array.isArray(defaultValue)\n ? defaultValue\n : [];\n return (\n <fieldset\n key={JSON.stringify(checkedValues)}\n data-aui=\"checkboxgroup\"\n data-aui-action={actionAttr($action)}\n aria-label={label}\n >\n {mapOptions(options, (option, key) => (\n <label key={key} data-aui=\"checkboxgroup-option\">\n <input\n type=\"checkbox\"\n name={fieldName}\n {...{ [CHECKBOX_GROUP_ATTR]: \"\" }}\n {...(name == null ? { [GENERATED_NAME_ATTR]: \"\" } : {})}\n value={option.value}\n {...(isBound\n ? {\n checked: (Array.isArray(answeredValue)\n ? checkedValues\n : (value ?? [])\n ).includes(option.value),\n }\n : { defaultChecked: checkedValues.includes(option.value) })}\n onChange={(e) => {\n const selected = checkedGroupValues(e.currentTarget);\n updateBinding?.(selected);\n fire($action, $dispatch, selected, e.currentTarget);\n }}\n />\n {option.description ? (\n <span data-aui=\"option-content\">\n <span data-aui=\"option-label\">{option.label}</span>\n <span data-aui=\"option-description\">{option.description}</span>\n </span>\n ) : (\n option.label\n )}\n </label>\n ))}\n {children}\n </fieldset>\n );\n}\n\ntype SelectRenderProps = {\n value?: string;\n options: Option[];\n placeholder?: string;\n label?: string;\n name?: string;\n defaultValue?: string;\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction SelectRender({\n value,\n options,\n placeholder,\n label,\n name,\n defaultValue,\n $action,\n $dispatch,\n children,\n}: SelectRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const placeholderText = toTextContent(placeholder);\n const initialValue =\n typeof answeredValue === \"string\"\n ? answeredValue\n : typeof defaultValue === \"string\"\n ? defaultValue\n : \"\";\n return (\n <select\n key={initialValue}\n data-aui=\"select\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n onChange={(e) => {\n updateBinding?.(e.currentTarget.value);\n fire($action, $dispatch, e.currentTarget.value, e.currentTarget);\n }}\n >\n {placeholderText ? (\n <option value=\"\" disabled>\n {placeholderText}\n </option>\n ) : null}\n {mapOptions(options, (option, key) => (\n <option key={key} value={option.value}>\n {option.label}\n </option>\n ))}\n {children}\n </select>\n );\n}\n\ntype InputRenderProps = {\n value?: string;\n inputType?: \"text\" | \"password\" | \"number\";\n placeholder?: string;\n multiline?: boolean;\n label?: string;\n name?: string;\n defaultValue?: string;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction InputRender({\n value,\n inputType,\n placeholder,\n multiline,\n label,\n name,\n defaultValue,\n $action,\n $dispatch,\n}: InputRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialValue =\n typeof answeredValue === \"string\" ? answeredValue : defaultValue;\n const submit = (control: HTMLInputElement | HTMLTextAreaElement) =>\n fire($action, $dispatch, control.value, control);\n return multiline && (inputType === undefined || inputType === \"text\") ? (\n <textarea\n key={initialValue}\n data-aui=\"input\"\n data-aui-multiline\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n placeholder={placeholder}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n onChange={\n updateBinding ? (e) => updateBinding(e.currentTarget.value) : undefined\n }\n onKeyDown={(e) => {\n if (\n e.key !== \"Enter\" ||\n !(e.ctrlKey || e.metaKey) ||\n e.nativeEvent.isComposing\n )\n return;\n if (e.currentTarget.form) {\n e.preventDefault();\n HTMLFormElement.prototype.requestSubmit.call(e.currentTarget.form);\n } else {\n submit(e.currentTarget);\n }\n }}\n />\n ) : (\n <input\n key={initialValue}\n type={inputType}\n step={inputType === \"number\" ? \"any\" : undefined}\n data-aui=\"input\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n placeholder={placeholder}\n {...(isBound\n ? {\n value:\n typeof answeredValue === \"string\" ? answeredValue : (value ?? \"\"),\n }\n : { defaultValue: initialValue })}\n onChange={\n updateBinding ? (e) => updateBinding(e.currentTarget.value) : undefined\n }\n onKeyDown={(e) => {\n if (\n e.key === \"Enter\" &&\n !e.nativeEvent.isComposing &&\n !e.currentTarget.form\n )\n submit(e.currentTarget);\n }}\n />\n );\n}\n\ntype DatePickerRenderProps = {\n inputType?: \"date\" | \"datetime\" | \"time\";\n value?: string;\n min?: string;\n max?: string;\n label?: string;\n name?: string;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nconst subscribeToHydration = () => () => {};\nconst clientHydrationSnapshot = () => true;\nconst serverHydrationSnapshot = () => false;\n\nfunction DatePickerRender({\n inputType = \"date\",\n value,\n min,\n max,\n label,\n name,\n $action,\n $dispatch,\n}: DatePickerRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialValue =\n typeof answeredValue === \"string\" ? answeredValue : value;\n const [selection, setSelection] = React.useState({\n initialValue,\n value: initialValue,\n anchor: initialValue,\n committedValue: initialValue,\n edited: false,\n });\n if (selection.initialValue !== initialValue) {\n const isEcho = isBound && initialValue === selection.value;\n setSelection({\n initialValue,\n value: initialValue,\n anchor: isEcho ? selection.anchor : initialValue,\n committedValue: isEcho ? selection.committedValue : initialValue,\n edited: isEcho && selection.edited,\n });\n }\n const currentValue = isBound ? initialValue : selection.value;\n const temporal = classifyTemporal(currentValue ?? \"\");\n const anchor = classifyTemporal(selection.anchor ?? \"\");\n const hasInstantAnchor =\n inputType === \"datetime\" && anchor.kind === \"instant\";\n const canonicalFieldValue = (value: string | undefined) => {\n const current = value ?? \"\";\n const kind = classifyTemporal(current).kind;\n if (inputType === \"time\")\n return kind === \"time\" && normalizeTemporalInputValue(current) !== current\n ? value\n : undefined;\n if (inputType !== \"datetime\") return undefined;\n if (kind === \"instant\") return value;\n if (hasInstantAnchor) return selection.anchor;\n return kind === \"floating\" &&\n normalizeTemporalInputValue(current) !== current\n ? value\n : undefined;\n };\n const minimum = classifyTemporal(min ?? \"\");\n const maximum = classifyTemporal(max ?? \"\");\n const hydrated = React.useSyncExternalStore(\n subscribeToHydration,\n clientHydrationSnapshot,\n serverHydrationSnapshot,\n );\n const showRawValue =\n inputType === \"datetime\" && temporal.kind === \"instant\" && !hydrated;\n const displayValue =\n currentValue === undefined\n ? undefined\n : inputType === \"datetime\" && hydrated\n ? toPickerLocalDateTime(currentValue)\n : normalizeTemporalInputValue(currentValue);\n const keyboardActive = React.useRef(false);\n const valueFromInput = (input: HTMLInputElement) => {\n const inputValue = normalizeTemporalInputValue(input.value);\n return inputType === \"datetime\"\n ? fromLocalDateTime(inputValue, selection.anchor)\n : inputValue;\n };\n const commit = (input: HTMLInputElement) => {\n if (!selection.edited) return;\n const nextValue = valueFromInput(input);\n setSelection({ ...selection, committedValue: nextValue, edited: false });\n if (nextValue !== selection.committedValue)\n fire($action, $dispatch, nextValue, input);\n };\n return (\n <input\n key={isBound ? undefined : initialValue}\n type={\n showRawValue\n ? \"text\"\n : inputType === \"datetime\"\n ? \"datetime-local\"\n : inputType\n }\n readOnly={showRawValue || undefined}\n data-aui=\"datepicker\"\n data-aui-action={actionAttr($action)}\n {...{\n [FIELD_VALUE_ATTR]: canonicalFieldValue(currentValue),\n }}\n name={name}\n aria-label={label}\n {...(isBound || inputType === \"datetime\"\n ? { value: displayValue ?? \"\" }\n : { defaultValue: displayValue })}\n min={\n inputType === \"datetime\" && hydrated && min !== undefined\n ? normalizeTemporalInputValue(\n toLocalDateTime(\n min,\n minimum.kind === \"instant\" ? minimum.precision : undefined,\n ),\n )\n : min === undefined\n ? undefined\n : normalizeTemporalInputValue(min)\n }\n max={\n inputType === \"datetime\" && hydrated && max !== undefined\n ? normalizeTemporalInputValue(\n toLocalDateTime(\n max,\n maximum.kind === \"instant\" ? maximum.precision : undefined,\n ),\n )\n : max === undefined\n ? undefined\n : normalizeTemporalInputValue(max)\n }\n step={\n inputType !== \"date\"\n ? getTemporalInputStep(\n selection.anchor,\n hasInstantAnchor ? displayValue : currentValue,\n min,\n max,\n )\n : undefined\n }\n onChange={(e) => {\n const nextValue = valueFromInput(e.currentTarget);\n const canonical = canonicalFieldValue(nextValue);\n if (canonical !== undefined) {\n e.currentTarget.setAttribute(FIELD_VALUE_ATTR, canonical);\n } else {\n e.currentTarget.removeAttribute(FIELD_VALUE_ATTR);\n }\n // A change without an editing key down is a pick from the native picker, which commits at once; a typed value waits for blur or Enter.\n const typed = keyboardActive.current;\n keyboardActive.current = false;\n setSelection({\n initialValue,\n value: nextValue,\n anchor: selection.anchor,\n committedValue: typed ? selection.committedValue : nextValue,\n edited: typed,\n });\n updateBinding?.(nextValue);\n if (!typed && nextValue !== selection.committedValue)\n fire($action, $dispatch, nextValue, e.currentTarget);\n }}\n onBlur={(e) => {\n keyboardActive.current = false;\n commit(e.currentTarget);\n }}\n onKeyDown={(e) => {\n if (\n e.key === \"Enter\" &&\n !e.nativeEvent.isComposing &&\n !e.currentTarget.form\n ) {\n commit(e.currentTarget);\n return;\n }\n keyboardActive.current =\n !e.altKey &&\n !e.ctrlKey &&\n !e.metaKey &&\n (e.key.length === 1 ||\n [\n \"ArrowDown\",\n \"ArrowUp\",\n \"Backspace\",\n \"Delete\",\n \"End\",\n \"Home\",\n \"PageDown\",\n \"PageUp\",\n ].includes(e.key));\n }}\n onKeyUp={() => {\n keyboardActive.current = false;\n }}\n onPaste={() => {\n keyboardActive.current = true;\n }}\n onCut={() => {\n keyboardActive.current = true;\n }}\n />\n );\n}\n\ntype CheckboxRenderProps = {\n checked?: boolean;\n label: string;\n name?: string;\n defaultChecked?: boolean;\n variant?: \"checkbox\" | \"switch\";\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction CheckboxRender({\n checked,\n label,\n name,\n defaultChecked,\n variant = \"checkbox\",\n $action,\n $dispatch,\n}: CheckboxRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const initialChecked =\n typeof answeredValue === \"boolean\" ? answeredValue : defaultChecked;\n return (\n <label\n data-aui=\"checkbox\"\n data-aui-variant={variant === \"switch\" ? variant : undefined}\n >\n <input\n key={String(initialChecked)}\n type=\"checkbox\"\n role={variant === \"switch\" ? \"switch\" : undefined}\n data-aui-action={actionAttr($action)}\n name={name}\n {...(isBound\n ? {\n checked:\n typeof answeredValue === \"boolean\"\n ? answeredValue\n : checked === true,\n }\n : { defaultChecked: initialChecked })}\n onChange={(e) => {\n updateBinding?.(e.currentTarget.checked);\n fire($action, $dispatch, e.currentTarget.checked, e.currentTarget);\n }}\n />\n <span data-aui=\"checkbox-label\">{toTextContent(label)}</span>\n </label>\n );\n}\n\nconst finiteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.min(Math.max(value, min), max);\n\ntype SliderRenderProps = {\n value?: number;\n name?: string;\n label?: string;\n min: number;\n max: number;\n step?: number;\n defaultValue?: number;\n unit?: string;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\ntype SliderControlProps = {\n controlledValue?: number;\n name?: string;\n label?: string;\n min: number;\n max: number;\n step: number;\n initialValue: number;\n unit?: string;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction SliderControl({\n controlledValue,\n name,\n label,\n min,\n max,\n step,\n initialValue,\n unit,\n $action,\n $dispatch,\n}: SliderControlProps) {\n const updateBinding = useA2uiBinding(name);\n const [localValue, setValue] = React.useState(initialValue);\n const value = controlledValue ?? localValue;\n const pointerActive = React.useRef(false);\n const keyboardActive = React.useRef(false);\n const lastCommitted = React.useRef(initialValue);\n const currentValue = (input: HTMLInputElement) =>\n clamp(Number(input.value), min, max);\n const commit = (input: HTMLInputElement) => {\n if (controlledValue !== undefined) return;\n const nextValue = currentValue(input);\n setValue(nextValue);\n if (lastCommitted.current === nextValue) return;\n lastCommitted.current = nextValue;\n fire($action, $dispatch, nextValue, input);\n };\n\n return (\n <label data-aui=\"slider-field\">\n {label ? <span data-aui=\"slider-label\">{label}</span> : null}\n <input\n type=\"range\"\n data-aui=\"slider\"\n data-aui-action={actionAttr($action)}\n name={name}\n aria-label={label}\n aria-valuetext={unit ? `${value} ${unit}` : String(value)}\n min={min}\n max={max}\n step={step}\n {...(controlledValue !== undefined\n ? { value }\n : { defaultValue: initialValue })}\n onInput={(e) => {\n const nextValue = currentValue(e.currentTarget);\n if (controlledValue !== undefined) updateBinding?.(nextValue);\n else setValue(nextValue);\n }}\n onPointerDown={() => {\n pointerActive.current = true;\n }}\n onPointerUp={(e) => {\n pointerActive.current = false;\n commit(e.currentTarget);\n }}\n onKeyDown={(e) => {\n keyboardActive.current = [\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"End\",\n \"Home\",\n \"PageDown\",\n \"PageUp\",\n ].includes(e.key);\n }}\n onKeyUp={(e) => {\n if (!keyboardActive.current) return;\n keyboardActive.current = false;\n commit(e.currentTarget);\n }}\n onChange={(e) => {\n if (!pointerActive.current && !keyboardActive.current)\n commit(e.currentTarget);\n }}\n />\n <output data-aui=\"slider-value\">\n {value}\n {unit ? ` ${unit}` : \"\"}\n </output>\n </label>\n );\n}\n\nfunction SliderRender({\n value,\n name,\n label,\n min,\n max,\n step,\n defaultValue,\n unit,\n $action,\n $dispatch,\n}: SliderRenderProps) {\n const answeredValue = useAnsweredValue(name);\n const updateBinding = useA2uiBinding(name);\n const isBound = updateBinding !== undefined;\n const safeMin = finiteNumber(min) ? min : 0;\n const safeMax = finiteNumber(max) ? Math.max(max, safeMin) : safeMin + 100;\n const safeStep = finiteNumber(step) && step > 0 ? step : 1;\n const defaultNumber = finiteNumber(isBound ? value : defaultValue)\n ? isBound\n ? value!\n : defaultValue!\n : safeMin;\n const initialValue = clamp(\n finiteNumber(answeredValue) ? answeredValue : defaultNumber,\n safeMin,\n safeMax,\n );\n return (\n <SliderControl\n key={`${safeMin}:${safeMax}:${safeStep}:${isBound ? \"bound\" : initialValue}`}\n {...(isBound ? { controlledValue: initialValue } : {})}\n min={safeMin}\n max={safeMax}\n step={safeStep}\n initialValue={initialValue}\n {...(name !== undefined ? { name } : {})}\n {...(label !== undefined ? { label } : {})}\n {...(unit !== undefined ? { unit } : {})}\n {...($action !== undefined ? { $action } : {})}\n {...($dispatch !== undefined ? { $dispatch } : {})}\n />\n );\n}\n\nconst UNDO_WINDOW_SECONDS = 5;\n\ntype ButtonRenderProps = {\n label: string;\n buttonStyle?: (typeof BUTTON_STYLES)[number];\n block?: boolean;\n submit?: boolean;\n undoable?: boolean;\n children?: React.ReactNode;\n $status: GenerativeUIStatus;\n $action?: Action;\n $dispatch?: GenerativeUIDispatch;\n};\n\nfunction ButtonRender({\n label,\n buttonStyle,\n block,\n submit,\n undoable,\n children,\n $action,\n $dispatch,\n}: ButtonRenderProps) {\n const bindings = React.useContext(A2uiBindingContext!)?.fields;\n const bindingsRef = React.useRef(bindings);\n bindingsRef.current = bindings;\n const [remaining, setRemaining] = React.useState<number | undefined>(\n undefined,\n );\n const labelText = String(toTextContent(label) ?? \"\");\n const undoLabel = labelText.trim();\n const pendingAction = React.useRef<\n | {\n $action: Action;\n $dispatch: GenerativeUIDispatch;\n source: HTMLButtonElement;\n }\n | undefined\n >(undefined);\n const canUndo =\n undoable && !submit && $action !== undefined && $dispatch !== undefined;\n\n React.useEffect(() => {\n if (remaining === undefined) return;\n const timer = setTimeout(() => {\n if (remaining > 1) {\n setRemaining(remaining - 1);\n return;\n }\n const action = pendingAction.current;\n pendingAction.current = undefined;\n setRemaining(undefined);\n if (action)\n fire(\n action.$action,\n action.$dispatch,\n undefined,\n action.source,\n bindingsRef.current,\n );\n }, 1_000);\n return () => clearTimeout(timer);\n }, [remaining]);\n\n const cancelUndo = () => {\n pendingAction.current = undefined;\n setRemaining(undefined);\n };\n\n return (\n <button\n type={submit ? \"submit\" : \"button\"}\n data-aui=\"button\"\n data-aui-style={buttonStyle}\n data-aui-block={block || undefined}\n data-aui-submit={submit || undefined}\n data-aui-state={remaining === undefined ? undefined : \"pending\"}\n data-aui-action={actionAttr($action)}\n aria-label={\n remaining === undefined\n ? undefined\n : undoLabel\n ? `Undo ${undoLabel}`\n : \"Undo\"\n }\n onClick={\n submit\n ? undefined\n : canUndo\n ? (e) => {\n if (remaining !== undefined) {\n cancelUndo();\n return;\n }\n pendingAction.current = {\n $action,\n $dispatch,\n source: e.currentTarget,\n };\n setRemaining(UNDO_WINDOW_SECONDS);\n }\n : (e) =>\n fire($action, $dispatch, undefined, e.currentTarget, bindings)\n }\n onKeyDown={\n canUndo\n ? (e) => {\n if (e.key !== \"Escape\" || remaining === undefined) return;\n e.preventDefault();\n cancelUndo();\n }\n : undefined\n }\n >\n {remaining === undefined ? (\n <>\n {labelText}\n {children}\n </>\n ) : (\n <>\n Undo <span data-aui=\"button-countdown\">{remaining}</span>\n <span data-aui=\"button-undo-status\" role=\"status\">\n {labelText} in {UNDO_WINDOW_SECONDS} seconds\n </span>\n </>\n )}\n </button>\n );\n}\n\nexport const interactiveVocabulary = {\n Button: {\n description:\n \"A clickable button. Carries `$action` describing the side effect or resume value. Set `submit` to submit an ancestor Form/Card instead of firing `$action` on click.\",\n properties: z.object({\n label: z.string().describe(\"Button label.\"),\n buttonStyle: z.enum(BUTTON_STYLES).optional().describe(\"Visual style.\"),\n block: z\n .boolean()\n .optional()\n .describe(\"Whether the button spans the full width.\"),\n submit: z\n .boolean()\n .optional()\n .describe(\n \"Render as a submit button for an ancestor Form/Card instead of a click button.\",\n ),\n undoable: z\n .boolean()\n .optional()\n .describe(\n \"Delay the action with an undo control, for sends and other hard-to-reverse actions.\",\n ),\n }),\n render: ButtonRender,\n },\n Select: {\n description:\n \"A dropdown selector. Carries `$action` describing the on-select behavior.\",\n properties: z.object({\n options: z.array(optionSchema).describe(\"Selectable options.\"),\n placeholder: z\n .string()\n .optional()\n .describe(\"Placeholder shown when nothing is selected.\"),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n defaultValue: z.string().optional().describe(\"Initially selected value.\"),\n }),\n render: SelectRender,\n },\n Input: {\n description:\n \"A text input. Carries `$action` describing the on-submit behavior.\",\n properties: z.object({\n inputType: z\n .enum([\"text\", \"password\", \"number\"])\n .optional()\n .describe(\"Single-line input type. Values remain strings.\"),\n placeholder: z.string().optional().describe(\"Placeholder text.\"),\n multiline: z\n .boolean()\n .optional()\n .describe(\n 'Render a textarea instead of a single-line input; ignored when `inputType` is `\"password\"` or `\"number\"`.',\n ),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n defaultValue: z.string().optional().describe(\"Initial text.\"),\n }),\n render: InputRender,\n },\n DatePicker: {\n description:\n \"A date, datetime, or time input. Carries `$action`, which runs once per committed value: a pick from the picker, or a typed value on blur or Enter.\",\n properties: z.object({\n inputType: z\n .enum([\"date\", \"datetime\", \"time\"])\n .optional()\n .describe(\n 'Temporal input type. Defaults to \"date\". Values remain strings.',\n ),\n value: z\n .string()\n .optional()\n .describe(\n \"Initial value: YYYY-MM-DD for date, HH:mm or HH:mm:ss with optional fraction of at most 9 digits for time, YYYY-MM-DDTHH:mm with optional :ss and fraction of at most 9 digits for datetime. A datetime with Z or ±HH:mm is an instant, displayed in the viewer's time zone and submitted with the same offset and precision. A datetime without an offset is local and submitted unchanged. An empty datetime submits with the viewer's offset and seconds.\",\n ),\n min: z\n .string()\n .optional()\n .describe(\n \"Minimum value: YYYY-MM-DD for date, HH:mm or HH:mm:ss with optional fraction of at most 9 digits for time, YYYY-MM-DDTHH:mm with optional :ss and fraction of at most 9 digits for datetime. Datetimes with Z or ±HH:mm are converted to the viewer's time zone.\",\n ),\n max: z\n .string()\n .optional()\n .describe(\n \"Maximum value: YYYY-MM-DD for date, HH:mm or HH:mm:ss with optional fraction of at most 9 digits for time, YYYY-MM-DDTHH:mm with optional :ss and fraction of at most 9 digits for datetime. Datetimes with Z or ±HH:mm are converted to the viewer's time zone.\",\n ),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n }),\n render: DatePickerRender,\n },\n Checkbox: {\n description:\n \"A checkbox with a label. Carries `$action` describing the on-change behavior.\",\n properties: z.object({\n label: z.string().describe(\"Label text next to the checkbox.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n defaultChecked: z\n .boolean()\n .optional()\n .describe(\"Whether the checkbox starts checked.\"),\n variant: z\n .enum([\"checkbox\", \"switch\"])\n .optional()\n .describe(\"Whether to render a checkbox or switch.\"),\n }),\n render: CheckboxRender,\n },\n Slider: {\n description:\n \"A numeric range control. Carries `$action` describing the committed value.\",\n properties: z.object({\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n label: z\n .string()\n .optional()\n .describe(\"Accessible label for the control.\"),\n min: z.number().describe(\"Minimum value.\"),\n max: z.number().describe(\"Maximum value.\"),\n step: z.number().optional().describe(\"Value increment. Defaults to 1.\"),\n defaultValue: z.number().optional().describe(\"Initial value.\"),\n unit: z.string().optional().describe(\"Unit shown with the value.\"),\n }),\n render: SliderRender,\n },\n RadioGroup: {\n description:\n \"A group of mutually exclusive radio options. Carries `$action` describing the on-change behavior.\",\n properties: z.object({\n options: z.array(describedOptionSchema).describe(\"Selectable options.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n label: z.string().optional().describe(\"Accessible name for the group.\"),\n defaultValue: z.string().optional().describe(\"Initially selected value.\"),\n }),\n render: RadioGroupRender,\n },\n CheckboxGroup: {\n description:\n \"A group of checkbox options where any number can be checked. Carries `$action` describing the on-change behavior.\",\n properties: z.object({\n options: z.array(describedOptionSchema).describe(\"Selectable options.\"),\n name: z.string().optional().describe(\"Field name used inside a Form.\"),\n label: z.string().optional().describe(\"Accessible name for the group.\"),\n defaultValue: z\n .array(z.string())\n .optional()\n .describe(\"Initially checked values.\"),\n }),\n render: CheckboxGroupRender,\n },\n} satisfies GenerativeUILibrary;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-generative-ui",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Generative UI components for assistant-ui",
5
5
  "keywords": [
6
6
  "generative-ui",
@@ -51,7 +51,7 @@
51
51
  "sideEffects": false,
52
52
  "dependencies": {
53
53
  "@types/json-schema": "^7.0.15",
54
- "assistant-stream": "^0.3.46"
54
+ "assistant-stream": "^0.3.48"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "@assistant-ui/react": "^0.15.0",
@@ -65,14 +65,14 @@
65
65
  }
66
66
  },
67
67
  "devDependencies": {
68
- "@assistant-ui/react": "0.15.23",
69
- "@assistant-ui/x-buildutils": "0.0.29",
68
+ "@assistant-ui/react": "0.15.25",
69
+ "@assistant-ui/x-buildutils": "0.0.30",
70
70
  "@assistant-ui/x-react18": "0.0.0",
71
71
  "@types/react": "^19.3.0",
72
72
  "jsdom": "^30.0.1",
73
73
  "react": "^19.3.0",
74
74
  "react-dom": "^19.3.0",
75
- "vitest": "^5.0.1",
75
+ "vitest": "^5.0.3",
76
76
  "zod": "^4.6.5"
77
77
  },
78
78
  "publishConfig": {
@@ -91,6 +91,7 @@
91
91
  "scripts": {
92
92
  "build": "aui-build",
93
93
  "test": "vitest run",
94
+ "test:coverage": "vitest run --coverage --coverage.reporter=text --coverage.reporter=html --coverage.reporter=json-summary",
94
95
  "typecheck": "tsc --noEmit",
95
96
  "test:peer-react18": "vitest run --config vitest.peer-react18.config.ts",
96
97
  "test:types:peer-react18": "aui-react18-types",
@@ -459,6 +459,7 @@ describe("convertSurfaceToUISpec", () => {
459
459
  },
460
460
  {
461
461
  $type: "DatePicker",
462
+ inputType: "date",
462
463
  value: "2026-06-01",
463
464
  min: "2026-01-01",
464
465
  max: "2026-12-31",
@@ -609,22 +610,44 @@ describe("convertSurfaceToUISpec", () => {
609
610
  );
610
611
 
611
612
  it.each([
612
- { mode: {}, value: "2025-12-15", type: "DatePicker" },
613
+ { mode: {}, value: "2025-12-15", type: "DatePicker", inputType: "date" },
613
614
  {
614
615
  mode: { enableDate: false, enableTime: false },
615
616
  value: "2025-12-15",
616
617
  type: "DatePicker",
618
+ inputType: "date",
619
+ },
620
+ {
621
+ mode: { enableDate: true },
622
+ value: "2025-12-15",
623
+ type: "DatePicker",
624
+ inputType: "date",
617
625
  },
618
- { mode: { enableDate: true }, value: "2025-12-15", type: "DatePicker" },
619
626
  {
620
627
  mode: { enableDate: true, enableTime: false },
621
628
  value: "2025-12-15",
622
629
  type: "DatePicker",
630
+ inputType: "date",
631
+ },
632
+ {
633
+ mode: { enableDate: true },
634
+ value: "",
635
+ type: "DatePicker",
636
+ inputType: "date",
637
+ },
638
+ {
639
+ mode: { enableDate: true },
640
+ value: undefined,
641
+ type: "DatePicker",
642
+ inputType: "date",
643
+ },
644
+ { mode: {}, value: undefined, type: "DatePicker", inputType: "date" },
645
+ {
646
+ mode: {},
647
+ value: "2025-12-15T17:00:00Z",
648
+ type: "DatePicker",
649
+ inputType: "datetime",
623
650
  },
624
- { mode: { enableDate: true }, value: "", type: "DatePicker" },
625
- { mode: { enableDate: true }, value: undefined, type: "DatePicker" },
626
- { mode: {}, value: undefined, type: "DatePicker" },
627
- { mode: {}, value: "2025-12-15T17:00:00Z", type: "Input" },
628
651
  {
629
652
  mode: { enableDate: true },
630
653
  value: "2025-12-15T17:00:00Z",
@@ -633,18 +656,25 @@ describe("convertSurfaceToUISpec", () => {
633
656
  {
634
657
  mode: { enableDate: true, enableTime: true },
635
658
  value: "2025-12-15T17:00:00Z",
636
- type: "Input",
659
+ type: "DatePicker",
660
+ inputType: "datetime",
637
661
  },
638
662
  {
639
663
  mode: { enableDate: true, enableTime: true },
640
664
  value: "2025-12-15",
641
665
  type: "Input",
642
666
  },
643
- { mode: { enableTime: true }, value: "17:00:00", type: "Input" },
667
+ {
668
+ mode: { enableTime: true },
669
+ value: "17:00:00",
670
+ type: "DatePicker",
671
+ inputType: "time",
672
+ },
644
673
  {
645
674
  mode: { enableDate: false, enableTime: true },
646
675
  value: "17:00:00",
647
- type: "Input",
676
+ type: "DatePicker",
677
+ inputType: "time",
648
678
  },
649
679
  {
650
680
  mode: { enableDate: true },
@@ -653,7 +683,7 @@ describe("convertSurfaceToUISpec", () => {
653
683
  },
654
684
  ])(
655
685
  "maps DateTimeInput $mode holding $value to $type with live field references",
656
- ({ mode, value, type }) => {
686
+ ({ mode, value, type, inputType }) => {
657
687
  const reference = {
658
688
  $field: "/form/due",
659
689
  ...(value !== undefined ? { fallback: value } : {}),
@@ -704,18 +734,30 @@ describe("convertSurfaceToUISpec", () => {
704
734
  ),
705
735
  );
706
736
 
707
- expect(result.warnings).toEqual([]);
737
+ const bounds =
738
+ inputType === "date"
739
+ ? { min: "2025-01-01", max: "2025-12-31" }
740
+ : inputType === "datetime"
741
+ ? { min: "2025-01-01T00:00", max: "2025-12-31T23:59:59.999" }
742
+ : {};
743
+ expect(result.warnings).toEqual(
744
+ inputType === "time"
745
+ ? [
746
+ 'A2UI DateTimeInput "min" of "2025-01-01" is not a time value and was dropped.',
747
+ 'A2UI DateTimeInput "max" of "2025-12-31" is not a time value and was dropped.',
748
+ ]
749
+ : [],
750
+ );
708
751
  expect(result.spec?.children).toEqual([
709
752
  {
710
753
  $type: type,
754
+ ...(inputType !== undefined ? { inputType } : {}),
711
755
  label: "Due",
712
756
  name: "/form/due",
713
757
  ...(value !== undefined
714
758
  ? { [type === "DatePicker" ? "value" : "defaultValue"]: value }
715
759
  : {}),
716
- ...(type === "DatePicker"
717
- ? { min: "2025-01-01", max: "2025-12-31" }
718
- : {}),
760
+ ...bounds,
719
761
  },
720
762
  {
721
763
  $type: "Button",
@@ -742,6 +784,161 @@ describe("convertSurfaceToUISpec", () => {
742
784
  },
743
785
  );
744
786
 
787
+ const convertedDateTimeInput = (
788
+ value: string | undefined,
789
+ mode: Record<string, unknown> = {},
790
+ bounds: Record<string, unknown> = {},
791
+ warnings: readonly string[] = [],
792
+ ) => {
793
+ const surface = surfaceFrom(
794
+ [
795
+ {
796
+ id: "root",
797
+ component: "DateTimeInput",
798
+ ...mode,
799
+ ...bounds,
800
+ value: { path: "/due" },
801
+ },
802
+ ],
803
+ value === undefined ? {} : { due: value },
804
+ );
805
+ const result = convertSurfaceToUISpec(surface);
806
+ expect(result.warnings).toEqual(warnings);
807
+ return result.spec;
808
+ };
809
+
810
+ it.each([
811
+ [{ enableDate: true, enableTime: true }, "2025-12-15T17:00Z", "datetime"],
812
+ [{ enableTime: true }, "17:00", "time"],
813
+ [{ enableDate: true }, "2025-12-15", "date"],
814
+ [{ enableDate: false, enableTime: false }, "2025-12-15", "date"],
815
+ [{ enableDate: true, enableTime: true }, "", "datetime"],
816
+ ] as const)(
817
+ "follows DateTimeInput flags %j for %j",
818
+ (mode, value, inputType) => {
819
+ expect(convertedDateTimeInput(value, mode)).toEqual({
820
+ $type: "DatePicker",
821
+ inputType,
822
+ value,
823
+ name: "/due",
824
+ });
825
+ },
826
+ );
827
+
828
+ it.each([
829
+ ["2025-12-15", "date"],
830
+ ["2025-12-15T17:00", "datetime"],
831
+ ["2025-12-15T17:00:30.125+02:00", "datetime"],
832
+ ["17:00", "time"],
833
+ ["17:00:30", "time"],
834
+ ["", "date"],
835
+ [undefined, "date"],
836
+ ] as const)("infers DateTimeInput type %s from %j", (value, inputType) => {
837
+ expect(convertedDateTimeInput(value)).toEqual({
838
+ $type: "DatePicker",
839
+ inputType,
840
+ ...(value !== undefined ? { value } : {}),
841
+ name: "/due",
842
+ });
843
+ });
844
+
845
+ it.each([
846
+ ["2025-12-15T17:00", { enableDate: true }],
847
+ ["17:00", { enableDate: true }],
848
+ ["2025-12-15", { enableDate: true, enableTime: true }],
849
+ ["2025-12-15", { enableTime: true }],
850
+ ["17:00Z", { enableTime: true }],
851
+ ["not a date", {}],
852
+ ["2025-02-30", {}],
853
+ ] as const)(
854
+ "keeps incompatible DateTimeInput value %j in a text Input",
855
+ (value, mode) => {
856
+ expect(convertedDateTimeInput(value, mode)).toEqual({
857
+ $type: "Input",
858
+ defaultValue: value,
859
+ name: "/due",
860
+ });
861
+ },
862
+ );
863
+
864
+ it.each([
865
+ {
866
+ value: "2025-12-15",
867
+ mode: { enableDate: true },
868
+ bounds: { min: "2025-01-01", max: "17:00" },
869
+ inputType: "date",
870
+ expected: { min: "2025-01-01" },
871
+ warnings: [
872
+ 'A2UI DateTimeInput "max" of "17:00" is not a date value and was dropped.',
873
+ ],
874
+ },
875
+ {
876
+ value: "17:00",
877
+ mode: { enableTime: true },
878
+ bounds: { min: "16:00", max: "2025-12-31" },
879
+ inputType: "time",
880
+ expected: { min: "16:00" },
881
+ warnings: [
882
+ 'A2UI DateTimeInput "max" of "2025-12-31" is not a time value and was dropped.',
883
+ ],
884
+ },
885
+ {
886
+ value: "2025-12-15T17:00Z",
887
+ mode: { enableDate: true, enableTime: true },
888
+ bounds: { min: "2025-01-01T08:00+02:00", max: "17:00" },
889
+ inputType: "datetime",
890
+ expected: { min: "2025-01-01T08:00+02:00" },
891
+ warnings: [
892
+ 'A2UI DateTimeInput "max" of "17:00" is not a datetime value and was dropped.',
893
+ ],
894
+ },
895
+ {
896
+ value: "17:00",
897
+ mode: { enableTime: true },
898
+ bounds: { min: "2025-12-31", max: "18:00" },
899
+ inputType: "time",
900
+ expected: { max: "18:00" },
901
+ warnings: [
902
+ 'A2UI DateTimeInput "min" of "2025-12-31" is not a time value and was dropped.',
903
+ ],
904
+ },
905
+ {
906
+ value: "2025-12-15T17:00Z",
907
+ mode: { enableDate: true, enableTime: true },
908
+ bounds: { min: "2025-01-01", max: "2025-12-31" },
909
+ inputType: "datetime",
910
+ expected: { min: "2025-01-01T00:00", max: "2025-12-31T23:59:59.999" },
911
+ warnings: [],
912
+ },
913
+ ] as const)(
914
+ "resolves DateTimeInput bounds $bounds for a $inputType value",
915
+ ({ value, mode, bounds, inputType, expected, warnings }) => {
916
+ expect(convertedDateTimeInput(value, mode, bounds, warnings)).toEqual({
917
+ $type: "DatePicker",
918
+ inputType,
919
+ value,
920
+ ...expected,
921
+ name: "/due",
922
+ });
923
+ },
924
+ );
925
+
926
+ it("keeps a DateTimeInput control shape tied to the agent model during local edits", () => {
927
+ const surface = surfaceFrom(
928
+ [{ id: "root", component: "DateTimeInput", value: { path: "/due" } }],
929
+ { due: "2025-12-15T17:00Z" },
930
+ );
931
+ const convert = createLiveSurfaceConverter(surface);
932
+ expect(convert(surface.dataModel).spec).toMatchObject({
933
+ $type: "DatePicker",
934
+ inputType: "datetime",
935
+ });
936
+ expect(convert({ due: "2025-12-15" }).spec).toMatchObject({
937
+ $type: "DatePicker",
938
+ inputType: "datetime",
939
+ });
940
+ });
941
+
745
942
  it.each([undefined, "mutuallyExclusive"])(
746
943
  "keeps chips with variant %s list-valued when empty and selected",
747
944
  (variant) => {
@@ -1897,6 +2094,18 @@ describe("convertSurfaceToUISpec", () => {
1897
2094
  const { spec, warnings } = convertSurfaceToUISpec(surface);
1898
2095
 
1899
2096
  expect(warnings).toEqual([]);
2097
+ expect(spec?.["children"]).toContainEqual({
2098
+ $type: "DatePicker",
2099
+ inputType: "date",
2100
+ value: "2026-01-02",
2101
+ name: "/form/start",
2102
+ });
2103
+ expect(spec?.["children"]).toContainEqual({
2104
+ $type: "DatePicker",
2105
+ inputType: "datetime",
2106
+ value: "2025-12-15T17:00:00Z",
2107
+ name: "/form/due",
2108
+ });
1900
2109
  expect(spec?.["children"]).toContainEqual({
1901
2110
  $type: "Button",
1902
2111
  label: "Send",
@@ -1,4 +1,5 @@
1
1
  import { ICON_NAMES, type UIElement } from "../ir";
2
+ import { classifyTemporal } from "../temporal";
2
3
  import { A2UI_SURFACE_ID, type A2uiSurfaceState } from "./types";
3
4
  import {
4
5
  evaluateA2uiValueFunction,
@@ -336,7 +337,13 @@ const INPUT_COMPONENTS: ReadonlySet<string> = new Set([
336
337
  "Slider",
337
338
  ]);
338
339
 
339
- const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
340
+ type DateInputType = "date" | "datetime" | "time";
341
+
342
+ const dateInputType = (value: string): DateInputType | undefined => {
343
+ const kind = classifyTemporal(value).kind;
344
+ if (kind === "date" || kind === "time") return kind;
345
+ return kind === "floating" || kind === "instant" ? "datetime" : undefined;
346
+ };
340
347
 
341
348
  const finiteNumber = (value: unknown): number | undefined =>
342
349
  typeof value === "number" && Number.isFinite(value) ? value : undefined;
@@ -807,11 +814,21 @@ const mappedProps = (
807
814
  const value = stringProp(props, ["value"]);
808
815
  const shapeValue =
809
816
  name === undefined ? value : resolvePointer(context.stepModel, name);
817
+ const shapeType =
818
+ typeof shapeValue === "string" ? dateInputType(shapeValue) : undefined;
819
+ let inputType: DateInputType = shapeType ?? "date";
820
+ if ("enableDate" in props || "enableTime" in props) {
821
+ inputType =
822
+ props["enableTime"] === true
823
+ ? props["enableDate"] === true
824
+ ? "datetime"
825
+ : "time"
826
+ : "date";
827
+ }
810
828
  if (
811
- props["enableTime"] === true ||
812
- (typeof shapeValue === "string" &&
813
- shapeValue !== "" &&
814
- !DATE_PATTERN.test(shapeValue))
829
+ typeof shapeValue === "string" &&
830
+ shapeValue !== "" &&
831
+ shapeType !== inputType
815
832
  ) {
816
833
  return {
817
834
  $type: "Input",
@@ -820,10 +837,27 @@ const mappedProps = (
820
837
  ...(name !== undefined ? { name } : {}),
821
838
  };
822
839
  }
823
- const min = stringProp(props, ["min"]);
824
- const max = stringProp(props, ["max"]);
840
+ // The spec types a bound as a date, a time or a date-time whatever the
841
+ // enabled flags are, so a date bound on a datetime control is the range of
842
+ // that whole local day rather than a mismatch.
843
+ const bound = (edge: "min" | "max"): string | undefined => {
844
+ const boundValue = stringProp(props, [edge]);
845
+ if (boundValue === undefined) return undefined;
846
+ const boundType = dateInputType(boundValue);
847
+ if (boundType === inputType) return boundValue;
848
+ if (inputType === "datetime" && boundType === "date") {
849
+ return `${boundValue}T${edge === "min" ? "00:00" : "23:59:59.999"}`;
850
+ }
851
+ context.warnings.push(
852
+ `A2UI DateTimeInput "${edge}" of "${boundValue}" is not a ${inputType} value and was dropped.`,
853
+ );
854
+ return undefined;
855
+ };
856
+ const min = bound("min");
857
+ const max = bound("max");
825
858
  return {
826
859
  $type: "DatePicker",
860
+ inputType,
827
861
  ...(value !== undefined ? { value } : {}),
828
862
  ...(min !== undefined ? { min } : {}),
829
863
  ...(max !== undefined ? { max } : {}),
package/src/constants.ts CHANGED
@@ -12,5 +12,6 @@ export const TYPE_KEY = "$type";
12
12
  export const GENERATED_NAME_ATTR = "data-aui-generated-name";
13
13
 
14
14
  export const FIELD_NAME_ATTR = "data-aui-field-name";
15
+ export const FIELD_VALUE_ATTR = "data-aui-field-value";
15
16
 
16
17
  export const CHECKBOX_GROUP_ATTR = "data-aui-checkbox-group";