@app-studio/web 0.9.80 → 0.9.81

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 (35) hide show
  1. package/dist/components/Accordion/Accordion/Accordion.type.d.ts +1 -1
  2. package/dist/components/Accordion/Accordion/Accordion.view.d.ts +1 -1
  3. package/dist/components/Badge/Badge/Badge.type.d.ts +1 -1
  4. package/dist/components/Card/Card/Card.type.d.ts +1 -1
  5. package/dist/components/ChatInput/ChatInput/ChatInput.type.d.ts +1 -1
  6. package/dist/components/ColorPicker/ColorPicker/ColorPicker.type.d.ts +1 -1
  7. package/dist/components/EmojiPicker/EmojiPicker/EmojiPicker.type.d.ts +1 -1
  8. package/dist/components/Form/ColorInput/ColorInput/ColorInput.type.d.ts +1 -1
  9. package/dist/components/Form/TagInput/TagInput/TagInput.type.d.ts +1 -1
  10. package/dist/components/Form/TextArea/TextArea/TextArea.type.d.ts +1 -1
  11. package/dist/components/Input/Input.type.d.ts +1 -1
  12. package/dist/components/Message/Message/Message.type.d.ts +1 -1
  13. package/dist/components/Modal/Modal/Modal.props.d.ts +2 -2
  14. package/dist/components/Slider/Slider/Slider.type.d.ts +1 -1
  15. package/dist/components/Title/Title/Title.props.d.ts +0 -5
  16. package/dist/components/Toggle/Toggle/Toggle.type.d.ts +1 -1
  17. package/dist/components/ToggleGroup/ToggleGroup/ToggleGroup.type.d.ts +1 -1
  18. package/dist/pages/tabs.page.d.ts +1 -1
  19. package/dist/web.cjs.development.js +61 -77
  20. package/dist/web.cjs.development.js.map +1 -1
  21. package/dist/web.cjs.production.min.js +1 -1
  22. package/dist/web.cjs.production.min.js.map +1 -1
  23. package/dist/web.esm.js +61 -77
  24. package/dist/web.esm.js.map +1 -1
  25. package/dist/web.umd.development.js +61 -77
  26. package/dist/web.umd.development.js.map +1 -1
  27. package/dist/web.umd.production.min.js +1 -1
  28. package/dist/web.umd.production.min.js.map +1 -1
  29. package/docs/components/Background.mdx +133 -134
  30. package/docs/components/Button.mdx +154 -131
  31. package/docs/components/Chart.mdx +93 -368
  32. package/docs/components/ProgressBar.mdx +77 -394
  33. package/docs/components/Title.mdx +102 -290
  34. package/package.json +1 -1
  35. package/docs/components/ChatInput.mdx +0 -1039
