@payfit/unity-components 3.2.3 → 3.2.5

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 (29) hide show
  1. package/dist/esm/ai-kit.js +7 -1
  2. package/dist/esm/core/components/icon-button/CircularIconButton.js +5 -4
  3. package/dist/esm/modules/ai-kit/components/ai-button/AIButton.js +25 -6
  4. package/dist/esm/modules/ai-kit/components/ai-composer/AIComposer.context.d.ts +27 -0
  5. package/dist/esm/modules/ai-kit/components/ai-composer/AIComposer.context.js +11 -0
  6. package/dist/esm/modules/ai-kit/components/ai-composer/AIComposer.d.ts +43 -0
  7. package/dist/esm/modules/ai-kit/components/ai-composer/AIComposer.js +52 -0
  8. package/dist/esm/modules/ai-kit/components/ai-composer/AIComposer.variants.d.ts +34 -0
  9. package/dist/esm/modules/ai-kit/components/ai-composer/AIComposer.variants.js +68 -0
  10. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAction.d.ts +24 -0
  11. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAction.js +27 -0
  12. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerActions.d.ts +25 -0
  13. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerActions.js +25 -0
  14. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAlert.d.ts +31 -0
  15. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAlert.js +37 -0
  16. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAttachment.d.ts +23 -4
  17. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAttachment.js +30 -28
  18. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAttachmentsGroup.d.ts +13 -0
  19. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerAttachmentsGroup.js +19 -7
  20. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerSubmitAction.d.ts +36 -0
  21. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerSubmitAction.js +56 -0
  22. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerTextArea.d.ts +20 -0
  23. package/dist/esm/modules/ai-kit/components/ai-composer/parts/AIComposerTextArea.js +82 -0
  24. package/dist/esm/modules/ai-kit/components/ai-trigger-button/AITriggerButton.js +1 -14
  25. package/dist/esm/modules/ai-kit/index.d.ts +7 -0
  26. package/dist/esm/modules/ai-kit/utils/ai-gradient-effect.d.ts +24 -35
  27. package/dist/esm/modules/ai-kit/utils/ai-gradient-effect.js +25 -67
  28. package/package.json +7 -7
  29. package/src/agent-references/component-catalog.json +24 -0
@@ -4,4 +4,10 @@ import { PayfitAIBrand as r } from "./modules/ai-kit/components/payfit-ai-brand/
4
4
  import { AITriggerButton as i } from "./modules/ai-kit/components/ai-trigger-button/AITriggerButton.js";
5
5
  import { AIComposerAttachment as a } from "./modules/ai-kit/components/ai-composer/parts/AIComposerAttachment.js";
6
6
  import { AIComposerAttachmentsGroup as o } from "./modules/ai-kit/components/ai-composer/parts/AIComposerAttachmentsGroup.js";
