reachat 2.0.1 → 2.1.0-alpha.1

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 (32) hide show
  1. package/dist/{CSVFileRenderer-Dy3iLTeu.js → CSVFileRenderer-BAbkFZ2w.js} +2 -2
  2. package/dist/{CSVFileRenderer-Dy3iLTeu.js.map → CSVFileRenderer-BAbkFZ2w.js.map} +1 -1
  3. package/dist/{DefaultFileRenderer-Dxar9MFe.js → DefaultFileRenderer-Bgc4Jadg.js} +2 -2
  4. package/dist/{DefaultFileRenderer-Dxar9MFe.js.map → DefaultFileRenderer-Bgc4Jadg.js.map} +1 -1
  5. package/dist/ImageFileRenderer-C8tVW3I8.js.map +1 -1
  6. package/dist/PDFFileRenderer-DQdFS2l6.js.map +1 -1
  7. package/dist/docs.json +6 -2
  8. package/dist/{index-NuRjkHCl.js → index-unCEyRCC.js} +12 -12
  9. package/dist/index-unCEyRCC.js.map +1 -0
  10. package/dist/index.css +2495 -673
  11. package/dist/index.js +2 -2
  12. package/dist/index.umd.cjs +9 -9
  13. package/dist/index.umd.cjs.map +1 -1
  14. package/dist/stories/Changelog.mdx +8 -0
  15. package/dist/stories/Chat.stories.tsx +265 -0
  16. package/dist/stories/ChatBubble.stories.tsx +267 -0
  17. package/dist/stories/Companion.stories.tsx +435 -0
  18. package/dist/stories/Console.stories.tsx +1154 -0
  19. package/dist/stories/Integration.stories.tsx +312 -0
  20. package/dist/stories/Intro.mdx +41 -0
  21. package/dist/stories/Support.mdx +9 -0
  22. package/dist/stories/assets/chat-voice-fill.svg +5 -0
  23. package/dist/stories/assets/close-fill.svg +5 -0
  24. package/dist/stories/assets/logo.svg +21 -0
  25. package/dist/stories/assets/menu.svg +1 -0
  26. package/dist/stories/assets/paperclip.svg +1 -0
  27. package/dist/stories/assets/placeholder-dark.svg +500 -0
  28. package/dist/stories/assets/placeholder.svg +258 -0
  29. package/dist/stories/assets/search.svg +1 -0
  30. package/dist/stories/examples.ts +267 -0
  31. package/package.json +8 -4
  32. package/dist/index-NuRjkHCl.js.map +0 -1
