@memori.ai/memori-react 8.12.0 → 8.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/components/Chat/Chat.css +37 -3
  3. package/dist/components/Chat/Chat.js +60 -22
  4. package/dist/components/Chat/Chat.js.map +1 -1
  5. package/dist/components/ChatBubble/ChatBubble.css +9 -5
  6. package/dist/components/ChatBubble/ChatBubble.js +54 -11
  7. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  8. package/dist/components/ChatInputs/ChatInputs.css +293 -17
  9. package/dist/components/ChatInputs/ChatInputs.js +41 -25
  10. package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
  11. package/dist/components/ChatTextArea/ChatTextArea.css +75 -31
  12. package/dist/components/ChatTextArea/ChatTextArea.js +47 -18
  13. package/dist/components/ChatTextArea/ChatTextArea.js.map +1 -1
  14. package/dist/components/FilePreview/FilePreview.css +225 -146
  15. package/dist/components/FilePreview/FilePreview.d.ts +1 -2
  16. package/dist/components/FilePreview/FilePreview.js +20 -6
  17. package/dist/components/FilePreview/FilePreview.js.map +1 -1
  18. package/dist/components/Header/Header.css +2 -2
  19. package/dist/components/MediaWidget/MediaItemWidget.js +2 -1
  20. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  21. package/dist/components/MediaWidget/MediaWidget.css +0 -4
  22. package/dist/components/MemoriWidget/MemoriWidget.css +11 -2
  23. package/dist/components/MemoriWidget/MemoriWidget.js +41 -5
  24. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  25. package/dist/components/MicrophoneButton/MicrophoneButton.css +2 -2
  26. package/dist/components/StartPanel/StartPanel.css +8 -0
  27. package/dist/components/UploadButton/UploadButton.css +20 -17
  28. package/dist/components/UploadButton/UploadButton.js +218 -89
  29. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  30. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +14 -4
  31. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
  32. package/dist/components/UploadButton/UploadImages/UploadImages.js +143 -16
  33. package/dist/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
  34. package/dist/components/layouts/chat.css +1 -1
  35. package/dist/helpers/constants.d.ts +1 -0
  36. package/dist/helpers/constants.js +2 -1
  37. package/dist/helpers/constants.js.map +1 -1
  38. package/dist/helpers/imageCompression.d.ts +7 -0
  39. package/dist/helpers/imageCompression.js +123 -0
  40. package/dist/helpers/imageCompression.js.map +1 -0
  41. package/dist/locales/de.json +7 -4
  42. package/dist/locales/en.json +8 -5
  43. package/dist/locales/es.json +7 -4
  44. package/dist/locales/fr.json +7 -4
  45. package/dist/locales/it.json +8 -5
  46. package/dist/styles.css +1 -2
  47. package/esm/components/Chat/Chat.css +37 -3
  48. package/esm/components/Chat/Chat.js +60 -22
  49. package/esm/components/Chat/Chat.js.map +1 -1
  50. package/esm/components/ChatBubble/ChatBubble.css +9 -5
  51. package/esm/components/ChatBubble/ChatBubble.js +54 -11
  52. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  53. package/esm/components/ChatInputs/ChatInputs.css +293 -17
  54. package/esm/components/ChatInputs/ChatInputs.js +42 -26
  55. package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
  56. package/esm/components/ChatTextArea/ChatTextArea.css +75 -31
  57. package/esm/components/ChatTextArea/ChatTextArea.js +49 -20
  58. package/esm/components/ChatTextArea/ChatTextArea.js.map +1 -1
  59. package/esm/components/FilePreview/FilePreview.css +225 -146
  60. package/esm/components/FilePreview/FilePreview.d.ts +1 -2
  61. package/esm/components/FilePreview/FilePreview.js +21 -7
  62. package/esm/components/FilePreview/FilePreview.js.map +1 -1
  63. package/esm/components/Header/Header.css +2 -2
  64. package/esm/components/MediaWidget/MediaItemWidget.js +2 -1
  65. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  66. package/esm/components/MediaWidget/MediaWidget.css +0 -4
  67. package/esm/components/MemoriWidget/MemoriWidget.css +11 -2
  68. package/esm/components/MemoriWidget/MemoriWidget.js +41 -5
  69. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  70. package/esm/components/MicrophoneButton/MicrophoneButton.css +2 -2
  71. package/esm/components/StartPanel/StartPanel.css +8 -0
  72. package/esm/components/UploadButton/UploadButton.css +20 -17
  73. package/esm/components/UploadButton/UploadButton.js +219 -90
  74. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  75. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +14 -4
  76. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
  77. package/esm/components/UploadButton/UploadImages/UploadImages.js +143 -16
  78. package/esm/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
  79. package/esm/components/layouts/chat.css +1 -1
  80. package/esm/helpers/constants.d.ts +1 -0
  81. package/esm/helpers/constants.js +1 -0
  82. package/esm/helpers/constants.js.map +1 -1
  83. package/esm/helpers/imageCompression.d.ts +7 -0
  84. package/esm/helpers/imageCompression.js +119 -0
  85. package/esm/helpers/imageCompression.js.map +1 -0
  86. package/esm/locales/de.json +7 -4
  87. package/esm/locales/en.json +8 -5
  88. package/esm/locales/es.json +7 -4
  89. package/esm/locales/fr.json +7 -4
  90. package/esm/locales/it.json +8 -5
  91. package/esm/styles.css +1 -2
  92. package/package.json +1 -1
  93. package/src/components/Chat/Chat.css +37 -3
  94. package/src/components/Chat/Chat.tsx +89 -21
  95. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +672 -732
  96. package/src/components/ChatBubble/ChatBubble.css +9 -5
  97. package/src/components/ChatBubble/ChatBubble.tsx +111 -20
  98. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +4 -4
  99. package/src/components/ChatInputs/ChatInputs.css +293 -17
  100. package/src/components/ChatInputs/ChatInputs.tsx +144 -87
  101. package/src/components/ChatInputs/__snapshots__/ChatInputs.test.tsx.snap +430 -424
  102. package/src/components/ChatTextArea/ChatTextArea.css +75 -31
  103. package/src/components/ChatTextArea/ChatTextArea.test.tsx +1 -16
  104. package/src/components/ChatTextArea/ChatTextArea.tsx +51 -22
  105. package/src/components/ChatTextArea/__snapshots__/ChatTextArea.test.tsx.snap +9 -72
  106. package/src/components/FilePreview/FilePreview.css +225 -146
  107. package/src/components/FilePreview/FilePreview.tsx +49 -36
  108. package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +2 -2
  109. package/src/components/Header/Header.css +2 -2
  110. package/src/components/MediaWidget/MediaItemWidget.tsx +2 -1
  111. package/src/components/MediaWidget/MediaWidget.css +0 -4
  112. package/src/components/MemoriWidget/MemoriWidget.css +11 -2
  113. package/src/components/MemoriWidget/MemoriWidget.tsx +61 -12
  114. package/src/components/MicrophoneButton/MicrophoneButton.css +2 -2
  115. package/src/components/StartPanel/StartPanel.css +8 -0
  116. package/src/components/UploadButton/UploadButton.css +20 -17
  117. package/src/components/UploadButton/UploadButton.stories.tsx +247 -35
  118. package/src/components/UploadButton/UploadButton.tsx +280 -175
  119. package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +19 -4
  120. package/src/components/UploadButton/UploadImages/UploadImages.tsx +195 -35
  121. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +10 -1
  122. package/src/components/layouts/chat.css +1 -1
  123. package/src/helpers/constants.ts +1 -1
  124. package/src/helpers/imageCompression.ts +230 -0
  125. package/src/locales/de.json +7 -4
  126. package/src/locales/en.json +8 -5
  127. package/src/locales/es.json +7 -4
  128. package/src/locales/fr.json +7 -4
  129. package/src/locales/it.json +8 -5
  130. package/src/styles.css +1 -2
  131. package/src/components/UploadMenu/UploadMenu.css +0 -47
  132. package/src/components/UploadMenu/UploadMenu.stories.tsx +0 -66
  133. package/src/components/UploadMenu/UploadMenu.test.tsx +0 -34
  134. package/src/components/UploadMenu/UploadMenu.tsx +0 -68
  135. package/src/components/UploadMenu/__snapshots__/UploadMenu.test.tsx.snap +0 -137
