@assistant-ui/react 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
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"]}