@assistant-ui/react-native 0.1.46 → 0.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.d.ts +2 -2
- package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js +2 -1
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts +2 -2
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +2 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts +2 -2
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +2 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +55 -38
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/message/MessageContent.d.ts.map +1 -1
- package/dist/primitives/message/MessageContent.js +13 -10
- package/dist/primitives/message/MessageContent.js.map +1 -1
- package/dist/primitives/message/MessageParts.d.ts +1 -0
- package/dist/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/primitives/message/MessageParts.js +22 -3
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/primitives/message.js +1 -1
- package/dist/primitives/messagePart.js +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTitle.d.ts +10 -0
- package/dist/primitives/threadListItem/ThreadListItemTitle.d.ts.map +1 -0
- package/dist/primitives/threadListItem/ThreadListItemTitle.js +47 -0
- package/dist/primitives/threadListItem/ThreadListItemTitle.js.map +1 -0
- package/dist/primitives/threadListItem.d.ts +1 -1
- package/dist/primitives/threadListItem.d.ts.map +1 -1
- package/dist/primitives/threadListItem.js +3 -3
- package/dist/primitives/threadListItem.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +4 -0
- package/src/primitives/actionBar/ActionBar.test.tsx +45 -0
- package/src/primitives/actionBar/ActionBarCopy.tsx +12 -3
- package/src/primitives/actionBar/ActionBarFeedbackNegative.tsx +13 -3
- package/src/primitives/actionBar/ActionBarFeedbackPositive.tsx +13 -3
- package/src/primitives/composer/ComposerInput.test.tsx +64 -4
- package/src/primitives/composer/ComposerInput.tsx +13 -2
- package/src/primitives/message/MessageContent.runtime.test.tsx +35 -0
- package/src/primitives/message/MessageContent.test.tsx +68 -4
- package/src/primitives/message/MessageContent.tsx +19 -9
- package/src/primitives/message/MessageParts.test.tsx +68 -1
- package/src/primitives/message/MessageParts.tsx +17 -1
- package/src/primitives/threadListItem/ThreadListItemTitle.test.tsx +164 -0
- package/src/primitives/threadListItem/ThreadListItemTitle.tsx +23 -0
- package/src/primitives/threadListItem.ts +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageParts.js","names":["FC","Text","MessagePrimitiveParts","MessagePrimitivePartsBase","MessagePartComponent","MessagePartComponentBase","MessagePrimitivePartByIndex","MessagePrimitivePartByIndexBase","messagePartsDefaultComponents","
|
|
1
|
+
{"version":3,"file":"MessageParts.js","names":["FC","Text","MessagePrimitiveParts","MessagePrimitivePartsBase","MessagePartComponent","MessagePartComponentBase","MessagePrimitivePartByIndex","MessagePrimitivePartByIndexBase","messagePartsDefaultComponents","MessagePartPrimitiveImage","DEFAULT_IMAGE_STYLE","width","aspectRatio","const","DefaultMessageImage","$","_c","t0","Symbol","for","rnDefaultComponents","text","Image","Props","props","children","components","rest","merged","t1","t2","displayName","_c","MessagePrimitivePartsBase","merged"],"sources":["../../../src/primitives/message/MessageParts.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { Text } from \"react-native\";\nimport {\n MessagePrimitiveParts as MessagePrimitivePartsBase,\n MessagePartComponent as MessagePartComponentBase,\n MessagePrimitivePartByIndex as MessagePrimitivePartByIndexBase,\n messagePartsDefaultComponents,\n} from \"@assistant-ui/core/react\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\n\n// React Native derives no intrinsic size from a remote or data URI, so an\n// Image with no dimensions lays out at zero. The default fills the available\n// width and keeps the picture whole inside a square box; a consumer that knows\n// its own aspect ratio overrides `components.Image`.\nconst DEFAULT_IMAGE_STYLE = { width: \"100%\", aspectRatio: 1 } as const;\n\nexport const DefaultMessageImage = () => (\n <MessagePartPrimitiveImage style={DEFAULT_IMAGE_STYLE} resizeMode=\"contain\" />\n);\n\nconst rnDefaultComponents = {\n ...messagePartsDefaultComponents,\n Text: ({ text }: { text: string }) => <Text>{text}</Text>,\n Image: DefaultMessageImage,\n} satisfies MessagePrimitiveParts.Props[\"components\"];\n\nexport namespace MessagePrimitiveParts {\n export type Props = MessagePrimitivePartsBase.Props;\n}\n\n/**\n * Renders the parts of a message with React Native-specific default components.\n */\nexport const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = (\n props,\n) => {\n if (\"children\" in props) {\n return (\n <MessagePrimitivePartsBase>{props.children}</MessagePrimitivePartsBase>\n );\n }\n\n const { components, ...rest } = props;\n const merged = components\n ? {\n ...components,\n Text: components.Text ?? rnDefaultComponents.Text,\n Image: components.Image ?? rnDefaultComponents.Image,\n }\n : rnDefaultComponents;\n\n return <MessagePrimitivePartsBase components={merged as any} {...rest} />;\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n\nexport {\n MessagePartComponentBase as MessagePartComponent,\n MessagePrimitivePartByIndexBase as MessagePrimitivePartByIndex,\n};\n"],"mappings":";;;;;;AAcA,MAAMU,sBAAsB;CAAEC,OAAO;CAAQC,aAAa;AAAE;AAE5D,MAAaE,4BAAsB;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACjCF,KAAA,oBAAC,2BAAD;GAAkCP,OAAAA;GAAgC,YAAA;EAAS,CAAA;EAAGK,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAA9EE;AAA8E;AAGhF,MAAMG,sBAAsB;CAC1B,GAAGZ;CACHP,OAAO,EAAEoB,WAA6B,oBAAC,MAAD,EAAA,UAAOA,KAAW,CAAA;CACxDC,OAAOR;AACT;;;;AASA,MAAaZ,yBAAyDsB,UAAA;CAAA,MAAAT,IAAAC,EAAA,EAAA;CAGpE,IAAI,cAAcQ,OAAK;EAAA,IAAAP;EAAA,IAAAF,EAAA,OAAAS,MAAAC,UAAA;GAEnBR,KAAA,oBAACgB,yBAAD,EAAA,UAA4BT,MAAKC,SAAP,CAAA;GAA6CV,EAAA,KAAAS,MAAAC;GAAAV,EAAA,KAAAE;EAAA,OAAAA,KAAAF,EAAA;EAAA,OAAvEE;CAAuE;CAE1E,IAAAS;CAAA,IAAAC;CAAA,IAAAZ,EAAA,OAAAS,OAAA;EAED,CAAA,CAAAE,YAAA,GAAAC,QAAgCH;EAAMT,EAAA,KAAAS;EAAAT,EAAA,KAAAW;EAAAX,EAAA,KAAAY;CAAA,OAAA;EAAAD,aAAAX,EAAA;EAAAY,OAAAZ,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAW,YAAA;EACvBT,KAAAS,aAAA;GAAA,GAENA;GAAUzB,MACPyB,WAAUzB,QAASmB,oBAAmBnB;GAAKqB,OAC1CI,WAAUJ,SAAUF,oBAAmBE;EAE9B,IANPF;EAMQL,EAAA,KAAAW;EAAAX,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAEuB,MAAAc,KAAAD;CAAa,IAAAE;CAAA,IAAAf,EAAA,OAAAY,QAAAZ,EAAA,OAAAc,IAAA;EAApDC,KAAA,oBAACG,yBAAD;GAAuC,YAAAJ;GAAa,GAAMF;EAAI,CAAA;EAAIZ,EAAA,KAAAY;EAAAZ,EAAA,KAAAc;EAAAd,EAAA,KAAAe;CAAA,OAAAA,KAAAf,EAAA;CAAA,OAAlEe;AAAkE;AAG3E5B,sBAAsB6B,cAAc"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { MessageRoot } from "./message/MessageRoot.js";
|
|
3
|
-
import { MessageContent } from "./message/MessageContent.js";
|
|
4
3
|
import { MessagePrimitivePartByIndex as MessagePrimitivePartByIndexBase, MessagePrimitiveParts } from "./message/MessageParts.js";
|
|
4
|
+
import { MessageContent } from "./message/MessageContent.js";
|
|
5
5
|
import { MessageIf } from "./message/MessageIf.js";
|
|
6
6
|
import { MessageAttachmentByIndex, MessageAttachments } from "./message/MessageAttachments.js";
|
|
7
7
|
import { MessagePrimitiveGroupedParts as GroupedParts, MessagePrimitiveQuote as Quote } from "@assistant-ui/core/react";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { MessagePartPrimitiveText } from "./messagePart/MessagePartText.js";
|
|
3
2
|
import { MessagePartPrimitiveImage } from "./messagePart/MessagePartImage.js";
|
|
3
|
+
import { MessagePartPrimitiveText } from "./messagePart/MessagePartText.js";
|
|
4
4
|
import { MessagePartPrimitiveInProgress } from "./messagePart/MessagePartInProgress.js";
|
|
5
5
|
import { PartPrimitiveMessages as Messages } from "@assistant-ui/core/react";
|
|
6
6
|
//#region src/primitives/messagePart.ts
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type TextProps } from "react-native";
|
|
3
|
+
export type ThreadListItemTitleProps = Omit<TextProps, "children"> & {
|
|
4
|
+
fallback?: ReactNode;
|
|
5
|
+
};
|
|
6
|
+
export declare function ThreadListItemTitle({ fallback, ...props }: ThreadListItemTitleProps): import("react").JSX.Element;
|
|
7
|
+
export declare namespace ThreadListItemTitle {
|
|
8
|
+
type Props = ThreadListItemTitleProps;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ThreadListItemTitle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListItemTitle.d.ts","sourceRoot":"","sources":["../../../src/primitives/threadListItem/ThreadListItemTitle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpD,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG;IACnE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,wBAAwB,+BAO1B;AAED,yBAAiB,mBAAmB,CAAC;IACnC,KAAY,KAAK,GAAG,wBAAwB,CAAC;CAC9C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
2
|
+
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
3
|
+
import { Text } from "react-native";
|
|
4
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/primitives/threadListItem/ThreadListItemTitle.tsx
|
|
6
|
+
function ThreadListItemTitle(t0) {
|
|
7
|
+
const $ = c(8);
|
|
8
|
+
let fallback;
|
|
9
|
+
let props;
|
|
10
|
+
if ($[0] !== t0) {
|
|
11
|
+
({fallback, ...props} = t0);
|
|
12
|
+
$[0] = t0;
|
|
13
|
+
$[1] = fallback;
|
|
14
|
+
$[2] = props;
|
|
15
|
+
} else {
|
|
16
|
+
fallback = $[1];
|
|
17
|
+
props = $[2];
|
|
18
|
+
}
|
|
19
|
+
const content = useAuiState(_temp) || fallback;
|
|
20
|
+
if (typeof content === "string" || typeof content === "number") {
|
|
21
|
+
let t1;
|
|
22
|
+
if ($[3] !== content || $[4] !== props) {
|
|
23
|
+
t1 = /* @__PURE__ */ jsx(Text, {
|
|
24
|
+
...props,
|
|
25
|
+
children: content
|
|
26
|
+
});
|
|
27
|
+
$[3] = content;
|
|
28
|
+
$[4] = props;
|
|
29
|
+
$[5] = t1;
|
|
30
|
+
} else t1 = $[5];
|
|
31
|
+
return t1;
|
|
32
|
+
}
|
|
33
|
+
let t1;
|
|
34
|
+
if ($[6] !== content) {
|
|
35
|
+
t1 = /* @__PURE__ */ jsx(Fragment, { children: content });
|
|
36
|
+
$[6] = content;
|
|
37
|
+
$[7] = t1;
|
|
38
|
+
} else t1 = $[7];
|
|
39
|
+
return t1;
|
|
40
|
+
}
|
|
41
|
+
function _temp(s) {
|
|
42
|
+
return s.threadListItem.title;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { ThreadListItemTitle };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=ThreadListItemTitle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListItemTitle.js","names":["ReactNode","Text","TextProps","useAuiState","ThreadListItemTitleProps","Omit","fallback","ThreadListItemTitle","t0","$","_c","props","title","_temp","content","t1","s","threadListItem","Props","_c"],"sources":["../../../src/primitives/threadListItem/ThreadListItemTitle.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Text, type TextProps } from \"react-native\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\nexport type ThreadListItemTitleProps = Omit<TextProps, \"children\"> & {\n fallback?: ReactNode;\n};\n\nexport function ThreadListItemTitle({\n fallback,\n ...props\n}: ThreadListItemTitleProps) {\n const title = useAuiState((s) => s.threadListItem.title);\n const content = title || fallback;\n if (typeof content === \"string\" || typeof content === \"number\") {\n return <Text {...props}>{content}</Text>;\n }\n return <>{content}</>;\n}\n\nexport namespace ThreadListItemTitle {\n export type Props = ThreadListItemTitleProps;\n}\n"],"mappings":";;;;;AAQA,SAAOO,oBAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAA,IAAAJ;CAAA,IAAAK;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAA6B,CAAA,CAAAF,UAAA,GAAAK,SAAAH;EAGTC,EAAA,KAAAD;EAAAC,EAAA,KAAAH;EAAAG,EAAA,KAAAE;CAAA,OAAA;EAAAL,WAAAG,EAAA;EAAAE,QAAAF,EAAA;CAAA;CAEzB,MAAAK,UADcX,YAAYU,KACVD,KAAAN;CAChB,IAAI,OAAOQ,YAAY,YAAY,OAAOA,YAAY,UAAQ;EAAA,IAAAC;EAAA,IAAAN,EAAA,OAAAK,WAAAL,EAAA,OAAAE,OAAA;GACrDI,KAAA,oBAAC,MAAD;IAAK,GAAKJ;IAAQG,UAAAA;GAAb,CAAA;GAA4BL,EAAA,KAAAK;GAAAL,EAAA,KAAAE;GAAAF,EAAA,KAAAM;EAAA,OAAAA,KAAAN,EAAA;EAAA,OAAjCM;CAAiC;CACzC,IAAAA;CAAA,IAAAN,EAAA,OAAAK,SAAA;EACMC,KAAA,oBAAA,UAAA,EAAA,UAAGD,QAAO,CAAA;EAAIL,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,OAAdM;AAAc;AAThB,SAAAF,MAAAG,GAAA;CAAA,OAI4BA,EAACC,eAAeL;AAAM"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ThreadListItemRoot as Root, type ThreadListItemRootProps as RootProps, } from "./threadListItem/ThreadListItemRoot.js";
|
|
2
|
-
export {
|
|
2
|
+
export { ThreadListItemTitle as Title, type ThreadListItemTitleProps as TitleProps, } from "./threadListItem/ThreadListItemTitle.js";
|
|
3
3
|
export { ThreadListItemTrigger as Trigger, type ThreadListItemTriggerProps as TriggerProps, } from "./threadListItem/ThreadListItemTrigger.js";
|
|
4
4
|
export { ThreadListItemDelete as Delete, type ThreadListItemDeleteProps as DeleteProps, } from "./threadListItem/ThreadListItemDelete.js";
|
|
5
5
|
export { ThreadListItemArchive as Archive, type ThreadListItemArchiveProps as ArchiveProps, } from "./threadListItem/ThreadListItemArchive.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threadListItem.d.ts","sourceRoot":"","sources":["../../src/primitives/threadListItem.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,IAAI,IAAI,EAC1B,KAAK,uBAAuB,IAAI,SAAS,GAC1C,+CAA4C;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"threadListItem.d.ts","sourceRoot":"","sources":["../../src/primitives/threadListItem.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,IAAI,IAAI,EAC1B,KAAK,uBAAuB,IAAI,SAAS,GAC1C,+CAA4C;AAC7C,OAAO,EACL,mBAAmB,IAAI,KAAK,EAC5B,KAAK,wBAAwB,IAAI,UAAU,GAC5C,gDAA6C;AAC9C,OAAO,EACL,qBAAqB,IAAI,OAAO,EAChC,KAAK,0BAA0B,IAAI,YAAY,GAChD,kDAA+C;AAChD,OAAO,EACL,oBAAoB,IAAI,MAAM,EAC9B,KAAK,yBAAyB,IAAI,WAAW,GAC9C,iDAA8C;AAC/C,OAAO,EACL,qBAAqB,IAAI,OAAO,EAChC,KAAK,0BAA0B,IAAI,YAAY,GAChD,kDAA+C;AAChD,OAAO,EACL,uBAAuB,IAAI,SAAS,EACpC,KAAK,4BAA4B,IAAI,cAAc,GACpD,oDAAiD"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { ThreadListItemRoot } from "./threadListItem/ThreadListItemRoot.js";
|
|
3
|
+
import { ThreadListItemTitle } from "./threadListItem/ThreadListItemTitle.js";
|
|
3
4
|
import { ThreadListItemTrigger } from "./threadListItem/ThreadListItemTrigger.js";
|
|
4
5
|
import { ThreadListItemDelete } from "./threadListItem/ThreadListItemDelete.js";
|
|
5
6
|
import { ThreadListItemArchive } from "./threadListItem/ThreadListItemArchive.js";
|
|
6
7
|
import { ThreadListItemUnarchive } from "./threadListItem/ThreadListItemUnarchive.js";
|
|
7
|
-
import { ThreadListItemPrimitiveTitle as Title } from "@assistant-ui/core/react";
|
|
8
8
|
//#region src/primitives/threadListItem.ts
|
|
9
9
|
var threadListItem_exports = /* @__PURE__ */ __exportAll({
|
|
10
10
|
Archive: () => ThreadListItemArchive,
|
|
11
11
|
Delete: () => ThreadListItemDelete,
|
|
12
12
|
Root: () => ThreadListItemRoot,
|
|
13
|
-
Title: () =>
|
|
13
|
+
Title: () => ThreadListItemTitle,
|
|
14
14
|
Trigger: () => ThreadListItemTrigger,
|
|
15
15
|
Unarchive: () => ThreadListItemUnarchive
|
|
16
16
|
});
|
|
17
17
|
//#endregion
|
|
18
|
-
export { ThreadListItemArchive as Archive, ThreadListItemDelete as Delete, ThreadListItemRoot as Root, Title, ThreadListItemTrigger as Trigger, ThreadListItemUnarchive as Unarchive, threadListItem_exports };
|
|
18
|
+
export { ThreadListItemArchive as Archive, ThreadListItemDelete as Delete, ThreadListItemRoot as Root, ThreadListItemTitle as Title, ThreadListItemTrigger as Trigger, ThreadListItemUnarchive as Unarchive, threadListItem_exports };
|
|
19
19
|
|
|
20
20
|
//# sourceMappingURL=threadListItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threadListItem.js","names":["ThreadListItemRoot","Root","ThreadListItemRootProps","RootProps","
|
|
1
|
+
{"version":3,"file":"threadListItem.js","names":["ThreadListItemRoot","Root","ThreadListItemRootProps","RootProps","ThreadListItemTitle","Title","ThreadListItemTitleProps","TitleProps","ThreadListItemTrigger","Trigger","ThreadListItemTriggerProps","TriggerProps","ThreadListItemDelete","Delete","ThreadListItemDeleteProps","DeleteProps","ThreadListItemArchive","Archive","ThreadListItemArchiveProps","ArchiveProps","ThreadListItemUnarchive","Unarchive","ThreadListItemUnarchiveProps","UnarchiveProps"],"sources":["../../src/primitives/threadListItem.ts"],"sourcesContent":["export {\n ThreadListItemRoot as Root,\n type ThreadListItemRootProps as RootProps,\n} from \"./threadListItem/ThreadListItemRoot\";\nexport {\n ThreadListItemTitle as Title,\n type ThreadListItemTitleProps as TitleProps,\n} from \"./threadListItem/ThreadListItemTitle\";\nexport {\n ThreadListItemTrigger as Trigger,\n type ThreadListItemTriggerProps as TriggerProps,\n} from \"./threadListItem/ThreadListItemTrigger\";\nexport {\n ThreadListItemDelete as Delete,\n type ThreadListItemDeleteProps as DeleteProps,\n} from \"./threadListItem/ThreadListItemDelete\";\nexport {\n ThreadListItemArchive as Archive,\n type ThreadListItemArchiveProps as ArchiveProps,\n} from \"./threadListItem/ThreadListItemArchive\";\nexport {\n ThreadListItemUnarchive as Unarchive,\n type ThreadListItemUnarchiveProps as UnarchiveProps,\n} from \"./threadListItem/ThreadListItemUnarchive\";\n"],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-native",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.47",
|
|
4
4
|
"description": "React Native bindings for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"assistant",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
],
|
|
32
32
|
"sideEffects": false,
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@assistant-ui/core": "^0.3.
|
|
35
|
-
"@assistant-ui/store": "^0.3.
|
|
36
|
-
"@assistant-ui/tap": "^0.9.
|
|
37
|
-
"assistant-cloud": "^0.2.
|
|
38
|
-
"assistant-stream": "^0.3.
|
|
34
|
+
"@assistant-ui/core": "^0.3.25",
|
|
35
|
+
"@assistant-ui/store": "^0.3.18",
|
|
36
|
+
"@assistant-ui/tap": "^0.9.22",
|
|
37
|
+
"assistant-cloud": "^0.2.6",
|
|
38
|
+
"assistant-stream": "^0.3.49"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@types/react": "*",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@babel/core": "^7.29.7",
|
|
54
54
|
"@types/react": "^19.3.0",
|
|
55
55
|
"@types/react-dom": "^19.3.0",
|
|
56
|
-
"jsdom": "^30.
|
|
56
|
+
"jsdom": "^30.1.2",
|
|
57
57
|
"react": "^19.3.0",
|
|
58
58
|
"react-dom": "^19.3.0",
|
|
59
59
|
"react-native": "^0.87.1",
|
package/src/index.ts
CHANGED
|
@@ -160,9 +160,13 @@ export {
|
|
|
160
160
|
useExternalStoreRuntime,
|
|
161
161
|
useExternalStoreSharedOptions,
|
|
162
162
|
useExternalMessageConverter,
|
|
163
|
+
/** @deprecated Experimental since 2025-01-26. Not scheduled for removal; the API may change in any release. */
|
|
163
164
|
convertExternalMessages as unstable_convertExternalMessages,
|
|
165
|
+
/** @deprecated Experimental since 2026-09-15. Not scheduled for removal; the API may change in any release. */
|
|
164
166
|
createExternalMessageConversionCache as unstable_createExternalMessageConversionCache,
|
|
167
|
+
/** @deprecated Experimental since 2025-02-02. Not scheduled for removal; the API may change in any release. */
|
|
165
168
|
createMessageConverter as unstable_createMessageConverter,
|
|
169
|
+
/** @deprecated Experimental since 2026-09-15. Not scheduled for removal; the API may change in any release. */
|
|
166
170
|
type ExternalMessageConversionCache as Unstable_ExternalMessageConversionCache,
|
|
167
171
|
type JoinStrategy,
|
|
168
172
|
} from "@assistant-ui/core/react";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { act, type ReactNode } from "react";
|
|
2
2
|
import { createRoot, type Root } from "react-dom/client";
|
|
3
|
+
import { Text } from "react-native";
|
|
3
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
5
|
import { ActionBarCopy } from "./ActionBarCopy";
|
|
5
6
|
import { ActionBarEdit } from "./ActionBarEdit";
|
|
@@ -222,6 +223,50 @@ describe("ActionBar", () => {
|
|
|
222
223
|
return container.querySelector('[data-testid="t"]') as HTMLElement;
|
|
223
224
|
};
|
|
224
225
|
|
|
226
|
+
const assertRenderState = async <TState extends object>(
|
|
227
|
+
render: (children: (state: TState) => ReactNode) => ReactNode,
|
|
228
|
+
expectedState: TState,
|
|
229
|
+
) => {
|
|
230
|
+
let renderState: unknown;
|
|
231
|
+
await mount(
|
|
232
|
+
render((state) => {
|
|
233
|
+
renderState = state;
|
|
234
|
+
return <Text>label</Text>;
|
|
235
|
+
}),
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
expect(renderState).toMatchObject(expectedState);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
it("ActionBarCopy passes Pressable state alongside isCopied", async () => {
|
|
242
|
+
await assertRenderState(
|
|
243
|
+
(children) => <ActionBarCopy testID="t">{children}</ActionBarCopy>,
|
|
244
|
+
{ pressed: false, disabled: false, isCopied: false },
|
|
245
|
+
);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("ActionBarFeedbackPositive passes Pressable state alongside isSubmitted", async () => {
|
|
249
|
+
await assertRenderState(
|
|
250
|
+
(children) => (
|
|
251
|
+
<ActionBarFeedbackPositive testID="t">
|
|
252
|
+
{children}
|
|
253
|
+
</ActionBarFeedbackPositive>
|
|
254
|
+
),
|
|
255
|
+
{ pressed: false, disabled: false, isSubmitted: false },
|
|
256
|
+
);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("ActionBarFeedbackNegative passes Pressable state alongside isSubmitted", async () => {
|
|
260
|
+
await assertRenderState(
|
|
261
|
+
(children) => (
|
|
262
|
+
<ActionBarFeedbackNegative testID="t">
|
|
263
|
+
{children}
|
|
264
|
+
</ActionBarFeedbackNegative>
|
|
265
|
+
),
|
|
266
|
+
{ pressed: false, disabled: false, isSubmitted: false },
|
|
267
|
+
);
|
|
268
|
+
});
|
|
269
|
+
|
|
225
270
|
for (const actionBar of actionBars) {
|
|
226
271
|
describe(actionBar.name, () => {
|
|
227
272
|
it("passes the effective disabled state to render children", async () => {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Pressable,
|
|
4
|
+
type PressableProps,
|
|
5
|
+
type PressableStateCallbackType,
|
|
6
|
+
} from "react-native";
|
|
3
7
|
import {
|
|
4
8
|
useActionBarCopy,
|
|
5
9
|
type UseActionBarCopyOptions,
|
|
@@ -9,7 +13,12 @@ export type ActionBarCopyProps = Omit<PressableProps, "onPress" | "children"> &
|
|
|
9
13
|
UseActionBarCopyOptions & {
|
|
10
14
|
children:
|
|
11
15
|
| ReactNode
|
|
12
|
-
| ((
|
|
16
|
+
| ((
|
|
17
|
+
props: PressableStateCallbackType & {
|
|
18
|
+
isCopied: boolean;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
},
|
|
21
|
+
) => ReactNode);
|
|
13
22
|
};
|
|
14
23
|
|
|
15
24
|
export const ActionBarCopy = ({
|
|
@@ -33,7 +42,7 @@ export const ActionBarCopy = ({
|
|
|
33
42
|
{...pressableProps}
|
|
34
43
|
>
|
|
35
44
|
{typeof children === "function"
|
|
36
|
-
? children({ isCopied, disabled: isDisabled })
|
|
45
|
+
? (state) => children({ ...state, isCopied, disabled: isDisabled })
|
|
37
46
|
: children}
|
|
38
47
|
</Pressable>
|
|
39
48
|
);
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Platform,
|
|
4
|
+
Pressable,
|
|
5
|
+
type PressableProps,
|
|
6
|
+
type PressableStateCallbackType,
|
|
7
|
+
} from "react-native";
|
|
3
8
|
import { useActionBarFeedbackNegative } from "@assistant-ui/core/react";
|
|
4
9
|
|
|
5
10
|
export type ActionBarFeedbackNegativeProps = Omit<
|
|
@@ -8,7 +13,12 @@ export type ActionBarFeedbackNegativeProps = Omit<
|
|
|
8
13
|
> & {
|
|
9
14
|
children:
|
|
10
15
|
| ReactNode
|
|
11
|
-
| ((
|
|
16
|
+
| ((
|
|
17
|
+
props: PressableStateCallbackType & {
|
|
18
|
+
isSubmitted: boolean;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
},
|
|
21
|
+
) => ReactNode);
|
|
12
22
|
};
|
|
13
23
|
|
|
14
24
|
export const ActionBarFeedbackNegative = ({
|
|
@@ -30,7 +40,7 @@ export const ActionBarFeedbackNegative = ({
|
|
|
30
40
|
{...pressableProps}
|
|
31
41
|
>
|
|
32
42
|
{typeof children === "function"
|
|
33
|
-
? children({ isSubmitted, disabled })
|
|
43
|
+
? (state) => children({ ...state, isSubmitted, disabled })
|
|
34
44
|
: children}
|
|
35
45
|
</Pressable>
|
|
36
46
|
);
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Platform,
|
|
4
|
+
Pressable,
|
|
5
|
+
type PressableProps,
|
|
6
|
+
type PressableStateCallbackType,
|
|
7
|
+
} from "react-native";
|
|
3
8
|
import { useActionBarFeedbackPositive } from "@assistant-ui/core/react";
|
|
4
9
|
|
|
5
10
|
export type ActionBarFeedbackPositiveProps = Omit<
|
|
@@ -8,7 +13,12 @@ export type ActionBarFeedbackPositiveProps = Omit<
|
|
|
8
13
|
> & {
|
|
9
14
|
children:
|
|
10
15
|
| ReactNode
|
|
11
|
-
| ((
|
|
16
|
+
| ((
|
|
17
|
+
props: PressableStateCallbackType & {
|
|
18
|
+
isSubmitted: boolean;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
},
|
|
21
|
+
) => ReactNode);
|
|
12
22
|
};
|
|
13
23
|
|
|
14
24
|
export const ActionBarFeedbackPositive = ({
|
|
@@ -30,7 +40,7 @@ export const ActionBarFeedbackPositive = ({
|
|
|
30
40
|
{...pressableProps}
|
|
31
41
|
>
|
|
32
42
|
{typeof children === "function"
|
|
33
|
-
? children({ isSubmitted, disabled })
|
|
43
|
+
? (state) => children({ ...state, isSubmitted, disabled })
|
|
34
44
|
: children}
|
|
35
45
|
</Pressable>
|
|
36
46
|
);
|
|
@@ -8,7 +8,12 @@ const h = vi.hoisted(() => ({
|
|
|
8
8
|
sendSpy: vi.fn<() => void>(),
|
|
9
9
|
flushTapSyncSpy: vi.fn(<T,>(fn: () => T) => fn()),
|
|
10
10
|
composerState: { text: "" },
|
|
11
|
-
threadState: {
|
|
11
|
+
threadState: {
|
|
12
|
+
isRunning: false,
|
|
13
|
+
queue: false,
|
|
14
|
+
voice: false,
|
|
15
|
+
isDisabled: false,
|
|
16
|
+
},
|
|
12
17
|
platform: { os: "web" as "web" | "ios" | "android" },
|
|
13
18
|
}));
|
|
14
19
|
|
|
@@ -28,12 +33,20 @@ vi.mock("@assistant-ui/store", () => {
|
|
|
28
33
|
return {
|
|
29
34
|
useAui: () => aui,
|
|
30
35
|
useAuiState: <T,>(
|
|
31
|
-
selector: (s: {
|
|
32
|
-
|
|
36
|
+
selector: (s: {
|
|
37
|
+
composer: typeof h.composerState;
|
|
38
|
+
thread: { isDisabled: boolean };
|
|
39
|
+
}) => T,
|
|
40
|
+
) =>
|
|
41
|
+
selector({
|
|
42
|
+
composer: h.composerState,
|
|
43
|
+
thread: { isDisabled: h.threadState.isDisabled },
|
|
44
|
+
}),
|
|
33
45
|
};
|
|
34
46
|
});
|
|
35
47
|
|
|
36
|
-
vi.mock("@assistant-ui/tap", () => ({
|
|
48
|
+
vi.mock("@assistant-ui/tap", async (importOriginal) => ({
|
|
49
|
+
...(await importOriginal<typeof import("@assistant-ui/tap")>()),
|
|
37
50
|
flushTapSync: h.flushTapSyncSpy,
|
|
38
51
|
}));
|
|
39
52
|
|
|
@@ -111,6 +124,7 @@ describe("ComposerInput", () => {
|
|
|
111
124
|
h.threadState.isRunning = false;
|
|
112
125
|
h.threadState.queue = false;
|
|
113
126
|
h.threadState.voice = false;
|
|
127
|
+
h.threadState.isDisabled = false;
|
|
114
128
|
h.platform.os = "web";
|
|
115
129
|
|
|
116
130
|
container = document.createElement("div");
|
|
@@ -421,4 +435,50 @@ describe("ComposerInput", () => {
|
|
|
421
435
|
expect(onKeyPress).toHaveBeenCalledTimes(1);
|
|
422
436
|
});
|
|
423
437
|
});
|
|
438
|
+
|
|
439
|
+
describe("disabled thread", () => {
|
|
440
|
+
beforeEach(() => {
|
|
441
|
+
h.threadState.isDisabled = true;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it("makes the input non-editable", async () => {
|
|
445
|
+
const input = await mount();
|
|
446
|
+
expect(input.disabled || input.readOnly).toBe(true);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it("does not let editable props override the disabled thread", async () => {
|
|
450
|
+
const input = await mount({ editable: true, readOnly: false });
|
|
451
|
+
expect(input.readOnly).toBe(true);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
it("ignores text changes", async () => {
|
|
455
|
+
const input = await mount();
|
|
456
|
+
await act(async () => fireInput(input, "hello"));
|
|
457
|
+
expect(h.setText).not.toHaveBeenCalled();
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it("does not submit on Enter", async () => {
|
|
461
|
+
const input = await mount();
|
|
462
|
+
await act(async () => fireKeyDown(input, { key: "Enter" }));
|
|
463
|
+
expect(h.sendSpy).not.toHaveBeenCalled();
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it("forwards caller key handlers while blocking submission", async () => {
|
|
467
|
+
const onKeyPress = vi.fn();
|
|
468
|
+
const input = await mount({ onKeyPress });
|
|
469
|
+
|
|
470
|
+
await act(async () => {
|
|
471
|
+
fireKeyDown(input, { key: "Escape" });
|
|
472
|
+
fireKeyDown(input, { key: "Enter" });
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
expect(onKeyPress).toHaveBeenCalledTimes(2);
|
|
476
|
+
expect(h.sendSpy).not.toHaveBeenCalled();
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it("preserves a caller-provided non-editable setting", async () => {
|
|
481
|
+
const input = await mount({ editable: false });
|
|
482
|
+
expect(input.readOnly).toBe(true);
|
|
483
|
+
});
|
|
424
484
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import { Platform, TextInput, type TextInputProps } from "react-native";
|
|
3
|
+
import { composerInputDisabled } from "@assistant-ui/core/store/internal";
|
|
3
4
|
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
4
5
|
import { flushTapSync } from "@assistant-ui/tap";
|
|
5
6
|
|
|
@@ -59,14 +60,19 @@ export const ComposerInput = ({
|
|
|
59
60
|
onKeyPress: onKeyPressProp,
|
|
60
61
|
numberOfLines,
|
|
61
62
|
style,
|
|
63
|
+
editable,
|
|
64
|
+
readOnly,
|
|
62
65
|
...props
|
|
63
66
|
}: ComposerInputProps) => {
|
|
64
67
|
const aui = useAui();
|
|
65
68
|
const text = useAuiState((s) => s.composer.text);
|
|
69
|
+
const isInputDisabled = useAuiState(composerInputDisabled);
|
|
66
70
|
const inputRef = useRef<TextInputInstance>(null);
|
|
67
71
|
|
|
68
72
|
const onChangeText = useCallback(
|
|
69
73
|
(value: string) => {
|
|
74
|
+
if (isInputDisabled) return;
|
|
75
|
+
|
|
70
76
|
if (Platform.OS === "web") {
|
|
71
77
|
// Keep the controlled value in sync mid-IME so react-dom does not reset the textarea to a stale value
|
|
72
78
|
flushTapSync(() => {
|
|
@@ -76,7 +82,7 @@ export const ComposerInput = ({
|
|
|
76
82
|
}
|
|
77
83
|
aui.composer.setText(value);
|
|
78
84
|
},
|
|
79
|
-
[aui],
|
|
85
|
+
[aui, isInputDisabled],
|
|
80
86
|
);
|
|
81
87
|
|
|
82
88
|
// Auto-resize textarea on web when text changes
|
|
@@ -89,6 +95,7 @@ export const ComposerInput = ({
|
|
|
89
95
|
(e: TextInputKeyPressEvent) => {
|
|
90
96
|
onKeyPressProp?.(e);
|
|
91
97
|
if (e.isDefaultPrevented()) return;
|
|
98
|
+
if (isInputDisabled) return;
|
|
92
99
|
|
|
93
100
|
if (Platform.OS !== "web") return;
|
|
94
101
|
if (submitMode !== "enter") return;
|
|
@@ -113,9 +120,11 @@ export const ComposerInput = ({
|
|
|
113
120
|
aui.composer.send();
|
|
114
121
|
}
|
|
115
122
|
},
|
|
116
|
-
[aui, submitMode, onKeyPressProp],
|
|
123
|
+
[aui, isInputDisabled, submitMode, onKeyPressProp],
|
|
117
124
|
);
|
|
118
125
|
|
|
126
|
+
const isReadOnly = isInputDisabled || editable === false || readOnly === true;
|
|
127
|
+
|
|
119
128
|
return (
|
|
120
129
|
<TextInput
|
|
121
130
|
ref={inputRef}
|
|
@@ -123,6 +132,8 @@ export const ComposerInput = ({
|
|
|
123
132
|
onChangeText={onChangeText}
|
|
124
133
|
onKeyPress={onKeyPress}
|
|
125
134
|
numberOfLines={numberOfLines ?? (Platform.OS === "web" ? 1 : undefined)}
|
|
135
|
+
editable={editable}
|
|
136
|
+
readOnly={isReadOnly}
|
|
126
137
|
style={style}
|
|
127
138
|
{...props}
|
|
128
139
|
/>
|
|
@@ -14,6 +14,41 @@ import { MessageContent } from "./MessageContent";
|
|
|
14
14
|
(globalThis as Record<string, unknown>).IS_REACT_ACT_ENVIRONMENT = true;
|
|
15
15
|
|
|
16
16
|
describe("MessageContent with a runtime", () => {
|
|
17
|
+
it("renders a default image after a text part", async () => {
|
|
18
|
+
const image = "data:image/png;base64,iVBORw0KGgo=";
|
|
19
|
+
const App = () => {
|
|
20
|
+
const runtime = useExternalStoreRuntime({
|
|
21
|
+
messages: [
|
|
22
|
+
{
|
|
23
|
+
role: "assistant",
|
|
24
|
+
content: [
|
|
25
|
+
{ type: "text", text: "lead" },
|
|
26
|
+
{ type: "image", image },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
] satisfies ThreadMessageLike[],
|
|
30
|
+
convertMessage: (value) => value,
|
|
31
|
+
onNew: async () => {},
|
|
32
|
+
});
|
|
33
|
+
return (
|
|
34
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
35
|
+
<MessageByIndexProvider index={0}>
|
|
36
|
+
<MessageContent />
|
|
37
|
+
</MessageByIndexProvider>
|
|
38
|
+
</AssistantRuntimeProvider>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
const container = document.createElement("div");
|
|
42
|
+
const root = createRoot(container);
|
|
43
|
+
try {
|
|
44
|
+
await act(async () => root.render(<App />));
|
|
45
|
+
expect(container.textContent).toContain("lead");
|
|
46
|
+
expect(container.querySelector("img")?.getAttribute("src")).toBe(image);
|
|
47
|
+
} finally {
|
|
48
|
+
await act(async () => root.unmount());
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
17
52
|
it.each(["tool-call", "data"] as const)(
|
|
18
53
|
"renders derived status for registered %s UIs",
|
|
19
54
|
async (type) => {
|