@app-studio/web 0.9.80 → 0.9.82
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/Accordion/Accordion/Accordion.type.d.ts +1 -1
- package/dist/components/Accordion/Accordion/Accordion.view.d.ts +1 -1
- package/dist/components/Badge/Badge/Badge.type.d.ts +1 -1
- package/dist/components/Card/Card/Card.type.d.ts +1 -1
- package/dist/components/ChatInput/ChatInput/ChatInput.type.d.ts +1 -1
- package/dist/components/ColorPicker/ColorPicker/ColorPicker.type.d.ts +1 -1
- package/dist/components/EmojiPicker/EmojiPicker/EmojiPicker.type.d.ts +1 -1
- package/dist/components/Form/ColorInput/ColorInput/ColorInput.type.d.ts +1 -1
- package/dist/components/Form/TagInput/TagInput/TagInput.type.d.ts +1 -1
- package/dist/components/Form/TextArea/TextArea/TextArea.type.d.ts +1 -1
- package/dist/components/Input/Input.type.d.ts +1 -1
- package/dist/components/Message/Message/Message.type.d.ts +1 -1
- package/dist/components/Modal/Modal/Modal.props.d.ts +2 -2
- package/dist/components/Slider/Slider/Slider.type.d.ts +1 -1
- package/dist/components/Title/Title/Title.props.d.ts +0 -5
- package/dist/components/Toggle/Toggle/Toggle.type.d.ts +1 -1
- package/dist/components/ToggleGroup/ToggleGroup/ToggleGroup.type.d.ts +1 -1
- package/dist/pages/tabs.page.d.ts +1 -1
- package/dist/web.cjs.development.js +61 -77
- 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 +61 -77
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +61 -77
- 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/Background.mdx +133 -134
- package/docs/components/Button.mdx +154 -131
- package/docs/components/Chart.mdx +93 -368
- package/docs/components/ChatWidget.mdx +106 -0
- package/docs/components/EditComponent.mdx +76 -0
- package/docs/components/ProgressBar.mdx +77 -394
- package/docs/components/Title.mdx +102 -290
- package/package.json +1 -1
- 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
|
-
|