@@ -1,1039 +0,0 @@
1
- # ChatInput
2
-
3
- A customizable chat input component with file upload support, mentions, suggestions, audio recording, and model selection.
4
-
5
- ## **Import**
6
- ```tsx
7
- import { ChatInput } from '@app-studio/web';
8
- ```
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
-
34
- ### **Default**
35
- ```tsx
36
- import React, { useState } from 'react';
37
- import { ChatInput } from '@app-studio/web';
38
-
39
- export const DefaultChatInput = () => {
40
- const [files, setFiles] = useState<File[]>([]);
41
-
42
- return (
43
- <ChatInput
44
- onSubmit={(message) => console.log('Message:', message)}
45
- getPendingFiles={() => files}
46
- clearPendingFiles={() => setFiles([])}
47
- />
48
- );
49
- };
50
- ```
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
-
90
- ### **onSubmit**
91
- Callback function when the form is submitted.
92
-
93
- - **Type:** `(message: string, options?: { model_name?: string; enable_thinking?: boolean }) => void`
94
- - **Required:** `true`
95
-
96
- ```tsx
97
- import React, { useState } from 'react';
98
- import { ChatInput } from '@app-studio/web';
99
-
100
- export const SubmitChatInput = () => {
101
- const [files, setFiles] = useState<File[]>([]);
102
-
103
- return (
104
- <ChatInput
105
- onSubmit={(message, options) => {
106
- console.log('Message:', message);
107
- console.log('Model:', options?.model_name);
108
- console.log('Thinking:', options?.enable_thinking);
109
- }}
110
- getPendingFiles={() => files}
111
- clearPendingFiles={() => setFiles([])}
112
- />
113
- );
114
- };
115
- ```
116
-
117
- ### **placeholder**
118
- Placeholder text for the input.
119
-
120
- - **Type:** `string`
121
- - **Default:** `'Type a message...'`
122
-
123
- ```tsx
124
- import React, { useState } from 'react';
125
- import { ChatInput } from '@app-studio/web';
126
-
127
- export const PlaceholderChatInput = () => {
128
- const [files, setFiles] = useState<File[]>([]);
129
-
130
- return (
131
- <ChatInput
132
- placeholder="Ask me anything..."
133
- onSubmit={(message) => console.log(message)}
134
- getPendingFiles={() => files}
135
- clearPendingFiles={() => setFiles([])}
136
- />
137
- );
138
- };
139
- ```
140
-
141
- ### **loading**
142
- Whether the input is in a loading state.
143
-
144
- - **Type:** `boolean`
145
- - **Default:** `false`
146
-
147
- ```tsx
148
- import React, { useState } from 'react';
149
- import { ChatInput } from '@app-studio/web';
150
-
151
- export const LoadingChatInput = () => {
152
- const [files, setFiles] = useState<File[]>([]);
153
- const [loading, setLoading] = useState(false);
154
-
155
- return (
156
- <ChatInput
157
- loading={loading}
158
- onSubmit={(message) => {
159
- setLoading(true);
160
- setTimeout(() => setLoading(false), 2000);
161
- }}
162
- getPendingFiles={() => files}
163
- clearPendingFiles={() => setFiles([])}
164
- />
165
- );
166
- };
167
- ```
168
-
169
- ### **disabled**
170
- Whether the input is disabled.
171
-
172
- - **Type:** `boolean`
173
- - **Default:** `false`
174
-
175
- ```tsx
176
- import React, { useState } from 'react';
177
- import { ChatInput } from '@app-studio/web';
178
-
179
- export const DisabledChatInput = () => {
180
- const [files, setFiles] = useState<File[]>([]);
181
-
182
- return (
183
- <ChatInput
184
- disabled
185
- onSubmit={(message) => console.log(message)}
186
- getPendingFiles={() => files}
187
- clearPendingFiles={() => setFiles([])}
188
- />
189
- );
190
- };
191
- ```
192
-
193
- ### **value & onChange**
194
- Controlled input value.
195
-
196
- - **Type:** `string` & `(value: string) => void`
197
-
198
- ```tsx
199
- import React, { useState } from 'react';
200
- import { ChatInput } from '@app-studio/web';
201
-
202
- export const ControlledChatInput = () => {
203
- const [value, setValue] = useState('');
204
- const [files, setFiles] = useState<File[]>([]);
205
-
206
- return (
207
- <ChatInput
208
- value={value}
209
- onChange={setValue}
210
- onSubmit={(message) => {
211
- console.log(message);
212
- setValue('');
213
- }}
214
- getPendingFiles={() => files}
215
- clearPendingFiles={() => setFiles([])}
216
- />
217
- );
218
- };
219
- ```
220
-
221
- ### **onFileUpload**
222
- Function to execute file upload. The parent component should provide this to handle the actual file upload logic.
223
-
224
- - **Type:** `(file: File) => void`
225
- - **Required:** `false`
226
-
227
- ```tsx
228
- import React, { useState } from 'react';
229
- import { ChatInput } from '@app-studio/web';
230
- import { UploadService } from 'src/services/api';
231
-
232
- export const FileUploadChatInput = () => {
233
- const [files, setFiles] = useState<File[]>([]);
234
-
235
- const uploadFileRequest = UploadService.useUploadControllerFileService({
236
- onProgress: (p) => console.log('Progress:', p),
237
- onSuccess: (data) => console.log('Success:', data),
238
- onError: (err) => console.error('Error:', err),
239
- });
240
-
241
- return (
242
- <ChatInput
243
- onFileUpload={(file) => uploadFileRequest.run({ file })}
244
- onSubmit={(message) => console.log(message)}
245
- getPendingFiles={() => files}
246
- clearPendingFiles={() => setFiles([])}
247
- />
248
- );
249
- };
250
- ```
251
-
252
- ### **onUploadProgress**
253
- Callback when file upload progress changes.
254
-
255
- - **Type:** `(progress: number) => void`
256
- - **Required:** `false`
257
-
258
- ```tsx
259
- import React, { useState } from 'react';
260
- import { ChatInput } from '@app-studio/web';
261
- import { UploadService } from 'src/services/api';
262
-
263
- export const UploadProgressChatInput = () => {
264
- const [files, setFiles] = useState<File[]>([]);
265
- const [progress, setProgress] = useState(0);
266
-
267
- const uploadFileRequest = UploadService.useUploadControllerFileService({
268
- onProgress: (p) => setProgress(p),
269
- onSuccess: () => setProgress(0),
270
- onError: () => setProgress(0),
271
- });
272
-
273
- return (
274
- <>
275
- {progress > 0 && <div>Upload Progress: {progress}%</div>}
276
- <ChatInput
277
- onFileUpload={(file) => uploadFileRequest.run({ file })}
278
- onUploadProgress={(p) => console.log('Upload progress:', p)}
279
- onSubmit={(message) => console.log(message)}
280
- getPendingFiles={() => files}
281
- clearPendingFiles={() => setFiles([])}
282
- />
283
- </>
284
- );
285
- };
286
- ```
287
-
288
- ### **onUploadSuccess**
289
- Callback when file upload succeeds.
290
-
291
- - **Type:** `(data: any) => void`
292
- - **Required:** `false`
293
-
294
- ```tsx
295
- import React, { useState } from 'react';
296
- import { ChatInput } from '@app-studio/web';
297
- import { UploadService } from 'src/services/api';
298
-
299
- export const UploadSuccessChatInput = () => {
300
- const [files, setFiles] = useState<File[]>([]);
301
-
302
- const uploadFileRequest = UploadService.useUploadControllerFileService({});
303
-
304
- return (
305
- <ChatInput
306
- onFileUpload={(file) => uploadFileRequest.run({ file })}
307
- onUploadSuccess={(data) => {
308
- console.log('Upload successful:', data);
309
- // Perform additional actions on success
310
- }}
311
- onSubmit={(message) => console.log(message)}
312
- getPendingFiles={() => files}
313
- clearPendingFiles={() => setFiles([])}
314
- />
315
- );
316
- };
317
- ```
318
-
319
- ### **onUploadError**
320
- Callback when file upload fails.
321
-
322
- - **Type:** `(error: any) => void`
323
- - **Required:** `false`
324
-
325
- ```tsx
326
- import React, { useState } from 'react';
327
- import { ChatInput } from '@app-studio/web';
328
- import { UploadService } from 'src/services/api';
329
-
330
- export const UploadErrorChatInput = () => {
331
- const [files, setFiles] = useState<File[]>([]);
332
- const [error, setError] = useState<string>('');
333
-
334
- const uploadFileRequest = UploadService.useUploadControllerFileService({});
335
-
336
- return (
337
- <>
338
- {error && <div style={{ color: 'red' }}>{error}</div>}
339
- <ChatInput
340
- onFileUpload={(file) => uploadFileRequest.run({ file })}
341
- onUploadError={(err) => {
342
- console.error('Upload failed:', err);
343
- setError('Failed to upload file. Please try again.');
344
- }}
345
- onSubmit={(message) => console.log(message)}
346
- getPendingFiles={() => files}
347
- clearPendingFiles={() => setFiles([])}
348
- />
349
- </>
350
- );
351
- };
352
- ```
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
-
595
- ### **hideAttachments**
596
- Whether to hide the attachment button.
597
-
598
- - **Type:** `boolean`
599
- - **Default:** `false`
600
-
601
- ```tsx
602
- import React, { useState } from 'react';
603
- import { ChatInput } from '@app-studio/web';
604
-
605
- export const NoAttachmentsChatInput = () => {
606
- const [files, setFiles] = useState<File[]>([]);
607
-
608
- return (
609
- <ChatInput
610
- hideAttachments
611
- onSubmit={(message) => console.log(message)}
612
- getPendingFiles={() => files}
613
- clearPendingFiles={() => setFiles([])}
614
- />
615
- );
616
- };
617
- ```
618
-
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.
677
-
678
- - **Type:** `boolean`
679
- - **Default:** `true`
680
-
681
- ```tsx
682
- import React, { useState } from 'react';
683
- import { ChatInput } from '@app-studio/web';
684
-
685
- export const AutoFocusChatInput = () => {
686
- const [files, setFiles] = useState<File[]>([]);
687
-
688
- return (
689
- <ChatInput
690
- autoFocus={false}
691
- onSubmit={(message) => console.log(message)}
692
- getPendingFiles={() => files}
693
- clearPendingFiles={() => setFiles([])}
694
- />
695
- );
696
- };
697
- ```
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
-
823
- ### **suggestions**
824
- List of suggestions for auto-completion.
825
-
826
- - **Type:** `Suggestion[]`
827
-
828
- ```tsx
829
- import React, { useState } from 'react';
830
- import { ChatInput } from '@app-studio/web';
831
-
832
- export const SuggestionsChatInput = () => {
833
- const [files, setFiles] = useState<File[]>([]);
834
-
835
- const suggestions = [
836
- { text: 'How do I...', value: 'how-to' },
837
- { text: 'What is...', value: 'what-is' },
838
- { text: 'Can you help me...', value: 'help' },
839
- ];
840
-
841
- return (
842
- <ChatInput
843
- suggestions={suggestions}
844
- onSubmit={(message) => console.log(message)}
845
- getPendingFiles={() => files}
846
- clearPendingFiles={() => setFiles([])}
847
- />
848
- );
849
- };
850
- ```
851
-
852
- ### **mentionData**
853
- Data for mention auto-completion.
854
-
855
- - **Type:** `Array<{ id: string; name: string; avatar?: string; description?: string }>`
856
-
857
- ```tsx
858
- import React, { useState } from 'react';
859
- import { ChatInput } from '@app-studio/web';
860
-
861
- export const MentionsChatInput = () => {
862
- const [files, setFiles] = useState<File[]>([]);
863
-
864
- const mentionData = [
865
- { id: '1', name: 'John Doe', avatar: '/avatars/john.jpg' },
866
- { id: '2', name: 'Jane Smith', avatar: '/avatars/jane.jpg' },
867
- { id: '3', name: 'Bob Johnson', description: 'Developer' },
868
- ];
869
-
870
- return (
871
- <ChatInput
872
- mentionData={mentionData}
873
- mentionTrigger="@"
874
- onMentionSelect={(mention) => console.log('Mentioned:', mention)}
875
- onSubmit={(message) => console.log(message)}
876
- getPendingFiles={() => files}
877
- clearPendingFiles={() => setFiles([])}
878
- />
879
- );
880
- };
881
- ```
882
-
883
- ### **promptExamples**
884
- List of prompt examples to display.
885
-
886
- - **Type:** `PromptExample[]`
887
-
888
- ```tsx
889
- import React, { useState } from 'react';
890
- import { ChatInput } from '@app-studio/web';
891
-
892
- export const PromptExamplesChatInput = () => {
893
- const [files, setFiles] = useState<File[]>([]);
894
-
895
- const promptExamples = [
896
- { title: 'Write a story', prompt: 'Write a short story about...' },
897
- { title: 'Explain a concept', prompt: 'Explain quantum physics in simple terms' },
898
- { title: 'Code help', prompt: 'Help me debug this code...' },
899
- ];
900
-
901
- return (
902
- <ChatInput
903
- promptExamples={promptExamples}
904
- onPromptExampleSelect={(example) => console.log('Selected:', example)}
905
- onSubmit={(message) => console.log(message)}
906
- getPendingFiles={() => files}
907
- clearPendingFiles={() => setFiles([])}
908
- />
909
- );
910
- };
911
- ```
912
-
913
- ### **isAgentRunning & onStopAgent**
914
- Agent running state and stop callback.
915
-
916
- - **Type:** `boolean` & `() => void`
917
-
918
- ```tsx
919
- import React, { useState } from 'react';
920
- import { ChatInput } from '@app-studio/web';
921
-
922
- export const AgentChatInput = () => {
923
- const [files, setFiles] = useState<File[]>([]);
924
- const [isRunning, setIsRunning] = useState(false);
925
-
926
- return (
927
- <ChatInput
928
- isAgentRunning={isRunning}
929
- onStopAgent={() => {
930
- console.log('Stopping agent');
931
- setIsRunning(false);
932
- }}
933
- onSubmit={(message) => {
934
- console.log(message);
935
- setIsRunning(true);
936
- }}
937
- getPendingFiles={() => files}
938
- clearPendingFiles={() => setFiles([])}
939
- />
940
- );
941
- };
942
- ```
943
-
944
- ### **size**
945
- Size of the input.
946
-
947
- - **Type:** `Size`
948
- - **Default:** `'md'`
949
- - **Possible Values:** `'xs' | 'sm' | 'md' | 'lg' | 'xl'`
950
-
951
- ```tsx
952
- import React, { useState } from 'react';
953
- import { ChatInput } from '@app-studio/web';
954
- import { Vertical } from 'app-studio';
955
-
956
- export const SizedChatInputs = () => {
957
- const [files, setFiles] = useState<File[]>([]);
958
-
959
- return (
960
- <Vertical gap={15}>
961
- {['sm', 'md', 'lg'].map((size) => (
962
- <ChatInput
963
- key={size}
964
- size={size as any}
965
- onSubmit={(message) => console.log(message)}
966
- getPendingFiles={() => files}
967
- clearPendingFiles={() => setFiles([])}
968
- />
969
- ))}
970
- </Vertical>
971
- );
972
- };
973
- ```
974
-
975
- ### **variant**
976
- Variant of the input.
977
-
978
- - **Type:** `Variant`
979
- - **Possible Values:** `'default' | 'outlined' | 'filled'`
980
-
981
- ```tsx
982
- import React, { useState } from 'react';
983
- import { ChatInput } from '@app-studio/web';
984
- import { Vertical } from 'app-studio';
985
-
986
- export const VariantChatInputs = () => {
987
- const [files, setFiles] = useState<File[]>([]);
988
-
989
- return (
990
- <Vertical gap={15}>
991
- {['default', 'outlined', 'filled'].map((variant) => (
992
- <ChatInput
993
- key={variant}
994
- variant={variant as any}
995
- onSubmit={(message) => console.log(message)}
996
- getPendingFiles={() => files}
997
- clearPendingFiles={() => setFiles([])}
998
- />
999
- ))}
1000
- </Vertical>
1001
- );
1002
- };
1003
- ```
1004
-
1005
- ### **views**
1006
- Custom styles for different parts of the chat input.
1007
-
1008
- - **Type:** `ChatInputStyles`
1009
-
1010
- ```tsx
1011
- import React, { useState } from 'react';
1012
- import { ChatInput } from '@app-studio/web';
1013
-
1014
- export const StyledChatInput = () => {
1015
- const [files, setFiles] = useState<File[]>([]);
1016
-
1017
- return (
1018
- <ChatInput
1019
- onSubmit={(message) => console.log(message)}
1020
- getPendingFiles={() => files}
1021
- clearPendingFiles={() => setFiles([])}
1022
- views={{
1023
- container: {
1024
- borderRadius: 16,
1025
- borderColor: '#3b82f6',
1026
- },
1027
- input: {
1028
- fontSize: 16,
1029
- padding: 12,
1030
- },
1031
- button: {
1032
- backgroundColor: '#3b82f6',
1033
- }
1034
- }}
1035
- />
1036
- );
1037
- };
1038
- ```
1039
-