@@ -3,50 +3,129 @@ import { Meta, Story } from '@storybook/react';
3
3
  import I18nWrapper from '../../I18nWrapper';
4
4
  import UploadButton from './UploadButton';
5
5
  import FilePreview from '../FilePreview/FilePreview';
6
+ import memoriApiClient from '@memori.ai/memori-api-client';
6
7
  import './UploadButton.css';
7
8
 
9
+ // Mock API client for stories
10
+ const createMockClient = () => {
11
+ return {
12
+ backend: {
13
+ uploadAsset: async (fileName: string, fileDataUrl: string, authToken: string) => {
14
+ // Simulate API delay
15
+ await new Promise(resolve => setTimeout(resolve, 1000));
16
+ return {
17
+ resultCode: 0,
18
+ resultMessage: 'Success',
19
+ asset: {
20
+ assetURL: `https://example.com/assets/${fileName}`,
21
+ mimeType: 'image/jpeg',
22
+ assetID: `asset-${Date.now()}`,
23
+ },
24
+ };
25
+ },
26
+ uploadAssetUnlogged: async (fileName: string, fileDataUrl: string, memoriID: string, sessionID: string) => {
27
+ // Simulate API delay
28
+ await new Promise(resolve => setTimeout(resolve, 1000));
29
+ return {
30
+ resultCode: 0,
31
+ resultMessage: 'Success',
32
+ asset: {
33
+ assetURL: `https://example.com/assets/${fileName}`,
34
+ mimeType: 'image/jpeg',
35
+ assetID: `asset-${Date.now()}`,
36
+ },
37
+ };
38
+ },
39
+ },
40
+ dialog: {
41
+ postMediumSelectedEvent: async (sessionID: string, medium: any) => {
42
+ await new Promise(resolve => setTimeout(resolve, 500));
43
+ return {
44
+ currentState: {
45
+ currentMedia: [
46
+ {
47
+ mediumID: `medium-${Date.now()}`,
48
+ url: medium.url,
49
+ mimeType: medium.mimeType,
50
+ },
51
+ ],
52
+ },
53
+ };
54
+ },
55
+ postMediumDeselectedEvent: async (sessionID: string, mediumID: string) => {
56
+ await new Promise(resolve => setTimeout(resolve, 500));
57
+ return { success: true };
58
+ },
59
+ },
60
+ };
61
+ };
62
+
8
63
  // Define the component props
