@payfit/unity-components 3.23.15 → 3.23.16

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 (49) hide show
  1. package/dist/esm/ai-kit.js +19 -9
  2. package/dist/esm/core/components/radio-button-group/parts/RadioButton.js +9 -9
  3. package/dist/esm/core/components/select-list/SelectList.context.d.ts +9 -0
  4. package/dist/esm/core/components/select-list/SelectList.context.js +11 -0
  5. package/dist/esm/core/components/select-list/SelectList.d.ts +18 -3
  6. package/dist/esm/core/components/select-list/SelectList.js +71 -62
  7. package/dist/esm/core/components/select-list/hooks/useSelectedFirstSorting.js +11 -4
  8. package/dist/esm/core/components/select-list/parts/SelectListOption.d.ts +15 -0
  9. package/dist/esm/core/components/select-list/parts/SelectListOption.js +74 -35
  10. package/dist/esm/core/components/select-list/parts/SelectedItemsSection.d.ts +3 -1
  11. package/dist/esm/core/components/select-list/parts/SelectedItemsSection.js +17 -21
  12. package/dist/esm/core/index.js +62 -62
  13. package/dist/esm/index.js +62 -62
  14. package/dist/esm/modules/ai-kit/components/ai-structured-input/AIStructuredInput.context.d.ts +30 -0
  15. package/dist/esm/modules/ai-kit/components/ai-structured-input/AIStructuredInput.context.js +5 -0
  16. package/dist/esm/modules/ai-kit/components/ai-structured-input/AIStructuredInput.d.ts +46 -0
  17. package/dist/esm/modules/ai-kit/components/ai-structured-input/AIStructuredInput.js +122 -0
  18. package/dist/esm/modules/ai-kit/components/ai-structured-input/form/TanstackAIStructuredInputAnswersField.d.ts +48 -0
  19. package/dist/esm/modules/ai-kit/components/ai-structured-input/form/TanstackAIStructuredInputAnswersField.js +62 -0
  20. package/dist/esm/modules/ai-kit/components/ai-structured-input/form/TanstackAIStructuredInputForm.d.ts +5 -0
  21. package/dist/esm/modules/ai-kit/components/ai-structured-input/form/TanstackAIStructuredInputForm.js +21 -0
  22. package/dist/esm/modules/ai-kit/components/ai-structured-input/hooks/use-ai-structured-input-navigation.d.ts +89 -0
  23. package/dist/esm/modules/ai-kit/components/ai-structured-input/hooks/use-ai-structured-input-navigation.js +39 -0
  24. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputActions.d.ts +25 -0
  25. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputActions.js +14 -0
  26. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswer.d.ts +15 -0
  27. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswer.js +50 -0
  28. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswers.context.d.ts +8 -0
  29. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswers.context.js +8 -0
  30. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswers.d.ts +73 -0
  31. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswers.js +30 -0
  32. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputContent.d.ts +24 -0
  33. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputContent.js +13 -0
  34. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputFreeTextAnswer.d.ts +28 -0
  35. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputFreeTextAnswer.js +125 -0
  36. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputHeader.d.ts +43 -0
  37. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputHeader.js +42 -0
  38. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputStep.d.ts +43 -0
  39. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputStep.js +14 -0
  40. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputStepTitle.d.ts +43 -0
  41. package/dist/esm/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputStepTitle.js +78 -0
  42. package/dist/esm/modules/ai-kit/hooks/use-ai-kit-form.d.ts +198 -1
  43. package/dist/esm/modules/ai-kit/hooks/use-ai-kit-form.js +11 -5
  44. package/dist/esm/modules/ai-kit/index.d.ts +12 -0
  45. package/i18n/en-GB.json +10 -1
  46. package/i18n/es-ES.json +10 -1
  47. package/i18n/fr-FR.json +10 -1
  48. package/package.json +6 -6
  49. package/src/agent-references/component-catalog.json +24 -0
