@assistant-ui/react 0.7.2 → 0.7.3

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 (55) hide show
  1. package/dist/api/ContentPartRuntime.d.ts +5 -1
  2. package/dist/api/ContentPartRuntime.d.ts.map +1 -1
  3. package/dist/api/ContentPartRuntime.js.map +1 -1
  4. package/dist/api/ContentPartRuntime.mjs.map +1 -1
  5. package/dist/api/RuntimePathTypes.d.ts +0 -3
  6. package/dist/api/RuntimePathTypes.d.ts.map +1 -1
  7. package/dist/api/RuntimePathTypes.js.map +1 -1
  8. package/dist/api/ThreadListRuntime.d.ts +0 -5
  9. package/dist/api/ThreadListRuntime.d.ts.map +1 -1
  10. package/dist/api/ThreadListRuntime.js +4 -10
  11. package/dist/api/ThreadListRuntime.js.map +1 -1
  12. package/dist/api/ThreadListRuntime.mjs +4 -10
  13. package/dist/api/ThreadListRuntime.mjs.map +1 -1
  14. package/dist/runtimes/edge/converters/fromLanguageModelMessages.d.ts.map +1 -1
  15. package/dist/runtimes/edge/converters/fromLanguageModelMessages.js +3 -2
  16. package/dist/runtimes/edge/converters/fromLanguageModelMessages.js.map +1 -1
  17. package/dist/runtimes/edge/converters/fromLanguageModelMessages.mjs +3 -2
  18. package/dist/runtimes/edge/converters/fromLanguageModelMessages.mjs.map +1 -1
  19. package/dist/types/AssistantTypes.d.ts +57 -57
  20. package/dist/types/AssistantTypes.d.ts.map +1 -1
  21. package/dist/types/AssistantTypes.js.map +1 -1
  22. package/dist/ui/{attachment.d.ts → attachment-ui.d.ts} +3 -3
  23. package/dist/ui/attachment-ui.d.ts.map +1 -0
  24. package/dist/ui/{attachment.js → attachment-ui.js} +9 -9
  25. package/dist/ui/attachment-ui.js.map +1 -0
  26. package/dist/ui/{attachment.mjs → attachment-ui.mjs} +6 -6
  27. package/dist/ui/attachment-ui.mjs.map +1 -0
  28. package/dist/ui/composer.js +2 -2
  29. package/dist/ui/composer.js.map +1 -1
  30. package/dist/ui/composer.mjs +1 -1
  31. package/dist/ui/composer.mjs.map +1 -1
  32. package/dist/ui/index.d.ts +1 -1
  33. package/dist/ui/index.d.ts.map +1 -1
  34. package/dist/ui/index.js +2 -2
  35. package/dist/ui/index.js.map +1 -1
  36. package/dist/ui/index.mjs +1 -1
  37. package/dist/ui/index.mjs.map +1 -1
  38. package/dist/ui/user-message.js +2 -2
  39. package/dist/ui/user-message.js.map +1 -1
  40. package/dist/ui/user-message.mjs +1 -1
  41. package/dist/ui/user-message.mjs.map +1 -1
  42. package/dist/utils/smooth/SmoothContext.d.ts +42 -42
  43. package/package.json +3 -3
  44. package/src/api/ContentPartRuntime.ts +6 -2
  45. package/src/api/RuntimePathTypes.ts +0 -4
  46. package/src/api/ThreadListRuntime.ts +4 -16
  47. package/src/runtimes/edge/converters/fromLanguageModelMessages.ts +5 -2
  48. package/src/types/AssistantTypes.ts +62 -57
  49. package/src/ui/{attachment.tsx → attachment-ui.tsx} +3 -3
  50. package/src/ui/composer.tsx +1 -1
  51. package/src/ui/index.ts +1 -1
  52. package/src/ui/user-message.tsx +1 -1
  53. package/dist/ui/attachment.d.ts.map +0 -1
  54. package/dist/ui/attachment.js.map +0 -1
  55. package/dist/ui/attachment.mjs.map +0 -1
@@ -1,7 +1,6 @@
1
1
  import { LazyMemoizeSubject } from "./subscribable/LazyMemoizeSubject";
