@admin-layout/tailwind-chat-pro 12.2.4-alpha.87 → 12.2.4-alpha.89
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/CHANGELOG.md +8 -0
- package/lib/components/messages-container-ui/ModernMessageGroup.d.ts.map +1 -1
- package/lib/components/messages-container-ui/ModernMessageGroup.js +111 -430
- package/lib/components/messages-container-ui/ModernMessageGroup.js.map +1 -1
- package/package.json +2 -2
- package/src/components/messages-container-ui/ModernMessageGroup.tsx +117 -458
|
@@ -2,7 +2,7 @@ import { Slot } from '@common-stack/components-pro';
|
|
|
2
2
|
import { AiAgentMessageRole, IAuthUser, IPost } from 'common';
|
|
3
3
|
import { differenceInMinutes, format } from 'date-fns';
|
|
4
4
|
import { marked } from 'marked';
|
|
5
|
-
import React, { useEffect, useMemo } from 'react';
|
|
5
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
6
6
|
import ReactMarkdown from 'react-markdown';
|
|
7
7
|
import remarkBreaks from 'remark-breaks';
|
|
8
8
|
import remarkGfm from 'remark-gfm';
|
|
@@ -24,6 +24,9 @@ const ASSISTANT_RESPONSE_BUBBLE_CLASS = 'llm-response__bubble';
|
|
|
24
24
|
const ASSISTANT_RESPONSE_MARKDOWN_CLASS = 'llm-response__markdown';
|
|
25
25
|
const USER_MESSAGE_TEXT_SIZE_CLASS = 'text-base';
|
|
26
26
|
const USER_MESSAGE_PROSE_SIZE_CLASS = 'prose-base';
|
|
27
|
+
/** Pasted queries longer than this collapse behind a "Show more" toggle. */
|
|
28
|
+
const USER_MESSAGE_COLLAPSE_CHAR_THRESHOLD = 600;
|
|
29
|
+
const USER_MESSAGE_COLLAPSED_MAX_HEIGHT = 220;
|
|
27
30
|
|
|
28
31
|
function getAssistantResponseClasses(innerClassName?: string): string {
|
|
29
32
|
return [ASSISTANT_RESPONSE_MARKDOWN_CLASS, innerClassName].filter(Boolean).join(' ');
|
|
@@ -52,15 +55,15 @@ const htmlContentStyles = `
|
|
|
52
55
|
.html-content {
|
|
53
56
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
54
57
|
line-height: 1.6;
|
|
55
|
-
color:
|
|
58
|
+
color: inherit;
|
|
56
59
|
}
|
|
57
|
-
|
|
60
|
+
|
|
58
61
|
.html-content h1, .html-content h2, .html-content h3, .html-content h4, .html-content h5, .html-content h6 {
|
|
59
62
|
margin-top: 1.5rem;
|
|
60
63
|
margin-bottom: 1rem;
|
|
61
64
|
font-weight: 600;
|
|
62
65
|
line-height: 1.25;
|
|
63
|
-
color:
|
|
66
|
+
color: inherit;
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
.html-content h1 {
|
|
@@ -362,347 +365,31 @@ const htmlContentStyles = `
|
|
|
362
365
|
box-shadow: none !important;
|
|
363
366
|
}
|
|
364
367
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
.assistant-html-content {
|
|
375
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
376
|
-
line-height: 1.6;
|
|
377
|
-
color: #374151;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
.assistant-html-content h1,
|
|
381
|
-
.assistant-html-content h2,
|
|
382
|
-
.assistant-html-content h3,
|
|
383
|
-
.assistant-html-content h4,
|
|
384
|
-
.assistant-html-content h5,
|
|
385
|
-
.assistant-html-content h6 {
|
|
386
|
-
font-weight: 600;
|
|
387
|
-
line-height: 1.25;
|
|
388
|
-
color: #111827;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
.assistant-html-content h1 {
|
|
392
|
-
font-size: 1.875rem;
|
|
393
|
-
margin-top: 2rem;
|
|
394
|
-
margin-bottom: 1rem;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.assistant-html-content h2 {
|
|
398
|
-
font-size: 1.5rem;
|
|
399
|
-
margin-top: 2rem;
|
|
400
|
-
margin-bottom: 1rem;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
.assistant-html-content h3 {
|
|
404
|
-
font-size: 1.25rem;
|
|
405
|
-
margin-top: 1.5rem;
|
|
406
|
-
margin-bottom: 1rem;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
.assistant-html-content h4 {
|
|
410
|
-
font-size: 1.125rem;
|
|
411
|
-
margin-top: 1rem;
|
|
412
|
-
margin-bottom: 0.5rem;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
.assistant-html-content p {
|
|
416
|
-
margin-top: 0;
|
|
417
|
-
margin-bottom: 1rem;
|
|
418
|
-
line-height: 1.625;
|
|
419
|
-
color: #374151;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
.assistant-html-content ul,
|
|
423
|
-
.assistant-html-content ol {
|
|
424
|
-
margin: 1rem 0;
|
|
425
|
-
padding-left: 1.25rem;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
.assistant-html-content ul {
|
|
429
|
-
list-style-type: disc;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
.assistant-html-content ol {
|
|
433
|
-
list-style-type: decimal;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
.assistant-html-content li {
|
|
437
|
-
margin-bottom: 0.375rem;
|
|
438
|
-
line-height: 1.625;
|
|
439
|
-
color: #374151;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
.assistant-html-content li > ul,
|
|
443
|
-
.assistant-html-content li > ol {
|
|
444
|
-
margin-top: 0.375rem;
|
|
445
|
-
margin-bottom: 0.375rem;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
.assistant-html-content a {
|
|
449
|
-
color: #2563eb;
|
|
450
|
-
text-decoration: none;
|
|
368
|
+
/* Safety net: long unbroken tokens (file paths, CSS selectors, URLs) inside a
|
|
369
|
+
pasted user query must never push the bubble past its own width — wrap
|
|
370
|
+
anywhere rather than overflow the card. */
|
|
371
|
+
.user-message,
|
|
372
|
+
.user-message * {
|
|
373
|
+
max-width: 100%;
|
|
374
|
+
overflow-wrap: anywhere;
|
|
451
375
|
}
|
|
452
376
|
|
|
453
|
-
.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
.
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
.assistant-html-content em,
|
|
466
|
-
.assistant-html-content i {
|
|
467
|
-
font-style: italic;
|
|
468
|
-
color: #4b5563;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
.assistant-html-content code {
|
|
472
|
-
background-color: #f3f4f6;
|
|
473
|
-
padding: 0.25rem 0.5rem;
|
|
474
|
-
border-radius: 0.375rem;
|
|
475
|
-
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
|
476
|
-
font-size: 0.875rem;
|
|
477
|
-
color: #dc2626;
|
|
478
|
-
border: 1px solid #e5e7eb;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
.assistant-html-content pre {
|
|
482
|
-
background-color: #f9fafb;
|
|
483
|
-
padding: 1rem;
|
|
484
|
-
border-radius: 0.5rem;
|
|
485
|
-
overflow-x: auto;
|
|
486
|
-
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
|
487
|
-
font-size: 0.875rem;
|
|
488
|
-
line-height: 1.5;
|
|
489
|
-
border: 1px solid #e5e7eb;
|
|
490
|
-
margin: 1.5rem 0;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.assistant-html-content pre code {
|
|
494
|
-
background-color: transparent;
|
|
495
|
-
padding: 0;
|
|
496
|
-
border: none;
|
|
497
|
-
color: #374151;
|
|
498
|
-
font-size: inherit;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
.assistant-html-content blockquote {
|
|
502
|
-
margin: 1.5rem 0;
|
|
503
|
-
padding: 0 0 0 1rem;
|
|
504
|
-
border-left: 4px solid #d1d5db;
|
|
505
|
-
font-style: italic;
|
|
506
|
-
color: #6b7280;
|
|
507
|
-
background-color: transparent;
|
|
508
|
-
border-radius: 0;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
.assistant-html-content blockquote p {
|
|
512
|
-
margin-bottom: 0;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
.assistant-html-content table {
|
|
516
|
-
border-collapse: collapse;
|
|
517
|
-
border: 1px solid #e5e7eb;
|
|
518
|
-
width: 100%;
|
|
519
|
-
margin: 1rem 0;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
.assistant-html-content th,
|
|
523
|
-
.assistant-html-content td {
|
|
524
|
-
text-align: left;
|
|
525
|
-
vertical-align: top;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
.assistant-html-content th {
|
|
529
|
-
padding: 0.5rem 1rem;
|
|
530
|
-
background-color: #f9fafb;
|
|
531
|
-
border: 1px solid #e5e7eb;
|
|
532
|
-
font-weight: 500;
|
|
533
|
-
font-size: 0.75rem;
|
|
534
|
-
letter-spacing: 0.04em;
|
|
535
|
-
text-transform: uppercase;
|
|
536
|
-
color: #4b5563;
|
|
377
|
+
/* Assistant replies must read as plain text on the page — no card. A shared
|
|
378
|
+
global class (.message-container, from @messenger-box/tailwind-ui-inbox)
|
|
379
|
+
ships its own pill background/padding; neutralize it here the same way the
|
|
380
|
+
user bubble already does above. */
|
|
381
|
+
.${ASSISTANT_RESPONSE_THEME_CLASS},
|
|
382
|
+
.${ASSISTANT_RESPONSE_CLASS},
|
|
383
|
+
.${ASSISTANT_RESPONSE_BUBBLE_CLASS},
|
|
384
|
+
.${ASSISTANT_RESPONSE_THEME_CLASS} .message-container {
|
|
385
|
+
background: transparent !important;
|
|
386
|
+
box-shadow: none !important;
|
|
537
387
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
border-top: 1px solid #e5e7eb;
|
|
542
|
-
color: #374151;
|
|
388
|
+
.${ASSISTANT_RESPONSE_THEME_CLASS} .message-container {
|
|
389
|
+
padding: 0 !important;
|
|
390
|
+
margin: 0 !important;
|
|
543
391
|
}
|
|
544
392
|
|
|
545
|
-
.assistant-html-content hr {
|
|
546
|
-
border: none;
|
|
547
|
-
border-top: 1px solid #e5e7eb;
|
|
548
|
-
margin: 2rem 0;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/* Markdown content styling */
|
|
552
|
-
.markdown-content {
|
|
553
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
554
|
-
line-height: 1.6;
|
|
555
|
-
color: #374151;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
.markdown-content h1 {
|
|
559
|
-
font-size: 1.5rem;
|
|
560
|
-
font-weight: 700;
|
|
561
|
-
margin-top: 1.5rem;
|
|
562
|
-
margin-bottom: 1rem;
|
|
563
|
-
color: #111827;
|
|
564
|
-
padding-bottom: 0.5rem;
|
|
565
|
-
border-bottom: 2px solid #e5e7eb;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
.markdown-content h2 {
|
|
569
|
-
font-size: 1.25rem;
|
|
570
|
-
font-weight: 600;
|
|
571
|
-
margin-top: 1.25rem;
|
|
572
|
-
margin-bottom: 0.75rem;
|
|
573
|
-
color: #1f2937;
|
|
574
|
-
padding-bottom: 0.375rem;
|
|
575
|
-
border-bottom: 1px solid #e5e7eb;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
.markdown-content h3 {
|
|
579
|
-
font-size: 1.125rem;
|
|
580
|
-
font-weight: 600;
|
|
581
|
-
margin-top: 1rem;
|
|
582
|
-
margin-bottom: 0.5rem;
|
|
583
|
-
color: #374151;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
.markdown-content p {
|
|
587
|
-
margin-bottom: 0.75rem;
|
|
588
|
-
line-height: 1.6;
|
|
589
|
-
color: #4b5563;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
.markdown-content ul, .markdown-content ol {
|
|
593
|
-
margin: 1rem 0;
|
|
594
|
-
padding-left: 1.5rem;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
.markdown-content li {
|
|
598
|
-
margin-bottom: 0.5rem;
|
|
599
|
-
line-height: 1.6;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
.markdown-content code {
|
|
603
|
-
background-color: #f3f4f6;
|
|
604
|
-
padding: 0.125rem 0.375rem;
|
|
605
|
-
border-radius: 0.25rem;
|
|
606
|
-
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
|
607
|
-
font-size: 0.875rem;
|
|
608
|
-
color: #dc2626;
|
|
609
|
-
border: 1px solid #e5e7eb;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
.markdown-content pre {
|
|
613
|
-
color: #1f2937;
|
|
614
|
-
border-radius: 8px;
|
|
615
|
-
overflow-x: auto;
|
|
616
|
-
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
|
617
|
-
font-size: 0.875rem;
|
|
618
|
-
line-height: 1.5;
|
|
619
|
-
margin: 1rem 0;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
.markdown-content pre code {
|
|
623
|
-
background-color: transparent;
|
|
624
|
-
padding: 0;
|
|
625
|
-
border: none;
|
|
626
|
-
color: #1f2937;
|
|
627
|
-
font-size: inherit;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
.markdown-content blockquote {
|
|
631
|
-
border-left: 4px solid #3b82f6;
|
|
632
|
-
background-color: #f8fafc;
|
|
633
|
-
padding: 1rem;
|
|
634
|
-
margin: 1rem 0;
|
|
635
|
-
border-radius: 6px;
|
|
636
|
-
font-style: italic;
|
|
637
|
-
color: #475569;
|
|
638
|
-
border-top: 1px solid #e5e7eb;
|
|
639
|
-
border-right: 1px solid #e5e7eb;
|
|
640
|
-
border-bottom: 1px solid #e5e7eb;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
.markdown-content table {
|
|
644
|
-
border-collapse: collapse;
|
|
645
|
-
border: 1px solid #e5e7eb;
|
|
646
|
-
width: 100%;
|
|
647
|
-
margin: 1rem 0;
|
|
648
|
-
border-radius: 8px;
|
|
649
|
-
overflow: hidden;
|
|
650
|
-
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
.markdown-content th {
|
|
654
|
-
background-color: #f9fafb;
|
|
655
|
-
color: #374151;
|
|
656
|
-
font-weight: 600;
|
|
657
|
-
padding: 0.75rem;
|
|
658
|
-
text-align: left;
|
|
659
|
-
border-bottom: 1px solid #e5e7eb;
|
|
660
|
-
font-size: 0.875rem;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
.markdown-content td {
|
|
664
|
-
border: 1px solid #e5e7eb;
|
|
665
|
-
padding: 0.75rem;
|
|
666
|
-
text-align: left;
|
|
667
|
-
vertical-align: top;
|
|
668
|
-
background-color: white;
|
|
669
|
-
font-size: 0.875rem;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
.markdown-content tr:nth-child(even) td {
|
|
673
|
-
background-color: #f9fafb;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
.markdown-content tr:hover td {
|
|
677
|
-
background-color: #f3f4f6;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
/* Enhanced list styling */
|
|
681
|
-
.markdown-content ul li {
|
|
682
|
-
position: relative;
|
|
683
|
-
padding-left: 0.5rem;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
.markdown-content ul li::before {
|
|
687
|
-
content: "•";
|
|
688
|
-
color: #000;
|
|
689
|
-
font-weight: bold;
|
|
690
|
-
position: absolute;
|
|
691
|
-
left: -1rem;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
.markdown-content ol li {
|
|
695
|
-
position: relative;
|
|
696
|
-
padding-left: 0.5rem;
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
.markdown-content ol li::before {
|
|
700
|
-
content: counter(list-item) ".";
|
|
701
|
-
font-weight: 600;
|
|
702
|
-
position: absolute;
|
|
703
|
-
left: -1.5rem;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
393
|
/* Code block container styling */
|
|
707
394
|
.code-block-container {
|
|
708
395
|
background: #ffffff;
|
|
@@ -724,38 +411,6 @@ const htmlContentStyles = `
|
|
|
724
411
|
letter-spacing: 0.05em;
|
|
725
412
|
}
|
|
726
413
|
|
|
727
|
-
.code-block-content {
|
|
728
|
-
padding: 1rem;
|
|
729
|
-
overflow-x: auto;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
/* Enhanced prose styling for markdown content */
|
|
733
|
-
.prose pre {
|
|
734
|
-
background-color: #f9fafb;
|
|
735
|
-
border: 1px solid #e5e7eb;
|
|
736
|
-
border-radius: 0.5rem;
|
|
737
|
-
padding: 1rem;
|
|
738
|
-
overflow-x: auto;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
.prose code {
|
|
742
|
-
background-color: #f3f4f6;
|
|
743
|
-
padding: 0.125rem 0.375rem;
|
|
744
|
-
border-radius: 0.25rem;
|
|
745
|
-
font-size: 0.875rem;
|
|
746
|
-
border: 1px solid #e5e7eb;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
.prose pre code {
|
|
750
|
-
background-color: transparent;
|
|
751
|
-
padding: 0;
|
|
752
|
-
border: none;
|
|
753
|
-
color:#000;
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
.hover\:bg-gray-100:hover {
|
|
757
|
-
background-color: transparent !important;
|
|
758
|
-
}
|
|
759
414
|
`;
|
|
760
415
|
|
|
761
416
|
// Hook to inject CSS styles
|
|
@@ -1318,11 +973,7 @@ export const CodeFormatter: React.FC<{
|
|
|
1318
973
|
<div
|
|
1319
974
|
key={index}
|
|
1320
975
|
className={`${variant === 'user' ? USER_MESSAGE_TEXT_SIZE_CLASS : 'text-sm'} ${
|
|
1321
|
-
variant === 'user'
|
|
1322
|
-
? planMode
|
|
1323
|
-
? 'text-primary-foreground'
|
|
1324
|
-
: 'text-gray-900'
|
|
1325
|
-
: 'text-gray-700'
|
|
976
|
+
variant === 'user' ? 'text-foreground' : 'text-gray-700'
|
|
1326
977
|
} leading-relaxed whitespace-pre-wrap break-words`}
|
|
1327
978
|
>
|
|
1328
979
|
{section.trim()}
|
|
@@ -1393,64 +1044,54 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1393
1044
|
}
|
|
1394
1045
|
}, [content]);
|
|
1395
1046
|
|
|
1396
|
-
const userMarkdownClasses = `${USER_MESSAGE_TEXT_SIZE_CLASS} prose ${USER_MESSAGE_PROSE_SIZE_CLASS} max-w-none leading-relaxed break-words
|
|
1397
|
-
prose-p:my-2 prose-p:text-
|
|
1047
|
+
const userMarkdownClasses = `${USER_MESSAGE_TEXT_SIZE_CLASS} prose ${USER_MESSAGE_PROSE_SIZE_CLASS} max-w-none leading-relaxed break-words
|
|
1048
|
+
prose-p:my-2 prose-p:text-foreground
|
|
1398
1049
|
prose-pre:my-2 prose-pre:bg-transparent prose-pre:border-0 prose-pre:p-0
|
|
1399
|
-
prose-ul:my-2 prose-ol:my-2
|
|
1400
|
-
prose-code:break-words prose-code:bg-
|
|
1401
|
-
prose-headings:font-semibold prose-headings:text-
|
|
1402
|
-
prose-h1:text-2xl prose-h1:border-b prose-h1:border-
|
|
1403
|
-
prose-h2:text-xl prose-h2:border-b prose-h2:border-
|
|
1050
|
+
prose-ul:my-2 prose-ol:my-2
|
|
1051
|
+
prose-code:break-words prose-code:bg-muted prose-code:text-foreground prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:text-sm prose-code:font-mono
|
|
1052
|
+
prose-headings:font-semibold prose-headings:text-foreground prose-headings:mt-4 prose-headings:mb-2
|
|
1053
|
+
prose-h1:text-2xl prose-h1:border-b prose-h1:border-border prose-h1:pb-2
|
|
1054
|
+
prose-h2:text-xl prose-h2:border-b prose-h2:border-border prose-h2:pb-1
|
|
1404
1055
|
prose-h3:text-lg
|
|
1405
1056
|
prose-h4:text-base
|
|
1406
|
-
prose-a:text-
|
|
1407
|
-
prose-strong:font-semibold prose-strong:text-
|
|
1408
|
-
prose-em:text-
|
|
1409
|
-
prose-blockquote:border-l-
|
|
1410
|
-
prose-table:w-full prose-table:border prose-table:border-
|
|
1411
|
-
prose-th:px-3 prose-th:py-2 prose-th:text-left prose-th:font-semibold prose-th:bg-
|
|
1412
|
-
prose-td:px-3 prose-td:py-2 prose-td:border prose-td:border-
|
|
1413
|
-
prose-li:my-1 prose-li:text-
|
|
1414
|
-
prose-hr:my-4 prose-hr:border-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
const userHtmlClasses = `${USER_MESSAGE_TEXT_SIZE_CLASS} prose ${USER_MESSAGE_PROSE_SIZE_CLASS} max-w-none leading-relaxed break-words
|
|
1422
|
-
prose-p:my-2 prose-p:text-gray-700
|
|
1423
|
-
prose-pre:my-2 prose-pre:bg-gray-50 prose-pre:border prose-pre:border-gray-200 prose-pre:rounded prose-pre:p-3
|
|
1424
|
-
prose-ul:my-2 prose-ol:my-2
|
|
1057
|
+
prose-a:text-foreground prose-a:underline hover:prose-a:text-foreground
|
|
1058
|
+
prose-strong:font-semibold prose-strong:text-foreground
|
|
1059
|
+
prose-em:text-muted-foreground
|
|
1060
|
+
prose-blockquote:border-l-2 prose-blockquote:border-border prose-blockquote:pl-4 prose-blockquote:py-2 prose-blockquote:bg-transparent prose-blockquote:my-3 prose-blockquote:italic prose-blockquote:text-muted-foreground
|
|
1061
|
+
prose-table:w-full prose-table:border prose-table:border-border prose-table:rounded-md prose-table:my-4
|
|
1062
|
+
prose-th:px-3 prose-th:py-2 prose-th:text-left prose-th:font-semibold prose-th:bg-muted prose-th:border prose-th:border-border
|
|
1063
|
+
prose-td:px-3 prose-td:py-2 prose-td:border prose-td:border-border prose-td:text-foreground
|
|
1064
|
+
prose-li:my-1 prose-li:text-foreground
|
|
1065
|
+
prose-hr:my-4 prose-hr:border-border
|
|
1066
|
+
!prose-p:text-foreground !prose-li:text-foreground !prose-strong:text-foreground !prose-em:text-muted-foreground !prose-a:text-foreground !prose-code:text-foreground`;
|
|
1067
|
+
|
|
1068
|
+
const userHtmlClasses = `${USER_MESSAGE_TEXT_SIZE_CLASS} prose ${USER_MESSAGE_PROSE_SIZE_CLASS} max-w-none leading-relaxed break-words
|
|
1069
|
+
prose-p:my-2 prose-p:text-foreground
|
|
1070
|
+
prose-pre:my-2 prose-pre:bg-muted prose-pre:border prose-pre:border-border prose-pre:rounded prose-pre:p-3
|
|
1071
|
+
prose-ul:my-2 prose-ol:my-2
|
|
1425
1072
|
prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:overflow-x-auto
|
|
1426
|
-
prose-code:break-words prose-code:bg-
|
|
1427
|
-
prose-headings:font-semibold prose-headings:text-
|
|
1428
|
-
prose-h1:text-2xl prose-h1:border-b prose-h1:border-
|
|
1429
|
-
prose-h2:text-xl prose-h2:border-b prose-h2:border-
|
|
1073
|
+
prose-code:break-words prose-code:bg-muted prose-code:text-foreground prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:text-sm prose-code:font-mono
|
|
1074
|
+
prose-headings:font-semibold prose-headings:text-foreground prose-headings:mt-4 prose-headings:mb-2
|
|
1075
|
+
prose-h1:text-2xl prose-h1:border-b prose-h1:border-border prose-h1:pb-2
|
|
1076
|
+
prose-h2:text-xl prose-h2:border-b prose-h2:border-border prose-h2:pb-1
|
|
1430
1077
|
prose-h3:text-lg
|
|
1431
1078
|
prose-h4:text-base
|
|
1432
|
-
prose-a:text-
|
|
1433
|
-
prose-strong:font-semibold prose-strong:text-
|
|
1434
|
-
prose-em:text-
|
|
1435
|
-
prose-blockquote:border-l-
|
|
1436
|
-
prose-table:w-full prose-table:border prose-table:border-
|
|
1437
|
-
prose-th:px-3 prose-th:py-2 prose-th:text-left prose-th:font-semibold prose-th:bg-
|
|
1438
|
-
prose-td:px-3 prose-td:py-2 prose-td:border prose-td:border-
|
|
1439
|
-
prose-li:my-1 prose-li:text-
|
|
1440
|
-
prose-hr:my-4 prose-hr:border-
|
|
1441
|
-
|
|
1442
|
-
planMode
|
|
1443
|
-
? '!prose-p:text-primary-foreground !prose-li:text-primary-foreground !prose-strong:text-primary-foreground !prose-em:text-primary-foreground !prose-a:text-primary-foreground'
|
|
1444
|
-
: '!prose-p:text-gray-900 !prose-li:text-gray-900 !prose-strong:text-gray-900 !prose-em:text-gray-700 !prose-a:text-blue-600'
|
|
1445
|
-
}`;
|
|
1079
|
+
prose-a:text-foreground prose-a:underline hover:prose-a:text-foreground
|
|
1080
|
+
prose-strong:font-semibold prose-strong:text-foreground
|
|
1081
|
+
prose-em:text-muted-foreground
|
|
1082
|
+
prose-blockquote:border-l-2 prose-blockquote:border-border prose-blockquote:pl-4 prose-blockquote:py-2 prose-blockquote:bg-transparent prose-blockquote:my-3 prose-blockquote:italic prose-blockquote:text-muted-foreground
|
|
1083
|
+
prose-table:w-full prose-table:border prose-table:border-border prose-table:rounded-md prose-table:my-4
|
|
1084
|
+
prose-th:px-3 prose-th:py-2 prose-th:text-left prose-th:font-semibold prose-th:bg-muted prose-th:border prose-th:border-border
|
|
1085
|
+
prose-td:px-3 prose-td:py-2 prose-td:border prose-td:border-border prose-td:text-foreground
|
|
1086
|
+
prose-li:my-1 prose-li:text-foreground
|
|
1087
|
+
prose-hr:my-4 prose-hr:border-border
|
|
1088
|
+
!prose-p:text-foreground !prose-li:text-foreground !prose-strong:text-foreground !prose-em:text-muted-foreground !prose-a:text-foreground !prose-code:text-foreground`;
|
|
1446
1089
|
|
|
1447
1090
|
const markdownComponents = useMemo(() => {
|
|
1448
1091
|
const isUserVariant = variant === 'user';
|
|
1449
|
-
const userTextClass =
|
|
1450
|
-
const userMutedTextClass =
|
|
1451
|
-
const userLinkClass =
|
|
1452
|
-
? 'text-primary-foreground underline underline-offset-2'
|
|
1453
|
-
: 'text-blue-600 hover:underline underline-offset-2';
|
|
1092
|
+
const userTextClass = 'text-foreground';
|
|
1093
|
+
const userMutedTextClass = 'text-muted-foreground';
|
|
1094
|
+
const userLinkClass = 'text-foreground underline underline-offset-2 hover:text-foreground/80';
|
|
1454
1095
|
|
|
1455
1096
|
return {
|
|
1456
1097
|
p: ({ children }: { children?: React.ReactNode }) =>
|
|
@@ -1486,19 +1127,19 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1486
1127
|
blockquote: ({ children }: { children?: React.ReactNode }) =>
|
|
1487
1128
|
isUserVariant ? (
|
|
1488
1129
|
<blockquote
|
|
1489
|
-
className={`border-l-
|
|
1130
|
+
className={`border-l-2 border-border pl-4 py-2 bg-transparent my-3 italic ${userMutedTextClass}`}
|
|
1490
1131
|
>
|
|
1491
1132
|
{children}
|
|
1492
1133
|
</blockquote>
|
|
1493
1134
|
) : (
|
|
1494
1135
|
<blockquote>{children}</blockquote>
|
|
1495
1136
|
),
|
|
1496
|
-
hr: () => (isUserVariant ? <hr className="my-4 border-
|
|
1137
|
+
hr: () => (isUserVariant ? <hr className="my-4 border-border" /> : <hr />),
|
|
1497
1138
|
ul: ({ children }: { children?: React.ReactNode }) => (
|
|
1498
1139
|
<ul
|
|
1499
1140
|
className={
|
|
1500
1141
|
isUserVariant
|
|
1501
|
-
? `list-disc pl-5 mb-4 space-y-1.5 marker:text-
|
|
1142
|
+
? `list-disc pl-5 mb-4 space-y-1.5 marker:text-muted-foreground [&_ul]:mt-1.5 [&_ol]:mt-1.5 ${userTextClass}`
|
|
1502
1143
|
: 'list-disc pl-5'
|
|
1503
1144
|
}
|
|
1504
1145
|
>
|
|
@@ -1509,7 +1150,7 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1509
1150
|
<ol
|
|
1510
1151
|
className={
|
|
1511
1152
|
isUserVariant
|
|
1512
|
-
? `list-decimal pl-5 mb-4 space-y-1.5 marker:text-
|
|
1153
|
+
? `list-decimal pl-5 mb-4 space-y-1.5 marker:text-muted-foreground [&_ul]:mt-1.5 [&_ol]:mt-1.5 ${userTextClass}`
|
|
1513
1154
|
: 'list-decimal pl-5'
|
|
1514
1155
|
}
|
|
1515
1156
|
>
|
|
@@ -1540,7 +1181,7 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1540
1181
|
...props
|
|
1541
1182
|
}: React.TableHTMLAttributes<HTMLTableElement> & { children?: React.ReactNode }) =>
|
|
1542
1183
|
isUserVariant ? (
|
|
1543
|
-
<div className="overflow-x-auto my-4 w-full rounded-md border border-
|
|
1184
|
+
<div className="overflow-x-auto my-4 w-full rounded-md border border-border">
|
|
1544
1185
|
<table className="w-full text-sm" {...props}>
|
|
1545
1186
|
{children}
|
|
1546
1187
|
</table>
|
|
@@ -1551,7 +1192,7 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1551
1192
|
</div>
|
|
1552
1193
|
),
|
|
1553
1194
|
thead: ({ children }: { children?: React.ReactNode }) =>
|
|
1554
|
-
isUserVariant ? <thead className="bg-
|
|
1195
|
+
isUserVariant ? <thead className="bg-muted text-left">{children}</thead> : <thead>{children}</thead>,
|
|
1555
1196
|
th: ({ children }: { children?: React.ReactNode }) =>
|
|
1556
1197
|
isUserVariant ? (
|
|
1557
1198
|
<th className={`px-3 py-2 text-left font-semibold ${userTextClass}`}>{children}</th>
|
|
@@ -1590,7 +1231,7 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1590
1231
|
<code
|
|
1591
1232
|
className={
|
|
1592
1233
|
isUserVariant
|
|
1593
|
-
? `rounded px-1.5 py-0.5 text-sm font-mono bg-
|
|
1234
|
+
? `rounded px-1.5 py-0.5 text-sm font-mono bg-muted text-foreground break-words ${className || ''}`
|
|
1594
1235
|
: `llm-inline-code break-words ${className || ''}`
|
|
1595
1236
|
}
|
|
1596
1237
|
{...rest}
|
|
@@ -1644,9 +1285,7 @@ export const FormattedMessageContent: React.FC<{
|
|
|
1644
1285
|
// For plain text content
|
|
1645
1286
|
return variant === 'user' ? (
|
|
1646
1287
|
<p
|
|
1647
|
-
className={`${USER_MESSAGE_TEXT_SIZE_CLASS} leading-relaxed whitespace-pre-wrap break-words
|
|
1648
|
-
planMode ? 'text-primary-foreground' : 'text-gray-900'
|
|
1649
|
-
}`}
|
|
1288
|
+
className={`${USER_MESSAGE_TEXT_SIZE_CLASS} leading-relaxed whitespace-pre-wrap break-words text-foreground`}
|
|
1650
1289
|
>
|
|
1651
1290
|
{content}
|
|
1652
1291
|
</p>
|
|
@@ -1873,6 +1512,7 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1873
1512
|
const handleClick = () => {
|
|
1874
1513
|
onMessageClick?.(message);
|
|
1875
1514
|
};
|
|
1515
|
+
const [expanded, setExpanded] = useState(false);
|
|
1876
1516
|
|
|
1877
1517
|
const isAssistantRole = (message as any)?.propsConfiguration?.contents?.role === AiAgentMessageRole.Assistant;
|
|
1878
1518
|
const messageMode =
|
|
@@ -1880,6 +1520,9 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1880
1520
|
(message as any)?.propsConfiguration?.content?.mode ??
|
|
1881
1521
|
(message as any)?.props?.mode;
|
|
1882
1522
|
const isPlanMode = messageMode === 'plan';
|
|
1523
|
+
const isLongUserMessage =
|
|
1524
|
+
!isAssistantRole && ((message as any)?.message?.length ?? 0) > USER_MESSAGE_COLLAPSE_CHAR_THRESHOLD;
|
|
1525
|
+
const isCollapsed = isLongUserMessage && !expanded;
|
|
1883
1526
|
// For user messages, create a right-aligned layout with avatar and name
|
|
1884
1527
|
if (isOwnMessage) {
|
|
1885
1528
|
const authorName =
|
|
@@ -1890,10 +1533,10 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1890
1533
|
return (
|
|
1891
1534
|
<div className="py-1 px-1 sm:px-2 -mx-1 sm:-mx-2 group">
|
|
1892
1535
|
<div className="flex items-start justify-end gap-2">
|
|
1893
|
-
<div className="flex flex-col items-end max-w-[85%]">
|
|
1536
|
+
<div className="flex flex-col items-end max-w-[85%] min-w-0">
|
|
1894
1537
|
{showAuthorName && (
|
|
1895
1538
|
<div className="flex items-end space-x-2 mb-0.5">
|
|
1896
|
-
<span className="text-sm font-semibold text-
|
|
1539
|
+
<span className="text-sm font-semibold text-foreground">{authorName}</span>
|
|
1897
1540
|
</div>
|
|
1898
1541
|
)}
|
|
1899
1542
|
|
|
@@ -1901,18 +1544,21 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1901
1544
|
<div
|
|
1902
1545
|
className={`${isAssistantRole ? 'text-sm' : USER_MESSAGE_TEXT_SIZE_CLASS} ${
|
|
1903
1546
|
isAssistantRole
|
|
1904
|
-
? 'cursor-pointer rounded-2xl border border-
|
|
1905
|
-
:
|
|
1906
|
-
isPlanMode
|
|
1907
|
-
? 'user-message rounded-[22px] rounded-br-[4px] px-4 py-3 bg-primary text-primary-foreground shadow-sm'
|
|
1908
|
-
: 'user-message rounded-[22px] rounded-br-[4px] px-4 py-3 '
|
|
1547
|
+
? 'cursor-pointer rounded-2xl border border-border bg-muted text-foreground px-4 py-2.5'
|
|
1548
|
+
: 'user-message rounded-[22px] rounded-br-[4px] px-4 py-3 bg-muted text-foreground shadow-sm'
|
|
1909
1549
|
}`}
|
|
1910
1550
|
onClick={isAssistantRole ? handleClick : undefined}
|
|
1911
1551
|
dir={detectTextDirection((message as any)?.message || '')}
|
|
1912
1552
|
lang={detectLanguageTag((message as any)?.message || '')}
|
|
1913
1553
|
>
|
|
1914
1554
|
{message.message && (
|
|
1915
|
-
<div
|
|
1555
|
+
<div
|
|
1556
|
+
className={`max-w-none ${isCollapsed ? 'relative overflow-hidden' : ''}`}
|
|
1557
|
+
style={isCollapsed ? { maxHeight: USER_MESSAGE_COLLAPSED_MAX_HEIGHT } : undefined}
|
|
1558
|
+
>
|
|
1559
|
+
{isCollapsed && (
|
|
1560
|
+
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t from-muted to-transparent" />
|
|
1561
|
+
)}
|
|
1916
1562
|
{(() => {
|
|
1917
1563
|
const contentType = detectContentType(message.message);
|
|
1918
1564
|
|
|
@@ -1943,11 +1589,7 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1943
1589
|
|
|
1944
1590
|
return (
|
|
1945
1591
|
<div
|
|
1946
|
-
className=
|
|
1947
|
-
isPlanMode
|
|
1948
|
-
? '!text-primary-foreground html-content'
|
|
1949
|
-
: 'text-gray-900 html-content'
|
|
1950
|
-
}
|
|
1592
|
+
className="text-foreground html-content"
|
|
1951
1593
|
dangerouslySetInnerHTML={{
|
|
1952
1594
|
__html: prettifyHtmlContent(sanitizeHtml(message.message)),
|
|
1953
1595
|
}}
|
|
@@ -1967,6 +1609,31 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1967
1609
|
</div>
|
|
1968
1610
|
)}
|
|
1969
1611
|
|
|
1612
|
+
{isLongUserMessage && (
|
|
1613
|
+
<button
|
|
1614
|
+
type="button"
|
|
1615
|
+
onClick={(e) => {
|
|
1616
|
+
e.stopPropagation();
|
|
1617
|
+
setExpanded((v) => !v);
|
|
1618
|
+
}}
|
|
1619
|
+
className="mt-1 flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground"
|
|
1620
|
+
>
|
|
1621
|
+
{expanded ? 'Show less' : 'Show more'}
|
|
1622
|
+
<svg
|
|
1623
|
+
viewBox="0 0 24 24"
|
|
1624
|
+
fill="none"
|
|
1625
|
+
stroke="currentColor"
|
|
1626
|
+
strokeWidth={2}
|
|
1627
|
+
strokeLinecap="round"
|
|
1628
|
+
strokeLinejoin="round"
|
|
1629
|
+
className={`h-3.5 w-3.5 transition-transform ${expanded ? 'rotate-180' : ''}`}
|
|
1630
|
+
aria-hidden
|
|
1631
|
+
>
|
|
1632
|
+
<path d="M6 9l6 6 6-6" />
|
|
1633
|
+
</svg>
|
|
1634
|
+
</button>
|
|
1635
|
+
)}
|
|
1636
|
+
|
|
1970
1637
|
{tryExtractBuilderBlocks((message as any)?.message)?.length ? (
|
|
1971
1638
|
<div className="mt-2">
|
|
1972
1639
|
<BuilderLikeRenderer blocks={tryExtractBuilderBlocks((message as any)?.message)} />
|
|
@@ -1985,15 +1652,7 @@ const ModernMessageBubble: React.FC<ModernMessageBubbleProps> = ({
|
|
|
1985
1652
|
</div>
|
|
1986
1653
|
)}
|
|
1987
1654
|
{showTimestamp ? (
|
|
1988
|
-
<div
|
|
1989
|
-
className={`text-[10px] mt-1 text-right ${
|
|
1990
|
-
isAssistantRole
|
|
1991
|
-
? 'text-gray-500'
|
|
1992
|
-
: isPlanMode
|
|
1993
|
-
? 'text-primary-foreground/80'
|
|
1994
|
-
: 'text-gray-500'
|
|
1995
|
-
}`}
|
|
1996
|
-
>
|
|
1655
|
+
<div className="text-[10px] mt-1 text-right text-muted-foreground">
|
|
1997
1656
|
{formatTime(message.createdAt)}
|
|
1998
1657
|
</div>
|
|
1999
1658
|
) : null}
|