@@ -0,0 +1,48 @@
1
+ import { Key } from 'react-aria-components/Breadcrumbs';
2
+ import { AIStructuredInputAnswerItem, AIStructuredInputAnswersProps } from '../parts/AIStructuredInputAnswers.js';
3
+ import { AIStructuredInputFreeTextAnswerProps } from '../parts/AIStructuredInputFreeTextAnswer.js';
4
+ /** A form-owned answer: unanswered, selected string or numeric keys, or a free-text draft. */
5
+ export type AIStructuredInputAnswerValue = null | {
6
+ kind: 'choices';
7
+ keys: Key[];
8
+ } | {
9
+ kind: 'text';
10
+ text: string;
11
+ };
12
+ /** Props for the AI Kit form-connected choice and optional free-text field. */
13
+ export type TanstackAIStructuredInputAnswersFieldProps<TItem extends AIStructuredInputAnswerItem> = Omit<AIStructuredInputAnswersProps<TItem>, 'value' | 'onChange'> & {
14
+ /** Called after a choice update; useful for consumer-owned navigation. */
15
+ onAnswerChange?: (value: AIStructuredInputAnswerValue) => void;
16
+ /** Optional text control. Its submit action is local, not a form submission. */
17
+ freeText?: Omit<AIStructuredInputFreeTextAnswerProps, 'value' | 'onChange' | 'isInvalid' | 'feedbackMessage' | 'feedbackId'>;
18
+ /** Override feedback from the field, for example after batch validation. */
19
+ feedbackMessage?: string;
20
+ };
21
+ /**
22
+ * Binds choice and optional text drafts to one AI Kit form field.
23
+ * Render inside `form.AppField` and initialize the field to an
24
+ * `AIStructuredInputAnswerValue`. Editing either answer kind replaces the
25
+ * other; focus alone does not change the answer. Text confirmation calls the
26
+ * supplied local `freeText.onSubmit`, not the form's submit action.
27
+ * The list and optional text input need accessible names. Field validation
28
+ * feedback is associated with the answer group and text input.
29
+ * @param props - Choice options, optional free text, and local callbacks.
30
+ * @param props.freeText - Optional free-text control and local confirmation action.
31
+ * @param props.onAnswerChange - Receives the new draft after a choice or text edit.
32
+ * @param props.feedbackMessage - Optional application-owned validation message.
33
+ * @example
34
+ * ```tsx
35
+ * <form.AppField name="answers.country">
36
+ * {field => (
37
+ * <field.StructuredInputAnswersField
38
+ * aria-label="Country"
39
+ * items={countries}
40
+ * freeText={{ 'aria-label': 'Other country', onSubmit: advance }}
41
+ * >
42
+ * {country => <AIStructuredInputAnswer id={country.id} number={country.number}>{country.label}</AIStructuredInputAnswer>}
43
+ * </field.StructuredInputAnswersField>
44
+ * )}
45
+ * </form.AppField>
46
+ * ```
47
+ */
48
+ export declare function TanstackAIStructuredInputAnswersField<TItem extends AIStructuredInputAnswerItem>({ freeText, onAnswerChange, feedbackMessage, ...props }: TanstackAIStructuredInputAnswersFieldProps<TItem>): import('react/jsx-runtime').JSX.Element;
@@ -0,0 +1,62 @@
1
+ import { Text as e } from "../../../../../core/components/text/Text.js";
2
+ import { AIStructuredInputAnswers as t } from "../parts/AIStructuredInputAnswers.js";
3
+ import { AIStructuredInputFreeTextAnswer as n } from "../parts/AIStructuredInputFreeTextAnswer.js";
4
+ import { useAIKitFieldContext as r } from "../../../hooks/ai-kit-form-context.js";
5
+ import { useId as i } from "react";
6
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
+ //#region src/modules/ai-kit/components/ai-structured-input/form/TanstackAIStructuredInputAnswersField.tsx
8
+ function s({ freeText: s, onAnswerChange: c, feedbackMessage: l, ...u }) {
9
+ let d = r(), f = i(), p = d.state.value, m = d.state.meta.errors[0], h;
10
+ typeof m == "string" ? h = m : typeof m == "object" && m && "message" in m && typeof m.message == "string" && (h = m.message);
11
+ let g = l ?? h, _ = (e) => {
12
+ d.handleChange(e), c?.(e);
13
+ };
14
+ return /* @__PURE__ */ o("div", {
15
+ role: "group",
16
+ "aria-label": u["aria-label"],
17
+ "aria-labelledby": u["aria-labelledby"],
18
+ "aria-describedby": [u["aria-describedby"], g && f].filter(Boolean).join(" ") || void 0,
19
+ children: [
20
+ /* @__PURE__ */ a(t, {
21
+ ...u,
22
+ value: new Set(p?.kind === "choices" ? p.keys : []),
23
+ "aria-describedby": [u["aria-describedby"], g && f].filter(Boolean).join(" ") || void 0,
24
+ onBlur: (e) => {
25
+ d.handleBlur(), u.onBlur?.(e);
26
+ },
27
+ onChange: (e) => {
28
+ let t = e === "all" ? u.items.map((e) => e.id) : Array.from(e);
29
+ _({
30
+ kind: "choices",
31
+ keys: t
32
+ });
33
+ }
34
+ }),
35
+ s && /* @__PURE__ */ a(n, {
36
+ ...s,
37
+ value: p?.kind === "text" ? p.text : "",
38
+ isInvalid: !!g,
39
+ feedbackMessage: g,
40
+ feedbackId: f,
41
+ onChange: (e) => {
42
+ _({
43
+ kind: "text",
44
+ text: e.target.value
45
+ });
46
+ },
47
+ onBlur: (e) => {
48
+ d.handleBlur(), s.onBlur?.(e);
49
+ }
50
+ }),
51
+ g && !s && /* @__PURE__ */ a(e, {
52
+ id: f,
53
+ role: "alert",
54
+ variant: "bodySmallStrong",
55
+ color: "content.danger",
56
+ children: g
57
+ })
58
+ ]
59
+ });
60
+ }
61
+ //#endregion
62
+ export { s as TanstackAIStructuredInputAnswersField };
@@ -0,0 +1,5 @@
1
+ import { ReactElement, RefAttributes } from 'react';
2
+ import { AIStructuredInputItem, AIStructuredInputProps } from '../AIStructuredInput.js';
3
+ /** Props for a structured question sequence connected to an AI Kit form. */
4
+ export type TanstackAIStructuredInputFormProps<TItem extends AIStructuredInputItem = AIStructuredInputItem> = AIStructuredInputProps<TItem>;
5
+ export declare const TanstackAIStructuredInputForm: <TItem extends AIStructuredInputItem = AIStructuredInputItem>(props: TanstackAIStructuredInputFormProps<TItem> & RefAttributes<HTMLDivElement>) => ReactElement | null;
@@ -0,0 +1,21 @@
1
+ import { AIStructuredInput as e } from "../AIStructuredInput.js";
2
+ import { useAIKitFormContext as t } from "../../../hooks/ai-kit-form-context.js";
3
+ import { forwardRef as n } from "react";
4
+ import { jsx as r } from "react/jsx-runtime";
5
+ //#region src/modules/ai-kit/components/ai-structured-input/form/TanstackAIStructuredInputForm.tsx
6
+ var i = n((n, i) => {
7
+ let a = t();
8
+ return /* @__PURE__ */ r("form", {
9
+ onSubmit: (e) => {
10
+ e.preventDefault(), e.stopPropagation(), a.handleSubmit();
11
+ },
12
+ children: /* @__PURE__ */ r(e, {
13
+ ...n,
14
+ ref: i
15
+ })
16
+ });
17
+ });
18
+ i.displayName = "TanstackAIStructuredInputForm";
19
+ var a = i;
20
+ //#endregion
21
+ export { a as TanstackAIStructuredInputForm };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Navigation policy for one structured-input step.
3
+ * @typeParam TStepId - The step's stable ID.
4
+ */
5
+ export interface AIStructuredInputNavigationStep<TStepId extends string = string> {
6
+ /** Stable ID matching an `AIStructuredInputStep`. */
7
+ id: TStepId;
8
+ /** Whether an answer action on this active step should advance to the next step. */
9
+ autoAdvanceOnAnswer: boolean;
10
+ }
11
+ /** Options for `useAIStructuredInputNavigation`. */
12
+ export interface UseAIStructuredInputNavigationOptions<TSteps extends readonly [
13
+ AIStructuredInputNavigationStep,
14
+ ...AIStructuredInputNavigationStep[]
15
+ ]> {
16
+ /**
17
+ * Ordered step IDs and required per-step answer-advance policy. Append new
18
+ * steps at the end; removing or reordering existing steps is unsupported.
19
+ */
20
+ steps: TSteps;
21
+ /**
22
+ * The initially active step. Its ID is inferred from `steps`; defaults to
23
+ * the first step when omitted.
24
+ */
25
+ initialStepId?: TSteps[number]['id'];
26
+ }
27
+ /** Navigation state and actions returned by `useAIStructuredInputNavigation`. */
28
+ export interface UseAIStructuredInputNavigationResult<TStepId extends string> {
29
+ /** Current step ID; pass this to `AIStructuredInput.activeStepId`. */
30
+ activeStepId: TStepId;
31
+ /** Pass this to `AIStructuredInput.onActiveStepChange` to control the root. */
32
+ onActiveStepChange: (stepId: string) => void;
33
+ /** Changes directly to a known step ID. */
34
+ goToStep: (stepId: TStepId) => void;
35
+ /** Advances one step, if a next step exists, regardless of answer policy. */
36
+ advance: () => void;
37
+ /** Moves back one step, when there is a previous step. */
38
+ goBack: () => void;
39
+ /** Advances only for an answer action on the active step when its policy allows it. */
40
+ onAnswer: (stepId: TStepId) => void;
41
+ /** Whether the active step is the first step. */
42
+ isFirstStep: boolean;
43
+ /** Whether the active step is the last step. */
44
+ isLastStep: boolean;
45
+ /** Whether a next step exists. */
46
+ canAdvance: boolean;
47
+ /** Whether a previous step exists. */
48
+ canGoBack: boolean;
49
+ }
50
+ /**
51
+ * Owns structured-input navigation and per-step answer progression policy.
52
+ *
53
+ * Pass the returned `activeStepId` and `onActiveStepChange` to
54
+ * `AIStructuredInput` to make it controlled. Call `onAnswer(stepId)` after the
55
+ * consumer has updated its answer store; it advances only when that step is
56
+ * active, has `autoAdvanceOnAnswer: true`, and has a next step. Use `advance`
57
+ * for explicit continuation, such as a multi-select Continue action.
58
+ *
59
+ * This hook never stores, inspects, validates, or submits answer values. Keep
60
+ * those in the consumer or a form library such as TanStack Form. Steps may be
61
+ * appended at the end while preserving the active ID; removing or reordering
62
+ * existing steps is unsupported.
63
+ * @typeParam TSteps - A non-empty ordered tuple whose IDs are inferred for the
64
+ * returned navigation API and optional `initialStepId`.
65
+ * @param options - Ordered step descriptors and optional initial step.
66
+ * @returns Controlled navigation state, actions, and derived boundaries.
67
+ * @throws {Error} If no steps are configured, `initialStepId` is not in `steps`, or the active step is removed.
68
+ * @example
69
+ * ```tsx
70
+ * const navigation = useAIStructuredInputNavigation({
71
+ * steps: [
72
+ * { id: 'bonus-type', autoAdvanceOnAnswer: true },
73
+ * { id: 'countries', autoAdvanceOnAnswer: false },
74
+ * ],
75
+ * })
76
+ *
77
+ * <AIStructuredInput
78
+ * activeStepId={navigation.activeStepId}
79
+ * onActiveStepChange={navigation.onActiveStepChange}
80
+ * >
81
+ * </AIStructuredInput>
82
+ * ```
83
+ * @see {@link UseAIStructuredInputNavigationOptions} for the input contract.
84
+ * @see {@link UseAIStructuredInputNavigationResult} for the returned API.
85
+ */
86
+ export declare function useAIStructuredInputNavigation<const TSteps extends readonly [
87
+ AIStructuredInputNavigationStep,
88
+ ...AIStructuredInputNavigationStep[]
89
+ ]>(options: UseAIStructuredInputNavigationOptions<TSteps>): UseAIStructuredInputNavigationResult<TSteps[number]['id']>;
@@ -0,0 +1,39 @@
1
+ import { useState as e } from "react";
2
+ //#region src/modules/ai-kit/components/ai-structured-input/hooks/use-ai-structured-input-navigation.ts
3
+ function t(t) {
4
+ let { steps: n, initialStepId: r } = t, i = n[0];
5
+ if (!i) throw Error("useAIStructuredInputNavigation requires at least one step.");
6
+ if (r !== void 0 && !n.some((e) => e.id === r)) throw Error(`Initial step ID "${r}" must match a configured step ID.`);
7
+ let [a, o] = e(() => r ?? i.id), s = n.findIndex((e) => e.id === a);
8
+ if (s < 0) throw Error(`Active step ID "${a}" is missing. Existing steps cannot be removed while the hook is active.`);
9
+ let c = n[s];
10
+ if (!c) throw Error("Could not resolve the active structured-input step.");
11
+ let l = (e) => {
12
+ n.some((t) => t.id === e) && o(e);
13
+ }, u = (e) => {
14
+ let t = n.find((t) => t.id === e);
15
+ t && o(t.id);
16
+ }, d = () => {
17
+ let e = n[s + 1];
18
+ e && o(e.id);
19
+ }, f = () => {
20
+ let e = n[s - 1];
21
+ e && o(e.id);
22
+ }, p = (e) => {
23
+ e !== a || !c.autoAdvanceOnAnswer || d();
24
+ }, m = s === 0, h = s === n.length - 1;
25
+ return {
26
+ activeStepId: a,
27
+ onActiveStepChange: u,
28
+ goToStep: l,
29
+ advance: d,
30
+ goBack: f,
31
+ onAnswer: p,
32
+ isFirstStep: m,
33
+ isLastStep: h,
34
+ canAdvance: !h,
35
+ canGoBack: !m
36
+ };
37
+ }
38
+ //#endregion
39
+ export { t as useAIStructuredInputNavigation };
@@ -0,0 +1,25 @@
1
+ import { ComponentPropsWithoutRef } from 'react';
2
+ /** Props for the action row at the end of an `AIStructuredInputStep`. */
3
+ export type AIStructuredInputActionsProps = ComponentPropsWithoutRef<'div'>;
4
+ /**
5
+ * Aligns step actions to the end of the structured-input surface.
6
+ * @param props - Action children and standard div attributes.
7
+ * @example
8
+ * ```tsx
9
+ * import { AIStructuredInputActions } from '@payfit/unity-components/ai-kit'
10
+ *
11
+ * <AIStructuredInputStep id="countries">
12
+ * <AIStructuredInputStepTitle>Which countries?</AIStructuredInputStepTitle>
13
+ * <AIStructuredInputContent>{answerControls}</AIStructuredInputContent>
14
+ * <AIStructuredInputActions>
15
+ * <Button onPress={continueToNextStep}>Continue</Button>
16
+ * </AIStructuredInputActions>
17
+ * </AIStructuredInputStep>
18
+ * ```
19
+ * @see {@link AIStructuredInputActionsProps} for all available props.
20
+ * @remarks
21
+ * - Actions align to the end of the step.
22
+ * - Multiple actions use a consistent compact gap.
23
+ */
24
+ declare const AIStructuredInputActions: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
25
+ export { AIStructuredInputActions };
@@ -0,0 +1,14 @@
1
+ import { forwardRef as e } from "react";
2
+ import { uyMerge as t, uyTv as n } from "@payfit/unity-themes";
3
+ import { jsx as r } from "react/jsx-runtime";
4
+ //#region src/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputActions.tsx
5
+ var i = n({ base: "uy:flex uy:w-full uy:items-center uy:justify-end uy:gap-100" }), a = e(({ children: e, className: n, ...a }, o) => /* @__PURE__ */ r("div", {
6
+ ref: o,
7
+ className: t(i(), n),
8
+ "data-unity-slot": "ai.structured-input.actions",
9
+ ...a,
10
+ children: e
11
+ }));
12
+ a.displayName = "AIStructuredInputActions";
13
+ //#endregion
14
+ export { a as AIStructuredInputActions };
@@ -0,0 +1,15 @@
1
+ import { ForwardedRef, ReactElement } from 'react';
2
+ import { Key } from 'react-aria-components/Breadcrumbs';
3
+ import { SelectListOptionProps } from '../../../../../core/components/select-list/parts/SelectListOption.js';
4
+ /** Props for one numbered answer option inside a `SelectList`. */
5
+ export interface AIStructuredInputAnswerProps extends Omit<SelectListOptionProps<object>, 'children' | 'prefixElement' | 'id'> {
6
+ /** Stable, explicit identity for this answer option. */
7
+ id: Key;
8
+ /** Ordinal shown in the option's leading number marker. */
9
+ number: number;
10
+ /** Visible option label and accessible text value. */
11
+ children: string;
12
+ }
13
+ export declare const AIStructuredInputAnswer: (props: AIStructuredInputAnswerProps & {
14
+ ref?: ForwardedRef<HTMLDivElement>;
15
+ }) => ReactElement;
@@ -0,0 +1,50 @@
1
+ import { Tooltip as e } from "../../../../../core/components/tooltip/Tooltip.js";
2
+ import { Text as t } from "../../../../../core/components/text/Text.js";
3
+ import { SelectListOption as n } from "../../../../../core/components/select-list/parts/SelectListOption.js";
4
+ import { useAIStructuredInputAnswersContext as r } from "./AIStructuredInputAnswers.context.js";
5
+ import { forwardRef as i } from "react";
6
+ import { uyTv as a } from "@payfit/unity-themes";
7
+ import { jsx as o } from "react/jsx-runtime";
8
+ //#region src/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswer.tsx
9
+ var s = a({ slots: {
10
+ option: [
11
+ "uy:px-125 uy:py-125 uy:rounded-150",
12
+ "uy:data-[hinted=true]:bg-surface-neutral-selected",
13
+ "uy:motion-safe:transition-[background-color,scale] uy:motion-safe:duration-150",
14
+ "uy:motion-safe:data-[pressed]:scale-[0.99]"
15
+ ],
16
+ numberBullet: [
17
+ "uy:flex uy:size-300 uy:shrink-0 uy:items-center uy:justify-center",
18
+ "uy:rounded-circle uy:bg-surface-neutral-lowest-hover",
19
+ "uy:typography-body-strong uy:text-content-neutral"
20
+ ]
21
+ } });
22
+ function c({ id: i, number: a, children: c, textValue: l, className: u, isHinted: d, ...f }, p) {
23
+ let m = r(), { option: h, numberBullet: g } = s();
24
+ return /* @__PURE__ */ o(n, {
25
+ ref: p,
26
+ id: i,
27
+ ...f,
28
+ isHinted: d ?? m?.hintedAnswerId === i,
29
+ className: h({ className: u }),
30
+ textValue: l ?? c,
31
+ prefixElement: /* @__PURE__ */ o("span", {
32
+ className: g(),
33
+ "aria-hidden": "true",
34
+ children: a
35
+ }),
36
+ children: /* @__PURE__ */ o(e, {
37
+ title: c,
38
+ children: /* @__PURE__ */ o(t, {
39
+ variant: "body",
40
+ isTruncated: !0,
41
+ children: c
42
+ })
43
+ })
44
+ });
45
+ }
46
+ var l = i(c);
47
+ l.displayName = "AIStructuredInputAnswer";
48
+ var u = l;
49
+ //#endregion
50
+ export { u as AIStructuredInputAnswer };
@@ -0,0 +1,8 @@
1
+ import { Key } from 'react-aria-components/Breadcrumbs';
2
+ interface AIStructuredInputAnswersContextValue {
3
+ /** The answer ID shown with the initial hint styling, when present. */
4
+ hintedAnswerId?: Key;
5
+ }
6
+ export declare const AIStructuredInputAnswersProvider: import('react').Provider<AIStructuredInputAnswersContextValue | null>;
7
+ export declare function useAIStructuredInputAnswersContext(): AIStructuredInputAnswersContextValue | null;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ import { createContext as e, useContext as t } from "react";
2
+ //#region src/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswers.context.ts
3
+ var n = e(null), r = n.Provider;
4
+ function i() {
5
+ return t(n);
6
+ }
7
+ //#endregion
8
+ export { r as AIStructuredInputAnswersProvider, i as useAIStructuredInputAnswersContext };
@@ -0,0 +1,73 @@
1
+ import { JSX, Ref } from 'react';
2
+ import { Key } from 'react-aria-components/Breadcrumbs';
3
+ import { SelectListProps } from '../../../../../core/components/select-list/SelectList.js';
4
+ /** An answer collection item must have an explicit, stable ID. */
5
+ export interface AIStructuredInputAnswerItem {
6
+ id: Key;
7
+ }
8
+ /** Props for a structured-input choice collection. */
9
+ export interface AIStructuredInputAnswersProps<TItem extends AIStructuredInputAnswerItem> extends Omit<SelectListProps<TItem>, 'items' | 'children' | 'value' | 'onChange'> {
10
+ /** The ordered answer options. Each item must have an explicit ID. */
11
+ items: readonly TItem[];
12
+ /** Renders each item, typically as an `AIStructuredInputAnswer`. */
13
+ children: SelectListProps<TItem>['children'];
14
+ /** The selected answer keys. Keep this value in application or form state. */
15
+ value: NonNullable<SelectListProps<TItem>['value']>;
16
+ /** Receives selection changes so the consumer can update its answer draft. */
17
+ onChange: NonNullable<SelectListProps<TItem>['onChange']>;
18
+ }
19
+ type AIStructuredInputAnswersComponent = {
20
+ <TItem extends AIStructuredInputAnswerItem>(props: AIStructuredInputAnswersProps<TItem> & {
21
+ ref?: Ref<HTMLDivElement>;
22
+ }): JSX.Element;
23
+ displayName: string;
24
+ };
25
+ /**
26
+ * Presents choice answers in the compact layout designed for structured questions.
27
+ * @param props - A controlled answer selection, ordered items, and an option renderer.
28
+ * @see {@link AIStructuredInputAnswersProps} for the complete API.
29
+ * @example
30
+ * ```tsx
31
+ * <AIStructuredInputAnswers
32
+ * aria-label="Choose a bonus type"
33
+ * items={answers}
34
+ * selectionMode="single"
35
+ * value={selectedAnswerIds}
36
+ * onChange={setSelectedAnswerIds}
37
+ * >
38
+ * {answer => (
39
+ * <AIStructuredInputAnswer id={answer.id} number={answer.number}>
40
+ * {answer.label}
41
+ * </AIStructuredInputAnswer>
42
+ * )}
43
+ * </AIStructuredInputAnswers>
44
+ * ```
45
+ * @remarks
46
+ * - Selection remains controlled by the consumer.
47
+ * - The defaults are multiple selection, end-position indicators, no search field, and a transparent wrapper.
48
+ * - The first option is hinted until the user changes the selection.
49
+ * - Unmounting and remounting resets the transient hint.
50
+ * @example Static option data
51
+ * ```tsx
52
+ * const bonusTypes = [
53
+ * { id: 'one-off', number: 1, label: 'One-off bonus' },
54
+ * { id: 'recurring', number: 2, label: 'Recurring bonus' },
55
+ * ]
56
+ *
57
+ * <AIStructuredInputAnswers
58
+ * aria-label="Choose a bonus type"
59
+ * items={bonusTypes}
60
+ * selectionMode="single"
61
+ * value={selectedBonusType}
62
+ * onChange={setSelectedBonusType}
63
+ * >
64
+ * {answer => (
65
+ * <AIStructuredInputAnswer id={answer.id} number={answer.number}>
66
+ * {answer.label}
67
+ * </AIStructuredInputAnswer>
68
+ * )}
69
+ * </AIStructuredInputAnswers>
70
+ * ```
71
+ */
72
+ declare const AIStructuredInputAnswers: AIStructuredInputAnswersComponent;
73
+ export { AIStructuredInputAnswers };
@@ -0,0 +1,30 @@
1
+ import { SelectList as e } from "../../../../../core/components/select-list/SelectList.js";
2
+ import { AIStructuredInputAnswersProvider as t } from "./AIStructuredInputAnswers.context.js";
3
+ import { forwardRef as n, useState as r } from "react";
4
+ import { uyMerge as i } from "@payfit/unity-themes";
5
+ import { jsx as a } from "react/jsx-runtime";
6
+ //#region src/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputAnswers.tsx
7
+ function o({ items: n, children: o, value: s, onChange: c, selectionMode: l = "multiple", showSearch: u = !1, indicatorPosition: d = "end", wrapperClassName: f, ...p }, m) {
8
+ let [h, g] = r(!1), _ = !(s === "all" || Array.from(s).length > 0) && !h ? n[0]?.id : void 0, v = (e) => {
9
+ g(!0), c(e);
10
+ };
11
+ return /* @__PURE__ */ a(t, {
12
+ value: { hintedAnswerId: _ },
13
+ children: /* @__PURE__ */ a(e, {
14
+ ...p,
15
+ ref: m,
16
+ items: n,
17
+ value: s,
18
+ onChange: v,
19
+ selectionMode: l,
20
+ showSearch: u,
21
+ indicatorPosition: d,
22
+ wrapperClassName: i("uy:bg-transparent uy:p-0", f),
23
+ children: o
24
+ })
25
+ });
26
+ }
27
+ var s = n(o);
28
+ s.displayName = "AIStructuredInputAnswers";
29
+ //#endregion
30
+ export { s as AIStructuredInputAnswers };
@@ -0,0 +1,24 @@
1
+ import { ComponentPropsWithoutRef } from 'react';
2
+ /** Props for the answer-control region of an `AIStructuredInputStep`. */
3
+ export type AIStructuredInputContentProps = ComponentPropsWithoutRef<'div'>;
4
+ /**
5
+ * Groups a step's answer controls with consistent spacing.
6
+ * @param props - Content children and standard div attributes.
7
+ * @example
8
+ * ```tsx
9
+ * import { AIStructuredInputContent } from '@payfit/unity-components/ai-kit'
10
+ *
11
+ * <AIStructuredInputContent>
12
+ * <AIStructuredInputAnswers items={answers} value={value} onChange={setValue}>
13
+ * {answer => <AIStructuredInputAnswer id={answer.id} number={answer.number}>{answer.label}</AIStructuredInputAnswer>}
14
+ * </AIStructuredInputAnswers>
15
+ * <AIStructuredInputFreeTextAnswer value={draft} onChange={handleChange} onSubmit={saveAnswer} />
16
+ * </AIStructuredInputContent>
17
+ * ```
18
+ * @see {@link AIStructuredInputContentProps} for all available props.
19
+ * @remarks
20
+ * - Use this region for answer controls, including choice lists and free-text fields.
21
+ * - Its compact vertical gap keeps related answer controls visually grouped.
22
+ */
23
+ declare const AIStructuredInputContent: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
24
+ export { AIStructuredInputContent };
@@ -0,0 +1,13 @@
1
+ import { forwardRef as e } from "react";
2
+ import { uyMerge as t, uyTv as n } from "@payfit/unity-themes";
3
+ import { jsx as r } from "react/jsx-runtime";
4
+ //#region src/modules/ai-kit/components/ai-structured-input/parts/AIStructuredInputContent.tsx
5
+ var i = n({ base: "uy:flex uy:min-w-0 uy:flex-col uy:gap-100" }), a = e(({ children: e, className: n, ...a }, o) => /* @__PURE__ */ r("div", {
6
+ ref: o,
7
+ className: t(i(), n),
8
+ ...a,
9
+ children: e
10
+ }));
11
+ a.displayName = "AIStructuredInputContent";
12
+ //#endregion
13
+ export { a as AIStructuredInputContent };
@@ -0,0 +1,28 @@
1
+ import { ChangeEventHandler, ReactElement, Ref } from 'react';
2
+ import { TextAreaProps as AriaTextAreaProps } from 'react-aria-components/TextArea';
3
+ /** Props for a controlled free-text answer field. */
4
+ export interface AIStructuredInputFreeTextAnswerProps extends Omit<AriaTextAreaProps, 'children' | 'className' | 'disabled' | 'onChange' | 'readOnly' | 'value'> {
5
+ /** The current answer draft, owned by the consumer or form. */
6
+ value: string;
7
+ /** Updates the consumer-owned answer draft. */
8
+ onChange: ChangeEventHandler<HTMLTextAreaElement>;
9
+ /** Called when the person confirms this answer. It does not submit the answer batch. */
10
+ onSubmit: () => void;
11
+ /** Whether the answer field is disabled. */
12
+ isDisabled?: boolean;
13
+ /** Whether confirming the answer is in progress. */
14
+ isLoading?: boolean;
15
+ /** Whether the answer needs correction. */
16
+ isInvalid?: boolean;
17
+ /** Feedback shown below the text area, normally when `isInvalid` is true. */
18
+ feedbackMessage?: string;
19
+ /** ID for the feedback message when another control also describes it. */
20
+ feedbackId?: string;
21
+ /** Accessible name for the answer confirmation button. */
22
+ submitAriaLabel?: string;
23
+ /** Merges custom styles with the field styles. */
24
+ className?: string;
25
+ }
26
+ export declare const AIStructuredInputFreeTextAnswer: (props: AIStructuredInputFreeTextAnswerProps & {
27
+ ref?: Ref<HTMLTextAreaElement>;
28
+ }) => ReactElement;