@shapesos/clay 0.4.0 → 0.5.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.
- package/dist/chat.cjs +259 -417
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.d.cts +16 -22
- package/dist/chat.d.ts +16 -22
- package/dist/chat.js +16 -6
- package/dist/chunk-72TJUKMV.js +1 -0
- package/dist/{chunk-UKM5VQKW.js → chunk-BIATJTD4.js} +5 -5
- package/dist/chunk-BIATJTD4.js.map +1 -0
- package/dist/chunk-DRBRT57F.js +1 -0
- package/dist/chunk-DRBRT57F.js.map +1 -0
- package/dist/chunk-JC2RQL5O.js +76 -0
- package/dist/chunk-JC2RQL5O.js.map +1 -0
- package/dist/{chunk-6HNZQ2BF.js → chunk-JF3P66JF.js} +2 -1
- package/dist/chunk-JF3P66JF.js.map +1 -0
- package/dist/chunk-K2Q5MQWJ.js +17 -0
- package/dist/chunk-K2Q5MQWJ.js.map +1 -0
- package/dist/chunk-MLCRDVQ2.js +89 -0
- package/dist/chunk-MLCRDVQ2.js.map +1 -0
- package/dist/chunk-OLJIJYB5.js +46 -0
- package/dist/chunk-OLJIJYB5.js.map +1 -0
- package/dist/chunk-PCBRMJJJ.js +415 -0
- package/dist/chunk-PCBRMJJJ.js.map +1 -0
- package/dist/chunk-SMTOVZ3O.js +19 -0
- package/dist/chunk-SMTOVZ3O.js.map +1 -0
- package/dist/{chunk-A6DKIFWS.js → chunk-WQ2QTUYA.js} +9 -1
- package/dist/chunk-WQ2QTUYA.js.map +1 -0
- package/dist/chunk-WZHNMC6P.js +77 -0
- package/dist/chunk-WZHNMC6P.js.map +1 -0
- package/dist/icon.cjs +38 -23
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.d.cts +6 -2
- package/dist/icon.d.ts +6 -2
- package/dist/icon.js +6 -4
- package/dist/index.cjs +417 -449
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -11
- package/dist/index.d.ts +5 -11
- package/dist/index.js +42 -34
- package/dist/index.js.map +1 -1
- package/dist/keyboard-shortcut.cjs +238 -0
- package/dist/keyboard-shortcut.cjs.map +1 -0
- package/dist/keyboard-shortcut.d.cts +19 -0
- package/dist/keyboard-shortcut.d.ts +19 -0
- package/dist/keyboard-shortcut.js +14 -0
- package/dist/keyboard-shortcut.js.map +1 -0
- package/dist/lottie.cjs +5 -5
- package/dist/lottie.cjs.map +1 -1
- package/dist/lottie.js +1 -1
- package/dist/text-area.cjs +497 -0
- package/dist/text-area.cjs.map +1 -0
- package/dist/text-area.d.cts +18 -0
- package/dist/text-area.d.ts +18 -0
- package/dist/text-area.js +11 -0
- package/dist/text-area.js.map +1 -0
- package/dist/tokens.cjs +9 -0
- package/dist/tokens.cjs.map +1 -1
- package/dist/tokens.d.cts +2 -0
- package/dist/tokens.d.ts +2 -0
- package/dist/tokens.js +2 -2
- package/dist/utils.cjs +60 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +7 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +13 -0
- package/dist/utils.js.map +1 -0
- package/package.json +17 -1
- package/dist/chunk-2GFOESHR.js +0 -613
- package/dist/chunk-2GFOESHR.js.map +0 -1
- package/dist/chunk-6HNZQ2BF.js.map +0 -1
- package/dist/chunk-7AJSQJQ5.js +0 -1
- package/dist/chunk-A6DKIFWS.js.map +0 -1
- package/dist/chunk-P7NISN4V.js +0 -115
- package/dist/chunk-P7NISN4V.js.map +0 -1
- package/dist/chunk-UKM5VQKW.js.map +0 -1
- /package/dist/{chunk-7AJSQJQ5.js.map → chunk-72TJUKMV.js.map} +0 -0
package/dist/chat.cjs
CHANGED
|
@@ -30,64 +30,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/chat/index.ts
|
|
31
31
|
var chat_exports = {};
|
|
32
32
|
__export(chat_exports, {
|
|
33
|
-
|
|
33
|
+
ChatContext: () => ChatContext,
|
|
34
|
+
ChatMessage: () => ChatMessage,
|
|
35
|
+
MESSAGE_ROLE: () => MESSAGE_ROLE,
|
|
36
|
+
useChatContext: () => useChatContext,
|
|
37
|
+
useCopyToClipboard: () => useCopyToClipboard
|
|
34
38
|
});
|
|
35
39
|
module.exports = __toCommonJS(chat_exports);
|
|
36
40
|
|
|
37
|
-
// src/chat/chat-root/chat-root.tsx
|
|
38
|
-
var import_react2 = require("react");
|
|
39
|
-
|
|
40
|
-
// src/chat/chat-context/chat-context.ts
|
|
41
|
-
var import_react = require("react");
|
|
42
|
-
var ChatContext = (0, import_react.createContext)(null);
|
|
43
|
-
function useChatContext() {
|
|
44
|
-
const context = (0, import_react.useContext)(ChatContext);
|
|
45
|
-
if (!context) {
|
|
46
|
-
throw new Error("useChatContext must be used within a Chat.Root component");
|
|
47
|
-
}
|
|
48
|
-
return context;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// src/chat/chat-root/chat-root-styles.ts
|
|
52
|
-
var import_styled_components = __toESM(require("styled-components"), 1);
|
|
53
|
-
var RootContainer = import_styled_components.default.div`
|
|
54
|
-
display: flex;
|
|
55
|
-
flex-direction: column;
|
|
56
|
-
height: 100%;
|
|
57
|
-
overflow: hidden;
|
|
58
|
-
`;
|
|
59
|
-
|
|
60
|
-
// src/chat/chat-root/chat-root.tsx
|
|
61
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
62
|
-
function ChatRoot({
|
|
63
|
-
messages,
|
|
64
|
-
onSendMessage,
|
|
65
|
-
isLoading = false,
|
|
66
|
-
onStop,
|
|
67
|
-
onCopyMessage,
|
|
68
|
-
onThumbUpClick,
|
|
69
|
-
onThumbDownClick,
|
|
70
|
-
children
|
|
71
|
-
}) {
|
|
72
|
-
const contextValue = (0, import_react2.useMemo)(
|
|
73
|
-
() => ({ messages, onSendMessage, isLoading, onStop, onCopyMessage, onThumbUpClick, onThumbDownClick }),
|
|
74
|
-
[messages, onSendMessage, isLoading, onStop, onCopyMessage, onThumbUpClick, onThumbDownClick]
|
|
75
|
-
);
|
|
76
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootContainer, { children }) });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
41
|
// src/chat/chat-message-content/chat-message-content.tsx
|
|
80
42
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
43
|
+
var import_remark_breaks = __toESM(require("remark-breaks"), 1);
|
|
81
44
|
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
82
45
|
|
|
83
46
|
// src/chat/chat-message-content/chat-message-content-styles.ts
|
|
84
|
-
var
|
|
47
|
+
var import_styled_components = __toESM(require("styled-components"), 1);
|
|
85
48
|
|
|
86
49
|
// src/tokens/colors.ts
|
|
87
50
|
var colors = {
|
|
88
51
|
// White
|
|
89
52
|
white: "#FFFFFF",
|
|
90
53
|
"white-alpha-85": "rgba(255, 255, 255, 0.85)",
|
|
54
|
+
"white-alpha-40": "rgba(255, 255, 255, 0.40)",
|
|
91
55
|
// Brown
|
|
92
56
|
"brown-10": "#FAF9F8",
|
|
93
57
|
"brown-20": "#F5F3F0",
|
|
@@ -188,6 +152,7 @@ var typographyTypes = {
|
|
|
188
152
|
GEIST_BODY_S_REGULAR: "GEIST_BODY_S_REGULAR",
|
|
189
153
|
GEIST_BODY_S_MEDIUM: "GEIST_BODY_S_MEDIUM",
|
|
190
154
|
GEIST_BODY_S_SEMI_BOLD: "GEIST_BODY_S_SEMI_BOLD",
|
|
155
|
+
GEIST_BODY_S_BOLD: "GEIST_BODY_S_BOLD",
|
|
191
156
|
// Geist Body Medium (18px)
|
|
192
157
|
GEIST_BODY_M_LIGHT: "GEIST_BODY_M_LIGHT",
|
|
193
158
|
GEIST_BODY_M_REGULAR: "GEIST_BODY_M_REGULAR",
|
|
@@ -281,6 +246,13 @@ var typographyStyles = {
|
|
|
281
246
|
lineHeight: 24,
|
|
282
247
|
letterSpacing: -0.08
|
|
283
248
|
},
|
|
249
|
+
[typographyTypes.GEIST_BODY_S_BOLD]: {
|
|
250
|
+
fontFamily: fontFamilies.GEIST,
|
|
251
|
+
fontSize: 16,
|
|
252
|
+
fontWeight: 700,
|
|
253
|
+
lineHeight: 24,
|
|
254
|
+
letterSpacing: -0.08
|
|
255
|
+
},
|
|
284
256
|
// Geist Body Medium (18px)
|
|
285
257
|
[typographyTypes.GEIST_BODY_M_LIGHT]: {
|
|
286
258
|
fontFamily: fontFamilies.GEIST,
|
|
@@ -456,88 +428,142 @@ function typographyMixin(type) {
|
|
|
456
428
|
}
|
|
457
429
|
|
|
458
430
|
// src/chat/chat-message-content/chat-message-content-styles.ts
|
|
459
|
-
var ContentWrapper =
|
|
460
|
-
${typographyMixin(typographyTypes.
|
|
431
|
+
var ContentWrapper = import_styled_components.default.div`
|
|
432
|
+
${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
|
|
461
433
|
color: ${colors["brown-100"]};
|
|
462
434
|
word-break: break-word;
|
|
463
435
|
|
|
464
|
-
&
|
|
465
|
-
|
|
436
|
+
& h1 {
|
|
437
|
+
${typographyMixin(typographyTypes.GEIST_HEADING_S_BOLD)};
|
|
438
|
+
margin-block: 20px;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
& h2 {
|
|
442
|
+
${typographyMixin(typographyTypes.GEIST_BODY_L_SEMI_BOLD)};
|
|
443
|
+
margin-block: 12px;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
& h3,
|
|
447
|
+
& h4,
|
|
448
|
+
& h5,
|
|
449
|
+
& h6 {
|
|
450
|
+
${typographyMixin(typographyTypes.GEIST_BODY_M_SEMI_BOLD)};
|
|
451
|
+
margin-block: 8px;
|
|
466
452
|
}
|
|
467
453
|
|
|
468
|
-
&
|
|
469
|
-
|
|
454
|
+
& strong {
|
|
455
|
+
${typographyMixin(typographyTypes.GEIST_BODY_S_SEMI_BOLD)};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
& p {
|
|
459
|
+
margin-block: 8px;
|
|
470
460
|
}
|
|
471
461
|
|
|
472
462
|
& ul,
|
|
473
463
|
& ol {
|
|
474
|
-
margin:
|
|
464
|
+
margin-block: 16px;
|
|
475
465
|
padding-left: 20px;
|
|
476
466
|
}
|
|
477
467
|
|
|
478
|
-
&
|
|
479
|
-
|
|
480
|
-
text-decoration: underline;
|
|
468
|
+
& li + li {
|
|
469
|
+
margin-block: 4px;
|
|
481
470
|
}
|
|
482
471
|
|
|
483
|
-
&
|
|
484
|
-
|
|
485
|
-
padding: 8px;
|
|
486
|
-
margin: 4px 0;
|
|
487
|
-
background: ${colors["brown-10"]};
|
|
488
|
-
border: 1px solid ${colors["brown-alpha-12"]};
|
|
489
|
-
border-radius: 8px;
|
|
472
|
+
& ol {
|
|
473
|
+
list-style-type: decimal;
|
|
490
474
|
}
|
|
491
475
|
|
|
492
|
-
&
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
476
|
+
& ol ol {
|
|
477
|
+
list-style-type: lower-alpha;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
& ol ol ol {
|
|
481
|
+
list-style-type: lower-roman;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
& a {
|
|
485
|
+
color: inherit;
|
|
486
|
+
text-decoration-line: underline;
|
|
487
|
+
text-decoration-style: dotted;
|
|
488
|
+
text-decoration-thickness: auto;
|
|
489
|
+
text-underline-offset: auto;
|
|
490
|
+
text-underline-position: from-font;
|
|
491
|
+
transition: color 75ms ease-in-out;
|
|
492
|
+
|
|
493
|
+
&:hover {
|
|
494
|
+
color: ${colors["blue-600"]};
|
|
495
|
+
}
|
|
496
496
|
}
|
|
497
497
|
|
|
498
|
-
&
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
& hr {
|
|
499
|
+
border: none;
|
|
500
|
+
border-top: 1px solid ${colors["brown-40"]};
|
|
501
|
+
margin-block: 20px;
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
& table {
|
|
505
|
-
|
|
506
|
-
margin: 8px 0;
|
|
505
|
+
margin: 0;
|
|
507
506
|
width: 100%;
|
|
507
|
+
border-collapse: collapse;
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
& th,
|
|
511
511
|
& td {
|
|
512
|
-
border:
|
|
513
|
-
|
|
512
|
+
border: none;
|
|
513
|
+
border-bottom: 1px solid ${colors["brown-40"]};
|
|
514
514
|
text-align: left;
|
|
515
515
|
}
|
|
516
516
|
|
|
517
517
|
& th {
|
|
518
|
-
|
|
519
|
-
|
|
518
|
+
${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};
|
|
519
|
+
padding: 8px;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
& td {
|
|
523
|
+
${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
|
|
524
|
+
padding: 16px 8px;
|
|
525
|
+
min-width: 150px;
|
|
526
|
+
width: 1%;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
& td strong {
|
|
530
|
+
font-weight: inherit;
|
|
531
|
+
font-size: inherit;
|
|
532
|
+
line-height: inherit;
|
|
520
533
|
}
|
|
521
534
|
|
|
522
535
|
& blockquote {
|
|
523
|
-
margin: 4px
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
536
|
+
margin-block: 4px;
|
|
537
|
+
margin-inline: 0px;
|
|
538
|
+
padding-left: 16px;
|
|
539
|
+
border-left: 4px solid ${colors["brown-40"]};
|
|
540
|
+
color: ${colors["brown-80"]};
|
|
527
541
|
}
|
|
528
542
|
`;
|
|
543
|
+
var TableScroll = import_styled_components.default.div`
|
|
544
|
+
width: 100%;
|
|
545
|
+
overflow-x: auto;
|
|
546
|
+
overflow-y: hidden;
|
|
547
|
+
margin-block: 8px 16px;
|
|
548
|
+
`;
|
|
529
549
|
|
|
530
550
|
// src/chat/chat-message-content/chat-message-content.tsx
|
|
531
|
-
var
|
|
551
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
552
|
+
function ScrollableTable({ node: _node, ...props }) {
|
|
553
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) });
|
|
554
|
+
}
|
|
555
|
+
var markdownComponents = {
|
|
556
|
+
table: ScrollableTable
|
|
557
|
+
};
|
|
532
558
|
function ChatMessageContent({ content }) {
|
|
533
|
-
return /* @__PURE__ */ (0,
|
|
559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: content }) });
|
|
534
560
|
}
|
|
535
561
|
|
|
536
562
|
// src/chat/chat-message-actions/chat-message-actions.tsx
|
|
537
|
-
var
|
|
563
|
+
var import_react5 = require("react");
|
|
538
564
|
|
|
539
565
|
// node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
|
|
540
|
-
var
|
|
566
|
+
var import_react = require("react");
|
|
541
567
|
|
|
542
568
|
// node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs
|
|
543
569
|
var defaultAttributes = {
|
|
@@ -564,8 +590,8 @@ var defaultAttributes = {
|
|
|
564
590
|
|
|
565
591
|
// node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
|
|
566
592
|
var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
|
|
567
|
-
const Component = (0,
|
|
568
|
-
({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0,
|
|
593
|
+
const Component = (0, import_react.forwardRef)(
|
|
594
|
+
({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0, import_react.createElement)(
|
|
569
595
|
"svg",
|
|
570
596
|
{
|
|
571
597
|
ref,
|
|
@@ -582,8 +608,8 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
|
|
|
582
608
|
...rest
|
|
583
609
|
},
|
|
584
610
|
[
|
|
585
|
-
title && (0,
|
|
586
|
-
...iconNode.map(([tag, attrs]) => (0,
|
|
611
|
+
title && (0, import_react.createElement)("title", { key: "svg-title" }, title),
|
|
612
|
+
...iconNode.map(([tag, attrs]) => (0, import_react.createElement)(tag, attrs)),
|
|
587
613
|
...Array.isArray(children) ? children : [children]
|
|
588
614
|
]
|
|
589
615
|
)
|
|
@@ -592,41 +618,30 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
|
|
|
592
618
|
return Component;
|
|
593
619
|
};
|
|
594
620
|
|
|
595
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconArrowUp.mjs
|
|
596
|
-
var __iconNode = [["path", { "d": "M12 5l0 14", "key": "svg-0" }], ["path", { "d": "M18 11l-6 -6", "key": "svg-1" }], ["path", { "d": "M6 11l6 -6", "key": "svg-2" }]];
|
|
597
|
-
var IconArrowUp = createReactComponent("outline", "arrow-up", "ArrowUp", __iconNode);
|
|
598
|
-
|
|
599
621
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
|
|
600
|
-
var
|
|
601
|
-
var IconCheck = createReactComponent("outline", "check", "Check",
|
|
622
|
+
var __iconNode = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
|
|
623
|
+
var IconCheck = createReactComponent("outline", "check", "Check", __iconNode);
|
|
602
624
|
|
|
603
625
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
|
|
604
|
-
var
|
|
605
|
-
var IconCopy = createReactComponent("outline", "copy", "Copy",
|
|
626
|
+
var __iconNode2 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
|
|
627
|
+
var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode2);
|
|
606
628
|
|
|
607
629
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconThumbDown.mjs
|
|
608
|
-
var
|
|
609
|
-
var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown",
|
|
630
|
+
var __iconNode3 = [["path", { "d": "M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3", "key": "svg-0" }]];
|
|
631
|
+
var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", __iconNode3);
|
|
610
632
|
|
|
611
633
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconThumbUp.mjs
|
|
612
|
-
var
|
|
613
|
-
var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp",
|
|
614
|
-
|
|
615
|
-
// node_modules/@tabler/icons-react/dist/esm/icons/IconPlayerStopFilled.mjs
|
|
616
|
-
var __iconNode6 = [["path", { "d": "M17 4h-10a3 3 0 0 0 -3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3 -3v-10a3 3 0 0 0 -3 -3z", "key": "svg-0" }]];
|
|
617
|
-
var IconPlayerStopFilled = createReactComponent("filled", "player-stop-filled", "PlayerStopFilled", __iconNode6);
|
|
618
|
-
|
|
619
|
-
// src/icon-button/icon-button.tsx
|
|
620
|
-
var import_react5 = require("react");
|
|
634
|
+
var __iconNode4 = [["path", { "d": "M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3", "key": "svg-0" }]];
|
|
635
|
+
var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode4);
|
|
621
636
|
|
|
622
|
-
// src/icon/icon.tsx
|
|
623
|
-
var
|
|
637
|
+
// src/components/icon/icon.tsx
|
|
638
|
+
var import_react2 = require("react");
|
|
624
639
|
|
|
625
|
-
// src/icon/icon-styles.ts
|
|
626
|
-
var
|
|
640
|
+
// src/components/icon/icon-styles.ts
|
|
641
|
+
var import_styled_components2 = __toESM(require("styled-components"), 1);
|
|
627
642
|
var STROKE_WIDTH_BY_SIZE = {
|
|
628
|
-
12: 1.
|
|
629
|
-
14: 1.
|
|
643
|
+
12: 1.4,
|
|
644
|
+
14: 1.4,
|
|
630
645
|
16: 1.8,
|
|
631
646
|
18: 1.8,
|
|
632
647
|
20: 1.8,
|
|
@@ -636,7 +651,7 @@ var DEFAULT_STROKE_WIDTH = 1.8;
|
|
|
636
651
|
function getStrokeWidth(size) {
|
|
637
652
|
return STROKE_WIDTH_BY_SIZE[size] ?? DEFAULT_STROKE_WIDTH;
|
|
638
653
|
}
|
|
639
|
-
var IconWrapper =
|
|
654
|
+
var IconWrapper = import_styled_components2.default.span`
|
|
640
655
|
display: inline-flex;
|
|
641
656
|
align-items: center;
|
|
642
657
|
justify-content: center;
|
|
@@ -644,11 +659,11 @@ var IconWrapper = import_styled_components3.default.span`
|
|
|
644
659
|
flex-shrink: 0;
|
|
645
660
|
`;
|
|
646
661
|
|
|
647
|
-
// src/icon/icon.tsx
|
|
648
|
-
var
|
|
662
|
+
// src/components/icon/icon.tsx
|
|
663
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
649
664
|
var DEFAULT_SIZE = 16;
|
|
650
|
-
var Icon = (0,
|
|
651
|
-
return /* @__PURE__ */ (0,
|
|
665
|
+
var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
|
|
666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
652
667
|
IconWrapper,
|
|
653
668
|
{
|
|
654
669
|
ref,
|
|
@@ -656,28 +671,32 @@ var Icon = (0, import_react4.forwardRef)(function Icon2({ icon: IconComponent, s
|
|
|
656
671
|
$color: color,
|
|
657
672
|
"aria-label": ariaLabel,
|
|
658
673
|
role: ariaLabel ? "img" : void 0,
|
|
659
|
-
children: /* @__PURE__ */ (0,
|
|
674
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
|
|
660
675
|
}
|
|
661
676
|
);
|
|
662
677
|
});
|
|
663
678
|
|
|
664
|
-
// src/icon-button/icon-button-styles.ts
|
|
665
|
-
var
|
|
666
|
-
var
|
|
667
|
-
|
|
668
|
-
|
|
679
|
+
// src/components/icon-button/icon-button-styles.ts
|
|
680
|
+
var import_styled_components3 = __toESM(require("styled-components"), 1);
|
|
681
|
+
var PADDING = {
|
|
682
|
+
short: {
|
|
683
|
+
small: "4px",
|
|
684
|
+
medium: "6px"
|
|
685
|
+
},
|
|
686
|
+
long: {
|
|
687
|
+
small: "4px 6px",
|
|
688
|
+
medium: "6px 10px"
|
|
689
|
+
}
|
|
669
690
|
};
|
|
670
691
|
var BORDER_RADIUS = {
|
|
671
692
|
small: 6,
|
|
672
693
|
medium: 10
|
|
673
694
|
};
|
|
674
|
-
var Button =
|
|
695
|
+
var Button = import_styled_components3.default.button`
|
|
675
696
|
display: inline-flex;
|
|
676
697
|
align-items: center;
|
|
677
698
|
justify-content: center;
|
|
678
|
-
|
|
679
|
-
height: ${({ $size }) => DIMENSIONS[$size]}px;
|
|
680
|
-
padding: 0;
|
|
699
|
+
padding: ${({ $size, $variant }) => PADDING[$variant][$size]};
|
|
681
700
|
border: none;
|
|
682
701
|
border-radius: ${({ $size }) => BORDER_RADIUS[$size]}px;
|
|
683
702
|
background: ${({ $isSelected }) => $isSelected ? colors["brown-40"] : "transparent"};
|
|
@@ -700,30 +719,54 @@ var Button = import_styled_components4.default.button`
|
|
|
700
719
|
}
|
|
701
720
|
`;
|
|
702
721
|
|
|
703
|
-
// src/icon-button/icon-button.tsx
|
|
704
|
-
var
|
|
722
|
+
// src/components/icon-button/icon-button.tsx
|
|
723
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
705
724
|
var ICON_SIZE_BY_BUTTON_SIZE = {
|
|
706
|
-
small:
|
|
707
|
-
medium:
|
|
725
|
+
small: 16,
|
|
726
|
+
medium: 20
|
|
708
727
|
};
|
|
709
|
-
|
|
710
|
-
|
|
728
|
+
function IconButton({
|
|
729
|
+
icon,
|
|
730
|
+
size = "small",
|
|
731
|
+
variant = "short",
|
|
732
|
+
isSelected = false,
|
|
733
|
+
disabled = false,
|
|
734
|
+
onClick,
|
|
735
|
+
className,
|
|
736
|
+
id,
|
|
737
|
+
as,
|
|
738
|
+
"aria-label": ariaLabel
|
|
739
|
+
}) {
|
|
740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
711
741
|
Button,
|
|
712
742
|
{
|
|
713
|
-
ref,
|
|
714
743
|
className,
|
|
744
|
+
id,
|
|
745
|
+
as,
|
|
715
746
|
$size: size,
|
|
747
|
+
$variant: variant,
|
|
716
748
|
$isSelected: isSelected,
|
|
717
749
|
disabled,
|
|
718
750
|
onClick: disabled ? void 0 : onClick,
|
|
719
751
|
"aria-label": ariaLabel,
|
|
720
|
-
children: /* @__PURE__ */ (0,
|
|
752
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
|
|
721
753
|
}
|
|
722
754
|
);
|
|
723
|
-
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// src/chat/chat-context/chat-context.ts
|
|
758
|
+
var import_react3 = require("react");
|
|
759
|
+
var ChatContext = (0, import_react3.createContext)(null);
|
|
760
|
+
function useChatContext() {
|
|
761
|
+
const context = (0, import_react3.useContext)(ChatContext);
|
|
762
|
+
if (!context) {
|
|
763
|
+
throw new Error("useChatContext must be used within a Chat.Root component");
|
|
764
|
+
}
|
|
765
|
+
return context;
|
|
766
|
+
}
|
|
724
767
|
|
|
725
768
|
// src/chat/hooks/use-copy-to-clipboard.ts
|
|
726
|
-
var
|
|
769
|
+
var import_react4 = require("react");
|
|
727
770
|
|
|
728
771
|
// src/utils/clipboard.ts
|
|
729
772
|
function copyToClipboard(text, options) {
|
|
@@ -733,18 +776,33 @@ function copyToClipboard(text, options) {
|
|
|
733
776
|
);
|
|
734
777
|
}
|
|
735
778
|
|
|
779
|
+
// src/utils/markdown-to-plain-text.ts
|
|
780
|
+
var PLACEHOLDER_PREFIX = "\u200B\u200BIC";
|
|
781
|
+
var PLACEHOLDER_SUFFIX = "\u200B\u200B";
|
|
782
|
+
var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUFFIX}`, "g");
|
|
783
|
+
function markdownToPlainText(markdown) {
|
|
784
|
+
if (!markdown) return "";
|
|
785
|
+
const inlineCodeSnippets = [];
|
|
786
|
+
let result = markdown.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
|
|
787
|
+
inlineCodeSnippets.push(code);
|
|
788
|
+
return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
|
|
789
|
+
}).replace(/^#{1,6}\s+/gm, "").replace(/^(?:---|\*\*\*|___)\s*$/gm, "").replace(/\*{3}(.+?)\*{3}/g, "$1").replace(/\*{2}(.+?)\*{2}/g, "$1").replace(/_{2}(.+?)_{2}/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/_(.+?)_/g, "$1").replace(/~~(.+?)~~/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s?/gm, "").replace(/^\|[-:\s|]+\|\s*$/gm, "").replace(/^\|\s?/gm, "").replace(/\s?\|$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
790
|
+
result = result.replace(PLACEHOLDER_REGEX, (_match, index) => inlineCodeSnippets[Number(index)]);
|
|
791
|
+
return result;
|
|
792
|
+
}
|
|
793
|
+
|
|
736
794
|
// src/chat/hooks/use-copy-to-clipboard.ts
|
|
737
795
|
var RESET_DELAY_MS = 2e3;
|
|
738
796
|
function useCopyToClipboard() {
|
|
739
|
-
const [isCopied, setIsCopied] = (0,
|
|
740
|
-
const timeoutRef = (0,
|
|
741
|
-
(0,
|
|
797
|
+
const [isCopied, setIsCopied] = (0, import_react4.useState)(false);
|
|
798
|
+
const timeoutRef = (0, import_react4.useRef)(null);
|
|
799
|
+
(0, import_react4.useEffect)(() => {
|
|
742
800
|
return () => {
|
|
743
801
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
744
802
|
};
|
|
745
803
|
}, []);
|
|
746
|
-
const copy = (0,
|
|
747
|
-
copyToClipboard(text, {
|
|
804
|
+
const copy = (0, import_react4.useCallback)((text) => {
|
|
805
|
+
copyToClipboard(markdownToPlainText(text), {
|
|
748
806
|
onSuccess: () => {
|
|
749
807
|
setIsCopied(true);
|
|
750
808
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
@@ -758,36 +816,49 @@ function useCopyToClipboard() {
|
|
|
758
816
|
return { isCopied, copy };
|
|
759
817
|
}
|
|
760
818
|
|
|
819
|
+
// src/chat/constants.ts
|
|
820
|
+
var MESSAGE_ROLE = {
|
|
821
|
+
USER: "user",
|
|
822
|
+
ASSISTANT: "assistant"
|
|
823
|
+
};
|
|
824
|
+
|
|
761
825
|
// src/chat/chat-message-actions/chat-message-actions-styles.ts
|
|
762
|
-
var
|
|
763
|
-
var
|
|
826
|
+
var import_styled_components4 = __toESM(require("styled-components"), 1);
|
|
827
|
+
var FADE_DURATION_MS = 150;
|
|
828
|
+
var ANIMATE_DURATION_MS = 200;
|
|
829
|
+
var ActionsContainer = import_styled_components4.default.div`
|
|
764
830
|
display: flex;
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
831
|
+
opacity: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? 1 : 0};
|
|
832
|
+
pointer-events: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? "auto" : "none"};
|
|
833
|
+
transition: opacity ${FADE_DURATION_MS}ms ease;
|
|
834
|
+
`;
|
|
835
|
+
var AnimatedAction = import_styled_components4.default.div`
|
|
836
|
+
display: flex;
|
|
837
|
+
overflow: hidden;
|
|
838
|
+
max-width: ${({ $visible }) => $visible ? "40px" : "0"};
|
|
839
|
+
opacity: ${({ $visible }) => $visible ? 1 : 0};
|
|
840
|
+
transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;
|
|
770
841
|
`;
|
|
771
842
|
|
|
772
843
|
// src/chat/chat-message-actions/chat-message-actions.tsx
|
|
773
|
-
var
|
|
774
|
-
function ChatMessageActions({ messageId, content, role, isHelpful }) {
|
|
844
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
845
|
+
function ChatMessageActions({ className, messageId, content, role, isHelpful }) {
|
|
775
846
|
const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
|
|
776
847
|
const { isCopied, copy } = useCopyToClipboard();
|
|
777
|
-
const handleCopy = (0,
|
|
848
|
+
const handleCopy = (0, import_react5.useCallback)(() => {
|
|
778
849
|
copy(content);
|
|
779
850
|
onCopyMessage?.(messageId);
|
|
780
851
|
}, [content, messageId, copy, onCopyMessage]);
|
|
781
|
-
const handleThumbUp = (0,
|
|
852
|
+
const handleThumbUp = (0, import_react5.useCallback)(() => {
|
|
782
853
|
onThumbUpClick?.(messageId, isHelpful === true ? null : true);
|
|
783
854
|
}, [messageId, isHelpful, onThumbUpClick]);
|
|
784
|
-
const handleThumbDown = (0,
|
|
855
|
+
const handleThumbDown = (0, import_react5.useCallback)(() => {
|
|
785
856
|
onThumbDownClick?.(messageId, isHelpful === false ? null : false);
|
|
786
857
|
}, [messageId, isHelpful, onThumbDownClick]);
|
|
787
|
-
const isAssistant = role ===
|
|
858
|
+
const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
|
|
788
859
|
const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
|
|
789
|
-
return /* @__PURE__ */ (0,
|
|
790
|
-
/* @__PURE__ */ (0,
|
|
860
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { $role: role, className, children: [
|
|
861
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
791
862
|
IconButton,
|
|
792
863
|
{
|
|
793
864
|
icon: isCopied ? IconCheck : IconCopy,
|
|
@@ -795,7 +866,7 @@ function ChatMessageActions({ messageId, content, role, isHelpful }) {
|
|
|
795
866
|
"aria-label": isCopied ? "Copied" : "Copy message"
|
|
796
867
|
}
|
|
797
868
|
),
|
|
798
|
-
hasFeedback && /* @__PURE__ */ (0,
|
|
869
|
+
hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
799
870
|
IconButton,
|
|
800
871
|
{
|
|
801
872
|
icon: IconThumbUp,
|
|
@@ -803,8 +874,8 @@ function ChatMessageActions({ messageId, content, role, isHelpful }) {
|
|
|
803
874
|
isSelected: isHelpful === true,
|
|
804
875
|
"aria-label": "Good response"
|
|
805
876
|
}
|
|
806
|
-
),
|
|
807
|
-
hasFeedback && /* @__PURE__ */ (0,
|
|
877
|
+
) }),
|
|
878
|
+
hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
808
879
|
IconButton,
|
|
809
880
|
{
|
|
810
881
|
icon: IconThumbDown,
|
|
@@ -812,41 +883,45 @@ function ChatMessageActions({ messageId, content, role, isHelpful }) {
|
|
|
812
883
|
isSelected: isHelpful === false,
|
|
813
884
|
"aria-label": "Bad response"
|
|
814
885
|
}
|
|
815
|
-
)
|
|
886
|
+
) })
|
|
816
887
|
] });
|
|
817
888
|
}
|
|
818
889
|
|
|
819
890
|
// src/chat/chat-message/chat-message-styles.ts
|
|
820
|
-
var
|
|
821
|
-
var MessageRow =
|
|
822
|
-
display: flex;
|
|
823
|
-
justify-content: ${({ $role }) => $role === "user" ? "flex-end" : "flex-start"};
|
|
824
|
-
`;
|
|
825
|
-
var MessageContainer = import_styled_components6.default.div`
|
|
891
|
+
var import_styled_components5 = __toESM(require("styled-components"), 1);
|
|
892
|
+
var MessageRow = import_styled_components5.default.div`
|
|
826
893
|
display: flex;
|
|
827
|
-
flex-
|
|
828
|
-
align-items: ${({ $role }) => $role === "user" ? "flex-end" : "flex-start"};
|
|
829
|
-
max-width: 90%;
|
|
894
|
+
justify-content: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
|
|
830
895
|
|
|
831
896
|
&:hover ${ActionsContainer} {
|
|
832
897
|
opacity: 1;
|
|
833
898
|
pointer-events: auto;
|
|
834
899
|
}
|
|
835
900
|
`;
|
|
836
|
-
var
|
|
837
|
-
|
|
901
|
+
var MessageContainer = import_styled_components5.default.div`
|
|
902
|
+
display: flex;
|
|
903
|
+
flex-direction: column;
|
|
904
|
+
align-items: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
|
|
905
|
+
max-width: 90%;
|
|
906
|
+
width: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "auto" : "100%"};
|
|
907
|
+
gap: 12px;
|
|
908
|
+
`;
|
|
909
|
+
var MessageBubble = import_styled_components5.default.div`
|
|
910
|
+
${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
|
|
838
911
|
color: ${colors["brown-100"]};
|
|
839
|
-
background: ${({ $role }) => $role ===
|
|
840
|
-
padding: ${({ $role }) => $role ===
|
|
841
|
-
border-radius: ${({ $role }) => $role ===
|
|
912
|
+
background: ${({ $role }) => $role === MESSAGE_ROLE.USER ? colors.white : "transparent"};
|
|
913
|
+
padding: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "12px 16px" : "0"};
|
|
914
|
+
border-radius: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "16px" : "0"};
|
|
915
|
+
max-width: 100%;
|
|
916
|
+
min-width: 0;
|
|
842
917
|
`;
|
|
843
918
|
|
|
844
919
|
// src/chat/chat-message/chat-message.tsx
|
|
845
|
-
var
|
|
920
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
846
921
|
function ChatMessage({ message }) {
|
|
847
|
-
return /* @__PURE__ */ (0,
|
|
848
|
-
/* @__PURE__ */ (0,
|
|
849
|
-
/* @__PURE__ */ (0,
|
|
922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageRow, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageContainer, { $role: message.role, children: [
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatMessageContent, { content: message.content }) }),
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
850
925
|
ChatMessageActions,
|
|
851
926
|
{
|
|
852
927
|
messageId: message.id,
|
|
@@ -857,255 +932,22 @@ function ChatMessage({ message }) {
|
|
|
857
932
|
)
|
|
858
933
|
] }) });
|
|
859
934
|
}
|
|
860
|
-
|
|
861
|
-
// src/chat/hooks/use-auto-scroll.ts
|
|
862
|
-
var import_react8 = require("react");
|
|
863
|
-
function useAutoScroll(messageCount) {
|
|
864
|
-
const scrollContainerRef = (0, import_react8.useRef)(null);
|
|
865
|
-
const sentinelRef = (0, import_react8.useRef)(null);
|
|
866
|
-
const [isAtBottom, setIsAtBottom] = (0, import_react8.useState)(true);
|
|
867
|
-
const prevMessageCountRef = (0, import_react8.useRef)(messageCount);
|
|
868
|
-
const hasInitializedRef = (0, import_react8.useRef)(false);
|
|
869
|
-
(0, import_react8.useLayoutEffect)(() => {
|
|
870
|
-
const el = scrollContainerRef.current;
|
|
871
|
-
if (el) {
|
|
872
|
-
el.scrollTop = el.scrollHeight;
|
|
873
|
-
}
|
|
874
|
-
}, []);
|
|
875
|
-
(0, import_react8.useEffect)(() => {
|
|
876
|
-
if (!hasInitializedRef.current) {
|
|
877
|
-
hasInitializedRef.current = true;
|
|
878
|
-
requestAnimationFrame(() => {
|
|
879
|
-
const el = scrollContainerRef.current;
|
|
880
|
-
if (el) {
|
|
881
|
-
el.scrollTop = el.scrollHeight;
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
}
|
|
885
|
-
}, []);
|
|
886
|
-
(0, import_react8.useEffect)(() => {
|
|
887
|
-
const sentinel = sentinelRef.current;
|
|
888
|
-
const scrollContainer = scrollContainerRef.current;
|
|
889
|
-
if (!sentinel || !scrollContainer) return;
|
|
890
|
-
const observer = new IntersectionObserver(
|
|
891
|
-
([entry]) => {
|
|
892
|
-
setIsAtBottom(entry.isIntersecting);
|
|
893
|
-
},
|
|
894
|
-
{ root: scrollContainer, threshold: 0 }
|
|
895
|
-
);
|
|
896
|
-
observer.observe(sentinel);
|
|
897
|
-
return () => observer.disconnect();
|
|
898
|
-
}, []);
|
|
899
|
-
(0, import_react8.useEffect)(() => {
|
|
900
|
-
if (!hasInitializedRef.current) return;
|
|
901
|
-
if (messageCount > prevMessageCountRef.current) {
|
|
902
|
-
requestAnimationFrame(() => {
|
|
903
|
-
const el = scrollContainerRef.current;
|
|
904
|
-
if (el) {
|
|
905
|
-
el.scrollTo({ top: el.scrollHeight, behavior: "smooth" });
|
|
906
|
-
}
|
|
907
|
-
});
|
|
908
|
-
}
|
|
909
|
-
prevMessageCountRef.current = messageCount;
|
|
910
|
-
}, [messageCount]);
|
|
911
|
-
const scrollToBottom = (0, import_react8.useCallback)(() => {
|
|
912
|
-
const el = scrollContainerRef.current;
|
|
913
|
-
if (el) {
|
|
914
|
-
el.scrollTo({ top: el.scrollHeight, behavior: "smooth" });
|
|
915
|
-
}
|
|
916
|
-
}, []);
|
|
917
|
-
return { scrollContainerRef, sentinelRef, isAtBottom, scrollToBottom };
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
// src/chat/chat-message-list/chat-message-list-styles.ts
|
|
921
|
-
var import_styled_components7 = __toESM(require("styled-components"), 1);
|
|
922
|
-
var ListContainer = import_styled_components7.default.div`
|
|
923
|
-
display: flex;
|
|
924
|
-
flex-direction: column;
|
|
925
|
-
flex: 1;
|
|
926
|
-
overflow-y: auto;
|
|
927
|
-
|
|
928
|
-
&::-webkit-scrollbar {
|
|
929
|
-
width: 6px;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
&::-webkit-scrollbar-track {
|
|
933
|
-
background: transparent;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
&::-webkit-scrollbar-thumb {
|
|
937
|
-
background: ${colors["brown-30"]};
|
|
938
|
-
border-radius: 3px;
|
|
939
|
-
}
|
|
940
|
-
`;
|
|
941
|
-
var MessagesList = import_styled_components7.default.div`
|
|
942
|
-
display: flex;
|
|
943
|
-
flex-direction: column;
|
|
944
|
-
gap: 40px;
|
|
945
|
-
padding: 0 16px 32px 16px;
|
|
946
|
-
`;
|
|
947
|
-
var ScrollSentinel = import_styled_components7.default.div`
|
|
948
|
-
flex-shrink: 0;
|
|
949
|
-
height: 16px;
|
|
950
|
-
`;
|
|
951
|
-
|
|
952
|
-
// src/chat/chat-message-list/chat-message-list.tsx
|
|
953
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
954
|
-
function ChatMessageList() {
|
|
955
|
-
const { messages } = useChatContext();
|
|
956
|
-
const { scrollContainerRef, sentinelRef } = useAutoScroll(messages.length);
|
|
957
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ListContainer, { ref: scrollContainerRef, "data-testid": "chat-list-container", children: [
|
|
958
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessagesList, { children: messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChatMessage, { message }, message.id)) }),
|
|
959
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScrollSentinel, { ref: sentinelRef, "data-testid": "chat-scroll-sentinel" })
|
|
960
|
-
] });
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
// src/chat/chat-composer/chat-composer.tsx
|
|
964
|
-
var import_react9 = require("react");
|
|
965
|
-
|
|
966
|
-
// src/chat/chat-composer/chat-composer-styles.ts
|
|
967
|
-
var import_styled_components8 = __toESM(require("styled-components"), 1);
|
|
968
|
-
var ComposerContainer = import_styled_components8.default.div`
|
|
969
|
-
position: relative;
|
|
970
|
-
background: ${colors.white};
|
|
971
|
-
border-radius: 12px;
|
|
972
|
-
box-shadow: 0 0 4px 0 ${colors["brown-alpha-12"]};
|
|
973
|
-
padding: 8px 0;
|
|
974
|
-
`;
|
|
975
|
-
var TextArea = import_styled_components8.default.textarea`
|
|
976
|
-
display: block;
|
|
977
|
-
width: 100%;
|
|
978
|
-
resize: none;
|
|
979
|
-
border: none;
|
|
980
|
-
background: transparent;
|
|
981
|
-
${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
|
|
982
|
-
color: ${colors["brown-90"]};
|
|
983
|
-
padding: 4px 46px 4px 16px;
|
|
984
|
-
min-height: 20px;
|
|
985
|
-
max-height: 200px;
|
|
986
|
-
overflow-y: auto;
|
|
987
|
-
box-sizing: border-box;
|
|
988
|
-
|
|
989
|
-
&::placeholder {
|
|
990
|
-
color: ${colors["brown-60"]};
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
&:focus {
|
|
994
|
-
outline: none;
|
|
995
|
-
}
|
|
996
|
-
`;
|
|
997
|
-
var SendButton = import_styled_components8.default.button`
|
|
998
|
-
position: absolute;
|
|
999
|
-
bottom: 8px;
|
|
1000
|
-
right: 8px;
|
|
1001
|
-
width: 30px;
|
|
1002
|
-
height: 30px;
|
|
1003
|
-
border: none;
|
|
1004
|
-
border-radius: 12px;
|
|
1005
|
-
cursor: pointer;
|
|
1006
|
-
display: flex;
|
|
1007
|
-
align-items: center;
|
|
1008
|
-
justify-content: center;
|
|
1009
|
-
background: ${colors["brown-100"]};
|
|
1010
|
-
color: ${colors.white};
|
|
1011
|
-
transition: background-color 75ms;
|
|
1012
|
-
padding: 0;
|
|
1013
|
-
|
|
1014
|
-
&:disabled {
|
|
1015
|
-
background: ${colors["brown-50"]};
|
|
1016
|
-
cursor: default;
|
|
1017
|
-
}
|
|
1018
|
-
`;
|
|
1019
|
-
|
|
1020
|
-
// src/chat/chat-composer/chat-composer.tsx
|
|
1021
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1022
|
-
function ChatComposer({ placeholder = "Type a message..." }) {
|
|
1023
|
-
const { onSendMessage, isLoading, onStop } = useChatContext();
|
|
1024
|
-
const [value, setValue] = (0, import_react9.useState)("");
|
|
1025
|
-
const textAreaRef = (0, import_react9.useRef)(null);
|
|
1026
|
-
const isEmpty = value.trim().length === 0;
|
|
1027
|
-
const resizeTextArea = (0, import_react9.useCallback)(() => {
|
|
1028
|
-
const el = textAreaRef.current;
|
|
1029
|
-
if (!el) return;
|
|
1030
|
-
el.style.height = "auto";
|
|
1031
|
-
el.style.height = `${el.scrollHeight}px`;
|
|
1032
|
-
}, []);
|
|
1033
|
-
(0, import_react9.useEffect)(() => {
|
|
1034
|
-
resizeTextArea();
|
|
1035
|
-
}, [value, resizeTextArea]);
|
|
1036
|
-
(0, import_react9.useEffect)(() => {
|
|
1037
|
-
textAreaRef.current?.focus();
|
|
1038
|
-
}, []);
|
|
1039
|
-
const handleSend = (0, import_react9.useCallback)(() => {
|
|
1040
|
-
const trimmed = value.trim();
|
|
1041
|
-
if (!trimmed) return;
|
|
1042
|
-
onSendMessage(trimmed);
|
|
1043
|
-
setValue("");
|
|
1044
|
-
requestAnimationFrame(() => textAreaRef.current?.focus());
|
|
1045
|
-
}, [value, onSendMessage]);
|
|
1046
|
-
const handleKeyDown = (0, import_react9.useCallback)(
|
|
1047
|
-
(e) => {
|
|
1048
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
1049
|
-
e.preventDefault();
|
|
1050
|
-
handleSend();
|
|
1051
|
-
}
|
|
1052
|
-
},
|
|
1053
|
-
[handleSend]
|
|
1054
|
-
);
|
|
1055
|
-
const handleChange = (0, import_react9.useCallback)((e) => {
|
|
1056
|
-
setValue(e.target.value);
|
|
1057
|
-
}, []);
|
|
1058
|
-
const handleButtonClick = (0, import_react9.useCallback)(() => {
|
|
1059
|
-
if (isLoading && onStop) {
|
|
1060
|
-
onStop();
|
|
1061
|
-
} else {
|
|
1062
|
-
handleSend();
|
|
1063
|
-
}
|
|
1064
|
-
}, [isLoading, onStop, handleSend]);
|
|
1065
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComposerContainer, { children: [
|
|
1066
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1067
|
-
TextArea,
|
|
1068
|
-
{
|
|
1069
|
-
ref: textAreaRef,
|
|
1070
|
-
value,
|
|
1071
|
-
onChange: handleChange,
|
|
1072
|
-
onKeyDown: handleKeyDown,
|
|
1073
|
-
placeholder,
|
|
1074
|
-
rows: 1
|
|
1075
|
-
}
|
|
1076
|
-
),
|
|
1077
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1078
|
-
SendButton,
|
|
1079
|
-
{
|
|
1080
|
-
onClick: handleButtonClick,
|
|
1081
|
-
disabled: !isLoading && isEmpty,
|
|
1082
|
-
"aria-label": isLoading ? "Stop generating" : "Send message",
|
|
1083
|
-
children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { icon: IconPlayerStopFilled, size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { icon: IconArrowUp, size: 16 })
|
|
1084
|
-
}
|
|
1085
|
-
)
|
|
1086
|
-
] });
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
// src/chat/chat-namespace.ts
|
|
1090
|
-
var Chat = {
|
|
1091
|
-
Root: ChatRoot,
|
|
1092
|
-
MessageList: ChatMessageList,
|
|
1093
|
-
Composer: ChatComposer
|
|
1094
|
-
};
|
|
1095
935
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1096
936
|
0 && (module.exports = {
|
|
1097
|
-
|
|
937
|
+
ChatContext,
|
|
938
|
+
ChatMessage,
|
|
939
|
+
MESSAGE_ROLE,
|
|
940
|
+
useChatContext,
|
|
941
|
+
useCopyToClipboard
|
|
1098
942
|
});
|
|
1099
943
|
/*! Bundled license information:
|
|
1100
944
|
|
|
1101
945
|
@tabler/icons-react/dist/esm/defaultAttributes.mjs:
|
|
1102
946
|
@tabler/icons-react/dist/esm/createReactComponent.mjs:
|
|
1103
|
-
@tabler/icons-react/dist/esm/icons/IconArrowUp.mjs:
|
|
1104
947
|
@tabler/icons-react/dist/esm/icons/IconCheck.mjs:
|
|
1105
948
|
@tabler/icons-react/dist/esm/icons/IconCopy.mjs:
|
|
1106
949
|
@tabler/icons-react/dist/esm/icons/IconThumbDown.mjs:
|
|
1107
950
|
@tabler/icons-react/dist/esm/icons/IconThumbUp.mjs:
|
|
1108
|
-
@tabler/icons-react/dist/esm/icons/IconPlayerStopFilled.mjs:
|
|
1109
951
|
@tabler/icons-react/dist/esm/tabler-icons-react.mjs:
|
|
1110
952
|
(**
|
|
1111
953
|
* @license @tabler/icons-react v3.37.1 - MIT
|