@app-studio/web 0.9.65 → 0.9.67
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/components/Title/Title/SlideEffect.d.ts +1 -1
- package/dist/web.cjs.development.js +22 -22
- package/dist/web.cjs.development.js.map +1 -1
- package/dist/web.cjs.production.min.js +1 -1
- package/dist/web.cjs.production.min.js.map +1 -1
- package/dist/web.esm.js +22 -22
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +22 -22
- package/dist/web.umd.development.js.map +1 -1
- package/dist/web.umd.production.min.js +1 -1
- package/dist/web.umd.production.min.js.map +1 -1
- package/docs/components/ChatInput.mdx +489 -8
- package/package.json +1 -1
|
@@ -2,11 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
A customizable chat input component with file upload support, mentions, suggestions, audio recording, and model selection.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## **Import**
|
|
6
6
|
```tsx
|
|
7
7
|
import { ChatInput } from '@app-studio/web';
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
+
## **Overview**
|
|
11
|
+
|
|
12
|
+
The ChatInput component is a feature-rich, production-ready chat input with comprehensive file handling capabilities. It provides:
|
|
13
|
+
|
|
14
|
+
- **File Upload Management**: Support for single and multiple file uploads with drag-and-drop
|
|
15
|
+
- **Progress Tracking**: Real-time upload progress monitoring
|
|
16
|
+
- **File Validation**: Built-in file size validation (50MB limit)
|
|
17
|
+
- **Audio Recording**: Optional audio recording with automatic file conversion
|
|
18
|
+
- **Mentions & Suggestions**: Auto-completion for mentions and suggestions
|
|
19
|
+
- **Agent Integration**: Support for running agents with stop functionality
|
|
20
|
+
- **Customizable Styling**: Flexible theming through the `views` prop
|
|
21
|
+
- **Accessibility**: Keyboard shortcuts and screen reader support
|
|
22
|
+
|
|
23
|
+
### **Key Features**
|
|
24
|
+
|
|
25
|
+
1. **Automatic File Queue Management**: Files are automatically queued and uploaded sequentially
|
|
26
|
+
2. **Drag-and-Drop Support**: Built-in drag-and-drop with visual feedback
|
|
27
|
+
3. **File Attachments Display**: Uploaded files are displayed as removable attachments
|
|
28
|
+
4. **Error Handling**: Comprehensive error handling with customizable error messages
|
|
29
|
+
5. **Model Selection**: Support for AI model selection with thinking mode
|
|
30
|
+
6. **Prompt Examples**: Display clickable prompt examples for quick input
|
|
31
|
+
|
|
32
|
+
## **Basic Usage**
|
|
33
|
+
|
|
10
34
|
### **Default**
|
|
11
35
|
```tsx
|
|
12
36
|
import React, { useState } from 'react';
|
|
@@ -25,6 +49,44 @@ export const DefaultChatInput = () => {
|
|
|
25
49
|
};
|
|
26
50
|
```
|
|
27
51
|
|
|
52
|
+
## **Required Props**
|
|
53
|
+
|
|
54
|
+
### **getPendingFiles**
|
|
55
|
+
Function to retrieve the current list of pending files. This is required for the component to access files that are staged for upload.
|
|
56
|
+
|
|
57
|
+
- **Type:** `() => File[]`
|
|
58
|
+
- **Required:** `true`
|
|
59
|
+
|
|
60
|
+
### **clearPendingFiles**
|
|
61
|
+
Function to clear all pending files. This is typically called after a successful submission or when files need to be reset.
|
|
62
|
+
|
|
63
|
+
- **Type:** `() => void`
|
|
64
|
+
- **Required:** `true`
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import React, { useState } from 'react';
|
|
68
|
+
import { ChatInput } from '@app-studio/web';
|
|
69
|
+
|
|
70
|
+
export const FileManagementExample = () => {
|
|
71
|
+
const [pendingFiles, setPendingFiles] = useState<File[]>([]);
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<ChatInput
|
|
75
|
+
onSubmit={(message) => {
|
|
76
|
+
console.log('Message:', message);
|
|
77
|
+
console.log('Files:', pendingFiles);
|
|
78
|
+
// Clear files after submission
|
|
79
|
+
setPendingFiles([]);
|
|
80
|
+
}}
|
|
81
|
+
getPendingFiles={() => pendingFiles}
|
|
82
|
+
clearPendingFiles={() => setPendingFiles([])}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## **Core Props**
|
|
89
|
+
|
|
28
90
|
### **onSubmit**
|
|
29
91
|
Callback function when the form is submitted.
|
|
30
92
|
|
|
@@ -289,6 +351,247 @@ export const UploadErrorChatInput = () => {
|
|
|
289
351
|
};
|
|
290
352
|
```
|
|
291
353
|
|
|
354
|
+
## **File Upload Management**
|
|
355
|
+
|
|
356
|
+
The ChatInput component provides comprehensive file upload capabilities with support for drag-and-drop, multiple file selection, progress tracking, and file validation. Here's how to properly manage file uploads:
|
|
357
|
+
|
|
358
|
+
### **Complete File Upload Example**
|
|
359
|
+
|
|
360
|
+
This example demonstrates the complete file upload workflow with all features:
|
|
361
|
+
|
|
362
|
+
```tsx
|
|
363
|
+
import React, { useState } from 'react';
|
|
364
|
+
import { ChatInput } from '@app-studio/web';
|
|
365
|
+
import { UploadService } from 'src/services/api';
|
|
366
|
+
|
|
367
|
+
export const CompleteFileUploadExample = () => {
|
|
368
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
369
|
+
const [uploadProgress, setUploadProgress] = useState(0);
|
|
370
|
+
const [error, setError] = useState<string>('');
|
|
371
|
+
|
|
372
|
+
const uploadFileRequest = UploadService.useUploadControllerFileService({
|
|
373
|
+
onProgress: (progress) => {
|
|
374
|
+
setUploadProgress(progress);
|
|
375
|
+
console.log(`Upload progress: ${progress}%`);
|
|
376
|
+
},
|
|
377
|
+
onSuccess: (data) => {
|
|
378
|
+
console.log('Upload successful:', data);
|
|
379
|
+
setUploadProgress(0);
|
|
380
|
+
setError('');
|
|
381
|
+
},
|
|
382
|
+
onError: (err) => {
|
|
383
|
+
console.error('Upload failed:', err);
|
|
384
|
+
setError('Failed to upload file. Please try again.');
|
|
385
|
+
setUploadProgress(0);
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
return (
|
|
390
|
+
<>
|
|
391
|
+
{error && <div style={{ color: 'red', marginBottom: 8 }}>{error}</div>}
|
|
392
|
+
{uploadProgress > 0 && (
|
|
393
|
+
<div style={{ marginBottom: 8 }}>
|
|
394
|
+
Upload Progress: {uploadProgress}%
|
|
395
|
+
</div>
|
|
396
|
+
)}
|
|
397
|
+
|
|
398
|
+
<ChatInput
|
|
399
|
+
onFileUpload={(file) => uploadFileRequest.run({ file })}
|
|
400
|
+
onUploadProgress={setUploadProgress}
|
|
401
|
+
onUploadSuccess={(data) => {
|
|
402
|
+
console.log('File uploaded:', data);
|
|
403
|
+
setError('');
|
|
404
|
+
}}
|
|
405
|
+
onUploadError={(err) => {
|
|
406
|
+
setError(err.message || 'Upload failed');
|
|
407
|
+
}}
|
|
408
|
+
onSubmit={(message) => {
|
|
409
|
+
console.log('Message:', message);
|
|
410
|
+
console.log('Attached files:', files);
|
|
411
|
+
setFiles([]);
|
|
412
|
+
}}
|
|
413
|
+
getPendingFiles={() => files}
|
|
414
|
+
clearPendingFiles={() => setFiles([])}
|
|
415
|
+
/>
|
|
416
|
+
</>
|
|
417
|
+
);
|
|
418
|
+
};
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### **Drag and Drop Support**
|
|
422
|
+
|
|
423
|
+
The ChatInput component automatically supports drag-and-drop file uploads. Simply drag files over the input area:
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
import React, { useState } from 'react';
|
|
427
|
+
import { ChatInput } from '@app-studio/web';
|
|
428
|
+
|
|
429
|
+
export const DragDropExample = () => {
|
|
430
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
431
|
+
|
|
432
|
+
return (
|
|
433
|
+
<ChatInput
|
|
434
|
+
onFileUpload={(file) => {
|
|
435
|
+
console.log('File dropped:', file.name);
|
|
436
|
+
// Handle file upload
|
|
437
|
+
}}
|
|
438
|
+
onSubmit={(message) => console.log(message)}
|
|
439
|
+
getPendingFiles={() => files}
|
|
440
|
+
clearPendingFiles={() => setFiles([])}
|
|
441
|
+
// The component automatically handles drag-over visual feedback
|
|
442
|
+
/>
|
|
443
|
+
);
|
|
444
|
+
};
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### **Multiple File Upload**
|
|
448
|
+
|
|
449
|
+
The ChatInput supports uploading multiple files at once. Files are processed sequentially:
|
|
450
|
+
|
|
451
|
+
```tsx
|
|
452
|
+
import React, { useState } from 'react';
|
|
453
|
+
import { ChatInput } from '@app-studio/web';
|
|
454
|
+
|
|
455
|
+
export const MultipleFilesExample = () => {
|
|
456
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
457
|
+
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);
|
|
458
|
+
|
|
459
|
+
const handleFileUpload = (file: File) => {
|
|
460
|
+
console.log('Uploading file:', file.name);
|
|
461
|
+
|
|
462
|
+
// Simulate upload
|
|
463
|
+
setTimeout(() => {
|
|
464
|
+
setUploadedFiles(prev => [...prev, file]);
|
|
465
|
+
console.log('File uploaded successfully:', file.name);
|
|
466
|
+
}, 1000);
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
return (
|
|
470
|
+
<div>
|
|
471
|
+
<div style={{ marginBottom: 8 }}>
|
|
472
|
+
Uploaded files: {uploadedFiles.length}
|
|
473
|
+
</div>
|
|
474
|
+
|
|
475
|
+
<ChatInput
|
|
476
|
+
onFileUpload={handleFileUpload}
|
|
477
|
+
onSubmit={(message) => {
|
|
478
|
+
console.log('Message:', message);
|
|
479
|
+
console.log('All files:', uploadedFiles);
|
|
480
|
+
setUploadedFiles([]);
|
|
481
|
+
}}
|
|
482
|
+
getPendingFiles={() => files}
|
|
483
|
+
clearPendingFiles={() => setFiles([])}
|
|
484
|
+
/>
|
|
485
|
+
</div>
|
|
486
|
+
);
|
|
487
|
+
};
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### **File Size Validation**
|
|
491
|
+
|
|
492
|
+
The component includes built-in file size validation (50MB limit by default):
|
|
493
|
+
|
|
494
|
+
```tsx
|
|
495
|
+
import React, { useState } from 'react';
|
|
496
|
+
import { ChatInput } from '@app-studio/web';
|
|
497
|
+
|
|
498
|
+
export const FileSizeValidationExample = () => {
|
|
499
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
500
|
+
const [error, setError] = useState<string>('');
|
|
501
|
+
|
|
502
|
+
const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB
|
|
503
|
+
|
|
504
|
+
return (
|
|
505
|
+
<>
|
|
506
|
+
{error && <div style={{ color: 'red' }}>{error}</div>}
|
|
507
|
+
|
|
508
|
+
<ChatInput
|
|
509
|
+
onFileUpload={(file) => {
|
|
510
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
511
|
+
setError(`File "${file.name}" exceeds 50MB limit`);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
setError('');
|
|
516
|
+
console.log('Uploading file:', file.name);
|
|
517
|
+
// Proceed with upload
|
|
518
|
+
}}
|
|
519
|
+
onUploadError={(err) => {
|
|
520
|
+
setError('Upload failed: ' + err.message);
|
|
521
|
+
}}
|
|
522
|
+
onSubmit={(message) => console.log(message)}
|
|
523
|
+
getPendingFiles={() => files}
|
|
524
|
+
clearPendingFiles={() => setFiles([])}
|
|
525
|
+
/>
|
|
526
|
+
</>
|
|
527
|
+
);
|
|
528
|
+
};
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### **File Upload Lifecycle**
|
|
532
|
+
|
|
533
|
+
Understanding the file upload lifecycle is crucial for proper implementation:
|
|
534
|
+
|
|
535
|
+
1. **File Selection**: User selects files via button click or drag-and-drop
|
|
536
|
+
2. **Validation**: Files are validated for size (50MB limit)
|
|
537
|
+
3. **Queue**: Valid files are added to the upload queue
|
|
538
|
+
4. **Upload**: Files are uploaded sequentially using `onFileUpload`
|
|
539
|
+
5. **Progress**: `onUploadProgress` is called with progress updates (0-100)
|
|
540
|
+
6. **Success/Error**: `onUploadSuccess` or `onUploadError` is called
|
|
541
|
+
7. **Display**: Uploaded files are displayed as attachments in the input
|
|
542
|
+
8. **Submission**: Files are included when the message is submitted
|
|
543
|
+
9. **Cleanup**: Files are cleared using `clearPendingFiles`
|
|
544
|
+
|
|
545
|
+
```tsx
|
|
546
|
+
import React, { useState } from 'react';
|
|
547
|
+
import { ChatInput } from '@app-studio/web';
|
|
548
|
+
|
|
549
|
+
export const FileLifecycleExample = () => {
|
|
550
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
551
|
+
const [uploadStatus, setUploadStatus] = useState<string>('idle');
|
|
552
|
+
|
|
553
|
+
return (
|
|
554
|
+
<>
|
|
555
|
+
<div>Status: {uploadStatus}</div>
|
|
556
|
+
|
|
557
|
+
<ChatInput
|
|
558
|
+
onFileUpload={(file) => {
|
|
559
|
+
setUploadStatus(`Uploading ${file.name}...`);
|
|
560
|
+
// Upload logic here
|
|
561
|
+
}}
|
|
562
|
+
onUploadProgress={(progress) => {
|
|
563
|
+
setUploadStatus(`Upload progress: ${progress}%`);
|
|
564
|
+
}}
|
|
565
|
+
onUploadSuccess={(data) => {
|
|
566
|
+
setUploadStatus('Upload complete!');
|
|
567
|
+
setTimeout(() => setUploadStatus('idle'), 2000);
|
|
568
|
+
}}
|
|
569
|
+
onUploadError={(error) => {
|
|
570
|
+
setUploadStatus(`Upload failed: ${error.message}`);
|
|
571
|
+
}}
|
|
572
|
+
onSubmit={(message) => {
|
|
573
|
+
console.log('Submitting with files:', files);
|
|
574
|
+
setFiles([]);
|
|
575
|
+
setUploadStatus('idle');
|
|
576
|
+
}}
|
|
577
|
+
getPendingFiles={() => files}
|
|
578
|
+
clearPendingFiles={() => {
|
|
579
|
+
setFiles([]);
|
|
580
|
+
setUploadStatus('idle');
|
|
581
|
+
}}
|
|
582
|
+
/>
|
|
583
|
+
</>
|
|
584
|
+
);
|
|
585
|
+
};
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### **Removing Uploaded Files**
|
|
589
|
+
|
|
590
|
+
Users can remove files before submission by clicking the remove button on each file attachment. The component handles this automatically.
|
|
591
|
+
|
|
592
|
+
## **Other Props**
|
|
593
|
+
|
|
594
|
+
|
|
292
595
|
### **hideAttachments**
|
|
293
596
|
Whether to hide the attachment button.
|
|
294
597
|
|
|
@@ -313,24 +616,78 @@ export const NoAttachmentsChatInput = () => {
|
|
|
313
616
|
};
|
|
314
617
|
```
|
|
315
618
|
|
|
316
|
-
|
|
317
|
-
|
|
619
|
+
|
|
620
|
+
### **sandboxId**
|
|
621
|
+
ID of the sandbox environment for file uploads. Used when integrating with sandbox-based file systems.
|
|
622
|
+
|
|
623
|
+
- **Type:** `string`
|
|
624
|
+
- **Required:** `false`
|
|
625
|
+
|
|
626
|
+
```tsx
|
|
627
|
+
import React, { useState } from 'react';
|
|
628
|
+
import { ChatInput } from '@app-studio/web';
|
|
629
|
+
|
|
630
|
+
export const SandboxChatInput = () => {
|
|
631
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
632
|
+
|
|
633
|
+
return (
|
|
634
|
+
<ChatInput
|
|
635
|
+
sandboxId="my-sandbox-123"
|
|
636
|
+
onFileUpload={(file) => {
|
|
637
|
+
console.log('Uploading to sandbox:', file.name);
|
|
638
|
+
// File will be uploaded to the specified sandbox
|
|
639
|
+
}}
|
|
640
|
+
onSubmit={(message) => console.log(message)}
|
|
641
|
+
getPendingFiles={() => files}
|
|
642
|
+
clearPendingFiles={() => setFiles([])}
|
|
643
|
+
/>
|
|
644
|
+
);
|
|
645
|
+
};
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### **onFileBrowse**
|
|
649
|
+
Callback function when the file browser is opened. Useful for tracking user interactions.
|
|
650
|
+
|
|
651
|
+
- **Type:** `() => void`
|
|
652
|
+
- **Required:** `false`
|
|
653
|
+
|
|
654
|
+
```tsx
|
|
655
|
+
import React, { useState } from 'react';
|
|
656
|
+
import { ChatInput } from '@app-studio/web';
|
|
657
|
+
|
|
658
|
+
export const FileBrowseChatInput = () => {
|
|
659
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
660
|
+
|
|
661
|
+
return (
|
|
662
|
+
<ChatInput
|
|
663
|
+
onFileBrowse={() => {
|
|
664
|
+
console.log('User opened file browser');
|
|
665
|
+
// Track analytics or perform other actions
|
|
666
|
+
}}
|
|
667
|
+
onSubmit={(message) => console.log(message)}
|
|
668
|
+
getPendingFiles={() => files}
|
|
669
|
+
clearPendingFiles={() => setFiles([])}
|
|
670
|
+
/>
|
|
671
|
+
);
|
|
672
|
+
};
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### **autoFocus**
|
|
676
|
+
Whether to automatically focus the input on mount.
|
|
318
677
|
|
|
319
678
|
- **Type:** `boolean`
|
|
320
|
-
- **Default:** `
|
|
679
|
+
- **Default:** `true`
|
|
321
680
|
|
|
322
681
|
```tsx
|
|
323
682
|
import React, { useState } from 'react';
|
|
324
683
|
import { ChatInput } from '@app-studio/web';
|
|
325
684
|
|
|
326
|
-
export const
|
|
685
|
+
export const AutoFocusChatInput = () => {
|
|
327
686
|
const [files, setFiles] = useState<File[]>([]);
|
|
328
687
|
|
|
329
688
|
return (
|
|
330
689
|
<ChatInput
|
|
331
|
-
|
|
332
|
-
onAudioRecordingStart={() => console.log('Recording started')}
|
|
333
|
-
onAudioRecordingStop={(audio) => console.log('Audio blob:', audio)}
|
|
690
|
+
autoFocus={false}
|
|
334
691
|
onSubmit={(message) => console.log(message)}
|
|
335
692
|
getPendingFiles={() => files}
|
|
336
693
|
clearPendingFiles={() => setFiles([])}
|
|
@@ -339,6 +696,130 @@ export const AudioChatInput = () => {
|
|
|
339
696
|
};
|
|
340
697
|
```
|
|
341
698
|
|
|
699
|
+
### **errorMessage**
|
|
700
|
+
Error message to display at the bottom of the input.
|
|
701
|
+
|
|
702
|
+
- **Type:** `string`
|
|
703
|
+
- **Required:** `false`
|
|
704
|
+
|
|
705
|
+
```tsx
|
|
706
|
+
import React, { useState } from 'react';
|
|
707
|
+
import { ChatInput } from '@app-studio/web';
|
|
708
|
+
|
|
709
|
+
export const ErrorMessageChatInput = () => {
|
|
710
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
711
|
+
const [error, setError] = useState<string>('');
|
|
712
|
+
|
|
713
|
+
return (
|
|
714
|
+
<ChatInput
|
|
715
|
+
errorMessage={error}
|
|
716
|
+
onSubmit={(message) => {
|
|
717
|
+
if (!message.trim()) {
|
|
718
|
+
setError('Message cannot be empty');
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
setError('');
|
|
722
|
+
console.log(message);
|
|
723
|
+
}}
|
|
724
|
+
getPendingFiles={() => files}
|
|
725
|
+
clearPendingFiles={() => setFiles([])}
|
|
726
|
+
/>
|
|
727
|
+
);
|
|
728
|
+
};
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### **shape**
|
|
732
|
+
Shape of the input container.
|
|
733
|
+
|
|
734
|
+
- **Type:** `Shape`
|
|
735
|
+
- **Default:** `'rounded'`
|
|
736
|
+
- **Possible Values:** `'rounded' | 'square'`
|
|
737
|
+
|
|
738
|
+
```tsx
|
|
739
|
+
import React, { useState } from 'react';
|
|
740
|
+
import { ChatInput } from '@app-studio/web';
|
|
741
|
+
import { Vertical } from 'app-studio';
|
|
742
|
+
|
|
743
|
+
export const ShapeChatInputs = () => {
|
|
744
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
745
|
+
|
|
746
|
+
return (
|
|
747
|
+
<Vertical gap={15}>
|
|
748
|
+
<ChatInput
|
|
749
|
+
shape="rounded"
|
|
750
|
+
onSubmit={(message) => console.log(message)}
|
|
751
|
+
getPendingFiles={() => files}
|
|
752
|
+
clearPendingFiles={() => setFiles([])}
|
|
753
|
+
/>
|
|
754
|
+
<ChatInput
|
|
755
|
+
shape="square"
|
|
756
|
+
onSubmit={(message) => console.log(message)}
|
|
757
|
+
getPendingFiles={() => files}
|
|
758
|
+
clearPendingFiles={() => setFiles([])}
|
|
759
|
+
/>
|
|
760
|
+
</Vertical>
|
|
761
|
+
);
|
|
762
|
+
};
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### **enableAudioRecording**
|
|
766
|
+
Enable audio recording button. When enabled, users can record audio which is automatically converted to a file and uploaded using the same file upload workflow.
|
|
767
|
+
|
|
768
|
+
- **Type:** `boolean`
|
|
769
|
+
- **Default:** `false`
|
|
770
|
+
|
|
771
|
+
### **onAudioRecordingStart**
|
|
772
|
+
Callback when audio recording starts.
|
|
773
|
+
|
|
774
|
+
- **Type:** `() => void`
|
|
775
|
+
- **Required:** `false`
|
|
776
|
+
|
|
777
|
+
### **onAudioRecordingStop**
|
|
778
|
+
Callback when audio recording stops. The recorded audio is provided as a Blob and is automatically added to the upload queue.
|
|
779
|
+
|
|
780
|
+
- **Type:** `(audio: Blob) => void`
|
|
781
|
+
- **Required:** `false`
|
|
782
|
+
|
|
783
|
+
```tsx
|
|
784
|
+
import React, { useState } from 'react';
|
|
785
|
+
import { ChatInput } from '@app-studio/web';
|
|
786
|
+
|
|
787
|
+
export const AudioChatInput = () => {
|
|
788
|
+
const [files, setFiles] = useState<File[]>([]);
|
|
789
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
790
|
+
|
|
791
|
+
return (
|
|
792
|
+
<>
|
|
793
|
+
{isRecording && <div>🎤 Recording...</div>}
|
|
794
|
+
|
|
795
|
+
<ChatInput
|
|
796
|
+
enableAudioRecording
|
|
797
|
+
onAudioRecordingStart={() => {
|
|
798
|
+
console.log('Recording started');
|
|
799
|
+
setIsRecording(true);
|
|
800
|
+
}}
|
|
801
|
+
onAudioRecordingStop={(audioBlob) => {
|
|
802
|
+
console.log('Recording stopped, audio blob:', audioBlob);
|
|
803
|
+
setIsRecording(false);
|
|
804
|
+
// The audio file is automatically added to the upload queue
|
|
805
|
+
}}
|
|
806
|
+
onFileUpload={(file) => {
|
|
807
|
+
console.log('Uploading file (could be audio):', file.name);
|
|
808
|
+
// Handle upload for both regular files and audio recordings
|
|
809
|
+
}}
|
|
810
|
+
onSubmit={(message) => {
|
|
811
|
+
console.log('Message:', message);
|
|
812
|
+
console.log('Files (including audio):', files);
|
|
813
|
+
}}
|
|
814
|
+
getPendingFiles={() => files}
|
|
815
|
+
clearPendingFiles={() => setFiles([])}
|
|
816
|
+
/>
|
|
817
|
+
</>
|
|
818
|
+
);
|
|
819
|
+
};
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
|
|
342
823
|
### **suggestions**
|
|
343
824
|
List of suggestions for auto-completion.
|
|
344
825
|
|