9
64
  interface UploadButtonProps {
10
65
  authToken?: string;
11
- apiUrl?: string;
66
+ client?: ReturnType<typeof memoriApiClient>;
12
67
  sessionID?: string;
13
68
  isMediaAccepted?: boolean;
14
- setDocumentPreviewFiles: (files: { name: string; id: string; content: string; type?: string }[]) => void;
15
- disabled?: boolean;
69
+ setDocumentPreviewFiles: (files: { name: string; id: string; content: string; type?: string; mediumID?: string; mimeType?: string; url?: string }[]) => void;
70
+ documentPreviewFiles: { name: string; id: string; content: string; type?: string; mediumID?: string; mimeType?: string; url?: string }[];
71
+ memoriID?: string;
16
72
  }
17
73
 
18
74
  const meta: Meta<UploadButtonProps> = {
19
75
  title: 'Widget/Upload Button',
20
76
  component: UploadButton as React.ComponentType<UploadButtonProps>,
21
77
  argTypes: {
22
- disabled: {
23
- control: {
24
- type: 'boolean',
25
- },
26
- },
27
78
  isMediaAccepted: {
28
79
  control: {
29
80
  type: 'boolean',
30
81
  },
82
+ description: 'Whether media (images) uploads are accepted',
31
83
  },
32
84
  authToken: {
33
85
  control: {
34
86
  type: 'text',
35
87
  },
88
+ description: 'Authentication token for logged-in users',
36
89
  },
37
- apiUrl: {
90
+ sessionID: {
38
91
  control: {
39
92
  type: 'text',
40
93
  },
94
+ description: 'Session ID for the current chat session',
41
95
  },
42
- sessionID: {
96
+ memoriID: {
43
97
  control: {
44
98
  type: 'text',
45
99
  },
100
+ description: 'Memori ID for unauthenticated uploads',
46
101
  },
47
102
  },
48
103
  parameters: {
49
104
  controls: { expanded: true },
105
+ docs: {
106
+ description: {
107
+ component: `
108
+ # Upload Button Component
109
+
110
+ A unified upload button that supports both images and documents with the following features:
111
+
112
+ ## Features
113
+
114
+ - **Direct File Chooser**: Clicking the button opens the file chooser directly (no menu)
115
+ - **Unified Input**: Single file input accepts both images and documents
116
+ - **Automatic File Type Detection**: Files are automatically categorized as images or documents and routed to the appropriate handler
117
+ - **Keyboard Shortcut**: Press \`Cmd+V\` (Mac) or \`Ctrl+V\` (Windows/Linux) to open the file chooser (when not in a text input)
118
+ - **Drag and Drop**: Drag files anywhere in the widget to upload them
119
+ - **Paste Support**: Paste files from clipboard using \`Cmd+V\` / \`Ctrl+V\`
120
+
121
+ ## Limits
122
+
123
+ - **Images**: Maximum 5 images, 10MB per file, formats: .jpg, .jpeg, .png
124
+ - **Documents**: Maximum 5 documents, 10MB per file, formats: .pdf, .txt, .json, .xlsx, .csv, .md
125
+ - **Content**: Document content is limited to 200,000 characters per document (truncated if exceeded)
126
+ `,
127
+ },
128
+ },
50
129
  },
51
130
  };
52
131
 
@@ -59,9 +138,12 @@ const Template: Story<UploadButtonProps> = (args) => {
59
138
  id: string;
60
139
  content: string;
61
140
  type?: string;
141
+ mediumID?: string;
142
+ mimeType?: string;
143
+ url?: string;
62
144
  }[]>([]);
63
145
 
64
- const removeFile = (id: string) => {
146
+ const removeFile = (id: string, mediumID?: string) => {
65
147
  setDocumentPreviewFiles(prev => prev.filter(file => file.id !== id));
66
148
  };
67
149
 
@@ -69,29 +151,64 @@ const Template: Story<UploadButtonProps> = (args) => {
69
151
  <I18nWrapper>
70
152
  <div
71
153
  style={{
72
- minHeight: '400px',
154
+ minHeight: '500px',
73
155
  display: 'flex',
74
156
  flexDirection: 'column',
75
157
  alignItems: 'flex-start',
76
- justifyContent: 'center',
158
+ justifyContent: 'flex-start',
77
159
  padding: '20px',
78
160
  border: '1px solid #eee',
79
161
  borderRadius: '8px',
162
+ backgroundColor: '#f9f9f9',
80
163
  }}
81
164
  >
82
- <div style={{ alignSelf: 'flex-end', marginBottom: '20px' }}>
83
- <UploadButton {...args} setDocumentPreviewFiles={setDocumentPreviewFiles} documentPreviewFiles={documentPreviewFiles} />
165
+ <div style={{
166
+ alignSelf: 'flex-end',
167
+ marginBottom: '20px',
168
+ position: 'relative',
169
+ }}>
170
+ <UploadButton
171
+ {...args}
172
+ setDocumentPreviewFiles={setDocumentPreviewFiles}
173
+ documentPreviewFiles={documentPreviewFiles}
174
+ {...(args.client ? { client: args.client } : { client: createMockClient() as any })}
175
+ />
84
176
  </div>
85
177
 
86
- {documentPreviewFiles.length > 0 && (
87
- <div style={{ width: '100%', marginTop: '20px' }}>
88
- <h3>Uploaded Files</h3>
178
+ <div style={{ width: '100%', marginTop: '20px' }}>
179
+ <h3 style={{ marginBottom: '10px', fontSize: '16px', fontWeight: '600' }}>
180
+ Uploaded Files ({documentPreviewFiles.length})
181
+ </h3>
182
+ {documentPreviewFiles.length > 0 ? (
89
183
  <FilePreview
90
184
  previewFiles={documentPreviewFiles}
91
185
  removeFile={removeFile}
92
186
  />
93
- </div>
94
- )}
187
+ ) : (
188
+ <p style={{ color: '#999', fontStyle: 'italic', fontSize: '14px' }}>
189
+ No files uploaded yet. Click the upload button, drag & drop files, or use Cmd+V / Ctrl+V to upload.
190
+ </p>
191
+ )}
192
+ </div>
193
+
194
+ <div style={{
195
+ marginTop: '30px',
196
+ padding: '15px',
197
+ backgroundColor: '#fff',
198
+ borderRadius: '6px',
199
+ border: '1px solid #ddd',
200
+ fontSize: '13px',
201
+ color: '#666',
202
+ }}>
203
+ <strong>Try these features:</strong>
204
+ <ul style={{ marginTop: '8px', paddingLeft: '20px' }}>
205
+ <li>Click the upload button to open file chooser</li>
206
+ <li>Drag and drop files anywhere in this area</li>
207
+ <li>Press <kbd style={{ padding: '2px 6px', backgroundColor: '#f0f0f0', borderRadius: '3px' }}>Cmd+V</kbd> / <kbd style={{ padding: '2px 6px', backgroundColor: '#f0f0f0', borderRadius: '3px' }}>Ctrl+V</kbd> to open file chooser</li>
208
+ <li>Paste files from clipboard using <kbd style={{ padding: '2px 6px', backgroundColor: '#f0f0f0', borderRadius: '3px' }}>Cmd+V</kbd> / <kbd style={{ padding: '2px 6px', backgroundColor: '#f0f0f0', borderRadius: '3px' }}>Ctrl+V</kbd></li>
209
+ <li>Upload both images (.jpg, .jpeg, .png) and documents (.pdf, .txt, .json, .xlsx, .csv, .md)</li>
210
+ </ul>
211
+ </div>
95
212
  </div>
96
213
  </I18nWrapper>
97
214
  );
@@ -101,56 +218,134 @@ const Template: Story<UploadButtonProps> = (args) => {
101
218
  export const Default = Template.bind({});
102
219
  Default.args = {
103
220
  authToken: '',
104
- apiUrl: 'https://api.example.com',
105
221
  sessionID: 'session-123',
106
222
  isMediaAccepted: false,
223
+ memoriID: 'memori-123',
224
+ documentPreviewFiles: [],
225
+ };
226
+ Default.parameters = {
227
+ docs: {
228
+ description: {
229
+ story: 'Default state with documents only (no images). Users can upload up to 5 documents. Click the button to open the file chooser directly.',
230
+ },
231
+ },
107
232
  };
108
233
 
109
234
  // Authenticated user - can upload documents
110
235
  export const AuthenticatedDocumentsOnly = Template.bind({});
111
236
  AuthenticatedDocumentsOnly.args = {
112
237
  authToken: 'dummy-auth-token-12345',
113
- apiUrl: 'https://api.example.com',
114
238
  sessionID: 'session-123',
115
239
  isMediaAccepted: false,
240
+ documentPreviewFiles: [],
241
+ };
242
+ AuthenticatedDocumentsOnly.parameters = {
243
+ docs: {
244
+ description: {
245
+ story: 'Authenticated user can upload documents. The button opens the file chooser directly when clicked.',
246
+ },
247
+ },
116
248
  };
117
249
 
118
250
  // Authenticated user - can upload documents and images
119
251
  export const AuthenticatedWithImages = Template.bind({});
120
252
  AuthenticatedWithImages.args = {
121
253
  authToken: 'dummy-auth-token-12345',
122
- apiUrl: 'https://api.example.com',
123
254
  sessionID: 'session-123',
124
255
  isMediaAccepted: true,
256
+ memoriID: 'memori-123',
257
+ documentPreviewFiles: [],
258
+ };
259
+ AuthenticatedWithImages.parameters = {
260
+ docs: {
261
+ description: {
262
+ story: 'Full functionality: authenticated user can upload both images and documents. Supports drag & drop, Cmd+V / Ctrl+V shortcut, and paste from clipboard.',
263
+ },
264
+ },
125
265
  };
126
266
 
127
- // Not authenticated but media accepted (should show warning for images)
128
- export const UnauthenticatedWithMediaAccepted = Template.bind({});
129
- UnauthenticatedWithMediaAccepted.args = {
130
- authToken: '',
131
- apiUrl: 'https://api.example.com',
267
+ // With existing files
268
+ export const WithExistingFiles = Template.bind({});
269
+ WithExistingFiles.args = {
270
+ authToken: 'dummy-auth-token-12345',
132
271
  sessionID: 'session-123',
133
272
  isMediaAccepted: true,
273
+ memoriID: 'memori-123',
274
+ documentPreviewFiles: [
275
+ {
276
+ id: '1',
277
+ name: 'document.pdf',
278
+ content: 'Sample document content',
279
+ type: 'document',
280
+ mimeType: 'application/pdf',
281
+ },
282
+ {
283
+ id: '2',
284
+ name: 'image.jpg',
285
+ content: 'https://example.com/image.jpg',
286
+ type: 'image',
287
+ mimeType: 'image/jpeg',
288
+ url: 'https://example.com/image.jpg',
289
+ mediumID: 'medium-123',
290
+ },
291
+ ],
292
+ };
293
+ WithExistingFiles.parameters = {
294
+ docs: {
295
+ description: {
296
+ story: 'Shows the upload button with existing files. The document count indicator shows 2/5. You can still upload more files up to the limit.',
297
+ },
298
+ },
134
299
  };
135
300
 
136
- // Disabled state
137
- export const Disabled = Template.bind({});
138
- Disabled.args = {
301
+ // At maximum capacity
302
+ export const AtMaximumCapacity = Template.bind({});
303
+ AtMaximumCapacity.args = {
139
304
  authToken: 'dummy-auth-token-12345',
140
- apiUrl: 'https://api.example.com',
141
305
  sessionID: 'session-123',
142
306
  isMediaAccepted: true,
143
- disabled: true,
307
+ memoriID: 'memori-123',
308
+ documentPreviewFiles: [
309
+ { id: '1', name: 'doc1.pdf', content: 'Content 1', type: 'document', mimeType: 'application/pdf' },
310
+ { id: '2', name: 'doc2.pdf', content: 'Content 2', type: 'document', mimeType: 'application/pdf' },
311
+ { id: '3', name: 'doc3.pdf', content: 'Content 3', type: 'document', mimeType: 'application/pdf' },
312
+ { id: '4', name: 'doc4.pdf', content: 'Content 4', type: 'document', mimeType: 'application/pdf' },
313
+ { id: '5', name: 'doc5.pdf', content: 'Content 5', type: 'document', mimeType: 'application/pdf' },
314
+ ],
315
+ };
316
+ AtMaximumCapacity.parameters = {
317
+ docs: {
318
+ description: {
319
+ story: 'Button is disabled when maximum capacity (5 documents) is reached. The count indicator shows 5/5.',
320
+ },
321
+ },
144
322
  };
145
323
 
324
+ // Not authenticated but media accepted
325
+ export const UnauthenticatedWithMediaAccepted = Template.bind({});
326
+ UnauthenticatedWithMediaAccepted.args = {
327
+ authToken: '',
328
+ sessionID: 'session-123',
329
+ isMediaAccepted: true,
330
+ memoriID: 'memori-123',
331
+ documentPreviewFiles: [],
332
+ };
333
+ UnauthenticatedWithMediaAccepted.parameters = {
334
+ docs: {
335
+ description: {
336
+ story: 'Unauthenticated user with media accepted. Images can be uploaded using unlogged API. Documents work normally.',
337
+ },
338
+ },
339
+ };
146
340
 
147
341
  // Mobile view simulation
148
342
  export const MobileView = Template.bind({});
149
343
  MobileView.args = {
150
344
  authToken: 'dummy-auth-token-12345',
151
- apiUrl: 'https://api.example.com',
152
345
  sessionID: 'session-123',
153
346
  isMediaAccepted: true,
347
+ memoriID: 'memori-123',
348
+ documentPreviewFiles: [],
154
349
  };
155
350
  MobileView.parameters = {
156
351
  viewport: {
@@ -158,7 +353,24 @@ MobileView.parameters = {
158
353
  },
159
354
  docs: {
160
355
  description: {
161
- story: 'A simulation of how the upload button appears on mobile devices.',
356
+ story: 'Mobile view simulation. All features work on mobile: tap to upload, drag & drop (on supported devices), and paste from clipboard.',
357
+ },
358
+ },
359
+ };
360
+
361
+ // Drag and drop demonstration
362
+ export const DragAndDropDemo = Template.bind({});
363
+ DragAndDropDemo.args = {
364
+ authToken: 'dummy-auth-token-12345',
365
+ sessionID: 'session-123',
366
+ isMediaAccepted: true,
367
+ memoriID: 'memori-123',
368
+ documentPreviewFiles: [],
369
+ };
370
+ DragAndDropDemo.parameters = {
371
+ docs: {
372
+ description: {
373
+ story: 'Try dragging files from your file system into this area. The overlay will appear when dragging files over the chat area. Files are automatically categorized as images or documents.',
162
374
  },
163
375
  },
164
376
  };