@anvia/react-ui 0.2.0 → 0.4.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.
Files changed (48) hide show
  1. package/README.md +14 -1
  2. package/dist/attachment/index.js +2 -2
  3. package/dist/chat/index.d.ts +39 -3
  4. package/dist/chat/index.js +4 -4
  5. package/dist/{chunk-RRINF6FN.js → chunk-32QFNRXR.js} +2 -2
  6. package/dist/chunk-657E5BPN.js +291 -0
  7. package/dist/chunk-657E5BPN.js.map +1 -0
  8. package/dist/{chunk-7AS6R7BB.js → chunk-BCCU3VT5.js} +93 -16
  9. package/dist/chunk-BCCU3VT5.js.map +1 -0
  10. package/dist/{chunk-AOZN3SWB.js → chunk-FZANAMWH.js} +4 -3
  11. package/dist/{chunk-AOZN3SWB.js.map → chunk-FZANAMWH.js.map} +1 -1
  12. package/dist/chunk-GXB4VINL.js +236 -0
  13. package/dist/chunk-GXB4VINL.js.map +1 -0
  14. package/dist/{chunk-WK33ER4Q.js → chunk-JUNV3MUR.js} +2 -2
  15. package/dist/chunk-KO36TK2O.js +1549 -0
  16. package/dist/chunk-KO36TK2O.js.map +1 -0
  17. package/dist/chunk-SE7I6ZXJ.js +432 -0
  18. package/dist/chunk-SE7I6ZXJ.js.map +1 -0
  19. package/dist/{chunk-LSHD67YK.js → chunk-TOBAQM2G.js} +2 -2
  20. package/dist/completion/index.js +2 -2
  21. package/dist/human-input/index.js +2 -2
  22. package/dist/image/index.d.ts +40 -0
  23. package/dist/image/index.js +12 -0
  24. package/dist/image/index.js.map +1 -0
  25. package/dist/image-DanUxcl2.d.ts +14 -0
  26. package/dist/index.d.ts +7 -1
  27. package/dist/index.js +32 -8
  28. package/dist/message/index.js +3 -3
  29. package/dist/selection-toolbar/index.d.ts +21 -0
  30. package/dist/selection-toolbar/index.js +12 -0
  31. package/dist/selection-toolbar/index.js.map +1 -0
  32. package/dist/selection-toolbar-Cwjbuv5S.d.ts +14 -0
  33. package/dist/shared.d.ts +4 -1
  34. package/dist/shared.js +13 -3
  35. package/dist/styles.css +42 -0
  36. package/dist/thread-C2-Xo08o.d.ts +102 -0
  37. package/dist/thread-list/index.d.ts +47 -0
  38. package/dist/thread-list/index.js +18 -0
  39. package/dist/thread-list/index.js.map +1 -0
  40. package/dist/thread-list-On8db4XL.d.ts +34 -0
  41. package/package.json +27 -4
  42. package/dist/chunk-7AS6R7BB.js.map +0 -1
  43. package/dist/chunk-AXZB6JSE.js +0 -813
  44. package/dist/chunk-AXZB6JSE.js.map +0 -1
  45. package/dist/thread-CluT3m5k.d.ts +0 -31
  46. /package/dist/{chunk-RRINF6FN.js.map → chunk-32QFNRXR.js.map} +0 -0
  47. /package/dist/{chunk-WK33ER4Q.js.map → chunk-JUNV3MUR.js.map} +0 -0
  48. /package/dist/{chunk-LSHD67YK.js.map → chunk-TOBAQM2G.js.map} +0 -0