2
2
  import { ThreadListRuntimeCore } from "../runtimes/core/ThreadListRuntimeCore";
3
3
  import { Unsubscribe } from "../types";
4
- import { ThreadListRuntimePath } from "./RuntimePathTypes";
5
4
  import {
6
5
  ThreadListItemRuntime,
7
6
  ThreadListItemRuntimeImpl,
@@ -18,7 +17,6 @@ export type ThreadListState = {
18
17
  };
19
18
 
20
19
  export type ThreadListRuntime = {
21
- readonly path: ThreadListRuntimePath;
22
20
  getState(): ThreadListState;
23
21
 
24
22
  subscribe(callback: () => void): Unsubscribe;
@@ -55,21 +53,13 @@ const getThreadListItemState = (
55
53
  };
56
54
  };
57
55
 
58
- const THREAD_MANAGER_PATH = {
59
- ref: "ThreadList",
60
- };
61
-
62
56
  export type ThreadListRuntimeCoreBinding = ThreadListRuntimeCore;
63
57
 
64
58
  export class ThreadListRuntimeImpl implements ThreadListRuntime {
65
- public get path() {
66
- return THREAD_MANAGER_PATH;
67
- }
68
-
69
59
  private _getState;
70
60
  constructor(private _core: ThreadListRuntimeCoreBinding) {
71
61
  const stateBinding = new LazyMemoizeSubject({
72
- path: THREAD_MANAGER_PATH,
62
+ path: {},
73
63
  getState: () => getThreadListState(_core),
74
64
  subscribe: (callback) => _core.subscribe(callback),
75
65
  });
@@ -89,7 +79,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
89
79
  return new ThreadListItemRuntimeImpl(
90
80
  new ShallowMemoizeSubject({
91
81
  path: {
92
- ref: this.path.ref + `${this.path.ref}.threadItems[${idx}]`,
82
+ ref: `threadItems[${idx}]`,
93
83
  threadSelector: { type: "index", index: idx },
94
84
  },
95
85
  getState: () => {
@@ -105,7 +95,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
105
95
  return new ThreadListItemRuntimeImpl(
106
96
  new ShallowMemoizeSubject({
107
97
  path: {
108
- ref: this.path.ref + `${this.path.ref}.archivedThreadItems[${idx}]`,
98
+ ref: `archivedThreadItems[${idx}]`,
109
99
  threadSelector: { type: "archiveIndex", index: idx },
110
100
  },
111
101
  getState: () => {
@@ -124,9 +114,7 @@ export class ThreadListRuntimeImpl implements ThreadListRuntime {
124
114
  return new ThreadListItemRuntimeImpl(
125
115
  new ShallowMemoizeSubject({
126
116
  path: {
127
- ref:
128
- this.path.ref +
129
- `${this.path.ref}.threadItems[threadId=${threadId}]`,
117
+ ref: `threadItems[threadId=${threadId}]`,
130
118
  threadSelector: { type: "threadId", threadId },
131
119
  },
132
120
  getState: () => {
@@ -1,5 +1,6 @@
1
1
  import { LanguageModelV1Message } from "@ai-sdk/provider";
2
2
  import { CoreMessage, ToolCallContentPart } from "../../../types";
3
+ import { Writable } from "stream";
3
4
 
4
5
  type fromLanguageModelMessagesOptions = {
5
6
  mergeSteps: boolean;
@@ -105,9 +106,11 @@ export const fromLanguageModelMessages = (
105
106
  if (toolCall.toolName !== tool.toolName)
106
107
  throw new Error("Tool call name mismatch.");
107
108
 
108
- toolCall.result = tool.result;
109
+ type Writable<T> = { -readonly [P in keyof T]: T[P] };
110
+ const writable = toolCall as Writable<ToolCallContentPart>;
111
+ writable.result = tool.result;
109
112
  if (tool.isError) {
110
- toolCall.isError = true;
113
+ writable.isError = true;
111
114
  }
112
115
  }
113
116
 
@@ -4,45 +4,45 @@ import { CompleteAttachment } from "./AttachmentTypes";
4
4
  export type MessageRole = "user" | "assistant" | "system";
5
5
 
6
6
  export type TextContentPart = {
7
- type: "text";
8
- text: string;
7
+ readonly type: "text";
8
+ readonly text: string;
9
9
  };
10
10
 
11
11
  export type ImageContentPart = {
12
- type: "image";
13
- image: string;
12
+ readonly type: "image";
13
+ readonly image: string;
14
14
  };
15
15
 
16
16
  export type Unstable_AudioContentPart = {
17
- type: "audio";
18
- audio: {
19
- data: string;
20
- format: "mp3" | "wav";
17
+ readonly type: "audio";
18
+ readonly audio: {
19
+ readonly data: string;
20
+ readonly format: "mp3" | "wav";
21
21
  };
22
22
  };
23
23
 
24
24
  export type UIContentPart = {
25
- type: "ui";
26
- display: ReactNode;
25
+ readonly type: "ui";
26
+ readonly display: ReactNode;
27
27
  };
28
28
 
29
29
  export type CoreToolCallContentPart<
30
30
  TArgs extends Record<string, unknown> = Record<string | number, unknown>,
31
31
  TResult = unknown,
32
32
  > = {
33
- type: "tool-call";
34
- toolCallId: string;
35
- toolName: string;
36
- args: TArgs;
37
- result?: TResult | undefined;
38
- isError?: boolean | undefined;
33
+ readonly type: "tool-call";
34
+ readonly toolCallId: string;
35
+ readonly toolName: string;
36
+ readonly args: TArgs;
37
+ readonly result?: TResult | undefined;
38
+ readonly isError?: boolean | undefined;
39
39
  };
40
40
 
41
41
  export type ToolCallContentPart<
42
42
  TArgs extends Record<string, unknown> = Record<string | number, unknown>,
43
43
  TResult = unknown,
44
44
  > = CoreToolCallContentPart<TArgs, TResult> & {
45
- argsText: string;
45
+ readonly argsText: string;
46
46
  };
47
47
 
48
48
  export type ThreadUserContentPart =
@@ -57,87 +57,92 @@ export type ThreadAssistantContentPart =
57
57
  | UIContentPart;
58
58
 
59
59
  type MessageCommonProps = {
60
- id: string;
61
- createdAt: Date;
60
+ readonly id: string;
61
+ readonly createdAt: Date;
62
62
  };
63
63
 
64
64
  export type ThreadStep = {
65
- usage?:
65
+ readonly usage?:
66
66
  | {
67
- promptTokens: number;
68
- completionTokens: number;
67
+ readonly promptTokens: number;
68
+ readonly completionTokens: number;
69
69
  }
70
70
  | undefined;
71
71
  };
72
72
 
73
73
  export type ContentPartStatus =
74
74
  | {
75
- type: "running";
75
+ readonly type: "running";
76
76
  }
77
77
  | {
78
- type: "complete";
78
+ readonly type: "complete";
79
79
  }
80
80
  | {
81
- type: "incomplete";
82
- reason: "cancelled" | "length" | "content-filter" | "other" | "error";
83
- error?: unknown;
81
+ readonly type: "incomplete";
82
+ readonly reason:
83
+ | "cancelled"
84
+ | "length"
85
+ | "content-filter"
86
+ | "other"
87
+ | "error";
88
+ readonly error?: unknown;
84
89
  };
85
90
 
86
91
  export type ToolCallContentPartStatus =
87
92
  | {
88
- type: "requires-action";
89
- reason: "tool-calls";
93
+ readonly type: "requires-action";
94
+ readonly reason: "tool-calls";
90
95
  }
91
96
  | ContentPartStatus;
92
97
 
93
98
  export type MessageStatus =
94
99
  | {
95
- type: "running";
100
+ readonly type: "running";
96
101
  }
97
102
  | {
98
- type: "requires-action";
99
- reason: "tool-calls";
103
+ readonly type: "requires-action";
104
+ readonly reason: "tool-calls";
100
105
  }
101
106
  | {
102
- type: "complete";
103
- reason: "stop" | "unknown";
107
+ readonly type: "complete";
108
+ readonly reason: "stop" | "unknown";
104
109
  }
105
110
  | {
106
- type: "incomplete";
107
- reason:
111
+ readonly type: "incomplete";
112
+ readonly reason:
108
113
  | "cancelled"
109
114
  | "tool-calls"
110
115
  | "length"
111
116
  | "content-filter"
112
117
  | "other"
113
118
  | "error";
114
- error?: unknown;
119
+ readonly error?: unknown;
115
120
  };
116
121
 
117
122
  export type ThreadSystemMessage = MessageCommonProps & {
118
- role: "system";
119
- content: [TextContentPart];
120
- metadata: {
121
- custom: Record<string, unknown>;
123
+ readonly role: "system";
124
+ readonly content: [TextContentPart];
125
+ readonly metadata: {
126
+ readonly custom: Record<string, unknown>;
122
127
  };
123
128
  };
124
129
 
125
130
  export type ThreadUserMessage = MessageCommonProps & {
126
- role: "user";
127
- content: ThreadUserContentPart[];
128
- attachments: readonly CompleteAttachment[];
129
- metadata: {
130
- custom: Record<string, unknown>;
131
+ readonly role: "user";
132
+ readonly content: ThreadUserContentPart[];
133
+ readonly attachments: readonly CompleteAttachment[];
134
+ readonly metadata: {
135
+ readonly custom: Record<string, unknown>;
131
136
  };
132
137
  };
133
138
 
134
139
  export type ThreadAssistantMessage = MessageCommonProps & {
135
- role: "assistant";
136
- content: ThreadAssistantContentPart[];
137
- status: MessageStatus;
138
- metadata: {
139
- steps: ThreadStep[];
140
- custom: Record<string, unknown>;
140
+ readonly role: "assistant";
141
+ readonly content: ThreadAssistantContentPart[];
142
+ readonly status: MessageStatus;
143
+ readonly metadata: {
144
+ readonly steps: ThreadStep[];
145
+ readonly custom: Record<string, unknown>;
141
146
  };
142
147
  };
143
148
 
@@ -148,12 +153,12 @@ export type AppendMessage = CoreMessage & {
148
153
  };
149
154
 
150
155
  type BaseThreadMessage = {
151
- status?: ThreadAssistantMessage["status"];
152
- metadata: {
153
- steps?: ThreadStep[];
154
- custom: Record<string, unknown>;
156
+ readonly status?: ThreadAssistantMessage["status"];
157
+ readonly metadata: {
158
+ readonly steps?: ThreadStep[];
159
+ readonly custom: Record<string, unknown>;
155
160
  };
156
- attachments?: ThreadUserMessage["attachments"];
161
+ readonly attachments?: ThreadUserMessage["attachments"];
157
162
  };
158
163
 
159
164
  export type ThreadMessage = BaseThreadMessage &
@@ -126,7 +126,7 @@ const AttachmentThumb: FC = () => {
126
126
  );
127
127
  };
128
128
 
129
- const Attachment: FC = () => {
129
+ const AttachmentUI: FC = () => {
130
130
  const canRemove = useAttachment((a) => a.source !== "message");
131
131
  const typeLabel = useAttachment((a) => {
132
132
  const type = a.type;
@@ -165,7 +165,7 @@ const Attachment: FC = () => {
165
165
  );
166
166
  };
167
167
 
168
- Attachment.displayName = "Attachment";
168
+ AttachmentUI.displayName = "Attachment";
169
169
 
170
170
  namespace AttachmentRemove {
171
171
  export type Element = HTMLButtonElement;
@@ -204,5 +204,5 @@ const exports = {
204
204
  Remove: AttachmentRemove,
205
205
  };
206
206
 
207
- export default Object.assign(Attachment, exports) as typeof Attachment &
207
+ export default Object.assign(AttachmentUI, exports) as typeof AttachmentUI &
208
208
  typeof exports;
@@ -12,7 +12,7 @@ import {
12
12
  import { CircleStopIcon } from "./base/CircleStopIcon";
13
13
  import { ComposerPrimitive, ThreadPrimitive } from "../primitives";
14
14
  import { useThread } from "../context/react/ThreadContext";
15
- import Attachment from "./attachment";
15
+ import Attachment from "./attachment-ui";
16
16
 
17
17
  const useAllowAttachments = (ensureCapability = false) => {
18
18
  const { composer: { allowAttachments = true } = {} } = useThreadConfig();
package/src/ui/index.ts CHANGED
@@ -22,7 +22,7 @@ export { default as Composer } from "./composer";
22
22
 
23
23
  export {
24
24
  default as AttachmentUI, // TODO name collision with Attachment
25
- } from "./attachment";
25
+ } from "./attachment-ui";
26
26
 
27
27
  export { default as EditComposer } from "./edit-composer";
28
28
 
@@ -7,7 +7,7 @@ import { withDefaults } from "./utils/withDefaults";
7
7
  import UserActionBar from "./user-action-bar";
8
8
  import ContentPart from "./content-part";
9
9
  import { MessagePrimitive } from "../primitives";
10
- import Attachment from "./attachment";
10
+ import Attachment from "./attachment-ui";
11
11
 
12
12
  const UserMessage: FC = () => {
13
13
  return (
@@ -1 +0,0 @@
1
- {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../src/ui/attachment.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,EAAE,EACR,MAAM,OAAO,CAAC;AAIf,OAAO,EAEL,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;AAiHpC,QAAA,MAAM,UAAU,EAAE,EAqCjB,CAAC;AAoCF,QAAA,MAAM,OAAO;;;;;;;CAGZ,CAAC;wBAEmD,OAAO,UAAU,GACpE,OAAO,OAAO;AADhB,wBACiB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/ui/attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n PropsWithChildren,\n useEffect,\n useState,\n type FC,\n} from \"react\";\nimport { CircleXIcon, FileIcon } from \"lucide-react\";\nimport { withDefaults } from \"./utils/withDefaults\";\nimport { useThreadConfig } from \"./thread-config\";\nimport {\n TooltipIconButton,\n TooltipIconButtonProps,\n} from \"./base/tooltip-icon-button\";\nimport { AttachmentPrimitive } from \"../primitives\";\nimport { useAttachment } from \"../context/react/AttachmentContext\";\nimport {\n AvatarImage,\n AvatarRoot,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"./base\";\nimport { Dialog, DialogTrigger, DialogContent } from \"./base/dialog\";\nimport { AvatarFallback } from \"@radix-ui/react-avatar\";\nimport { useShallow } from \"zustand/shallow\";\nimport { DialogTitle } from \"@radix-ui/react-dialog\";\n\nconst AttachmentRoot = withDefaults(AttachmentPrimitive.Root, {\n className: \"aui-attachment-root\",\n});\n\nAttachmentRoot.displayName = \"AttachmentRoot\";\n\nconst useFileSrc = (file: File | undefined) => {\n const [src, setSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!file) {\n setSrc(undefined);\n return;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [file]);\n\n return src;\n};\n\nconst useAttachmentSrc = () => {\n const { file, src } = useAttachment(\n useShallow((a): { file?: File; src?: string } => {\n if (a.type !== \"image\") return {};\n if (a.file) return { file: a.file };\n const src = a.content?.filter((c) => c.type === \"image\")[0]?.image;\n if (!src) return {};\n return { src };\n }),\n );\n\n return useFileSrc(file) ?? src;\n};\n\ntype AttachmentPreviewProps = {\n src: string;\n};\n\nconst AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {\n const [isLoaded, setIsLoaded] = useState(false);\n\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={src}\n style={{\n width: \"auto\",\n height: \"auto\",\n maxWidth: \"75dvh\",\n maxHeight: \"75dvh\",\n display: isLoaded ? \"block\" : \"none\",\n overflow: \"clip\",\n }}\n onLoad={() => setIsLoaded(true)}\n alt=\"Image Preview\"\n />\n );\n};\n\nconst AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {\n const src = useAttachmentSrc();\n\n if (!src) return children;\n\n return (\n <Dialog>\n <DialogTrigger className=\"aui-attachment-preview-trigger\" asChild>\n {children}\n </DialogTrigger>\n <DialogContent>\n <DialogTitle className=\"aui-sr-only\">\n Image Attachment Preview\n </DialogTitle>\n <AttachmentPreview src={src} />\n </DialogContent>\n </Dialog>\n );\n};\n\nconst AttachmentThumb: FC = () => {\n const isImage = useAttachment((a) => a.type === \"image\");\n const src = useAttachmentSrc();\n return (\n <AvatarRoot className=\"aui-attachment-thumb\">\n <AvatarFallback delayMs={isImage ? 200 : 0}>\n <FileIcon />\n </AvatarFallback>\n <AvatarImage src={src}></AvatarImage>\n </AvatarRoot>\n );\n};\n\nconst Attachment: FC = () => {\n const canRemove = useAttachment((a) => a.source !== \"message\");\n const typeLabel = useAttachment((a) => {\n const type = a.type;\n switch (type) {\n case \"image\":\n return \"Image\";\n case \"document\":\n return \"Document\";\n case \"file\":\n return \"File\";\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);\n }\n });\n return (\n <Tooltip>\n <AttachmentPreviewDialog>\n <TooltipTrigger asChild>\n <AttachmentRoot>\n <AttachmentThumb />\n <div className=\"aui-attachment-text\">\n <p className=\"aui-attachment-name\">\n <AttachmentPrimitive.Name />\n </p>\n <p className=\"aui-attachment-type\">{typeLabel}</p>\n </div>\n {canRemove && <AttachmentRemove />}\n </AttachmentRoot>\n </TooltipTrigger>\n </AttachmentPreviewDialog>\n <TooltipContent side=\"top\">\n <AttachmentPrimitive.Name />\n </TooltipContent>\n </Tooltip>\n );\n};\n\nAttachment.displayName = \"Attachment\";\n\nnamespace AttachmentRemove {\n export type Element = HTMLButtonElement;\n export type Props = Partial<TooltipIconButtonProps>;\n}\n\nconst AttachmentRemove = forwardRef<\n AttachmentRemove.Element,\n AttachmentRemove.Props\n>((props, ref) => {\n const {\n strings: {\n composer: { removeAttachment: { tooltip = \"Remove file\" } = {} } = {},\n } = {},\n } = useThreadConfig();\n\n return (\n <AttachmentPrimitive.Remove asChild>\n <TooltipIconButton\n tooltip={tooltip}\n className=\"aui-attachment-remove\"\n side=\"top\"\n {...props}\n ref={ref}\n >\n {props.children ?? <CircleXIcon />}\n </TooltipIconButton>\n </AttachmentPrimitive.Remove>\n );\n});\n\nAttachmentRemove.displayName = \"AttachmentRemove\";\n\nconst exports = {\n Root: AttachmentRoot,\n Remove: AttachmentRemove,\n};\n\nexport default Object.assign(Attachment, exports) as typeof Attachment &\n typeof exports;\n"],"mappings":"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","names":["src","exports"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/ui/attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n PropsWithChildren,\n useEffect,\n useState,\n type FC,\n} from \"react\";\nimport { CircleXIcon, FileIcon } from \"lucide-react\";\nimport { withDefaults } from \"./utils/withDefaults\";\nimport { useThreadConfig } from \"./thread-config\";\nimport {\n TooltipIconButton,\n TooltipIconButtonProps,\n} from \"./base/tooltip-icon-button\";\nimport { AttachmentPrimitive } from \"../primitives\";\nimport { useAttachment } from \"../context/react/AttachmentContext\";\nimport {\n AvatarImage,\n AvatarRoot,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"./base\";\nimport { Dialog, DialogTrigger, DialogContent } from \"./base/dialog\";\nimport { AvatarFallback } from \"@radix-ui/react-avatar\";\nimport { useShallow } from \"zustand/shallow\";\nimport { DialogTitle } from \"@radix-ui/react-dialog\";\n\nconst AttachmentRoot = withDefaults(AttachmentPrimitive.Root, {\n className: \"aui-attachment-root\",\n});\n\nAttachmentRoot.displayName = \"AttachmentRoot\";\n\nconst useFileSrc = (file: File | undefined) => {\n const [src, setSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!file) {\n setSrc(undefined);\n return;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [file]);\n\n return src;\n};\n\nconst useAttachmentSrc = () => {\n const { file, src } = useAttachment(\n useShallow((a): { file?: File; src?: string } => {\n if (a.type !== \"image\") return {};\n if (a.file) return { file: a.file };\n const src = a.content?.filter((c) => c.type === \"image\")[0]?.image;\n if (!src) return {};\n return { src };\n }),\n );\n\n return useFileSrc(file) ?? src;\n};\n\ntype AttachmentPreviewProps = {\n src: string;\n};\n\nconst AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {\n const [isLoaded, setIsLoaded] = useState(false);\n\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={src}\n style={{\n width: \"auto\",\n height: \"auto\",\n maxWidth: \"75dvh\",\n maxHeight: \"75dvh\",\n display: isLoaded ? \"block\" : \"none\",\n overflow: \"clip\",\n }}\n onLoad={() => setIsLoaded(true)}\n alt=\"Image Preview\"\n />\n );\n};\n\nconst AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {\n const src = useAttachmentSrc();\n\n if (!src) return children;\n\n return (\n <Dialog>\n <DialogTrigger className=\"aui-attachment-preview-trigger\" asChild>\n {children}\n </DialogTrigger>\n <DialogContent>\n <DialogTitle className=\"aui-sr-only\">\n Image Attachment Preview\n </DialogTitle>\n <AttachmentPreview src={src} />\n </DialogContent>\n </Dialog>\n );\n};\n\nconst AttachmentThumb: FC = () => {\n const isImage = useAttachment((a) => a.type === \"image\");\n const src = useAttachmentSrc();\n return (\n <AvatarRoot className=\"aui-attachment-thumb\">\n <AvatarFallback delayMs={isImage ? 200 : 0}>\n <FileIcon />\n </AvatarFallback>\n <AvatarImage src={src}></AvatarImage>\n </AvatarRoot>\n );\n};\n\nconst Attachment: FC = () => {\n const canRemove = useAttachment((a) => a.source !== \"message\");\n const typeLabel = useAttachment((a) => {\n const type = a.type;\n switch (type) {\n case \"image\":\n return \"Image\";\n case \"document\":\n return \"Document\";\n case \"file\":\n return \"File\";\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);\n }\n });\n return (\n <Tooltip>\n <AttachmentPreviewDialog>\n <TooltipTrigger asChild>\n <AttachmentRoot>\n <AttachmentThumb />\n <div className=\"aui-attachment-text\">\n <p className=\"aui-attachment-name\">\n <AttachmentPrimitive.Name />\n </p>\n <p className=\"aui-attachment-type\">{typeLabel}</p>\n </div>\n {canRemove && <AttachmentRemove />}\n </AttachmentRoot>\n </TooltipTrigger>\n </AttachmentPreviewDialog>\n <TooltipContent side=\"top\">\n <AttachmentPrimitive.Name />\n </TooltipContent>\n </Tooltip>\n );\n};\n\nAttachment.displayName = \"Attachment\";\n\nnamespace AttachmentRemove {\n export type Element = HTMLButtonElement;\n export type Props = Partial<TooltipIconButtonProps>;\n}\n\nconst AttachmentRemove = forwardRef<\n AttachmentRemove.Element,\n AttachmentRemove.Props\n>((props, ref) => {\n const {\n strings: {\n composer: { removeAttachment: { tooltip = \"Remove file\" } = {} } = {},\n } = {},\n } = useThreadConfig();\n\n return (\n <AttachmentPrimitive.Remove asChild>\n <TooltipIconButton\n tooltip={tooltip}\n className=\"aui-attachment-remove\"\n side=\"top\"\n {...props}\n ref={ref}\n >\n {props.children ?? <CircleXIcon />}\n </TooltipIconButton>\n </AttachmentPrimitive.Remove>\n );\n});\n\nAttachmentRemove.displayName = \"AttachmentRemove\";\n\nconst exports = {\n Root: AttachmentRoot,\n Remove: AttachmentRemove,\n};\n\nexport default Object.assign(Attachment, exports) as typeof Attachment &\n typeof exports;\n"],"mappings":"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","names":["src"]}