7
- export { n as AIButton, a as AIComposerAttachment, o as AIComposerAttachmentsGroup, i as AITriggerButton, r as PayfitAIBrand, e as aiGradientEffect, t as aiGradientSurfaceEffect };
7
+ import { AIComposer as s } from "./modules/ai-kit/components/ai-composer/AIComposer.js";
8
+ import { AIComposerAction as c } from "./modules/ai-kit/components/ai-composer/parts/AIComposerAction.js";
9
+ import { AIComposerActions as l } from "./modules/ai-kit/components/ai-composer/parts/AIComposerActions.js";
10
+ import { AIComposerAlert as u } from "./modules/ai-kit/components/ai-composer/parts/AIComposerAlert.js";
11
+ import { AIComposerSubmitAction as d } from "./modules/ai-kit/components/ai-composer/parts/AIComposerSubmitAction.js";
12
+ import { AIComposerTextArea as f } from "./modules/ai-kit/components/ai-composer/parts/AIComposerTextArea.js";
13
+ export { n as AIButton, s as AIComposer, c as AIComposerAction, l as AIComposerActions, u as AIComposerAlert, a as AIComposerAttachment, o as AIComposerAttachmentsGroup, d as AIComposerSubmitAction, f as AIComposerTextArea, i as AITriggerButton, r as PayfitAIBrand, e as aiGradientEffect, t as aiGradientSurfaceEffect };
@@ -12,8 +12,8 @@ var u = a({
12
12
  base: [
13
13
  "uy:rounded-circle uy:cursor-pointer uy:flex uy:items-center uy:justify-center uy:transition-colors",
14
14
  "uy:disabled:cursor-not-allowed uy:disabled:text-content-neutral-disabled uy:disabled:data-[hovered=\"true\"]:bg-transparent",
15
- "uy:focus-visible:outline-2 uy:focus-visible:outline-offset-2 uy:focus-visible:outline-utility-focus-ring",
16
- "uy:aria-busy:text-content-neutral-disabled uy:aria-busy:cursor-progress"
15
+ "uy:focus-visible:outline-2 uy:focus-visible:outline-offset-2 uy:focus-visible:outline-utility-focus-ring uy:data-[focus-visible=\"true\"]:outline-2 uy:data-[focus-visible=\"true\"]:outline-offset-2 uy:data-[focus-visible=\"true\"]:outline-utility-focus-ring",
16
+ "uy:data-[pending=\"true\"]:text-content-neutral-disabled uy:data-[pending=\"true\"]:cursor-progress"
17
17
  ],
18
18
  variants: {
19
19
  size: {
@@ -32,7 +32,7 @@ var u = a({
32
32
  "uy:data-[hovered=\"true\"]:bg-surface-neutral-low-hover",
33
33
  "uy:active:bg-surface-neutral-low-active",
34
34
  "uy:data-[pressed=true]:bg-surface-neutral-low-active",
35
- "uy:focus-visible:bg-surface-neutral-low-focus",
35
+ "uy:focus-visible:bg-surface-neutral-low-focus uy:data-[focus-visible=\"true\"]:bg-surface-neutral-low-focus",
36
36
  "uy:disabled:bg-surface-neutral-low-disabled"
37
37
  ],
38
38
  "content.neutral.lowest": [
@@ -63,9 +63,10 @@ var u = a({
63
63
  ...C,
64
64
  type: f,
65
65
  onPress: p,
66
- isDisabled: y || _,
66
+ isDisabled: y,
67
67
  "aria-labelledby": S ?? w,
68
68
  "aria-busy": _,
69
+ isPending: _,
69
70
  className: T,
70
71
  children: [_ ? /* @__PURE__ */ o(n, {
71
72
  size: "small",
@@ -13,7 +13,10 @@ var p = c({
13
13
  base: [
14
14
  "uy:relative",
15
15
  "uy:isolate",
16
- "uy:[--uy-ai-gradient-border-width:1px]"
16
+ "uy:[--uy-ai-gradient-border-width:1px]",
17
+ "uy:[--uy-ai-gradient-border-opacity:0]",
18
+ "uy:[--uy-ai-gradient-surface-opacity:0]",
19
+ "uy:[--uy-ai-gradient-animation-play-state:paused]"
17
20
  ],
18
21
  aiSurface: [i()],
19
22
  content: [
@@ -33,10 +36,17 @@ var p = c({
33
36
  variant: {
34
37
  outlined: { base: [
35
38
  "uy:text-content-neutral-enabled",
39
+ "uy:[--uy-ai-gradient-border-opacity:1]",
36
40
  "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-border-width:2px]",
37
41
  "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-border-width:2px]",
38
- "uy:enabled:hover:[--uy-ai-gradient-border-width:2px]",
39
- "uy:enabled:focus-visible:[--uy-ai-gradient-border-width:2px]",
42
+ "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-surface-opacity:0.06]",
43
+ "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-animation-play-state:running]",
44
+ "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-surface-opacity:0.06]",
45
+ "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-animation-play-state:running]",
46
+ "uy:enabled:data-[pressed=\"true\"]:[--uy-ai-gradient-surface-opacity:0.06]",
47
+ "uy:enabled:data-[pressed=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
48
+ "uy:enabled:data-[pressed=\"true\"]:data-[hovered=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
49
+ "uy:enabled:data-[pressed=\"true\"]:data-[focus-visible=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
40
50
  "uy:enabled:data-[hovered=\"true\"]:text-content-neutral-hover",
41
51
  "uy:enabled:active:text-content-neutral-active",
42
52
  "uy:enabled:data-[pressed=\"true\"]:text-content-neutral-pressed",
@@ -47,10 +57,21 @@ var p = c({
47
57
  "uy:text-content-neutral-enabled",
48
58
  "uy:enabled:data-[hovered=\"true\"]:text-content-neutral-hover",
49
59
  "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-border-width:2px]",
60
+ "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-border-opacity:1]",
61
+ "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-surface-opacity:0.06]",
62
+ "uy:enabled:data-[hovered=\"true\"]:[--uy-ai-gradient-animation-play-state:running]",
50
63
  "uy:enabled:active:text-content-neutral-active",
51
64
  "uy:enabled:data-[pressed=\"true\"]:text-content-neutral-pressed",
65
+ "uy:enabled:data-[pressed=\"true\"]:[--uy-ai-gradient-border-opacity:1]",
66
+ "uy:enabled:data-[pressed=\"true\"]:[--uy-ai-gradient-surface-opacity:0.06]",
67
+ "uy:enabled:data-[pressed=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
68
+ "uy:enabled:data-[pressed=\"true\"]:data-[hovered=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
69
+ "uy:enabled:data-[pressed=\"true\"]:data-[focus-visible=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
52
70
  "uy:enabled:data-[focus-visible=\"true\"]:text-content-neutral-focus",
53
- "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-border-width:2px]"
71
+ "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-border-width:2px]",
72
+ "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-border-opacity:1]",
73
+ "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-surface-opacity:0.06]",
74
+ "uy:enabled:data-[focus-visible=\"true\"]:[--uy-ai-gradient-animation-play-state:running]"
54
75
  ] }
55
76
  },
56
77
  isDisabled: { true: {
@@ -65,7 +86,6 @@ var p = c({
65
86
  variant: "outlined",
66
87
  className: { base: r({
67
88
  gradient: "linear",
68
- variant: "outlined",
69
89
  glow: !1
70
90
  }) }
71
91
  },
@@ -74,7 +94,6 @@ var p = c({
74
94
  variant: "ghost",
75
95
  className: { base: r({
76
96
  gradient: "linear",
77
- variant: "ghost",
78
97
  glow: !1
79
98
  }) }
80
99
  },
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Describes the request lifecycle so Composer parts can present the right
3
+ * controls while a person writes, sends, or stops a prompt.
4
+ * @remarks
5
+ * - `enabled` accepts a new prompt.
6
+ * - `loading` marks a submitted prompt while the request starts.
7
+ * - `streaming` turns the primary action into a stop control.
8
+ * - `disabled` disables the prompt and actions.
9
+ */
10
+ export type AIComposerState = 'disabled' | 'loading' | 'streaming' | 'enabled';
11
+ /**
12
+ * Selects whether plain Enter sends a ready prompt or adds a new line.
13
+ * @remarks
14
+ * `submit` is the default and keeps Shift+Enter for new lines. `newline`
15
+ * reserves Enter for new lines and requires the primary action to send.
16
+ */
17
+ export type AIComposerEnterKeyBehavior = 'submit' | 'newline';
18
+ export interface AIComposerContextValue {
19
+ enterKeyBehavior: AIComposerEnterKeyBehavior;
20
+ state?: AIComposerState;
21
+ onStop?: () => void;
22
+ requestSubmit: () => void;
23
+ hasValue: boolean;
24
+ setHasValue: (hasValue: boolean) => void;
25
+ }
26
+ export declare const AIComposerContextProvider: import('react').Provider<AIComposerContextValue>;
27
+ export declare const useAIComposerContext: () => AIComposerContextValue;
@@ -0,0 +1,11 @@
1
+ import { createContext as e, useContext as t } from "react";
2
+ //#region src/modules/ai-kit/components/ai-composer/AIComposer.context.tsx
3
+ var n = e({
4
+ enterKeyBehavior: "submit",
5
+ state: "enabled",
6
+ requestSubmit: () => void 0,
7
+ hasValue: !1,
8
+ setHasValue: () => void 0
9
+ }), r = n.Provider, i = () => t(n);
10
+ //#endregion
11
+ export { r as AIComposerContextProvider, i as useAIComposerContext };
@@ -0,0 +1,43 @@
1
+ import { ComponentPropsWithoutRef, FormEventHandler, ReactNode } from 'react';
2
+ import { AIComposerEnterKeyBehavior, AIComposerState } from './AIComposer.context.js';
3
+ export interface AIComposerProps extends Omit<ComponentPropsWithoutRef<'form'>, 'children' | 'className' | 'onSubmit' | 'style'> {
4
+ /** Composes the prompt, optional context, feedback, and action regions. */
5
+ children?: ReactNode;
6
+ /**
7
+ * Controls how Enter behaves in the prompt field.
8
+ * @default 'submit'
9
+ */
10
+ enterKeyBehavior?: AIComposerEnterKeyBehavior;
11
+ /**
12
+ * Selects the interaction lifecycle and its visual treatment.
13
+ * @default 'enabled'
14
+ */
15
+ state?: AIComposerState;
16
+ /** Receives the submit event after the browser default is prevented. */
17
+ onSubmit?: FormEventHandler<HTMLFormElement>;
18
+ /** Stops the active response while the composer is streaming. */
19
+ onStop?: () => void;
20
+ }
21
+ /**
22
+ * Gives people one consistent place to write an AI request, add context, and
23
+ * follow the request lifecycle without leaving the conversation.
24
+ *
25
+ * Compose `AIComposerTextArea`, `AIComposerActions`, and any optional
26
+ * attachment or feedback parts inside the form. Set `state` from the request
27
+ * lifecycle and pass `onSubmit` to send the prompt.
28
+ * @param props - Form attributes, composer state, and composable child regions.
29
+ * @param props.children - Renders the Composer parts in their semantic order.
30
+ * @param props.enterKeyBehavior - Chooses `submit` for Enter-to-send or
31
+ * `newline` for Enter-to-add-a-line.
32
+ * @param props.state - Selects `enabled`, `loading`, `streaming`, or `disabled`.
33
+ * @param props.onSubmit - Sends a ready prompt after form validation succeeds.
34
+ * @param props.onStop - Stops an in-progress response during `streaming`.
35
+ * @see {@link AIComposerProps} for all available props.
36
+ * @remarks
37
+ * The root renders a semantic `<form>`; give it an `aria-label` or
38
+ * `aria-labelledby` when it needs a landmark name. `AIComposerTextArea`
39
+ * derives whether the prompt contains meaningful text, so consumers do not
40
+ * need to maintain a separate active state. The streaming submit action calls
41
+ * `onStop` instead of submitting a new prompt.
42
+ */
43
+ export declare const AIComposer: import('react').ForwardRefExoticComponent<AIComposerProps & import('react').RefAttributes<HTMLFormElement>>;
@@ -0,0 +1,52 @@
1
+ import { AIComposerContextProvider as e } from "./AIComposer.context.js";
2
+ import { aiComposer as t } from "./AIComposer.variants.js";
3
+ import { forwardRef as n, useCallback as r, useImperativeHandle as i, useRef as a, useState as o } from "react";
4
+ import { mergeProps as s, useFocusWithin as c } from "react-aria";
5
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
+ //#region src/modules/ai-kit/components/ai-composer/AIComposer.tsx
7
+ var d = n(({ children: n, enterKeyBehavior: d = "submit", state: f = "enabled", onSubmit: p, onStop: m, ...h }, g) => {
8
+ let _ = t({ state: f }), v = a(null), [y, b] = o(!1), [x, S] = o(!1), { focusWithinProps: C } = c({
9
+ isDisabled: f === "disabled",
10
+ onFocusWithinChange: S
11
+ }), w = s(h, C);
12
+ i(g, () => {
13
+ if (!v.current) throw Error("Expected the AI Composer form to be mounted");
14
+ return v.current;
15
+ }, []);
16
+ let T = r(() => {
17
+ v.current?.requestSubmit();
18
+ }, []), E = (e) => {
19
+ e.preventDefault(), p?.(e);
20
+ };
21
+ return /* @__PURE__ */ l(e, {
22
+ value: {
23
+ enterKeyBehavior: d,
24
+ state: f,
25
+ hasValue: y,
26
+ setHasValue: b,
27
+ onStop: m,
28
+ requestSubmit: T
29
+ },
30
+ children: /* @__PURE__ */ u("form", {
31
+ ref: v,
32
+ ...w,
33
+ onSubmit: E,
34
+ className: _.base(),
35
+ "data-focus-within": x || void 0,
36
+ "data-has-value": y || void 0,
37
+ "data-state": f,
38
+ "data-unity-component": "ai.composer",
39
+ children: [/* @__PURE__ */ l("span", {
40
+ "aria-hidden": "true",
41
+ className: _.surface(),
42
+ "data-unity-slot": "ai.surface"
43
+ }), /* @__PURE__ */ l("div", {
44
+ className: _.content(),
45
+ children: n
46
+ })]
47
+ })
48
+ });
49
+ });
50
+ d.displayName = "AIComposer";
51
+ //#endregion
52
+ export { d as AIComposer };
@@ -0,0 +1,34 @@
1
+ export declare const aiComposer: import('tailwind-variants').TVReturnType<{
2
+ state: {
3
+ enabled: {};
4
+ disabled: {};
5
+ loading: {};
6
+ streaming: {};
7
+ };
8
+ }, {
9
+ base: string[];
10
+ surface: string;
11
+ content: string;
12
+ }, undefined, {
13
+ state: {
14
+ enabled: {};
15
+ disabled: {};
16
+ loading: {};
17
+ streaming: {};
18
+ };
19
+ }, {
20
+ base: string[];
21
+ surface: string;
22
+ content: string;
23
+ }, import('tailwind-variants').TVReturnTypeLike<{
24
+ state: {
25
+ enabled: {};
26
+ disabled: {};
27
+ loading: {};
28
+ streaming: {};
29
+ };
30
+ }, {
31
+ base: string[];
32
+ surface: string;
33
+ content: string;
34
+ }>>;
@@ -0,0 +1,68 @@
1
+ import { aiGradientEffect as e, aiGradientSurfaceEffect as t } from "../../utils/ai-gradient-effect.js";
2
+ import { uyTv as n } from "@payfit/unity-themes";
3
+ //#region src/modules/ai-kit/components/ai-composer/AIComposer.variants.ts
4
+ var r = n({
5
+ slots: {
6
+ base: [
7
+ "uy:flex uy:min-h-[120px] uy:rounded-200 uy:border-2 uy:px-200 uy:py-150 uy:not-data-[state=\"disabled\"]:shadow-100",
8
+ "uy:bg-surface-neutral",
9
+ "uy:[--uy-ai-gradient-border-width:2px]",
10
+ "uy:[--uy-ai-gradient-border-opacity:0]",
11
+ "uy:[--uy-ai-gradient-surface-opacity:0]",
12
+ "uy:[--uy-ai-gradient-animation-play-state:paused]",
13
+ "uy:[--uy-ai-gradient-glow-opacity:0%]",
14
+ "uy:data-[state=\"enabled\"]:border-border-neutral",
15
+ "uy:data-[state=\"disabled\"]:cursor-not-allowed uy:data-[state=\"disabled\"]:bg-surface-neutral-disabled uy:data-[state=\"disabled\"]:border-border-neutral-disabled",
16
+ "uy:hover:border-border-neutral-hover",
17
+ "uy:data-[hovered=\"true\"]:border-border-neutral-hover",
18
+ "uy:focus-within:outline-2 uy:focus-within:outline-solid uy:focus-within:outline-offset-2 uy:focus-within:outline-utility-focus-ring",
19
+ "uy:data-[focus-visible=\"true\"]:outline-2 uy:data-[focus-visible=\"true\"]:outline-solid uy:data-[focus-visible=\"true\"]:outline-offset-2 uy:data-[focus-visible=\"true\"]:outline-utility-focus-ring",
20
+ "uy:data-[focus-within=\"true\"]:[--uy-ai-gradient-border-width:2px]",
21
+ "uy:data-[focus-within=\"true\"]:[--uy-ai-gradient-border-opacity:1]",
22
+ "uy:data-[focus-within=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
23
+ "uy:data-[focus-visible=\"true\"]:[--uy-ai-gradient-border-width:2px]",
24
+ "uy:data-[focus-visible=\"true\"]:[--uy-ai-gradient-border-opacity:1]",
25
+ "uy:data-[focus-visible=\"true\"]:[--uy-ai-gradient-animation-play-state:paused]",
26
+ "uy:data-[has-value=\"true\"]:[--uy-ai-gradient-border-width:2px]",
27
+ "uy:data-[has-value=\"true\"]:[--uy-ai-gradient-border-opacity:1]",
28
+ "uy:data-[has-value=\"true\"]:data-[focus-within=\"true\"]:[--uy-ai-gradient-border-width:2px]",
29
+ "uy:data-[has-value=\"true\"]:data-[focus-within=\"true\"]:[--uy-ai-gradient-animation-play-state:running]",
30
+ "uy:data-[state=\"loading\"]:[--uy-ai-gradient-border-width:2px]",
31
+ "uy:data-[state=\"loading\"]:[--uy-ai-gradient-border-opacity:1]",
32
+ "uy:data-[state=\"loading\"]:[--uy-ai-gradient-surface-opacity:0.06]",
33
+ "uy:data-[state=\"loading\"]:[--uy-ai-gradient-animation-play-state:running]",
34
+ "uy:data-[state=\"loading\"]:[--uy-ai-gradient-glow-opacity:20%]",
35
+ "uy:data-[state=\"loading\"]:[--uy-ai-gradient-glow-visibility:1]",
36
+ "uy:data-[state=\"streaming\"]:[--uy-ai-gradient-border-width:2px]",
37
+ "uy:data-[state=\"streaming\"]:[--uy-ai-gradient-border-opacity:1]",
38
+ "uy:data-[state=\"streaming\"]:[--uy-ai-gradient-surface-opacity:0.06]",
39
+ "uy:data-[state=\"streaming\"]:[--uy-ai-gradient-animation-play-state:running]",
40
+ "uy:data-[state=\"streaming\"]:[--uy-ai-gradient-glow-opacity:20%]",
41
+ "uy:data-[state=\"streaming\"]:[--uy-ai-gradient-glow-visibility:1]",
42
+ "uy:data-[state=\"loading\"]:data-[focus-within=\"true\"]:[--uy-ai-gradient-border-width:2px]",
43
+ "uy:data-[state=\"loading\"]:data-[has-value=\"true\"]:[--uy-ai-gradient-border-width:2px]",
44
+ "uy:data-[state=\"streaming\"]:data-[focus-within=\"true\"]:[--uy-ai-gradient-border-width:2px]",
45
+ "uy:data-[state=\"streaming\"]:data-[has-value=\"true\"]:[--uy-ai-gradient-border-width:2px]",
46
+ "uy:data-[state=\"disabled\"]:[--uy-ai-gradient-border-width:2px]",
47
+ "uy:data-[state=\"disabled\"]:[--uy-ai-gradient-border-opacity:0]",
48
+ "uy:data-[state=\"disabled\"]:[--uy-ai-gradient-surface-opacity:0]",
49
+ "uy:data-[state=\"disabled\"]:[--uy-ai-gradient-animation-play-state:paused]",
50
+ "uy:data-[state=\"disabled\"]:[--uy-ai-gradient-glow-opacity:0%]",
51
+ "uy:data-[state=\"disabled\"]:[--uy-ai-gradient-glow-visibility:0]",
52
+ e({
53
+ gradient: "linear",
54
+ glow: !0
55
+ })
56
+ ],
57
+ surface: t(),
58
+ content: "uy:relative uy:z-20 uy:flex uy:min-h-0 uy:min-w-0 uy:flex-1 uy:flex-col"
59
+ },
60
+ variants: { state: {
61
+ enabled: {},
62
+ disabled: {},
63
+ loading: {},
64
+ streaming: {}
65
+ } }
66
+ });
67
+ //#endregion
68
+ export { r as aiComposer };
@@ -0,0 +1,24 @@
1
+ import { CircularIconButtonProps } from '../../../../../core/components/icon-button/CircularIconButton.js';
2
+ export interface AIComposerActionProps extends Omit<CircularIconButtonProps, 'asElement' | 'className' | 'isLoading' | 'title' | 'style'> {
3
+ /** Supplies the tooltip and fallback accessible name for the icon action. */
4
+ title?: string;
5
+ /** Names the action when its icon alone does not communicate its purpose. */
6
+ 'aria-label'?: string;
7
+ }
8
+ declare const getActionTitle: (title: string | undefined, ariaLabel: string | undefined, defaultTitle: string) => string;
9
+ /**
10
+ * Keeps supporting Composer actions discoverable without competing with the
11
+ * primary send or stop action.
12
+ *
13
+ * Render it in the `left` region of `AIComposerActions` for actions such as
14
+ * attaching a file. Pass a specific `aria-label` or `title` for every icon so
15
+ * assistive technology can identify its purpose.
16
+ * @param props - Icon-button props and the supporting action name.
17
+ * @param props.title - Provides the tooltip and fallback accessible name.
18
+ * @param props.aria-label - Provides a specific accessible action name.
19
+ * @see {@link AIComposerActionProps} for all available props.
20
+ * @remarks
21
+ * The action inherits `state="disabled"` from the parent Composer.
22
+ */
23
+ export declare const AIComposerAction: import('react').ForwardRefExoticComponent<AIComposerActionProps & import('react').RefAttributes<HTMLButtonElement>>;
24
+ export { getActionTitle };
@@ -0,0 +1,27 @@
1
+ import { CircularIconButton as e } from "../../../../../core/components/icon-button/CircularIconButton.js";
2
+ import { useAIComposerContext as t } from "../AIComposer.context.js";
3
+ import { forwardRef as n } from "react";
4
+ import { uyTv as r } from "@payfit/unity-themes";
5
+ import { jsx as i } from "react/jsx-runtime";
6
+ import { useIntl as a } from "react-intl";
7
+ //#region src/modules/ai-kit/components/ai-composer/parts/AIComposerAction.tsx
8
+ var o = r({ base: ["uy:data-[disabled=\"true\"]:bg-surface-neutral-lowest-disabled"] }), s = (e, t, n) => e ?? t ?? n, c = n(({ icon: n, title: r, "aria-label": c, isDisabled: l, ...u }, d) => {
9
+ let f = a(), { state: p } = t(), m = s(r, c, f.formatMessage({
10
+ id: "unity:module:ai-kit:composer:action",
11
+ defaultMessage: "Composer action"
12
+ })), h = o();
13
+ return /* @__PURE__ */ i(e, {
14
+ ...u,
15
+ ref: d,
16
+ asElement: "button",
17
+ icon: n,
18
+ title: m,
19
+ "aria-label": c,
20
+ isDisabled: l || p === "disabled",
21
+ className: h,
22
+ color: "content.neutral.lowest"
23
+ });
24
+ });
25
+ c.displayName = "AIComposerAction";
26
+ //#endregion
27
+ export { c as AIComposerAction, s as getActionTitle };
@@ -0,0 +1,25 @@
1
+ import { ReactNode } from 'react';
2
+ export interface AIComposerActionsProps {
3
+ /** Renders supporting actions, such as attachment controls, on the left. */
4
+ left?: ReactNode;
5
+ /** Renders the primary send or stop action on the right. */
6
+ right?: ReactNode;
7
+ /** Adds layout styling to the action row. */
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Keeps prompt actions predictable by separating supporting controls from the
12
+ * primary send or stop action.
13
+ *
14
+ * Pass secondary `AIComposerAction` controls through `left` and an
15
+ * `AIComposerSubmitAction` through `right`.
16
+ * @param props - The optional left and right action regions.
17
+ * @param props.left - Renders supporting actions on the left.
18
+ * @param props.right - Renders the primary action on the right.
19
+ * @param props.className - Adds layout styling to the action row.
20
+ * @see {@link AIComposerActionsProps} for all available props.
21
+ */
22
+ export declare const AIComposerActions: {
23
+ ({ left, right, className, }: AIComposerActionsProps): import('react/jsx-runtime').JSX.Element;
24
+ displayName: string;
25
+ };
@@ -0,0 +1,25 @@
1
+ import { uyMerge as e, uyTv as t } from "@payfit/unity-themes";
2
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
3
+ //#region src/modules/ai-kit/components/ai-composer/parts/AIComposerActions.tsx
4
+ var i = t({ slots: {
5
+ base: "uy:flex uy:items-center uy:justify-between uy:gap-2 uy:mt-100",
6
+ actionGroup: "uy:flex uy:items-center uy:gap-2"
7
+ } }), a = ({ left: t, right: a, className: o }) => {
8
+ let { base: s, actionGroup: c } = i();
9
+ return /* @__PURE__ */ r("div", {
10
+ className: e(s(), o),
11
+ "data-unity-slot": "actions",
12
+ children: [/* @__PURE__ */ n("div", {
13
+ className: c(),
14
+ "data-unity-slot": "actions-left",
15
+ children: t
16
+ }), /* @__PURE__ */ n("div", {
17
+ className: c(),
18
+ "data-unity-slot": "actions-right",
19
+ children: a
20
+ })]
21
+ });
22
+ };
23
+ a.displayName = "AIComposerActions";
24
+ //#endregion
25
+ export { a as AIComposerActions };
@@ -0,0 +1,31 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ export interface AIComposerAlertProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'className'> {
3
+ /** Renders the actionable feedback message. */
4
+ children: ReactNode;
5
+ /** Selects the visual treatment and live-region priority. */
6
+ variant: 'warning' | 'error';
7
+ /** Adds layout styling to the feedback region. */
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Explains what needs attention without making people lose the prompt they
12
+ * have already written.
13
+ *
14
+ * Render it below `AIComposerTextArea` when the request needs feedback. Set
15
+ * `variant="warning"` for non-blocking guidance and `variant="error"` when a
16
+ * person must resolve a problem before continuing.
17
+ * @param props - Feedback content and its severity variant.
18
+ * @param props.children - Renders the actionable feedback message.
19
+ * @param props.variant - Selects warning or error semantics and treatment.
20
+ * @param props.className - Adds consumer styling to the alert region.
21
+ * @see {@link AIComposerAlertProps} for all available props.
22
+ * @remarks
23
+ * Warnings render `role="status"` with a polite announcement. Errors render
24
+ * `role="alert"` with an assertive announcement. Connect validation errors to
25
+ * the prompt with `aria-describedby` and `aria-invalid` on
26
+ * `AIComposerTextArea`.
27
+ */
28
+ export declare const AIComposerAlert: {
29
+ ({ children, variant, className, ...props }: AIComposerAlertProps): import('react/jsx-runtime').JSX.Element;
30
+ displayName: string;
31
+ };
@@ -0,0 +1,37 @@
1
+ import { Icon as e } from "../../../../../core/components/icon/Icon.js";
2
+ import { uyMerge as t, uyTv as n } from "@payfit/unity-themes";
3
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ //#region src/modules/ai-kit/components/ai-composer/parts/AIComposerAlert.tsx
5
+ var a = n({
6
+ slots: {
7
+ base: "uy:flex uy:items-start uy:gap-50",
8
+ alertMessage: "uy:min-w-0 uy:whitespace-pre-wrap"
9
+ },
10
+ variants: { variant: {
11
+ warning: { alertMessage: "uy:typography-body-small uy:text-content-warning-high" },
12
+ error: { alertMessage: "uy:typography-body-small uy:text-content-danger" }
13
+ } }
14
+ }), o = ({ children: n, variant: o, className: s, ...c }) => {
15
+ let { base: l, alertMessage: u } = a({ variant: o }), d = o === "error" ? "WarningCircleFilled" : "WarningFilled", f = o === "error" ? "content.danger" : "content.warning";
16
+ return /* @__PURE__ */ i("div", {
17
+ ...c,
18
+ role: o === "error" ? "alert" : "status",
19
+ "aria-live": o === "error" ? "assertive" : "polite",
20
+ className: t(l(), s),
21
+ "data-unity-slot": "alert",
22
+ "data-variant": o,
23
+ children: [/* @__PURE__ */ r(e, {
24
+ src: d,
25
+ size: 20,
26
+ color: f,
27
+ "aria-hidden": "true",
28
+ role: "presentation"
29
+ }), /* @__PURE__ */ r("span", {
30
+ className: u(),
31
+ children: n
32
+ })]
33
+ });
34
+ };
35
+ o.displayName = "AIComposerAlert";
36
+ //#endregion
37
+ export { o as AIComposerAlert };
@@ -3,17 +3,36 @@ import { UnityIcon } from '@payfit/unity-icons';
3
3
  import { TagProps } from 'react-aria-components/TagGroup';
4
4
  export type AIComposerAttachmentProps = Omit<TagProps, 'children' | 'className' | 'style'> & {
5
5
  children: ReactNode;
6
- /** Icon displayed before the attachment name. */
6
+ /** Identifies the attachment type before its name. */
7
7
  icon: UnityIcon;
8
- /** Maximum number of characters displayed in the attachment name. */
8
+ /** Limits the visible attachment name without changing its accessible text. */
9
9
  maxCharactersTruncation?: number;
10
+ /** Adds styling to the attachment tag. */
10
11
  className?: string;
11
12
  };
13
+ /**
14
+ * Keeps each selected file identifiable and removable while preserving space
15
+ * for the prompt.
16
+ *
17
+ * Render it inside `AIComposerAttachmentsGroup` with a stable `id` and the
18
+ * full filename as children. Pass `textValue` when children are not a plain
19
+ * string, and use `maxCharactersTruncation` only to shorten the visual label.
20
+ * @param props - Attachment text, icon, and React Aria tag props.
21
+ * @param props.icon - Identifies the attachment type before its name.
22
+ * @param props.maxCharactersTruncation - Sets the visible-name limit. Defaults
23
+ * to `12` while preserving the complete accessible filename.
24
+ * @see {@link AIComposerAttachmentProps} for all available props.
25
+ * @remarks
26
+ * The attachment receives React Aria tag semantics and a localized remove
27
+ * control. It disables itself while the parent Composer is `disabled` or
28
+ * `loading`.
29
+ */
12
30
  export declare const AIComposerAttachment: import('react').ForwardRefExoticComponent<Omit<TagProps, "children" | "className" | "style"> & {
13
31
  children: ReactNode;
14
- /** Icon displayed before the attachment name. */
32
+ /** Identifies the attachment type before its name. */
15
33
  icon: UnityIcon;
16
- /** Maximum number of characters displayed in the attachment name. */
34
+ /** Limits the visible attachment name without changing its accessible text. */
17
35
  maxCharactersTruncation?: number;
36
+ /** Adds styling to the attachment tag. */
18
37
  className?: string;
19
38
  } & import('react').RefAttributes<HTMLDivElement>>;