@@ -0,0 +1,1154 @@
1
+ import { useState, useRef, FC, useContext } from 'react';
2
+ import AttachIcon from './assets/paperclip.svg?react';
3
+ import { Meta } from '@storybook/react';
4
+ import {
5
+ Chat,
6
+ Session,
7
+ remarkCve,
8
+ SessionsList,
9
+ SessionsGroup,
10
+ SessionListItem,
11
+ NewSessionButton,
12
+ SessionMessages,
13
+ SessionGroups,
14
+ ChatInput,
15
+ SessionListItemProps,
16
+ SessionMessagePanel,
17
+ SessionMessagesHeader,
18
+ ChatContext,
19
+ SessionMessage,
20
+ } from 'reachat';
21
+ import {
22
+ Card,
23
+ Chip,
24
+ cn,
25
+ DateFormat,
26
+ Divider,
27
+ IconButton,
28
+ List,
29
+ ListItem,
30
+ Menu
31
+ } from 'reablocks';
32
+ import { subDays, subMinutes, subHours } from 'date-fns';
33
+ import MenuIcon from './assets/menu.svg?react';
34
+ import Placeholder from './assets/placeholder.svg?react';
35
+ import PlaceholderDark from './assets/placeholder-dark.svg?react';
36
+ import { MessageActions } from 'reachat';
37
+ import { MessageFiles } from 'reachat';
38
+ import { MessageQuestion } from 'reachat';
39
+ import { MessageResponse } from 'reachat';
40
+ import { MessageSources } from 'reachat';
41
+ import {
42
+ fakeSessions,
43
+ fakeSessionsWithEmbeds,
44
+ sessionWithSources,
45
+ sessionsWithFiles,
46
+ sessionsWithPartialConversation,
47
+ sessionWithCSVFiles
48
+ } from './examples';
49
+
50
+ export default {
51
+ title: 'Demos/Console',
52
+ component: Chat
53
+ } as Meta;
54
+
55
+ export const Basic = () => {
56
+ return (
57
+ <div
58
+ className="dark:bg-gray-950 bg-white"
59
+ style={{
60
+ position: 'absolute',
61
+ top: 0,
62
+ left: 0,
63
+ right: 0,
64
+ bottom: 0,
65
+ padding: 20,
66
+ margin: 20,
67
+ borderRadius: 5
68
+ }}
69
+ >
70
+ <Chat
71
+ sessions={fakeSessions}
72
+ viewType="console"
73
+ onDeleteSession={() => alert('delete!')}
74
+ >
75
+ <SessionsList>
76
+ <NewSessionButton />
77
+ <SessionGroups />
78
+ </SessionsList>
79
+ <SessionMessagePanel>
80
+ <SessionMessagesHeader />
81
+ <SessionMessages />
82
+ <ChatInput />
83
+ </SessionMessagePanel>
84
+ </Chat>
85
+ </div>
86
+ );
87
+ };
88
+
89
+ export const Embeds = () => {
90
+ return (
91
+ <div
92
+ className="dark:bg-gray-950 bg-white"
93
+ style={{
94
+ position: 'absolute',
95
+ top: 0,
96
+ left: 0,
97
+ right: 0,
98
+ bottom: 0,
99
+ padding: 20,
100
+ margin: 20,
101
+ borderRadius: 5
102
+ }}
103
+ >
104
+ <Chat
105
+ sessions={fakeSessionsWithEmbeds}
106
+ activeSessionId="1"
107
+ onDeleteSession={() => alert('delete!')}
108
+ >
109
+ <SessionsList>
110
+ <NewSessionButton />
111
+ <SessionGroups />
112
+ </SessionsList>
113
+ <SessionMessagePanel>
114
+ <SessionMessagesHeader />
115
+ <SessionMessages />
116
+ <ChatInput />
117
+ </SessionMessagePanel>
118
+ </Chat>
119
+ </div>
120
+ );
121
+ };
122
+
123
+ export const DefaultSession = () => {
124
+ return (
125
+ <div
126
+ className="dark:bg-gray-950 bg-white"
127
+ style={{
128
+ position: 'absolute',
129
+ top: 0,
130
+ left: 0,
131
+ right: 0,
132
+ bottom: 0,
133
+ padding: 20,
134
+ margin: 20,
135
+ borderRadius: 5
136
+ }}
137
+ >
138
+ <Chat
139
+ viewType="console"
140
+ sessions={fakeSessions}
141
+ activeSessionId="1"
142
+ onDeleteSession={() => alert('delete!')}
143
+ >
144
+ <SessionsList>
145
+ <NewSessionButton />
146
+ <SessionGroups />
147
+ </SessionsList>
148
+
149
+ <SessionMessagePanel>
150
+ <SessionMessagesHeader />
151
+ <SessionMessages />
152
+ <ChatInput />
153
+ </SessionMessagePanel>
154
+ </Chat>
155
+ </div>
156
+ );
157
+ };
158
+
159
+ export const Loading = () => {
160
+ return (
161
+ <div
162
+ className="dark:bg-gray-950 bg-white"
163
+ style={{
164
+ position: 'absolute',
165
+ top: 0,
166
+ left: 0,
167
+ right: 0,
168
+ bottom: 0,
169
+ padding: 20,
170
+ margin: 20,
171
+ borderRadius: 5
172
+ }}
173
+ >
174
+ <Chat
175
+ isLoading
176
+ viewType="console"
177
+ sessions={sessionsWithPartialConversation}
178
+ activeSessionId="1"
179
+ onDeleteSession={() => alert('delete!')}
180
+ >
181
+ <SessionsList>
182
+ <NewSessionButton />
183
+ <SessionGroups />
184
+ </SessionsList>
185
+
186
+ <SessionMessagePanel>
187
+ <SessionMessagesHeader />
188
+ <SessionMessages />
189
+ <ChatInput />
190
+ </SessionMessagePanel>
191
+ </Chat>
192
+ </div>
193
+ );
194
+ };
195
+
196
+ export const FileUploads = () => {
197
+ const [sessions, setSessions] = useState(sessionsWithFiles);
198
+ const [selectedFile, setSelectedFile] = useState<File | null>(null);
199
+
200
+ return (
201
+ <div
202
+ className="dark:bg-gray-950 bg-white"
203
+ style={{
204
+ position: 'absolute',
205
+ top: 0,
206
+ left: 0,
207
+ right: 0,
208
+ bottom: 0,
209
+ padding: 20,
210
+ margin: 20,
211
+ borderRadius: 5
212
+ }}
213
+ >
214
+ <Chat
215
+ viewType="console"
216
+ sessions={sessions}
217
+ activeSessionId="session-files"
218
+ onSendMessage={(message) => setSessions((sessions) => {
219
+ const session = sessions[0];
220
+
221
+ setSelectedFile(null);
222
+
223
+ return [{
224
+ ...session,
225
+ conversations: [
226
+ ...session.conversations,
227
+ {
228
+ id: (Math.random() * 100).toString(),
229
+ createdAt: new Date(),
230
+ question: message,
231
+ ...(selectedFile ? { files: [{
232
+ name: selectedFile.name,
233
+ size: selectedFile.size,
234
+ type: selectedFile.type,
235
+ }]} : [])
236
+ }
237
+ ]
238
+ }];
239
+ })}
240
+ onFileUpload={setSelectedFile}
241
+ onDeleteSession={() => alert('delete!')}
242
+ >
243
+ <SessionsList>
244
+ <NewSessionButton />
245
+ <SessionGroups />
246
+ </SessionsList>
247
+ <SessionMessagePanel>
248
+ <SessionMessagesHeader />
249
+ <SessionMessages />
250
+ <ChatInput attachIcon={<AttachIcon className={cn({'text-green-500': selectedFile})} />} allowedFiles={['.pdf', '.docx']} />
251
+ </SessionMessagePanel>
252
+ </Chat>
253
+ </div>
254
+ );
255
+ };
256
+
257
+ export const DefaultInputValue = () => {
258
+ return (
259
+ <div
260
+ className="dark:bg-gray-950 bg-white"
261
+ style={{
262
+ position: 'absolute',
263
+ top: 0,
264
+ left: 0,
265
+ right: 0,
266
+ bottom: 0,
267
+ padding: 20,
268
+ margin: 20,
269
+ borderRadius: 5
270
+ }}
271
+ >
272
+ <Chat
273
+ viewType="console"
274
+ sessions={fakeSessions}
275
+ activeSessionId="1"
276
+ onDeleteSession={() => alert('delete!')}
277
+ >
278
+ <SessionsList>
279
+ <NewSessionButton />
280
+ <SessionGroups />
281
+ </SessionsList>
282
+
283
+ <SessionMessagePanel>
284
+ <SessionMessagesHeader />
285
+ <SessionMessages />
286
+ <ChatInput />
287
+ </SessionMessagePanel>
288
+ </Chat>
289
+ </div>
290
+ );
291
+ };
292
+
293
+ export const UndeleteableSessions = () => {
294
+ return (
295
+ <div
296
+ className="dark:bg-gray-950 bg-white"
297
+ style={{
298
+ position: 'absolute',
299
+ top: 0,
300
+ left: 0,
301
+ right: 0,
302
+ bottom: 0,
303
+ padding: 20,
304
+ margin: 20,
305
+ borderRadius: 5
306
+ }}
307
+ >
308
+ <Chat viewType="console" sessions={fakeSessions} activeSessionId="1">
309
+ <SessionsList>
310
+ <NewSessionButton />
311
+ <SessionGroups>
312
+ {groups =>
313
+ groups.map(({ heading, sessions }) => (
314
+ <SessionsGroup heading={heading} key={heading}>
315
+ {sessions.map(s => (
316
+ <SessionListItem key={s.id} session={s} deletable={false} />
317
+ ))}
318
+ </SessionsGroup>
319
+ ))
320
+ }
321
+ </SessionGroups>
322
+ </SessionsList>
323
+
324
+ <SessionMessagePanel>
325
+ <SessionMessagesHeader />
326
+ <SessionMessages />
327
+ <ChatInput />
328
+ </SessionMessagePanel>
329
+ </Chat>
330
+ </div>
331
+ );
332
+ };
333
+
334
+ export const SessionGrouping = () => {
335
+ const createSessionWithDate = (
336
+ id: string,
337
+ title: string,
338
+ daysAgo: number
339
+ ): Session => ({
340
+ id,
341
+ title,
342
+ createdAt: subDays(new Date(), daysAgo),
343
+ updatedAt: subDays(new Date(), daysAgo),
344
+ conversations: [
345
+ {
346
+ id: `${id}-1`,
347
+ question: 'Sample question',
348
+ response: 'Sample response',
349
+ createdAt: subDays(new Date(), daysAgo),
350
+ updatedAt: subDays(new Date(), daysAgo)
351
+ }
352
+ ]
353
+ });
354
+
355
+ const sessionsWithVariousDates: Session[] = [
356
+ createSessionWithDate('1', 'Today Session', 0),
357
+ createSessionWithDate('2', 'Yesterday Session', 1),
358
+ createSessionWithDate('3', 'Yesterday Session 2', 1),
359
+ createSessionWithDate('4', 'Last Week Session', 6),
360
+ createSessionWithDate('5', 'Two Weeks Ago Session', 14),
361
+ createSessionWithDate('6', 'Last Month Session', 32),
362
+ createSessionWithDate('7', 'Two Months Ago Session', 65),
363
+ createSessionWithDate('8', 'Six Months Ago Session', 180),
364
+ createSessionWithDate('9', 'Last Year Session', 370),
365
+ createSessionWithDate('10', 'Two Years Ago Session', 740)
366
+ ];
367
+
368
+ return (
369
+ <div
370
+ className="dark:bg-gray-950 bg-white"
371
+ style={{
372
+ position: 'absolute',
373
+ top: 0,
374
+ left: 0,
375
+ right: 0,
376
+ bottom: 0,
377
+ padding: 20,
378
+ margin: 20,
379
+ borderRadius: 5
380
+ }}
381
+ >
382
+ <Chat
383
+ viewType="console"
384
+ sessions={sessionsWithVariousDates}
385
+ isLoading={false}
386
+ onDeleteSession={() => {}}
387
+ >
388
+ <SessionsList>
389
+ <NewSessionButton />
390
+ <SessionGroups />
391
+ </SessionsList>
392
+
393
+ <SessionMessagePanel>
394
+ <SessionMessagesHeader />
395
+ <SessionMessages />
396
+ <ChatInput placeholder="Send a message" />
397
+ </SessionMessagePanel>
398
+ </Chat>
399
+ </div>
400
+ );
401
+ };
402
+
403
+ export const HundredSessions = () => {
404
+ const generateFakeSessions = (count: number): Session[] => {
405
+ return Array.from({ length: count }, (_, index) => ({
406
+ id: `session-${index + 1}`,
407
+ title: `Session ${index + 1}`,
408
+ createdAt: subDays(new Date(), index),
409
+ updatedAt: subDays(new Date(), index),
410
+ conversations: [
411
+ {
412
+ id: `conv-${index}-1`,
413
+ question: `Question for session ${index + 1}`,
414
+ response: `Response for session ${index + 1}`,
415
+ createdAt: subDays(new Date(), index),
416
+ updatedAt: subDays(new Date(), index)
417
+ }
418
+ ]
419
+ }));
420
+ };
421
+
422
+ const hundredSessions = generateFakeSessions(100);
423
+
424
+ return (
425
+ <div
426
+ className="dark:bg-gray-950 bg-white"
427
+ style={{
428
+ position: 'absolute',
429
+ top: 0,
430
+ left: 0,
431
+ right: 0,
432
+ bottom: 0,
433
+ padding: 20,
434
+ margin: 20,
435
+ borderRadius: 5
436
+ }}
437
+ >
438
+ <Chat viewType="console" sessions={hundredSessions}>
439
+ <SessionsList>
440
+ <NewSessionButton />
441
+ <SessionGroups />
442
+ </SessionsList>
443
+
444
+ <SessionMessagePanel>
445
+ <SessionMessagesHeader />
446
+ <SessionMessages />
447
+ <ChatInput />
448
+ </SessionMessagePanel>
449
+ </Chat>
450
+ </div>
451
+ );
452
+ };
453
+
454
+ export const HundredConversations = () => {
455
+ const generateFakeConversations = (count: number) => {
456
+ return Array.from({ length: count }, (_, index) => ({
457
+ id: `conv-${index + 1}`,
458
+ question: `Question ${index + 1}: What is the meaning of life, the universe, and everything?`,
459
+ response: `Answer ${index + 1}: According to The Hitchhiker's Guide to the Galaxy, it's 42. But in reality, that's a complex philosophical question that has puzzled humanity for centuries.`,
460
+ createdAt: subMinutes(new Date(), count - index),
461
+ updatedAt: subMinutes(new Date(), count - index)
462
+ }));
463
+ };
464
+
465
+ const sessionWithHundredConversations: Session[] = [
466
+ {
467
+ id: 'session-100',
468
+ title: 'Session with 100 Conversations',
469
+ createdAt: subHours(new Date(), 5),
470
+ updatedAt: new Date(),
471
+ conversations: generateFakeConversations(100)
472
+ }
473
+ ];
474
+
475
+ return (
476
+ <div
477
+ className="dark:bg-gray-950 bg-white"
478
+ style={{
479
+ position: 'absolute',
480
+ top: 0,
481
+ left: 0,
482
+ right: 0,
483
+ bottom: 0,
484
+ padding: 20,
485
+ margin: 20,
486
+ borderRadius: 5
487
+ }}
488
+ >
489
+ <Chat
490
+ viewType="console"
491
+ sessions={sessionWithHundredConversations}
492
+ activeSessionId="session-100"
493
+ >
494
+ <SessionsList>
495
+ <NewSessionButton />
496
+ <SessionGroups />
497
+ </SessionsList>
498
+
499
+ <SessionMessagePanel>
500
+ <SessionMessagesHeader />
501
+ <SessionMessages />
502
+ <ChatInput />
503
+ </SessionMessagePanel>
504
+ </Chat>
505
+ </div>
506
+ );
507
+ };
508
+
509
+ export const LongSessionNames = () => {
510
+ const generateFakeSessionsWithLongNames = (count: number) => {
511
+ return Array.from({ length: count }, (_, index) => ({
512
+ id: `session-${index + 1}`,
513
+ title: `Session ${index + 1}: This is a very long session name to test how the UI handles overflow and text wrapping in the session list. It should be truncated or wrapped appropriately to ensure a good user experience.`,
514
+ createdAt: subHours(new Date(), count - index),
515
+ updatedAt: new Date(),
516
+ conversations: [
517
+ {
518
+ id: '1',
519
+ question:
520
+ 'Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics?',
521
+ response:
522
+ 'Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics? Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics?',
523
+ createdAt: new Date(),
524
+ updatedAt: new Date()
525
+ }
526
+ ]
527
+ }));
528
+ };
529
+
530
+ const sessionsWithLongNames = generateFakeSessionsWithLongNames(10);
531
+
532
+ return (
533
+ <div
534
+ className="dark:bg-gray-950 bg-white"
535
+ style={{
536
+ position: 'absolute',
537
+ top: 0,
538
+ left: 0,
539
+ right: 0,
540
+ bottom: 0,
541
+ padding: 20,
542
+ margin: 20,
543
+ borderRadius: 5
544
+ }}
545
+ >
546
+ <Chat
547
+ viewType="console"
548
+ sessions={sessionsWithLongNames}
549
+ activeSessionId="session-10"
550
+ >
551
+ <SessionsList>
552
+ <NewSessionButton />
553
+ <SessionGroups />
554
+ </SessionsList>
555
+
556
+ <SessionMessagePanel>
557
+ <SessionMessagesHeader />
558
+ <SessionMessages />
559
+ <ChatInput />
560
+ </SessionMessagePanel>
561
+ </Chat>
562
+ </div>
563
+ );
564
+ };
565
+
566
+ export const MarkdownShowcase = () => {
567
+ const markdownQuestion = `
568
+ **What is the purpose of life?**
569
+ `;
570
+
571
+ const markdownResponse = `
572
+ **The purpose of life is a philosophical question concerning the significance of life or existence in general.**
573
+
574
+ 1. Burning of fossil fuels (coal, oil, and natural gas)
575
+ 2. Deforestation and land-use changes
576
+ 3. Industrial processes
577
+ 4. Agriculture and livestock farming
578
+
579
+ or
580
+
581
+ - Burning
582
+ - Deforestation
583
+ - Industrial
584
+ - Agriculture
585
+
586
+ Here is a table to illustrate different perspectives:
587
+
588
+ | Perspective | Description |
589
+ |-------------------|-----------------------------------------------------------------------------|
590
+ | Religious | Belief in a higher power or divine purpose. |
591
+ | Philosophical | Various theories including existentialism, nihilism, and absurdism. |
592
+ | Scientific | Understanding life through biology, evolution, and the universe. |
593
+ | Personal | Individual goals, happiness, and fulfillment. |
594
+
595
+ \`\`\`python
596
+ def purpose_of_life():
597
+ return 42
598
+ \`\`\`
599
+
600
+ \`\`\`json
601
+ {
602
+ "perspectives": [
603
+ {
604
+ "type": "Religious",
605
+ "description": "Belief in a higher power or divine purpose."
606
+ },
607
+ {
608
+ "type": "Philosophical",
609
+ "description": "Various theories including existentialism, nihilism, and absurdism."
610
+ },
611
+ {
612
+ "type": "Scientific",
613
+ "description": "Understanding life through biology, evolution, and the universe."
614
+ },
615
+ {
616
+ "type": "Personal",
617
+ "description": "Individual goals, happiness, and fulfillment."
618
+ }
619
+ ]
620
+ }
621
+ \`\`\`
622
+
623
+ The answer to the ultimate question of life, the universe, and everything is **42**.
624
+
625
+ \`\`\`math
626
+ L = \\frac{1}{2} \\rho v^2 S C_L
627
+ \`\`\`
628
+
629
+ [Perspective](https://en.wikipedia.org/wiki/Philosophical_question)
630
+ `;
631
+
632
+ const sessionWithMarkdown: Session[] = [
633
+ {
634
+ id: 'session-markdown',
635
+ title: 'Markdown Showcase',
636
+ createdAt: subHours(new Date(), 1),
637
+ updatedAt: new Date(),
638
+ conversations: [
639
+ {
640
+ id: 'conversation-1',
641
+ question: markdownQuestion,
642
+ response: markdownResponse,
643
+ createdAt: new Date()
644
+ }
645
+ ]
646
+ }
647
+ ];
648
+
649
+ return (
650
+ <div
651
+ className="dark:bg-gray-950 bg-white"
652
+ style={{
653
+ position: 'absolute',
654
+ top: 0,
655
+ left: 0,
656
+ right: 0,
657
+ bottom: 0,
658
+ padding: 20,
659
+ margin: 20,
660
+ borderRadius: 5
661
+ }}
662
+ >
663
+ <Chat
664
+ viewType="console"
665
+ sessions={sessionWithMarkdown}
666
+ activeSessionId="session-markdown"
667
+ >
668
+ <SessionsList>
669
+ <NewSessionButton />
670
+ <SessionGroups />
671
+ </SessionsList>
672
+
673
+ <SessionMessagePanel>
674
+ <SessionMessagesHeader />
675
+ <SessionMessages />
676
+ <ChatInput />
677
+ </SessionMessagePanel>
678
+ </Chat>
679
+ </div>
680
+ );
681
+ };
682
+
683
+ export const CVEExample = () => {
684
+ const markdownQuestion = `# Security Report
685
+
686
+ Please review the following CVEs:
687
+
688
+ - CVE-2021-34527
689
+ - CVE-2021-44228
690
+ - CVE-2021-45046
691
+ `;
692
+
693
+ const markdownResponse = `## Analysis
694
+
695
+ The listed CVEs are critical vulnerabilities that need immediate attention.
696
+
697
+ - CVE-2021-34527
698
+ - CVE-2021-44228
699
+ - CVE-2021-45046
700
+ `;
701
+
702
+ const sessionWithMarkdown: Session[] = [
703
+ {
704
+ id: 'session-cve',
705
+ title: 'CVE Showcase',
706
+ createdAt: subHours(new Date(), 1),
707
+ updatedAt: new Date(),
708
+ conversations: [
709
+ {
710
+ id: 'conversation-1',
711
+ question: markdownQuestion,
712
+ response: markdownResponse,
713
+ createdAt: new Date()
714
+ }
715
+ ]
716
+ }
717
+ ];
718
+
719
+ return (
720
+ <div
721
+ className="dark:bg-gray-950 bg-white"
722
+ style={{
723
+ position: 'absolute',
724
+ top: 0,
725
+ left: 0,
726
+ right: 0,
727
+ bottom: 0,
728
+ padding: 20,
729
+ margin: 20,
730
+ borderRadius: 5
731
+ }}
732
+ >
733
+ <Chat
734
+ viewType="console"
735
+ sessions={sessionWithMarkdown}
736
+ activeSessionId="session-cve"
737
+ remarkPlugins={[remarkCve as any]}
738
+ >
739
+ <SessionsList>
740
+ <NewSessionButton />
741
+ <SessionGroups />
742
+ </SessionsList>
743
+
744
+ <SessionMessagePanel>
745
+ <SessionMessagesHeader />
746
+ <SessionMessages />
747
+ <ChatInput />
748
+ </SessionMessagePanel>
749
+ </Chat>
750
+ </div>
751
+ );
752
+ };
753
+
754
+ export const Empty = () => {
755
+ return (
756
+ <div
757
+ className="dark:bg-gray-950 bg-white"
758
+ style={{
759
+ position: 'absolute',
760
+ top: 0,
761
+ left: 0,
762
+ right: 0,
763
+ bottom: 0,
764
+ padding: 20,
765
+ margin: 20,
766
+ borderRadius: 5
767
+ }}
768
+ >
769
+ <Chat
770
+ viewType="console"
771
+ sessions={[]}
772
+ onDeleteSession={() => alert('delete!')}
773
+ >
774
+ <SessionsList>
775
+ <NewSessionButton />
776
+ <SessionGroups>
777
+ {groups => (
778
+ <>
779
+ {groups.map(({ heading, sessions }) => (
780
+ <SessionsGroup heading={heading} key={heading}>
781
+ {sessions.map(s => (
782
+ <SessionListItem key={s.id} session={s} />
783
+ ))}
784
+ </SessionsGroup>
785
+ ))}
786
+ {groups.length === 0 && (
787
+ <div className="flex flex-1 items-center justify-center">
788
+ <p className="text-gray-500">
789
+ No sessions yet. Start a new session!
790
+ </p>
791
+ </div>
792
+ )}
793
+ </>
794
+ )}
795
+ </SessionGroups>
796
+ </SessionsList>
797
+ <div className="flex-1 h-full flex flex-col">
798
+ <SessionMessages
799
+ newSessionContent={
800
+ <div className="flex flex-col gap-2 items-center justify-center h-full">
801
+ <Placeholder className="block dark:hidden" />
802
+ <PlaceholderDark className="hidden dark:block" />
803
+ <p className="text-gray-500 max-w-[400px] text-center">
804
+ Welcome to Reachat, a UI library for effortlessly building and
805
+ customizing chat experiences with Tailwind.
806
+ </p>
807
+ </div>
808
+ }
809
+ />
810
+ <ChatInput />
811
+ </div>
812
+ </Chat>
813
+ </div>
814
+ );
815
+ };
816
+
817
+ export const ConversationSources = () => {
818
+ return (
819
+ <div
820
+ className="dark:bg-gray-950 bg-white"
821
+ style={{
822
+ position: 'absolute',
823
+ top: 0,
824
+ left: 0,
825
+ right: 0,
826
+ bottom: 0,
827
+ padding: 20,
828
+ margin: 20,
829
+ borderRadius: 5
830
+ }}
831
+ >
832
+ <Chat
833
+ viewType="console"
834
+ sessions={sessionWithSources}
835
+ activeSessionId="session-sources"
836
+ >
837
+ <SessionsList>
838
+ <NewSessionButton />
839
+ <SessionGroups />
840
+ </SessionsList>
841
+
842
+ <SessionMessagePanel>
843
+ <SessionMessagesHeader />
844
+ <SessionMessages />
845
+ <ChatInput />
846
+ </SessionMessagePanel>
847
+ </Chat>
848
+ </div>
849
+ );
850
+ };
851
+
852
+ const CustomMessagesHeader: FC<any> = () => {
853
+ const { activeSession } = useContext(ChatContext);
854
+
855
+ return (
856
+ <div>
857
+ <h6 className="text-gray-400">
858
+ <DateFormat date={activeSession?.createdAt} format="MMMM dd, yyyy" />
859
+ </h6>
860
+ <h1 className="text-2xl font-semibold">{activeSession?.title}</h1>
861
+ </div>
862
+ );
863
+ };
864
+
865
+ const CustomMessageQuestion: FC<any> = ({ question, files }) => (
866
+ <>
867
+ <span className="text-lg font-semibold text-blue-500">
868
+ This is my question: {question}
869
+ </span>
870
+ <MessageFiles files={files}>
871
+ <CustomMessageFile />
872
+ </MessageFiles>
873
+ </>
874
+ );
875
+
876
+ const CustomMessageResponse: FC<any> = ({ response }) => (
877
+ <blockquote className="border-l border-blue-500 pl-2">
878
+ This is the response: {response}
879
+ </blockquote>
880
+ );
881
+
882
+ const CustomMessageFile: FC<any> = ({ name, type }) => (
883
+ <Chip size="small" className="rounded-full border border-gray-700">
884
+ {name || type}
885
+ </Chip>
886
+ );
887
+
888
+ const CustomMessageSource: FC<any> = ({ title, url, image }) => {
889
+ const { theme } = useContext(ChatContext);
890
+ return (
891
+ <Chip
892
+ size="small"
893
+ className="rounded-full border border-blue-500 border-opacity-50"
894
+ onClick={() => alert('take me to ' + url)}
895
+ start={
896
+ image && (
897
+ <img
898
+ src={image}
899
+ alt={title}
900
+ className={cn(theme?.messages?.message?.sources?.source?.image)}
901
+ />
902
+ )
903
+ }
904
+ >
905
+ {title || url}
906
+ </Chip>
907
+ );
908
+ };
909
+
910
+ const CustomSessionListItem: FC<SessionListItemProps> = ({
911
+ session,
912
+ children,
913
+ ...rest
914
+ }) => {
915
+ const [open, setOpen] = useState(false);
916
+ const btnRef = useRef(null);
917
+ return (
918
+ <>
919
+ <ListItem
920
+ {...rest}
921
+ end={
922
+ <IconButton
923
+ ref={btnRef}
924
+ size="small"
925
+ variant="text"
926
+ onClick={e => {
927
+ e.stopPropagation();
928
+ setOpen(true);
929
+ }}
930
+ >
931
+ <MenuIcon />
932
+ </IconButton>
933
+ }
934
+ >
935
+ <span className="truncate">{session.title}</span>
936
+ </ListItem>
937
+ <Menu
938
+ open={open}
939
+ onClose={() => setOpen(false)}
940
+ reference={btnRef}
941
+ appendToBody={false}
942
+ >
943
+ <Card disablePadding>
944
+ <List>
945
+ <ListItem onClick={() => alert('rename')}>Rename</ListItem>
946
+ <ListItem onClick={() => alert('delete')}>Delete</ListItem>
947
+ </List>
948
+ </Card>
949
+ </Menu>
950
+ </>
951
+ );
952
+ };
953
+
954
+ export const CustomComponents = () => {
955
+ return (
956
+ <div
957
+ className="dark:bg-gray-950 bg-white"
958
+ style={{
959
+ position: 'absolute',
960
+ top: 0,
961
+ left: 0,
962
+ right: 0,
963
+ bottom: 0,
964
+ padding: 20,
965
+ margin: 20,
966
+ borderRadius: 5
967
+ }}
968
+ >
969
+ <Chat
970
+ sessions={[
971
+ ...fakeSessions,
972
+ ...sessionsWithFiles,
973
+ ...sessionWithSources
974
+ ]}
975
+ activeSessionId="1"
976
+ >
977
+ <SessionsList>
978
+ <NewSessionButton>
979
+ <button className="text-blue-500">New Session</button>
980
+ </NewSessionButton>
981
+ <Divider variant="secondary" />
982
+ <SessionGroups>
983
+ {groups =>
984
+ groups.map(({ heading, sessions }) => (
985
+ <SessionsGroup heading={heading} key={heading}>
986
+ {sessions.map(s => (
987
+ <SessionListItem key={s.id} session={s}>
988
+ <CustomSessionListItem session={s} />
989
+ </SessionListItem>
990
+ ))}
991
+ </SessionsGroup>
992
+ ))
993
+ }
994
+ </SessionGroups>
995
+ </SessionsList>
996
+ <SessionMessagePanel>
997
+ <SessionMessagesHeader>
998
+ <CustomMessagesHeader />
999
+ </SessionMessagesHeader>
1000
+ <SessionMessages>
1001
+ {conversations =>
1002
+ conversations.map((conversation, index) => (
1003
+ <SessionMessage
1004
+ conversation={conversation}
1005
+ isLast={index === conversations.length - 1}
1006
+ key={conversation.id}
1007
+ >
1008
+ <MessageQuestion
1009
+ question={conversation.question}
1010
+ files={conversation.files}
1011
+ >
1012
+ <CustomMessageQuestion />
1013
+ </MessageQuestion>
1014
+ <MessageResponse response={conversation.response}>
1015
+ <CustomMessageResponse />
1016
+ </MessageResponse>
1017
+ <MessageSources sources={conversation.sources}>
1018
+ <CustomMessageSource />
1019
+ </MessageSources>
1020
+ <MessageActions
1021
+ question={conversation.question}
1022
+ response={conversation.response}
1023
+ />
1024
+ </SessionMessage>
1025
+ ))
1026
+ }
1027
+ </SessionMessages>
1028
+ <ChatInput />
1029
+ </SessionMessagePanel>
1030
+ </Chat>
1031
+ </div>
1032
+ );
1033
+ };
1034
+
1035
+ export const ImageFiles = () => {
1036
+ const staticImageFiles = [
1037
+ {
1038
+ id: '1',
1039
+ name: 'landscape.jpg',
1040
+ type: 'image/jpeg',
1041
+ url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Faustin.1ee6ee64.jpg&w=640&q=75'
1042
+ },
1043
+ {
1044
+ id: '2',
1045
+ name: 'portrait.jpg',
1046
+ type: 'image/jpeg',
1047
+ url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fandrew.50c21037.jpeg&w=640&q=75'
1048
+ },
1049
+ {
1050
+ id: '3',
1051
+ name: 'abstract.png',
1052
+ type: 'image/jpg',
1053
+ url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fkyle.52befaed.jpg&w=640&q=75'
1054
+ },
1055
+ {
1056
+ id: '4',
1057
+ name: 'nature.jpg',
1058
+ type: 'image/jpeg',
1059
+ url: 'https://www.goodcode.us/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsteph.8a52b5d2.jpg&w=640&q=75'
1060
+ }
1061
+ ];
1062
+
1063
+ const sessionWithImages: Session[] = [
1064
+ {
1065
+ id: 'session-images',
1066
+ title: 'Multiple Image Files Showcase',
1067
+ createdAt: subHours(new Date(), 1),
1068
+ updatedAt: new Date(),
1069
+ conversations: [
1070
+ {
1071
+ id: 'conversation-1',
1072
+ question: 'Analyze these images and describe what you see.',
1073
+ response:
1074
+ 'I\'m sorry, but as an AI language model, I cannot actually see or analyze images. I can only process and respond to text input. If you\'d like me to describe or analyze images, you would need to provide detailed textual descriptions of the images.',
1075
+ createdAt: new Date(),
1076
+ files: staticImageFiles
1077
+ },
1078
+ {
1079
+ id: 'conversation-2',
1080
+ question: 'Analyze these images and describe what you see.',
1081
+ response:
1082
+ 'I\'m sorry, but as an AI language model, I cannot actually see or analyze images. I can only process and respond to text input. If you\'d like me to describe or analyze images, you would need to provide detailed textual descriptions of the images.',
1083
+ createdAt: new Date(),
1084
+ files: [staticImageFiles[0]]
1085
+ }
1086
+ ]
1087
+ }
1088
+ ];
1089
+
1090
+ return (
1091
+ <div
1092
+ className="dark:bg-gray-950 bg-white"
1093
+ style={{
1094
+ position: 'absolute',
1095
+ top: 0,
1096
+ left: 0,
1097
+ right: 0,
1098
+ bottom: 0,
1099
+ padding: 20,
1100
+ margin: 20,
1101
+ borderRadius: 5
1102
+ }}
1103
+ >
1104
+ <Chat
1105
+ viewType="console"
1106
+ sessions={sessionWithImages}
1107
+ activeSessionId="session-images"
1108
+ >
1109
+ <SessionsList>
1110
+ <NewSessionButton />
1111
+ <SessionGroups />
1112
+ </SessionsList>
1113
+
1114
+ <SessionMessagePanel>
1115
+ <SessionMessagesHeader />
1116
+ <SessionMessages />
1117
+ <ChatInput />
1118
+ </SessionMessagePanel>
1119
+ </Chat>
1120
+ </div>
1121
+ );
1122
+ };
1123
+
1124
+ export const CSVPreview = () => {
1125
+ return (
1126
+ <div
1127
+ className="dark:bg-gray-950 bg-white"
1128
+ style={{
1129
+ position: 'absolute',
1130
+ inset: 0,
1131
+ padding: 20,
1132
+ margin: 20,
1133
+ borderRadius: 5
1134
+ }}
1135
+ >
1136
+ <Chat
1137
+ sessions={sessionWithCSVFiles}
1138
+ activeSessionId="1"
1139
+ onDeleteSession={() => alert('delete!')}
1140
+ >
1141
+ <SessionsList>
1142
+ <NewSessionButton />
1143
+ <SessionGroups />
1144
+ </SessionsList>
1145
+
1146
+ <SessionMessagePanel>
1147
+ <SessionMessagesHeader />
1148
+ <SessionMessages />
1149
+ <ChatInput allowedFiles={['.pdf', '.docx', '.csv']} />
1150
+ </SessionMessagePanel>
1151
+ </Chat>
1152
+ </div>
1153
+ );
1154
+ };