@@ -1,813 +0,0 @@
1
- import {
2
- Message
3
- } from "./chunk-AOZN3SWB.js";
4
- import {
5
- Attachment
6
- } from "./chunk-RRINF6FN.js";
7
- import {
8
- composeRefs,
9
- renderPrimitive
10
- } from "./chunk-T3ZFZ3NP.js";
11
- import {
12
- InternalAttachmentProvider,
13
- InternalComposerProvider,
14
- InternalMessageProvider,
15
- InternalThreadProvider,
16
- useChatContext,
17
- useComposer,
18
- useThread
19
- } from "./chunk-7AS6R7BB.js";
20
-
21
- // src/chat/composer.tsx
22
- import {
23
- forwardRef,
24
- useCallback,
25
- useEffect,
26
- useMemo,
27
- useRef,
28
- useState
29
- } from "react";
30
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
31
- var ComposerRoot = forwardRef(function ComposerRoot2({
32
- attachments: attachmentsProp,
33
- defaultAttachments,
34
- defaultInput = "",
35
- input: inputProp,
36
- onAttachmentsChange,
37
- onInputChange,
38
- submitMessage,
39
- onSubmit,
40
- ...props
41
- }, ref) {
42
- const chat = useChatContext();
43
- const [uncontrolledInput, setUncontrolledInput] = useState(defaultInput);
44
- const [uncontrolledAttachments, setUncontrolledAttachments] = useState(() => [
45
- ...defaultAttachments ?? []
46
- ]);
47
- const input = inputProp ?? uncontrolledInput;
48
- const attachments = attachmentsProp ?? uncontrolledAttachments;
49
- const attachmentsRef = useRef(attachments);
50
- attachmentsRef.current = attachments;
51
- const inputControlled = inputProp !== void 0;
52
- const attachmentsControlled = attachmentsProp !== void 0;
53
- const canSubmit = (input.trim().length > 0 || attachments.length > 0) && chat.status !== "streaming";
54
- const canStop = chat.status === "streaming";
55
- const setInput = useCallback(
56
- (nextInput) => {
57
- if (!inputControlled) {
58
- setUncontrolledInput(nextInput);
59
- }
60
- onInputChange?.(nextInput);
61
- },
62
- [inputControlled, onInputChange]
63
- );
64
- const setAttachments = useCallback(
65
- (update) => {
66
- const nextAttachments = typeof update === "function" ? update(attachmentsRef.current) : update;
67
- attachmentsRef.current = nextAttachments;
68
- if (!attachmentsControlled) {
69
- setUncontrolledAttachments(nextAttachments);
70
- }
71
- onAttachmentsChange?.(nextAttachments);
72
- },
73
- [attachmentsControlled, onAttachmentsChange]
74
- );
75
- const addAttachment = useCallback(
76
- async (attachment) => {
77
- const normalized = isFileAttachmentInput(attachment) ? await attachmentFromFile(attachment) : createAttachment(attachment);
78
- setAttachments((current) => [...current, normalized]);
79
- },
80
- [setAttachments]
81
- );
82
- const removeAttachment = useCallback(
83
- (id) => {
84
- setAttachments((current) => current.filter((attachment) => attachment.id !== id));
85
- },
86
- [setAttachments]
87
- );
88
- const clearAttachments = useCallback(() => {
89
- setAttachments([]);
90
- }, [setAttachments]);
91
- const clear = useCallback(() => {
92
- setInput("");
93
- setAttachments([]);
94
- }, [setAttachments, setInput]);
95
- const submit = useCallback(async () => {
96
- const prompt = input;
97
- if (prompt.trim().length === 0 && attachments.length === 0 || chat.status === "streaming") {
98
- return;
99
- }
100
- if (submitMessage !== void 0) {
101
- await submitMessage({
102
- input: prompt,
103
- attachments,
104
- chat,
105
- clear
106
- });
107
- return;
108
- }
109
- if (attachments.length === 0) {
110
- await chat.sendMessage(prompt);
111
- } else {
112
- await chat.sendMessage({
113
- text: prompt,
114
- attachments
115
- });
116
- }
117
- clear();
118
- }, [attachments, chat, clear, input, submitMessage]);
119
- const value = useMemo(
120
- () => ({
121
- input,
122
- setInput,
123
- attachments,
124
- setAttachments,
125
- addAttachment,
126
- removeAttachment,
127
- clearAttachments,
128
- submit,
129
- stop: chat.stop,
130
- status: chat.status,
131
- canSubmit,
132
- canStop
133
- }),
134
- [
135
- addAttachment,
136
- attachments,
137
- canStop,
138
- canSubmit,
139
- chat.status,
140
- chat.stop,
141
- clearAttachments,
142
- input,
143
- removeAttachment,
144
- setAttachments,
145
- setInput,
146
- submit
147
- ]
148
- );
149
- const handleSubmit = useCallback(
150
- (event) => {
151
- onSubmit?.(event);
152
- if (event.defaultPrevented) {
153
- return;
154
- }
155
- event.preventDefault();
156
- void submit();
157
- },
158
- [onSubmit, submit]
159
- );
160
- return /* @__PURE__ */ jsx(InternalComposerProvider, { value, children: renderPrimitive(
161
- "form",
162
- {
163
- ...props,
164
- onSubmit: handleSubmit,
165
- "data-anvia-composer": "",
166
- "data-state": chat.status
167
- },
168
- ref
169
- ) });
170
- });
171
- var ComposerInput = forwardRef(function ComposerInput2({
172
- autoResize = true,
173
- maxRows: maxRowsProp,
174
- minRows: minRowsProp,
175
- onChange,
176
- onKeyDown,
177
- rows,
178
- ...props
179
- }, ref) {
180
- const composer = useComposer();
181
- const inputRef = useRef(null);
182
- const wasAutoResizeRef = useRef(autoResize);
183
- const composedInputRef = useMemo(() => composeRefs(inputRef, ref), [ref]);
184
- const minRows = normalizeRows(minRowsProp ?? rows ?? 1, 1);
185
- const maxRows = normalizeRows(maxRowsProp ?? 6, minRows);
186
- useEffect(() => {
187
- const wasAutoResize = wasAutoResizeRef.current;
188
- wasAutoResizeRef.current = autoResize;
189
- if (!autoResize) {
190
- if (wasAutoResize) {
191
- resetComposerInputSize(inputRef.current);
192
- }
193
- return;
194
- }
195
- resizeComposerInput(inputRef.current, { maxRows, minRows });
196
- });
197
- const handleChange = useCallback(
198
- (event) => {
199
- onChange?.(event);
200
- if (!event.defaultPrevented) {
201
- composer.setInput(event.currentTarget.value);
202
- if (autoResize) {
203
- resizeComposerInput(event.currentTarget, { maxRows, minRows });
204
- }
205
- }
206
- },
207
- [autoResize, composer, maxRows, minRows, onChange]
208
- );
209
- const handleKeyDown = useCallback(
210
- (event) => {
211
- onKeyDown?.(event);
212
- if (event.defaultPrevented || event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) {
213
- return;
214
- }
215
- event.preventDefault();
216
- void composer.submit();
217
- },
218
- [composer, onKeyDown]
219
- );
220
- return renderPrimitive(
221
- "textarea",
222
- {
223
- ...props,
224
- "aria-label": props["aria-label"] ?? "Message",
225
- disabled: props.disabled ?? composer.status === "streaming",
226
- onChange: handleChange,
227
- onKeyDown: handleKeyDown,
228
- rows: autoResize ? minRows : rows,
229
- value: composer.input,
230
- "data-anvia-composer-input": ""
231
- },
232
- composedInputRef
233
- );
234
- });
235
- function resizeComposerInput(input, { maxRows, minRows }) {
236
- if (input === null) {
237
- return;
238
- }
239
- const style = getComputedStyle(input);
240
- const lineHeight = lineHeightFromStyle(style);
241
- const paddingHeight = pixelValue(style.paddingTop) + pixelValue(style.paddingBottom);
242
- const borderHeight = pixelValue(style.borderTopWidth) + pixelValue(style.borderBottomWidth);
243
- const minContentHeight = lineHeight * minRows;
244
- const maxContentHeight = Math.max(minContentHeight, lineHeight * maxRows);
245
- input.style.height = "auto";
246
- const scrollContentHeight = Math.max(input.scrollHeight - paddingHeight, 0);
247
- const contentHeight = clamp(scrollContentHeight, minContentHeight, maxContentHeight);
248
- const nextHeight = style.boxSizing === "border-box" ? contentHeight + paddingHeight + borderHeight : contentHeight;
249
- input.style.height = `${Math.ceil(nextHeight)}px`;
250
- input.style.overflowY = scrollContentHeight > maxContentHeight ? "auto" : "hidden";
251
- }
252
- function resetComposerInputSize(input) {
253
- if (input === null) {
254
- return;
255
- }
256
- input.style.height = "";
257
- input.style.overflowY = "";
258
- }
259
- function normalizeRows(value, min) {
260
- if (!Number.isFinite(value)) {
261
- return min;
262
- }
263
- return Math.max(min, Math.floor(value));
264
- }
265
- function lineHeightFromStyle(style) {
266
- return pixelValue(style.lineHeight) || (pixelValue(style.fontSize) || 16) * 1.2;
267
- }
268
- function pixelValue(value) {
269
- const parsed = Number.parseFloat(value);
270
- return Number.isFinite(parsed) ? parsed : 0;
271
- }
272
- function clamp(value, min, max) {
273
- return Math.min(Math.max(value, min), max);
274
- }
275
- var ComposerSubmit = forwardRef(
276
- function ComposerSubmit2(props, ref) {
277
- const composer = useComposer();
278
- const disabled = props.disabled ?? !composer.canSubmit;
279
- return renderPrimitive(
280
- "button",
281
- {
282
- ...props,
283
- children: props.children ?? "Send",
284
- disabled,
285
- type: props.type ?? "submit",
286
- "data-anvia-submit": "",
287
- "data-state": disabled ? "disabled" : "enabled"
288
- },
289
- ref
290
- );
291
- }
292
- );
293
- var ComposerStop = forwardRef(function ComposerStop2({ onClick, ...props }, ref) {
294
- const composer = useComposer();
295
- const disabled = props.disabled ?? !composer.canStop;
296
- const handleClick = useCallback(
297
- (event) => {
298
- onClick?.(event);
299
- if (event.defaultPrevented || disabled) {
300
- return;
301
- }
302
- composer.stop();
303
- },
304
- [composer, disabled, onClick]
305
- );
306
- return renderPrimitive(
307
- "button",
308
- {
309
- ...props,
310
- children: props.children ?? "Stop",
311
- disabled,
312
- onClick: handleClick,
313
- type: props.type ?? "button",
314
- "data-anvia-stop": "",
315
- "data-state": disabled ? "disabled" : "enabled"
316
- },
317
- ref
318
- );
319
- });
320
- var ComposerAttachments = forwardRef(
321
- function ComposerAttachments2({ children, keepMounted = false, ...props }, ref) {
322
- const composer = useComposer();
323
- const empty = composer.attachments.length === 0;
324
- if (empty && !keepMounted) {
325
- return null;
326
- }
327
- return renderPrimitive(
328
- "div",
329
- {
330
- ...props,
331
- children: composer.attachments.map((attachment) => /* @__PURE__ */ jsx(
332
- InternalAttachmentProvider,
333
- {
334
- value: {
335
- attachment,
336
- remove: () => {
337
- composer.removeAttachment(attachment.id);
338
- }
339
- },
340
- children: typeof children === "function" ? children(attachment) : children ?? /* @__PURE__ */ jsx(Attachment.Root, {})
341
- },
342
- attachment.id
343
- )),
344
- "data-anvia-composer-attachments": "",
345
- "data-empty": empty ? "" : void 0
346
- },
347
- ref
348
- );
349
- }
350
- );
351
- var ComposerAttachmentInput = forwardRef(
352
- function ComposerAttachmentInput2({ onChange, ...props }, ref) {
353
- const composer = useComposer();
354
- const disabled = props.disabled ?? composer.status === "streaming";
355
- const handleChange = useCallback(
356
- async (event) => {
357
- onChange?.(event);
358
- if (event.defaultPrevented) {
359
- return;
360
- }
361
- const files = Array.from(event.currentTarget.files ?? []);
362
- event.currentTarget.value = "";
363
- for (const file of files) {
364
- await composer.addAttachment(file);
365
- }
366
- },
367
- [composer, onChange]
368
- );
369
- return renderPrimitive(
370
- "input",
371
- {
372
- ...props,
373
- disabled,
374
- onChange: (event) => {
375
- void handleChange(event);
376
- },
377
- type: "file",
378
- "data-anvia-attachment-input": "",
379
- "data-state": disabled ? "disabled" : "enabled"
380
- },
381
- ref
382
- );
383
- }
384
- );
385
- var ComposerAddAttachment = forwardRef(
386
- function ComposerAddAttachment2({ accept, multiple = false, onClick, ...props }, ref) {
387
- const composer = useComposer();
388
- const inputRef = useRef(null);
389
- const disabled = props.disabled ?? composer.status === "streaming";
390
- const handleClick = useCallback(
391
- (event) => {
392
- onClick?.(event);
393
- if (event.defaultPrevented || disabled) {
394
- return;
395
- }
396
- inputRef.current?.click();
397
- },
398
- [disabled, onClick]
399
- );
400
- return /* @__PURE__ */ jsxs(Fragment, { children: [
401
- renderPrimitive(
402
- "button",
403
- {
404
- ...props,
405
- children: props.children ?? "Attach",
406
- disabled,
407
- onClick: handleClick,
408
- type: props.type ?? "button",
409
- "data-anvia-add-attachment": "",
410
- "data-state": disabled ? "disabled" : "enabled"
411
- },
412
- ref
413
- ),
414
- /* @__PURE__ */ jsx(
415
- ComposerAttachmentInput,
416
- {
417
- accept,
418
- "aria-hidden": "true",
419
- hidden: true,
420
- multiple,
421
- ref: inputRef,
422
- tabIndex: -1
423
- }
424
- )
425
- ] });
426
- }
427
- );
428
- var ComposerAttachmentDropzone = forwardRef(
429
- function ComposerAttachmentDropzone2({ disabled: disabledProp = false, onDragLeave, onDragOver, onDrop, ...props }, ref) {
430
- const composer = useComposer();
431
- const [dragging, setDragging] = useState(false);
432
- const disabled = disabledProp || composer.status === "streaming";
433
- const handleDragOver = useCallback(
434
- (event) => {
435
- onDragOver?.(event);
436
- if (event.defaultPrevented || disabled) {
437
- return;
438
- }
439
- event.preventDefault();
440
- setDragging(true);
441
- },
442
- [disabled, onDragOver]
443
- );
444
- const handleDragLeave = useCallback(
445
- (event) => {
446
- onDragLeave?.(event);
447
- if (!event.defaultPrevented) {
448
- setDragging(false);
449
- }
450
- },
451
- [onDragLeave]
452
- );
453
- const handleDrop = useCallback(
454
- (event) => {
455
- onDrop?.(event);
456
- if (event.defaultPrevented || disabled) {
457
- return;
458
- }
459
- event.preventDefault();
460
- setDragging(false);
461
- const files = Array.from(event.dataTransfer.files);
462
- void Promise.all(files.map((file) => composer.addAttachment(file)));
463
- },
464
- [composer, disabled, onDrop]
465
- );
466
- return renderPrimitive(
467
- "div",
468
- {
469
- ...props,
470
- onDragLeave: handleDragLeave,
471
- onDragOver: handleDragOver,
472
- onDrop: handleDrop,
473
- "data-anvia-attachment-dropzone": "",
474
- "data-dragging": dragging ? "" : void 0,
475
- "data-state": disabled ? "disabled" : "enabled"
476
- },
477
- ref
478
- );
479
- }
480
- );
481
- function createAttachment(attachment) {
482
- return {
483
- ...attachment,
484
- id: attachment.id ?? createAttachmentId()
485
- };
486
- }
487
- function isFileAttachmentInput(attachment) {
488
- return typeof File !== "undefined" && attachment instanceof File;
489
- }
490
- async function attachmentFromFile(file) {
491
- return {
492
- id: createAttachmentId(),
493
- type: file.type.startsWith("image/") ? "image" : "document",
494
- name: file.name,
495
- mediaType: file.type.length > 0 ? file.type : "application/octet-stream",
496
- data: await readFileData(file)
497
- };
498
- }
499
- async function readFileData(file) {
500
- const dataUrl = await new Promise((resolve, reject) => {
501
- const reader = new FileReader();
502
- reader.addEventListener("load", () => {
503
- resolve(String(reader.result ?? ""));
504
- });
505
- reader.addEventListener("error", () => {
506
- reject(reader.error ?? new Error("Failed to read attachment."));
507
- });
508
- reader.readAsDataURL(file);
509
- });
510
- return dataUrl.includes(",") ? dataUrl.slice(dataUrl.indexOf(",") + 1) : dataUrl;
511
- }
512
- var nextAttachmentId = 0;
513
- function createAttachmentId() {
514
- const random = globalThis.crypto?.randomUUID?.();
515
- if (random !== void 0) {
516
- return `attachment_${random}`;
517
- }
518
- nextAttachmentId += 1;
519
- return `attachment_${nextAttachmentId.toString(36)}`;
520
- }
521
- var Composer = {
522
- Root: ComposerRoot,
523
- Input: ComposerInput,
524
- Attachments: ComposerAttachments,
525
- AddAttachment: ComposerAddAttachment,
526
- AttachmentInput: ComposerAttachmentInput,
527
- AttachmentDropzone: ComposerAttachmentDropzone,
528
- Submit: ComposerSubmit,
529
- Stop: ComposerStop
530
- };
531
-
532
- // src/chat/thread.tsx
533
- import {
534
- Fragment as Fragment2,
535
- forwardRef as forwardRef2,
536
- useCallback as useCallback2,
537
- useEffect as useEffect2,
538
- useMemo as useMemo2,
539
- useRef as useRef2,
540
- useState as useState2
541
- } from "react";
542
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
543
- var ThreadRoot = forwardRef2(
544
- function ThreadRoot2(props, ref) {
545
- const chat = useChatContext();
546
- const viewportRef = useRef2(null);
547
- const [atBottom, setAtBottom] = useState2(true);
548
- const scrollToBottom = useCallback2((behavior = "smooth") => {
549
- const viewport = viewportRef.current;
550
- if (viewport === null) {
551
- return;
552
- }
553
- viewport.scrollTo({ top: viewport.scrollHeight, behavior });
554
- }, []);
555
- const thread = useMemo2(
556
- () => ({ viewportRef, atBottom, setAtBottom, scrollToBottom }),
557
- [atBottom, scrollToBottom]
558
- );
559
- return /* @__PURE__ */ jsx2(InternalThreadProvider, { value: thread, children: renderPrimitive(
560
- "div",
561
- {
562
- ...props,
563
- "data-anvia-thread": "",
564
- "data-state": chat.status
565
- },
566
- ref
567
- ) });
568
- }
569
- );
570
- var ThreadViewport = forwardRef2(function ThreadViewport2({ autoScroll = true, onScroll, ...props }, ref) {
571
- const chat = useChatContext();
572
- const thread = useThread();
573
- const messages = chat.messages;
574
- const composedRef = useMemo2(
575
- () => composeRefs(ref, (node) => {
576
- thread.viewportRef.current = node;
577
- }),
578
- [ref, thread.viewportRef]
579
- );
580
- useEffect2(() => {
581
- const hasMessages = messages.length > 0;
582
- if (autoScroll && (thread.atBottom || !hasMessages)) {
583
- thread.scrollToBottom("auto");
584
- }
585
- }, [autoScroll, messages, thread]);
586
- const handleScroll = useCallback2(
587
- (event) => {
588
- onScroll?.(event);
589
- const node = event.currentTarget;
590
- const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
591
- thread.setAtBottom(distanceFromBottom < 8);
592
- },
593
- [onScroll, thread]
594
- );
595
- return renderPrimitive(
596
- "div",
597
- {
598
- ...props,
599
- onScroll: handleScroll,
600
- "data-anvia-thread-viewport": "",
601
- "data-state": thread.atBottom ? "bottom" : "away"
602
- },
603
- composedRef
604
- );
605
- });
606
- var ThreadViewportFooter = forwardRef2(
607
- function ThreadViewportFooter2(props, ref) {
608
- return renderPrimitive(
609
- "div",
610
- {
611
- ...props,
612
- "data-anvia-thread-viewport-footer": ""
613
- },
614
- ref
615
- );
616
- }
617
- );
618
- var ThreadEmpty = forwardRef2(
619
- function ThreadEmpty2(props, ref) {
620
- const chat = useChatContext();
621
- if (chat.messages.length > 0) {
622
- return null;
623
- }
624
- return renderPrimitive(
625
- "div",
626
- {
627
- ...props,
628
- "data-anvia-thread-empty": ""
629
- },
630
- ref
631
- );
632
- }
633
- );
634
- var ThreadStatus = forwardRef2(function ThreadStatus2({ children, ...props }, ref) {
635
- const chat = useChatContext();
636
- const renderedChildren = typeof children === "function" ? children(chat.status) : children;
637
- return renderPrimitive(
638
- "div",
639
- {
640
- ...props,
641
- children: renderedChildren ?? chat.status,
642
- "data-anvia-thread-status": "",
643
- "data-state": chat.status
644
- },
645
- ref
646
- );
647
- });
648
- var ThreadLoading = forwardRef2(
649
- function ThreadLoading2(props, ref) {
650
- const chat = useChatContext();
651
- if (chat.status !== "streaming") {
652
- return null;
653
- }
654
- return renderPrimitive(
655
- "div",
656
- {
657
- ...props,
658
- children: props.children ?? "Loading",
659
- "data-anvia-thread-loading": ""
660
- },
661
- ref
662
- );
663
- }
664
- );
665
- var ThreadError = forwardRef2(function ThreadError2({ children, ...props }, ref) {
666
- const chat = useChatContext();
667
- if (chat.status !== "error" && chat.error === void 0) {
668
- return null;
669
- }
670
- const renderedChildren = typeof children === "function" ? children(chat.error) : children;
671
- return renderPrimitive(
672
- "div",
673
- {
674
- ...props,
675
- children: renderedChildren ?? errorMessage(chat.error),
676
- "data-anvia-thread-error": "",
677
- role: props.role ?? "alert"
678
- },
679
- ref
680
- );
681
- });
682
- var ThreadMessages = forwardRef2(function ThreadMessages2({ children, keepMounted = true, ...props }, ref) {
683
- const chat = useChatContext();
684
- const empty = chat.messages.length === 0;
685
- if (empty && !keepMounted) {
686
- return null;
687
- }
688
- return renderPrimitive(
689
- "div",
690
- {
691
- ...props,
692
- children: chat.messages.map((message) => /* @__PURE__ */ jsx2(InternalMessageProvider, { message, children: typeof children === "function" ? children(message) : children ?? defaultMessage() }, message.id)),
693
- "data-anvia-thread-messages": "",
694
- "data-empty": empty ? "" : void 0
695
- },
696
- ref
697
- );
698
- });
699
- var ThreadSuggestions = forwardRef2(
700
- function ThreadSuggestions2({ children, keepMounted = false, ...props }, ref) {
701
- const chat = useChatContext();
702
- const suggestions = chat.suggestions ?? [];
703
- const empty = suggestions.length === 0;
704
- if (empty && !keepMounted) {
705
- return null;
706
- }
707
- return renderPrimitive(
708
- "div",
709
- {
710
- ...props,
711
- children: suggestions.map(
712
- (suggestion) => typeof children === "function" ? /* @__PURE__ */ jsx2(Fragment2, { children: children(suggestion) }, suggestion.id) : /* @__PURE__ */ jsx2(ThreadSuggestion, { suggestion, children }, suggestion.id)
713
- ),
714
- "data-anvia-thread-suggestions": "",
715
- "data-empty": empty ? "" : void 0
716
- },
717
- ref
718
- );
719
- }
720
- );
721
- var ThreadSuggestion = forwardRef2(
722
- function ThreadSuggestion2({ onClick, prompt, suggestion, ...props }, ref) {
723
- const chat = useChatContext();
724
- const suggestionPrompt = prompt ?? suggestion?.prompt ?? "";
725
- const disabled = props.disabled ?? (suggestionPrompt.length === 0 || chat.status === "streaming");
726
- const handleClick = useCallback2(
727
- (event) => {
728
- onClick?.(event);
729
- if (event.defaultPrevented || disabled) {
730
- return;
731
- }
732
- void chat.sendMessage(suggestionPrompt);
733
- },
734
- [chat, disabled, onClick, suggestionPrompt]
735
- );
736
- return renderPrimitive(
737
- "button",
738
- {
739
- ...props,
740
- children: props.children ?? suggestion?.label ?? suggestionPrompt,
741
- disabled,
742
- onClick: handleClick,
743
- type: props.type ?? "button",
744
- "data-anvia-thread-suggestion": "",
745
- "data-state": disabled ? "disabled" : "enabled"
746
- },
747
- ref
748
- );
749
- }
750
- );
751
- var ThreadScrollToBottom = forwardRef2(
752
- function ThreadScrollToBottom2({ onClick, ...props }, ref) {
753
- const thread = useThread();
754
- const disabled = props.disabled ?? thread.atBottom;
755
- const handleClick = useCallback2(
756
- (event) => {
757
- onClick?.(event);
758
- if (event.defaultPrevented || disabled) {
759
- return;
760
- }
761
- thread.scrollToBottom();
762
- },
763
- [disabled, onClick, thread]
764
- );
765
- return renderPrimitive(
766
- "button",
767
- {
768
- ...props,
769
- children: props.children ?? "Scroll to bottom",
770
- disabled,
771
- onClick: handleClick,
772
- type: props.type ?? "button",
773
- "data-anvia-scroll-to-bottom": "",
774
- "data-state": thread.atBottom ? "bottom" : "away"
775
- },
776
- ref
777
- );
778
- }
779
- );
780
- function defaultMessage() {
781
- return /* @__PURE__ */ jsxs2(Message.Root, { children: [
782
- /* @__PURE__ */ jsx2(Message.Content, { children: /* @__PURE__ */ jsx2(Message.Parts, {}) }),
783
- /* @__PURE__ */ jsx2(Message.Actions, {})
784
- ] });
785
- }
786
- function errorMessage(error) {
787
- if (error instanceof Error) {
788
- return error.message;
789
- }
790
- if (typeof error === "string") {
791
- return error;
792
- }
793
- return "Something went wrong.";
794
- }
795
- var Thread = {
796
- Root: ThreadRoot,
797
- Viewport: ThreadViewport,
798
- ViewportFooter: ThreadViewportFooter,
799
- Messages: ThreadMessages,
800
- Empty: ThreadEmpty,
801
- Status: ThreadStatus,
802
- Loading: ThreadLoading,
803
- Error: ThreadError,
804
- Suggestions: ThreadSuggestions,
805
- Suggestion: ThreadSuggestion,
806
- ScrollToBottom: ThreadScrollToBottom
807
- };
808
-
809
- export {
810
- Composer,
811
- Thread
812
- };
813
- //# sourceMappingURL=chunk-AXZB6JSE.js.map