@anvia/react-ui 0.2.0 → 0.3.0
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/attachment/index.js +2 -2
- package/dist/chat/index.d.ts +13 -2
- package/dist/chat/index.js +4 -4
- package/dist/{chunk-LSHD67YK.js → chunk-4Z7LULAM.js} +2 -2
- package/dist/{chunk-7AS6R7BB.js → chunk-5IHC7D4U.js} +93 -16
- package/dist/chunk-5IHC7D4U.js.map +1 -0
- package/dist/{chunk-AOZN3SWB.js → chunk-5Z2IWZ5O.js} +4 -3
- package/dist/{chunk-AOZN3SWB.js.map → chunk-5Z2IWZ5O.js.map} +1 -1
- package/dist/chunk-IHRCKGRS.js +432 -0
- package/dist/chunk-IHRCKGRS.js.map +1 -0
- package/dist/{chunk-AXZB6JSE.js → chunk-LRAQW3ZK.js} +125 -11
- package/dist/chunk-LRAQW3ZK.js.map +1 -0
- package/dist/chunk-MXYHYD3O.js +291 -0
- package/dist/chunk-MXYHYD3O.js.map +1 -0
- package/dist/chunk-OKTDYMSA.js +236 -0
- package/dist/chunk-OKTDYMSA.js.map +1 -0
- package/dist/{chunk-RRINF6FN.js → chunk-QHP4GSRG.js} +2 -2
- package/dist/{chunk-WK33ER4Q.js → chunk-YDMDLFU4.js} +2 -2
- package/dist/completion/index.js +2 -2
- package/dist/human-input/index.js +2 -2
- package/dist/image/index.d.ts +40 -0
- package/dist/image/index.js +12 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image-DanUxcl2.d.ts +14 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +32 -8
- package/dist/message/index.js +3 -3
- package/dist/selection-toolbar/index.d.ts +21 -0
- package/dist/selection-toolbar/index.js +12 -0
- package/dist/selection-toolbar/index.js.map +1 -0
- package/dist/selection-toolbar-Cwjbuv5S.d.ts +14 -0
- package/dist/shared.d.ts +4 -1
- package/dist/shared.js +13 -3
- package/dist/styles.css +22 -0
- package/dist/{thread-CluT3m5k.d.ts → thread-DYPvlsJa.d.ts} +8 -1
- package/dist/thread-list/index.d.ts +47 -0
- package/dist/thread-list/index.js +18 -0
- package/dist/thread-list/index.js.map +1 -0
- package/dist/thread-list-On8db4XL.d.ts +34 -0
- package/package.json +17 -4
- package/dist/chunk-7AS6R7BB.js.map +0 -1
- package/dist/chunk-AXZB6JSE.js.map +0 -1
- /package/dist/{chunk-LSHD67YK.js.map → chunk-4Z7LULAM.js.map} +0 -0
- /package/dist/{chunk-RRINF6FN.js.map → chunk-QHP4GSRG.js.map} +0 -0
- /package/dist/{chunk-WK33ER4Q.js.map → chunk-YDMDLFU4.js.map} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Message
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5Z2IWZ5O.js";
|
|
4
4
|
import {
|
|
5
5
|
Attachment
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QHP4GSRG.js";
|
|
7
7
|
import {
|
|
8
8
|
composeRefs,
|
|
9
9
|
renderPrimitive
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
useChatContext,
|
|
17
17
|
useComposer,
|
|
18
18
|
useThread
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-5IHC7D4U.js";
|
|
20
20
|
|
|
21
21
|
// src/chat/composer.tsx
|
|
22
22
|
import {
|
|
@@ -32,9 +32,12 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
32
32
|
attachments: attachmentsProp,
|
|
33
33
|
defaultAttachments,
|
|
34
34
|
defaultInput = "",
|
|
35
|
+
defaultQuote,
|
|
35
36
|
input: inputProp,
|
|
36
37
|
onAttachmentsChange,
|
|
37
38
|
onInputChange,
|
|
39
|
+
onQuoteChange,
|
|
40
|
+
quote: quoteProp,
|
|
38
41
|
submitMessage,
|
|
39
42
|
onSubmit,
|
|
40
43
|
...props
|
|
@@ -44,13 +47,25 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
44
47
|
const [uncontrolledAttachments, setUncontrolledAttachments] = useState(() => [
|
|
45
48
|
...defaultAttachments ?? []
|
|
46
49
|
]);
|
|
50
|
+
const [uncontrolledQuote, setUncontrolledQuote] = useState(
|
|
51
|
+
defaultQuote
|
|
52
|
+
);
|
|
47
53
|
const input = inputProp ?? uncontrolledInput;
|
|
48
54
|
const attachments = attachmentsProp ?? uncontrolledAttachments;
|
|
55
|
+
const rawQuote = quoteProp ?? uncontrolledQuote;
|
|
56
|
+
const rawQuoteMessageId = rawQuote?.messageId;
|
|
57
|
+
const rawQuoteText = rawQuote?.text;
|
|
58
|
+
const quote = useMemo(
|
|
59
|
+
() => rawQuoteMessageId === void 0 || rawQuoteText === void 0 ? void 0 : { messageId: rawQuoteMessageId, text: rawQuoteText },
|
|
60
|
+
[rawQuoteMessageId, rawQuoteText]
|
|
61
|
+
);
|
|
49
62
|
const attachmentsRef = useRef(attachments);
|
|
50
63
|
attachmentsRef.current = attachments;
|
|
51
64
|
const inputControlled = inputProp !== void 0;
|
|
52
65
|
const attachmentsControlled = attachmentsProp !== void 0;
|
|
53
|
-
const
|
|
66
|
+
const quoteControlled = quoteProp !== void 0;
|
|
67
|
+
const hasMessageContent = input.trim().length > 0 || attachments.length > 0 || quote !== void 0;
|
|
68
|
+
const canSubmit = hasMessageContent && chat.status !== "streaming";
|
|
54
69
|
const canStop = chat.status === "streaming";
|
|
55
70
|
const setInput = useCallback(
|
|
56
71
|
(nextInput) => {
|
|
@@ -72,6 +87,16 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
72
87
|
},
|
|
73
88
|
[attachmentsControlled, onAttachmentsChange]
|
|
74
89
|
);
|
|
90
|
+
const setQuote = useCallback(
|
|
91
|
+
(nextQuote) => {
|
|
92
|
+
const normalizedQuote = normalizeQuote(nextQuote);
|
|
93
|
+
if (!quoteControlled) {
|
|
94
|
+
setUncontrolledQuote(normalizedQuote);
|
|
95
|
+
}
|
|
96
|
+
onQuoteChange?.(normalizedQuote);
|
|
97
|
+
},
|
|
98
|
+
[onQuoteChange, quoteControlled]
|
|
99
|
+
);
|
|
75
100
|
const addAttachment = useCallback(
|
|
76
101
|
async (attachment) => {
|
|
77
102
|
const normalized = isFileAttachmentInput(attachment) ? await attachmentFromFile(attachment) : createAttachment(attachment);
|
|
@@ -88,13 +113,17 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
88
113
|
const clearAttachments = useCallback(() => {
|
|
89
114
|
setAttachments([]);
|
|
90
115
|
}, [setAttachments]);
|
|
116
|
+
const clearQuote = useCallback(() => {
|
|
117
|
+
setQuote(void 0);
|
|
118
|
+
}, [setQuote]);
|
|
91
119
|
const clear = useCallback(() => {
|
|
92
120
|
setInput("");
|
|
93
121
|
setAttachments([]);
|
|
94
|
-
|
|
122
|
+
clearQuote();
|
|
123
|
+
}, [clearQuote, setAttachments, setInput]);
|
|
95
124
|
const submit = useCallback(async () => {
|
|
96
125
|
const prompt = input;
|
|
97
|
-
if (prompt.trim().length === 0 && attachments.length === 0 || chat.status === "streaming") {
|
|
126
|
+
if (prompt.trim().length === 0 && attachments.length === 0 && quote === void 0 || chat.status === "streaming") {
|
|
98
127
|
return;
|
|
99
128
|
}
|
|
100
129
|
if (submitMessage !== void 0) {
|
|
@@ -102,20 +131,30 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
102
131
|
input: prompt,
|
|
103
132
|
attachments,
|
|
104
133
|
chat,
|
|
134
|
+
quote,
|
|
105
135
|
clear
|
|
106
136
|
});
|
|
107
137
|
return;
|
|
108
138
|
}
|
|
139
|
+
const submittedText = quote === void 0 ? prompt : promptWithQuote(prompt, quote);
|
|
109
140
|
if (attachments.length === 0) {
|
|
110
|
-
|
|
141
|
+
if (quote === void 0) {
|
|
142
|
+
await chat.sendMessage(prompt);
|
|
143
|
+
} else {
|
|
144
|
+
await chat.sendMessage({
|
|
145
|
+
text: submittedText,
|
|
146
|
+
metadata: { quote }
|
|
147
|
+
});
|
|
148
|
+
}
|
|
111
149
|
} else {
|
|
112
150
|
await chat.sendMessage({
|
|
113
|
-
text:
|
|
114
|
-
attachments
|
|
151
|
+
text: submittedText,
|
|
152
|
+
attachments,
|
|
153
|
+
...quote === void 0 ? {} : { metadata: { quote } }
|
|
115
154
|
});
|
|
116
155
|
}
|
|
117
156
|
clear();
|
|
118
|
-
}, [attachments, chat, clear, input, submitMessage]);
|
|
157
|
+
}, [attachments, chat, clear, input, quote, submitMessage]);
|
|
119
158
|
const value = useMemo(
|
|
120
159
|
() => ({
|
|
121
160
|
input,
|
|
@@ -125,6 +164,9 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
125
164
|
addAttachment,
|
|
126
165
|
removeAttachment,
|
|
127
166
|
clearAttachments,
|
|
167
|
+
quote,
|
|
168
|
+
setQuote,
|
|
169
|
+
clearQuote,
|
|
128
170
|
submit,
|
|
129
171
|
stop: chat.stop,
|
|
130
172
|
status: chat.status,
|
|
@@ -139,10 +181,13 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
139
181
|
chat.status,
|
|
140
182
|
chat.stop,
|
|
141
183
|
clearAttachments,
|
|
184
|
+
clearQuote,
|
|
142
185
|
input,
|
|
186
|
+
quote,
|
|
143
187
|
removeAttachment,
|
|
144
188
|
setAttachments,
|
|
145
189
|
setInput,
|
|
190
|
+
setQuote,
|
|
146
191
|
submit
|
|
147
192
|
]
|
|
148
193
|
);
|
|
@@ -168,6 +213,55 @@ var ComposerRoot = forwardRef(function ComposerRoot2({
|
|
|
168
213
|
ref
|
|
169
214
|
) });
|
|
170
215
|
});
|
|
216
|
+
var ComposerQuotePreview = forwardRef(
|
|
217
|
+
function ComposerQuotePreview2({ children, ...props }, ref) {
|
|
218
|
+
const composer = useComposer();
|
|
219
|
+
const quote = composer.quote;
|
|
220
|
+
if (quote === void 0) {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
const renderedChildren = typeof children === "function" ? children(quote) : children ?? quote.text;
|
|
224
|
+
return renderPrimitive(
|
|
225
|
+
"blockquote",
|
|
226
|
+
{
|
|
227
|
+
...props,
|
|
228
|
+
children: renderedChildren,
|
|
229
|
+
"data-anvia-composer-quote": "",
|
|
230
|
+
"data-message-id": quote.messageId
|
|
231
|
+
},
|
|
232
|
+
ref
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
var ComposerClearQuote = forwardRef(
|
|
237
|
+
function ComposerClearQuote2({ onClick, ...props }, ref) {
|
|
238
|
+
const composer = useComposer();
|
|
239
|
+
const disabled = props.disabled ?? composer.quote === void 0;
|
|
240
|
+
const handleClick = useCallback(
|
|
241
|
+
(event) => {
|
|
242
|
+
onClick?.(event);
|
|
243
|
+
if (event.defaultPrevented || disabled) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
composer.clearQuote();
|
|
247
|
+
},
|
|
248
|
+
[composer, disabled, onClick]
|
|
249
|
+
);
|
|
250
|
+
return renderPrimitive(
|
|
251
|
+
"button",
|
|
252
|
+
{
|
|
253
|
+
...props,
|
|
254
|
+
children: props.children ?? "Clear quote",
|
|
255
|
+
disabled,
|
|
256
|
+
onClick: handleClick,
|
|
257
|
+
type: props.type ?? "button",
|
|
258
|
+
"data-anvia-clear-quote": "",
|
|
259
|
+
"data-state": disabled ? "disabled" : "enabled"
|
|
260
|
+
},
|
|
261
|
+
ref
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
);
|
|
171
265
|
var ComposerInput = forwardRef(function ComposerInput2({
|
|
172
266
|
autoResize = true,
|
|
173
267
|
maxRows: maxRowsProp,
|
|
@@ -272,6 +366,24 @@ function pixelValue(value) {
|
|
|
272
366
|
function clamp(value, min, max) {
|
|
273
367
|
return Math.min(Math.max(value, min), max);
|
|
274
368
|
}
|
|
369
|
+
function promptWithQuote(prompt, quote) {
|
|
370
|
+
const quotedText = quote.text.split(/\r?\n/).map((line) => `> ${line}`).join("\n");
|
|
371
|
+
if (prompt.trim().length === 0) {
|
|
372
|
+
return quotedText;
|
|
373
|
+
}
|
|
374
|
+
return `${quotedText}
|
|
375
|
+
|
|
376
|
+
${prompt}`;
|
|
377
|
+
}
|
|
378
|
+
function normalizeQuote(quote) {
|
|
379
|
+
if (quote === void 0) {
|
|
380
|
+
return void 0;
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
text: quote.text,
|
|
384
|
+
messageId: quote.messageId
|
|
385
|
+
};
|
|
386
|
+
}
|
|
275
387
|
var ComposerSubmit = forwardRef(
|
|
276
388
|
function ComposerSubmit2(props, ref) {
|
|
277
389
|
const composer = useComposer();
|
|
@@ -520,6 +632,8 @@ function createAttachmentId() {
|
|
|
520
632
|
}
|
|
521
633
|
var Composer = {
|
|
522
634
|
Root: ComposerRoot,
|
|
635
|
+
Quote: ComposerQuotePreview,
|
|
636
|
+
ClearQuote: ComposerClearQuote,
|
|
523
637
|
Input: ComposerInput,
|
|
524
638
|
Attachments: ComposerAttachments,
|
|
525
639
|
AddAttachment: ComposerAddAttachment,
|
|
@@ -810,4 +924,4 @@ export {
|
|
|
810
924
|
Composer,
|
|
811
925
|
Thread
|
|
812
926
|
};
|
|
813
|
-
//# sourceMappingURL=chunk-
|
|
927
|
+
//# sourceMappingURL=chunk-LRAQW3ZK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chat/composer.tsx","../src/chat/thread.tsx"],"sourcesContent":["import type { CreateUIAttachment, UIAttachment } from \"@anvia/react\";\nimport {\n type ChangeEvent,\n type DragEvent,\n type FormEvent,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Attachment } from \"../attachment/index\";\nimport {\n type ChatController,\n type ComposerAttachmentInput as ComposerAttachmentInputValue,\n type ComposerAttachmentsUpdate,\n type ComposerContextValue,\n type ComposerQuote,\n InternalAttachmentProvider,\n InternalComposerProvider,\n useChatContext,\n useComposer,\n} from \"../contexts\";\nimport { composeRefs, type PrimitiveProps, renderPrimitive } from \"../primitives\";\n\ntype ComposerRootProps = PrimitiveProps<\"form\"> & {\n attachments?: UIAttachment[];\n defaultAttachments?: UIAttachment[];\n defaultInput?: string;\n defaultQuote?: ComposerQuote | undefined;\n input?: string;\n onAttachmentsChange?: (attachments: UIAttachment[]) => void;\n onInputChange?: (input: string) => void;\n onQuoteChange?: (quote: ComposerQuote | undefined) => void;\n quote?: ComposerQuote | undefined;\n submitMessage?: ComposerSubmitMessage;\n};\n\nexport type ComposerSubmitMessageArgs<TEvent = unknown> = {\n input: string;\n attachments: UIAttachment[];\n chat: ChatController<TEvent>;\n quote?: ComposerQuote | undefined;\n clear(): void;\n};\n\nexport type ComposerSubmitMessage<TEvent = unknown> = (\n args: ComposerSubmitMessageArgs<TEvent>,\n) => Promise<void> | void;\n\nconst ComposerRoot = forwardRef<HTMLFormElement, ComposerRootProps>(function ComposerRoot(\n {\n attachments: attachmentsProp,\n defaultAttachments,\n defaultInput = \"\",\n defaultQuote,\n input: inputProp,\n onAttachmentsChange,\n onInputChange,\n onQuoteChange,\n quote: quoteProp,\n submitMessage,\n onSubmit,\n ...props\n },\n ref,\n) {\n const chat = useChatContext();\n const [uncontrolledInput, setUncontrolledInput] = useState(defaultInput);\n const [uncontrolledAttachments, setUncontrolledAttachments] = useState<UIAttachment[]>(() => [\n ...(defaultAttachments ?? []),\n ]);\n const [uncontrolledQuote, setUncontrolledQuote] = useState<ComposerQuote | undefined>(\n defaultQuote,\n );\n const input = inputProp ?? uncontrolledInput;\n const attachments = attachmentsProp ?? uncontrolledAttachments;\n const rawQuote = quoteProp ?? uncontrolledQuote;\n const rawQuoteMessageId = rawQuote?.messageId;\n const rawQuoteText = rawQuote?.text;\n const quote = useMemo(\n () =>\n rawQuoteMessageId === undefined || rawQuoteText === undefined\n ? undefined\n : { messageId: rawQuoteMessageId, text: rawQuoteText },\n [rawQuoteMessageId, rawQuoteText],\n );\n const attachmentsRef = useRef(attachments);\n attachmentsRef.current = attachments;\n const inputControlled = inputProp !== undefined;\n const attachmentsControlled = attachmentsProp !== undefined;\n const quoteControlled = quoteProp !== undefined;\n const hasMessageContent =\n input.trim().length > 0 || attachments.length > 0 || quote !== undefined;\n const canSubmit = hasMessageContent && chat.status !== \"streaming\";\n const canStop = chat.status === \"streaming\";\n\n const setInput = useCallback(\n (nextInput: string) => {\n if (!inputControlled) {\n setUncontrolledInput(nextInput);\n }\n onInputChange?.(nextInput);\n },\n [inputControlled, onInputChange],\n );\n\n const setAttachments = useCallback(\n (update: ComposerAttachmentsUpdate) => {\n const nextAttachments =\n typeof update === \"function\" ? update(attachmentsRef.current) : update;\n attachmentsRef.current = nextAttachments;\n if (!attachmentsControlled) {\n setUncontrolledAttachments(nextAttachments);\n }\n onAttachmentsChange?.(nextAttachments);\n },\n [attachmentsControlled, onAttachmentsChange],\n );\n\n const setQuote = useCallback(\n (nextQuote: ComposerQuote | undefined) => {\n const normalizedQuote = normalizeQuote(nextQuote);\n if (!quoteControlled) {\n setUncontrolledQuote(normalizedQuote);\n }\n onQuoteChange?.(normalizedQuote);\n },\n [onQuoteChange, quoteControlled],\n );\n\n const addAttachment = useCallback(\n async (attachment: ComposerAttachmentInputValue) => {\n const normalized = isFileAttachmentInput(attachment)\n ? await attachmentFromFile(attachment)\n : createAttachment(attachment);\n setAttachments((current) => [...current, normalized]);\n },\n [setAttachments],\n );\n\n const removeAttachment = useCallback(\n (id: string) => {\n setAttachments((current) => current.filter((attachment) => attachment.id !== id));\n },\n [setAttachments],\n );\n\n const clearAttachments = useCallback(() => {\n setAttachments([]);\n }, [setAttachments]);\n\n const clearQuote = useCallback(() => {\n setQuote(undefined);\n }, [setQuote]);\n\n const clear = useCallback(() => {\n setInput(\"\");\n setAttachments([]);\n clearQuote();\n }, [clearQuote, setAttachments, setInput]);\n\n const submit = useCallback(async () => {\n const prompt = input;\n if (\n (prompt.trim().length === 0 && attachments.length === 0 && quote === undefined) ||\n chat.status === \"streaming\"\n ) {\n return;\n }\n if (submitMessage !== undefined) {\n await submitMessage({\n input: prompt,\n attachments,\n chat,\n quote,\n clear,\n });\n return;\n }\n const submittedText = quote === undefined ? prompt : promptWithQuote(prompt, quote);\n if (attachments.length === 0) {\n if (quote === undefined) {\n await chat.sendMessage(prompt);\n } else {\n await chat.sendMessage({\n text: submittedText,\n metadata: { quote },\n });\n }\n } else {\n await chat.sendMessage({\n text: submittedText,\n attachments,\n ...(quote === undefined ? {} : { metadata: { quote } }),\n });\n }\n clear();\n }, [attachments, chat, clear, input, quote, submitMessage]);\n\n const value = useMemo<ComposerContextValue>(\n () => ({\n input,\n setInput,\n attachments,\n setAttachments,\n addAttachment,\n removeAttachment,\n clearAttachments,\n quote,\n setQuote,\n clearQuote,\n submit,\n stop: chat.stop,\n status: chat.status,\n canSubmit,\n canStop,\n }),\n [\n addAttachment,\n attachments,\n canStop,\n canSubmit,\n chat.status,\n chat.stop,\n clearAttachments,\n clearQuote,\n input,\n quote,\n removeAttachment,\n setAttachments,\n setInput,\n setQuote,\n submit,\n ],\n );\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n (onSubmit as ((event: FormEvent<HTMLFormElement>) => void) | undefined)?.(event);\n if (event.defaultPrevented) {\n return;\n }\n event.preventDefault();\n void submit();\n },\n [onSubmit, submit],\n );\n\n return (\n <InternalComposerProvider value={value}>\n {renderPrimitive(\n \"form\",\n {\n ...props,\n onSubmit: handleSubmit,\n \"data-anvia-composer\": \"\",\n \"data-state\": chat.status,\n } as PrimitiveProps<\"form\">,\n ref,\n )}\n </InternalComposerProvider>\n );\n});\n\ntype ComposerQuoteProps = Omit<PrimitiveProps<\"blockquote\">, \"children\"> & {\n children?: ReactNode | ((quote: ComposerQuote) => ReactNode);\n};\n\nconst ComposerQuotePreview = forwardRef<HTMLQuoteElement, ComposerQuoteProps>(\n function ComposerQuotePreview({ children, ...props }, ref) {\n const composer = useComposer();\n const quote = composer.quote;\n if (quote === undefined) {\n return null;\n }\n const renderedChildren =\n typeof children === \"function\" ? children(quote) : (children ?? quote.text);\n\n return renderPrimitive(\n \"blockquote\",\n {\n ...props,\n children: renderedChildren,\n \"data-anvia-composer-quote\": \"\",\n \"data-message-id\": quote.messageId,\n } as PrimitiveProps<\"blockquote\">,\n ref,\n );\n },\n);\n\nconst ComposerClearQuote = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(\n function ComposerClearQuote({ onClick, ...props }, ref) {\n const composer = useComposer();\n const disabled = props.disabled ?? composer.quote === undefined;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n composer.clearQuote();\n },\n [composer, disabled, onClick],\n );\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Clear quote\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-anvia-clear-quote\": \"\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\ntype ComposerInputProps = PrimitiveProps<\"textarea\"> & {\n autoResize?: boolean;\n maxRows?: number;\n minRows?: number;\n};\n\nconst ComposerInput = forwardRef<HTMLTextAreaElement, ComposerInputProps>(function ComposerInput(\n {\n autoResize = true,\n maxRows: maxRowsProp,\n minRows: minRowsProp,\n onChange,\n onKeyDown,\n rows,\n ...props\n },\n ref,\n) {\n const composer = useComposer();\n const inputRef = useRef<HTMLTextAreaElement | null>(null);\n const wasAutoResizeRef = useRef(autoResize);\n const composedInputRef = useMemo(() => composeRefs(inputRef, ref), [ref]);\n const minRows = normalizeRows(minRowsProp ?? rows ?? 1, 1);\n const maxRows = normalizeRows(maxRowsProp ?? 6, minRows);\n\n useEffect(() => {\n const wasAutoResize = wasAutoResizeRef.current;\n wasAutoResizeRef.current = autoResize;\n if (!autoResize) {\n if (wasAutoResize) {\n resetComposerInputSize(inputRef.current);\n }\n return;\n }\n resizeComposerInput(inputRef.current, { maxRows, minRows });\n });\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLTextAreaElement>) => {\n onChange?.(event);\n if (!event.defaultPrevented) {\n composer.setInput(event.currentTarget.value);\n if (autoResize) {\n resizeComposerInput(event.currentTarget, { maxRows, minRows });\n }\n }\n },\n [autoResize, composer, maxRows, minRows, onChange],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLTextAreaElement>) => {\n onKeyDown?.(event);\n if (\n event.defaultPrevented ||\n event.key !== \"Enter\" ||\n event.shiftKey ||\n event.nativeEvent.isComposing\n ) {\n return;\n }\n event.preventDefault();\n void composer.submit();\n },\n [composer, onKeyDown],\n );\n\n return renderPrimitive(\n \"textarea\",\n {\n ...props,\n \"aria-label\": props[\"aria-label\"] ?? \"Message\",\n disabled: props.disabled ?? composer.status === \"streaming\",\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n rows: autoResize ? minRows : rows,\n value: composer.input,\n \"data-anvia-composer-input\": \"\",\n } as PrimitiveProps<\"textarea\">,\n composedInputRef,\n );\n});\n\ntype ComposerInputResizeOptions = {\n maxRows: number;\n minRows: number;\n};\n\nfunction resizeComposerInput(\n input: HTMLTextAreaElement | null,\n { maxRows, minRows }: ComposerInputResizeOptions,\n): void {\n if (input === null) {\n return;\n }\n\n const style = getComputedStyle(input);\n const lineHeight = lineHeightFromStyle(style);\n const paddingHeight = pixelValue(style.paddingTop) + pixelValue(style.paddingBottom);\n const borderHeight = pixelValue(style.borderTopWidth) + pixelValue(style.borderBottomWidth);\n const minContentHeight = lineHeight * minRows;\n const maxContentHeight = Math.max(minContentHeight, lineHeight * maxRows);\n\n input.style.height = \"auto\";\n const scrollContentHeight = Math.max(input.scrollHeight - paddingHeight, 0);\n const contentHeight = clamp(scrollContentHeight, minContentHeight, maxContentHeight);\n const nextHeight =\n style.boxSizing === \"border-box\" ? contentHeight + paddingHeight + borderHeight : contentHeight;\n\n input.style.height = `${Math.ceil(nextHeight)}px`;\n input.style.overflowY = scrollContentHeight > maxContentHeight ? \"auto\" : \"hidden\";\n}\n\nfunction resetComposerInputSize(input: HTMLTextAreaElement | null): void {\n if (input === null) {\n return;\n }\n input.style.height = \"\";\n input.style.overflowY = \"\";\n}\n\nfunction normalizeRows(value: number, min: number): number {\n if (!Number.isFinite(value)) {\n return min;\n }\n return Math.max(min, Math.floor(value));\n}\n\nfunction lineHeightFromStyle(style: CSSStyleDeclaration): number {\n return pixelValue(style.lineHeight) || (pixelValue(style.fontSize) || 16) * 1.2;\n}\n\nfunction pixelValue(value: string): number {\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction promptWithQuote(prompt: string, quote: ComposerQuote): string {\n const quotedText = quote.text\n .split(/\\r?\\n/)\n .map((line) => `> ${line}`)\n .join(\"\\n\");\n if (prompt.trim().length === 0) {\n return quotedText;\n }\n return `${quotedText}\\n\\n${prompt}`;\n}\n\nfunction normalizeQuote(quote: ComposerQuote | undefined): ComposerQuote | undefined {\n if (quote === undefined) {\n return undefined;\n }\n return {\n text: quote.text,\n messageId: quote.messageId,\n };\n}\n\nconst ComposerSubmit = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(\n function ComposerSubmit(props, ref) {\n const composer = useComposer();\n const disabled = props.disabled ?? !composer.canSubmit;\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Send\",\n disabled,\n type: props.type ?? \"submit\",\n \"data-anvia-submit\": \"\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\nconst ComposerStop = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(function ComposerStop(\n { onClick, ...props },\n ref,\n) {\n const composer = useComposer();\n const disabled = props.disabled ?? !composer.canStop;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n composer.stop();\n },\n [composer, disabled, onClick],\n );\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Stop\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-anvia-stop\": \"\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n});\n\ntype ComposerAttachmentsChildren = ReactNode | ((attachment: UIAttachment) => ReactNode);\n\ntype ComposerAttachmentsProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: ComposerAttachmentsChildren;\n keepMounted?: boolean;\n};\n\nconst ComposerAttachments = forwardRef<HTMLDivElement, ComposerAttachmentsProps>(\n function ComposerAttachments({ children, keepMounted = false, ...props }, ref) {\n const composer = useComposer();\n const empty = composer.attachments.length === 0;\n if (empty && !keepMounted) {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: composer.attachments.map((attachment) => (\n <InternalAttachmentProvider\n key={attachment.id}\n value={{\n attachment,\n remove: () => {\n composer.removeAttachment(attachment.id);\n },\n }}\n >\n {typeof children === \"function\"\n ? children(attachment)\n : (children ?? <Attachment.Root />)}\n </InternalAttachmentProvider>\n )),\n \"data-anvia-composer-attachments\": \"\",\n \"data-empty\": empty ? \"\" : undefined,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\ntype ComposerAddAttachmentProps = PrimitiveProps<\"button\"> & {\n accept?: string;\n multiple?: boolean;\n};\n\ntype ComposerAttachmentInputProps = PrimitiveProps<\"input\">;\n\nconst ComposerAttachmentInput = forwardRef<HTMLInputElement, ComposerAttachmentInputProps>(\n function ComposerAttachmentInput({ onChange, ...props }, ref) {\n const composer = useComposer();\n const disabled = props.disabled ?? composer.status === \"streaming\";\n\n const handleChange = useCallback(\n async (event: ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n if (event.defaultPrevented) {\n return;\n }\n const files = Array.from(event.currentTarget.files ?? []);\n event.currentTarget.value = \"\";\n for (const file of files) {\n await composer.addAttachment(file);\n }\n },\n [composer, onChange],\n );\n\n return renderPrimitive(\n \"input\",\n {\n ...props,\n disabled,\n onChange: (event) => {\n void handleChange(event);\n },\n type: \"file\",\n \"data-anvia-attachment-input\": \"\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"input\">,\n ref,\n );\n },\n);\n\nconst ComposerAddAttachment = forwardRef<HTMLButtonElement, ComposerAddAttachmentProps>(\n function ComposerAddAttachment({ accept, multiple = false, onClick, ...props }, ref) {\n const composer = useComposer();\n const inputRef = useRef<HTMLInputElement | null>(null);\n const disabled = props.disabled ?? composer.status === \"streaming\";\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n inputRef.current?.click();\n },\n [disabled, onClick],\n );\n\n return (\n <>\n {renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Attach\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-anvia-add-attachment\": \"\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n )}\n <ComposerAttachmentInput\n accept={accept}\n aria-hidden=\"true\"\n hidden\n multiple={multiple}\n ref={inputRef}\n tabIndex={-1}\n />\n </>\n );\n },\n);\n\ntype ComposerAttachmentDropzoneProps = PrimitiveProps<\"div\"> & {\n disabled?: boolean;\n};\n\nconst ComposerAttachmentDropzone = forwardRef<HTMLDivElement, ComposerAttachmentDropzoneProps>(\n function ComposerAttachmentDropzone(\n { disabled: disabledProp = false, onDragLeave, onDragOver, onDrop, ...props },\n ref,\n ) {\n const composer = useComposer();\n const [dragging, setDragging] = useState(false);\n const disabled = disabledProp || composer.status === \"streaming\";\n\n const handleDragOver = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n onDragOver?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n event.preventDefault();\n setDragging(true);\n },\n [disabled, onDragOver],\n );\n\n const handleDragLeave = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n onDragLeave?.(event);\n if (!event.defaultPrevented) {\n setDragging(false);\n }\n },\n [onDragLeave],\n );\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n onDrop?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n event.preventDefault();\n setDragging(false);\n const files = Array.from(event.dataTransfer.files);\n void Promise.all(files.map((file) => composer.addAttachment(file)));\n },\n [composer, disabled, onDrop],\n );\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n onDragLeave: handleDragLeave,\n onDragOver: handleDragOver,\n onDrop: handleDrop,\n \"data-anvia-attachment-dropzone\": \"\",\n \"data-dragging\": dragging ? \"\" : undefined,\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nfunction createAttachment(attachment: CreateUIAttachment): UIAttachment {\n return {\n ...attachment,\n id: attachment.id ?? createAttachmentId(),\n };\n}\n\nfunction isFileAttachmentInput(attachment: File | CreateUIAttachment): attachment is File {\n return typeof File !== \"undefined\" && attachment instanceof File;\n}\n\nasync function attachmentFromFile(file: File): Promise<UIAttachment> {\n return {\n id: createAttachmentId(),\n type: file.type.startsWith(\"image/\") ? \"image\" : \"document\",\n name: file.name,\n mediaType: file.type.length > 0 ? file.type : \"application/octet-stream\",\n data: await readFileData(file),\n };\n}\n\nasync function readFileData(file: File): Promise<string> {\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.addEventListener(\"load\", () => {\n resolve(String(reader.result ?? \"\"));\n });\n reader.addEventListener(\"error\", () => {\n reject(reader.error ?? new Error(\"Failed to read attachment.\"));\n });\n reader.readAsDataURL(file);\n });\n return dataUrl.includes(\",\") ? dataUrl.slice(dataUrl.indexOf(\",\") + 1) : dataUrl;\n}\n\nlet nextAttachmentId = 0;\n\nfunction createAttachmentId(): string {\n const random = globalThis.crypto?.randomUUID?.();\n if (random !== undefined) {\n return `attachment_${random}`;\n }\n nextAttachmentId += 1;\n return `attachment_${nextAttachmentId.toString(36)}`;\n}\n\nexport const Composer = {\n Root: ComposerRoot,\n Quote: ComposerQuotePreview,\n ClearQuote: ComposerClearQuote,\n Input: ComposerInput,\n Attachments: ComposerAttachments,\n AddAttachment: ComposerAddAttachment,\n AttachmentInput: ComposerAttachmentInput,\n AttachmentDropzone: ComposerAttachmentDropzone,\n Submit: ComposerSubmit,\n Stop: ComposerStop,\n} as const;\n","import type { ChatSuggestion, UIMessage, UseChatStatus } from \"@anvia/react\";\nimport {\n Fragment,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n type UIEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport {\n InternalMessageProvider,\n InternalThreadProvider,\n type ThreadContextValue,\n useChatContext,\n useThread,\n} from \"../contexts\";\nimport { Message } from \"../message/index\";\nimport { composeRefs, type PrimitiveProps, renderPrimitive } from \"../primitives\";\n\ntype ThreadMessagesChildren = ReactNode | ((message: UIMessage) => ReactNode);\ntype ThreadSuggestionChildren = ReactNode | ((suggestion: ChatSuggestion) => ReactNode);\n\nconst ThreadRoot = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function ThreadRoot(props, ref) {\n const chat = useChatContext();\n const viewportRef = useRef<HTMLElement | null>(null);\n const [atBottom, setAtBottom] = useState(true);\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"smooth\") => {\n const viewport = viewportRef.current;\n if (viewport === null) {\n return;\n }\n viewport.scrollTo({ top: viewport.scrollHeight, behavior });\n }, []);\n const thread = useMemo<ThreadContextValue>(\n () => ({ viewportRef, atBottom, setAtBottom, scrollToBottom }),\n [atBottom, scrollToBottom],\n );\n\n return (\n <InternalThreadProvider value={thread}>\n {renderPrimitive(\n \"div\",\n {\n ...props,\n \"data-anvia-thread\": \"\",\n \"data-state\": chat.status,\n } as PrimitiveProps<\"div\">,\n ref,\n )}\n </InternalThreadProvider>\n );\n },\n);\n\ntype ThreadViewportProps = PrimitiveProps<\"div\"> & {\n autoScroll?: boolean;\n};\n\nconst ThreadViewport = forwardRef<HTMLDivElement, ThreadViewportProps>(function ThreadViewport(\n { autoScroll = true, onScroll, ...props },\n ref,\n) {\n const chat = useChatContext();\n const thread = useThread();\n const messages = chat.messages;\n const composedRef = useMemo(\n () =>\n composeRefs<HTMLDivElement>(ref, (node) => {\n thread.viewportRef.current = node;\n }),\n [ref, thread.viewportRef],\n );\n\n useEffect(() => {\n const hasMessages = messages.length > 0;\n if (autoScroll && (thread.atBottom || !hasMessages)) {\n thread.scrollToBottom(\"auto\");\n }\n }, [autoScroll, messages, thread]);\n\n const handleScroll = useCallback(\n (event: UIEvent<HTMLDivElement>) => {\n onScroll?.(event);\n const node = event.currentTarget;\n const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;\n thread.setAtBottom(distanceFromBottom < 8);\n },\n [onScroll, thread],\n );\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n onScroll: handleScroll,\n \"data-anvia-thread-viewport\": \"\",\n \"data-state\": thread.atBottom ? \"bottom\" : \"away\",\n } as PrimitiveProps<\"div\">,\n composedRef,\n );\n});\n\nconst ThreadViewportFooter = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function ThreadViewportFooter(props, ref) {\n return renderPrimitive(\n \"div\",\n {\n ...props,\n \"data-anvia-thread-viewport-footer\": \"\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nconst ThreadEmpty = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function ThreadEmpty(props, ref) {\n const chat = useChatContext();\n if (chat.messages.length > 0) {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n \"data-anvia-thread-empty\": \"\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\ntype ThreadStatusProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: ReactNode | ((status: UseChatStatus) => ReactNode);\n};\n\nconst ThreadStatus = forwardRef<HTMLDivElement, ThreadStatusProps>(function ThreadStatus(\n { children, ...props },\n ref,\n) {\n const chat = useChatContext();\n const renderedChildren = typeof children === \"function\" ? children(chat.status) : children;\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderedChildren ?? chat.status,\n \"data-anvia-thread-status\": \"\",\n \"data-state\": chat.status,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n});\n\nconst ThreadLoading = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function ThreadLoading(props, ref) {\n const chat = useChatContext();\n if (chat.status !== \"streaming\") {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: props.children ?? \"Loading\",\n \"data-anvia-thread-loading\": \"\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\ntype ThreadErrorProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: ReactNode | ((error: unknown) => ReactNode);\n};\n\nconst ThreadError = forwardRef<HTMLDivElement, ThreadErrorProps>(function ThreadError(\n { children, ...props },\n ref,\n) {\n const chat = useChatContext();\n if (chat.status !== \"error\" && chat.error === undefined) {\n return null;\n }\n const renderedChildren = typeof children === \"function\" ? children(chat.error) : children;\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderedChildren ?? errorMessage(chat.error),\n \"data-anvia-thread-error\": \"\",\n role: props.role ?? \"alert\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n});\n\ntype ThreadMessagesProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: ThreadMessagesChildren;\n keepMounted?: boolean;\n};\n\nconst ThreadMessages = forwardRef<HTMLDivElement, ThreadMessagesProps>(function ThreadMessages(\n { children, keepMounted = true, ...props },\n ref,\n) {\n const chat = useChatContext();\n const empty = chat.messages.length === 0;\n if (empty && !keepMounted) {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: chat.messages.map((message) => (\n <InternalMessageProvider key={message.id} message={message}>\n {typeof children === \"function\" ? children(message) : (children ?? defaultMessage())}\n </InternalMessageProvider>\n )),\n \"data-anvia-thread-messages\": \"\",\n \"data-empty\": empty ? \"\" : undefined,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n});\n\ntype ThreadSuggestionsProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: ThreadSuggestionChildren;\n keepMounted?: boolean;\n};\n\nconst ThreadSuggestions = forwardRef<HTMLDivElement, ThreadSuggestionsProps>(\n function ThreadSuggestions({ children, keepMounted = false, ...props }, ref) {\n const chat = useChatContext();\n const suggestions = chat.suggestions ?? [];\n const empty = suggestions.length === 0;\n if (empty && !keepMounted) {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: suggestions.map((suggestion) =>\n typeof children === \"function\" ? (\n <Fragment key={suggestion.id}>{children(suggestion)}</Fragment>\n ) : (\n <ThreadSuggestion key={suggestion.id} suggestion={suggestion}>\n {children}\n </ThreadSuggestion>\n ),\n ),\n \"data-anvia-thread-suggestions\": \"\",\n \"data-empty\": empty ? \"\" : undefined,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\ntype ThreadSuggestionProps = Omit<PrimitiveProps<\"button\">, \"children\"> & {\n children?: ReactNode;\n prompt?: string;\n suggestion?: ChatSuggestion;\n};\n\nconst ThreadSuggestion = forwardRef<HTMLButtonElement, ThreadSuggestionProps>(\n function ThreadSuggestion({ onClick, prompt, suggestion, ...props }, ref) {\n const chat = useChatContext();\n const suggestionPrompt = prompt ?? suggestion?.prompt ?? \"\";\n const disabled =\n props.disabled ?? (suggestionPrompt.length === 0 || chat.status === \"streaming\");\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n void chat.sendMessage(suggestionPrompt);\n },\n [chat, disabled, onClick, suggestionPrompt],\n );\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? suggestion?.label ?? suggestionPrompt,\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-anvia-thread-suggestion\": \"\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\nconst ThreadScrollToBottom = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(\n function ThreadScrollToBottom({ onClick, ...props }, ref) {\n const thread = useThread();\n const disabled = props.disabled ?? thread.atBottom;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n thread.scrollToBottom();\n },\n [disabled, onClick, thread],\n );\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Scroll to bottom\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-anvia-scroll-to-bottom\": \"\",\n \"data-state\": thread.atBottom ? \"bottom\" : \"away\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\nfunction defaultMessage(): ReactNode {\n return (\n <Message.Root>\n <Message.Content>\n <Message.Parts />\n </Message.Content>\n <Message.Actions />\n </Message.Root>\n );\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n return \"Something went wrong.\";\n}\n\nexport const Thread = {\n Root: ThreadRoot,\n Viewport: ThreadViewport,\n ViewportFooter: ThreadViewportFooter,\n Messages: ThreadMessages,\n Empty: ThreadEmpty,\n Status: ThreadStatus,\n Loading: ThreadLoading,\n Error: ThreadError,\n Suggestions: ThreadSuggestions,\n Suggestion: ThreadSuggestion,\n ScrollToBottom: ThreadScrollToBottom,\n} as const;\n"],"mappings":"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","names":["ComposerRoot","ComposerQuotePreview","ComposerClearQuote","ComposerInput","ComposerSubmit","ComposerStop","ComposerAttachments","ComposerAttachmentInput","ComposerAddAttachment","ComposerAttachmentDropzone","Fragment","forwardRef","useCallback","useEffect","useMemo","useRef","useState","jsx","jsxs","forwardRef","ThreadRoot","useRef","useState","useCallback","useMemo","ThreadViewport","useEffect","ThreadViewportFooter","ThreadEmpty","ThreadStatus","ThreadLoading","ThreadError","ThreadMessages","ThreadSuggestions","Fragment","ThreadSuggestion","ThreadScrollToBottom"]}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderPrimitive
|
|
3
|
+
} from "./chunk-T3ZFZ3NP.js";
|
|
4
|
+
import {
|
|
5
|
+
InternalThreadListItemProvider,
|
|
6
|
+
useThreadList,
|
|
7
|
+
useThreadListItem
|
|
8
|
+
} from "./chunk-5IHC7D4U.js";
|
|
9
|
+
|
|
10
|
+
// src/thread-list/parts.tsx
|
|
11
|
+
import {
|
|
12
|
+
forwardRef,
|
|
13
|
+
useCallback
|
|
14
|
+
} from "react";
|
|
15
|
+
import { jsx } from "react/jsx-runtime";
|
|
16
|
+
var ThreadListRoot = forwardRef(function ThreadListRoot2({ onKeyDown, ...props }, ref) {
|
|
17
|
+
const threadList = useThreadList();
|
|
18
|
+
const handleKeyDown = useCallback(
|
|
19
|
+
(event) => {
|
|
20
|
+
onKeyDown?.(event);
|
|
21
|
+
if (event.defaultPrevented || !["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const triggers = Array.from(
|
|
25
|
+
event.currentTarget.querySelectorAll(
|
|
26
|
+
"[data-anvia-thread-list-trigger]:not(:disabled)"
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
if (triggers.length === 0) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
const activeElement = document.activeElement;
|
|
34
|
+
const currentIndex = activeElement instanceof HTMLButtonElement ? triggers.indexOf(activeElement) : -1;
|
|
35
|
+
const nextIndex = nextTriggerIndex(event.key, currentIndex, triggers.length);
|
|
36
|
+
triggers[nextIndex]?.focus();
|
|
37
|
+
},
|
|
38
|
+
[onKeyDown]
|
|
39
|
+
);
|
|
40
|
+
return renderPrimitive(
|
|
41
|
+
"div",
|
|
42
|
+
{
|
|
43
|
+
...props,
|
|
44
|
+
onKeyDown: handleKeyDown,
|
|
45
|
+
"data-anvia-thread-list": "",
|
|
46
|
+
"data-state": threadList.status ?? "idle"
|
|
47
|
+
},
|
|
48
|
+
ref
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
var ThreadListNew = forwardRef(
|
|
52
|
+
function ThreadListNew2({ onClick, ...props }, ref) {
|
|
53
|
+
const threadList = useThreadList();
|
|
54
|
+
const handleClick = useCallback(
|
|
55
|
+
(event) => {
|
|
56
|
+
onClick?.(event);
|
|
57
|
+
if (event.defaultPrevented || props.disabled) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
void threadList.createThread();
|
|
61
|
+
},
|
|
62
|
+
[onClick, props.disabled, threadList]
|
|
63
|
+
);
|
|
64
|
+
return renderPrimitive(
|
|
65
|
+
"button",
|
|
66
|
+
{
|
|
67
|
+
...props,
|
|
68
|
+
children: props.children ?? "New chat",
|
|
69
|
+
onClick: handleClick,
|
|
70
|
+
type: props.type ?? "button",
|
|
71
|
+
"data-anvia-thread-list-new": "",
|
|
72
|
+
"data-state": props.disabled ? "disabled" : "enabled"
|
|
73
|
+
},
|
|
74
|
+
ref
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
var ThreadListItems = forwardRef(function ThreadListItems2({ archived = false, children, keepMounted = false, ...props }, ref) {
|
|
79
|
+
const threadList = useThreadList();
|
|
80
|
+
const threads = threadList.threads.filter((thread) => Boolean(thread.archived) === archived);
|
|
81
|
+
const empty = threads.length === 0;
|
|
82
|
+
if (empty && !keepMounted) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return renderPrimitive(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
...props,
|
|
89
|
+
children: threads.map((thread) => /* @__PURE__ */ jsx(
|
|
90
|
+
InternalThreadListItemProvider,
|
|
91
|
+
{
|
|
92
|
+
value: { thread, active: thread.id === threadList.activeThreadId },
|
|
93
|
+
children: typeof children === "function" ? children(thread) : children ?? /* @__PURE__ */ jsx(DefaultThreadItem, {})
|
|
94
|
+
},
|
|
95
|
+
thread.id
|
|
96
|
+
)),
|
|
97
|
+
"data-anvia-thread-list-items": "",
|
|
98
|
+
"data-archived": archived ? "" : void 0,
|
|
99
|
+
"data-empty": empty ? "" : void 0
|
|
100
|
+
},
|
|
101
|
+
ref
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
var ThreadListEmpty = forwardRef(function ThreadListEmpty2({ archived = false, ...props }, ref) {
|
|
105
|
+
const threadList = useThreadList();
|
|
106
|
+
const hasVisibleThreads = threadList.threads.some(
|
|
107
|
+
(thread) => Boolean(thread.archived) === archived
|
|
108
|
+
);
|
|
109
|
+
if (hasVisibleThreads) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return renderPrimitive(
|
|
113
|
+
"div",
|
|
114
|
+
{
|
|
115
|
+
...props,
|
|
116
|
+
children: props.children ?? "No conversations.",
|
|
117
|
+
"data-anvia-thread-list-empty": ""
|
|
118
|
+
},
|
|
119
|
+
ref
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
var ThreadListItemRoot = forwardRef(
|
|
123
|
+
function ThreadListItemRoot2(props, ref) {
|
|
124
|
+
const item = useThreadListItem();
|
|
125
|
+
return renderPrimitive(
|
|
126
|
+
"div",
|
|
127
|
+
{
|
|
128
|
+
...props,
|
|
129
|
+
"data-anvia-thread-list-item": "",
|
|
130
|
+
"data-active": item.active ? "" : void 0,
|
|
131
|
+
"data-thread-id": item.thread.id
|
|
132
|
+
},
|
|
133
|
+
ref
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
var ThreadListItemTrigger = forwardRef(
|
|
138
|
+
function ThreadListItemTrigger2({ onClick, ...props }, ref) {
|
|
139
|
+
const threadList = useThreadList();
|
|
140
|
+
const item = useThreadListItem();
|
|
141
|
+
const disabled = props.disabled ?? false;
|
|
142
|
+
const handleClick = useCallback(
|
|
143
|
+
(event) => {
|
|
144
|
+
onClick?.(event);
|
|
145
|
+
if (event.defaultPrevented || disabled) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
void threadList.switchThread(item.thread.id);
|
|
149
|
+
},
|
|
150
|
+
[disabled, item.thread.id, onClick, threadList]
|
|
151
|
+
);
|
|
152
|
+
return renderPrimitive(
|
|
153
|
+
"button",
|
|
154
|
+
{
|
|
155
|
+
...props,
|
|
156
|
+
children: props.children ?? /* @__PURE__ */ jsx(ThreadListItemTitle, {}),
|
|
157
|
+
disabled,
|
|
158
|
+
onClick: handleClick,
|
|
159
|
+
type: props.type ?? "button",
|
|
160
|
+
"aria-current": item.active ? "true" : void 0,
|
|
161
|
+
"data-anvia-thread-list-trigger": "",
|
|
162
|
+
"data-state": disabled ? "disabled" : "enabled"
|
|
163
|
+
},
|
|
164
|
+
ref
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
var ThreadListItemTitle = forwardRef(
|
|
169
|
+
function ThreadListItemTitle2({ fallback = "New chat", ...props }, ref) {
|
|
170
|
+
const { thread } = useThreadListItem();
|
|
171
|
+
return renderPrimitive(
|
|
172
|
+
"span",
|
|
173
|
+
{
|
|
174
|
+
...props,
|
|
175
|
+
children: props.children ?? thread.title ?? fallback,
|
|
176
|
+
"data-anvia-thread-list-title": ""
|
|
177
|
+
},
|
|
178
|
+
ref
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
function createThreadListItemAction(action, defaultLabel, dataAttribute) {
|
|
183
|
+
return forwardRef(function ThreadListItemAction({ onClick, ...props }, ref) {
|
|
184
|
+
const threadList = useThreadList();
|
|
185
|
+
const { thread } = useThreadListItem();
|
|
186
|
+
const actionHandler = threadList[action];
|
|
187
|
+
const disabled = props.disabled ?? actionHandler === void 0;
|
|
188
|
+
const handleClick = useCallback(
|
|
189
|
+
(event) => {
|
|
190
|
+
onClick?.(event);
|
|
191
|
+
if (event.defaultPrevented || disabled) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
focusAfterThreadItemRemoval(event.currentTarget);
|
|
195
|
+
void actionHandler?.(thread.id);
|
|
196
|
+
},
|
|
197
|
+
[actionHandler, disabled, onClick, thread.id]
|
|
198
|
+
);
|
|
199
|
+
return renderPrimitive(
|
|
200
|
+
"button",
|
|
201
|
+
{
|
|
202
|
+
...props,
|
|
203
|
+
children: props.children ?? defaultLabel,
|
|
204
|
+
disabled,
|
|
205
|
+
onClick: handleClick,
|
|
206
|
+
type: props.type ?? "button",
|
|
207
|
+
[dataAttribute]: "",
|
|
208
|
+
"data-state": disabled ? "disabled" : "enabled"
|
|
209
|
+
},
|
|
210
|
+
ref
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
var ThreadListItemArchive = createThreadListItemAction(
|
|
215
|
+
"archiveThread",
|
|
216
|
+
"Archive",
|
|
217
|
+
"data-anvia-thread-list-archive"
|
|
218
|
+
);
|
|
219
|
+
var ThreadListItemUnarchive = createThreadListItemAction(
|
|
220
|
+
"unarchiveThread",
|
|
221
|
+
"Unarchive",
|
|
222
|
+
"data-anvia-thread-list-unarchive"
|
|
223
|
+
);
|
|
224
|
+
var ThreadListItemDelete = createThreadListItemAction(
|
|
225
|
+
"deleteThread",
|
|
226
|
+
"Delete",
|
|
227
|
+
"data-anvia-thread-list-delete"
|
|
228
|
+
);
|
|
229
|
+
function DefaultThreadItem() {
|
|
230
|
+
return /* @__PURE__ */ jsx(ThreadListItemRoot, { children: /* @__PURE__ */ jsx(ThreadListItemTrigger, {}) });
|
|
231
|
+
}
|
|
232
|
+
function nextTriggerIndex(key, currentIndex, triggerCount) {
|
|
233
|
+
if (key === "Home") {
|
|
234
|
+
return 0;
|
|
235
|
+
}
|
|
236
|
+
if (key === "End") {
|
|
237
|
+
return triggerCount - 1;
|
|
238
|
+
}
|
|
239
|
+
if (currentIndex === -1) {
|
|
240
|
+
return key === "ArrowUp" ? triggerCount - 1 : 0;
|
|
241
|
+
}
|
|
242
|
+
if (key === "ArrowUp") {
|
|
243
|
+
return (currentIndex - 1 + triggerCount) % triggerCount;
|
|
244
|
+
}
|
|
245
|
+
return (currentIndex + 1) % triggerCount;
|
|
246
|
+
}
|
|
247
|
+
function focusAfterThreadItemRemoval(actionButton) {
|
|
248
|
+
const root = actionButton.closest("[data-anvia-thread-list]");
|
|
249
|
+
const currentItem = actionButton.closest("[data-anvia-thread-list-item]");
|
|
250
|
+
if (root === null || currentItem === null || !currentItem.contains(root.ownerDocument.activeElement)) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const triggers = Array.from(
|
|
254
|
+
root.querySelectorAll("[data-anvia-thread-list-trigger]:not(:disabled)")
|
|
255
|
+
);
|
|
256
|
+
const currentTrigger = currentItem.querySelector(
|
|
257
|
+
"[data-anvia-thread-list-trigger]"
|
|
258
|
+
);
|
|
259
|
+
const currentIndex = currentTrigger === null ? -1 : triggers.indexOf(currentTrigger);
|
|
260
|
+
const remainingTriggers = triggers.filter((trigger) => !currentItem.contains(trigger));
|
|
261
|
+
const fallback = root.querySelector(
|
|
262
|
+
"[data-anvia-thread-list-new]:not(:disabled)"
|
|
263
|
+
);
|
|
264
|
+
const focusTarget = remainingTriggers[Math.min(Math.max(currentIndex, 0), remainingTriggers.length - 1)] ?? fallback ?? root;
|
|
265
|
+
if (focusTarget === root && !root.hasAttribute("tabindex")) {
|
|
266
|
+
root.tabIndex = -1;
|
|
267
|
+
}
|
|
268
|
+
focusTarget.focus();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/thread-list/index.ts
|
|
272
|
+
var ThreadList = {
|
|
273
|
+
Root: ThreadListRoot,
|
|
274
|
+
New: ThreadListNew,
|
|
275
|
+
Items: ThreadListItems,
|
|
276
|
+
Empty: ThreadListEmpty
|
|
277
|
+
};
|
|
278
|
+
var ThreadListItem = {
|
|
279
|
+
Root: ThreadListItemRoot,
|
|
280
|
+
Trigger: ThreadListItemTrigger,
|
|
281
|
+
Title: ThreadListItemTitle,
|
|
282
|
+
Archive: ThreadListItemArchive,
|
|
283
|
+
Unarchive: ThreadListItemUnarchive,
|
|
284
|
+
Delete: ThreadListItemDelete
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export {
|
|
288
|
+
ThreadList,
|
|
289
|
+
ThreadListItem
|
|
290
|
+
};
|
|
291
|
+
//# sourceMappingURL=chunk-MXYHYD3O.js.map
|