@shapesos/clay 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/dist/chat.cjs +1117 -0
  4. package/dist/chat.cjs.map +1 -0
  5. package/dist/chat.d.cts +46 -0
  6. package/dist/chat.d.ts +46 -0
  7. package/dist/chat.js +11 -0
  8. package/dist/chat.js.map +1 -0
  9. package/dist/chunk-2GFOESHR.js +613 -0
  10. package/dist/chunk-2GFOESHR.js.map +1 -0
  11. package/dist/chunk-5WRI5ZAA.js +31 -0
  12. package/dist/chunk-5WRI5ZAA.js.map +1 -0
  13. package/dist/chunk-6HNZQ2BF.js +91 -0
  14. package/dist/chunk-6HNZQ2BF.js.map +1 -0
  15. package/dist/chunk-7AJSQJQ5.js +1 -0
  16. package/dist/chunk-7AJSQJQ5.js.map +1 -0
  17. package/dist/chunk-A6DKIFWS.js +292 -0
  18. package/dist/chunk-A6DKIFWS.js.map +1 -0
  19. package/dist/chunk-C77QMQNT.js +1 -0
  20. package/dist/chunk-C77QMQNT.js.map +1 -0
  21. package/dist/chunk-P7NISN4V.js +115 -0
  22. package/dist/chunk-P7NISN4V.js.map +1 -0
  23. package/dist/chunk-XY2OM47L.js +16511 -0
  24. package/dist/chunk-XY2OM47L.js.map +1 -0
  25. package/dist/icon.cjs +237 -0
  26. package/dist/icon.cjs.map +1 -0
  27. package/dist/icon.d.cts +27 -0
  28. package/dist/icon.d.ts +27 -0
  29. package/dist/icon.js +12 -0
  30. package/dist/icon.js.map +1 -0
  31. package/dist/index.cjs +17634 -0
  32. package/dist/index.cjs.map +1 -0
  33. package/dist/index.d.cts +7 -0
  34. package/dist/index.d.ts +7 -0
  35. package/dist/index.js +34 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/lottie.cjs +16545 -0
  38. package/dist/lottie.cjs.map +1 -0
  39. package/dist/lottie.d.cts +38 -0
  40. package/dist/lottie.d.ts +38 -0
  41. package/dist/lottie.js +8 -0
  42. package/dist/lottie.js.map +1 -0
  43. package/dist/tokens.cjs +410 -0
  44. package/dist/tokens.cjs.map +1 -0
  45. package/dist/tokens.d.cts +121 -0
  46. package/dist/tokens.d.ts +121 -0
  47. package/dist/tokens.js +19 -0
  48. package/dist/tokens.js.map +1 -0
  49. package/package.json +110 -0
package/dist/chat.cjs ADDED
@@ -0,0 +1,1117 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/chat/index.ts
31
+ var chat_exports = {};
32
+ __export(chat_exports, {
33
+ Chat: () => Chat
34
+ });
35
+ module.exports = __toCommonJS(chat_exports);
36
+
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
+ // src/chat/chat-message-content/chat-message-content.tsx
80
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
81
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
82
+
83
+ // src/chat/chat-message-content/chat-message-content-styles.ts
84
+ var import_styled_components2 = __toESM(require("styled-components"), 1);
85
+
86
+ // src/tokens/colors.ts
87
+ var colors = {
88
+ // White
89
+ white: "#FFFFFF",
90
+ "white-alpha-85": "rgba(255, 255, 255, 0.85)",
91
+ // Brown
92
+ "brown-10": "#FAF9F8",
93
+ "brown-20": "#F5F3F0",
94
+ "brown-30": "#EEEBE5",
95
+ "brown-40": "#E6E2DA",
96
+ "brown-50": "#CFCBC4",
97
+ "brown-60": "#A19E99",
98
+ "brown-70": "#73716D",
99
+ "brown-80": "#5C5A57",
100
+ "brown-90": "#2E2D2C",
101
+ "brown-100": "#171716",
102
+ "brown-alpha-12": "rgba(23, 23, 22, 0.12)",
103
+ "brown-alpha-20": "rgba(23, 23, 22, 0.20)",
104
+ "brown-alpha-55": "rgba(23, 23, 22, 0.55)",
105
+ "brown-alpha-70": "rgba(23, 23, 22, 0.70)",
106
+ "brown-alpha-80": "rgba(23, 23, 22, 0.80)",
107
+ "brown-alpha-90": "rgba(23, 23, 22, 0.90)",
108
+ // Fuchsia
109
+ "fuchsia-50": "#FAF5FF",
110
+ "fuchsia-300": "#F0ABFC",
111
+ "fuchsia-500": "#D946EF",
112
+ "fuchsia-600": "#C026D3",
113
+ "fuchsia-800": "#86198F",
114
+ // Pink
115
+ "pink-50": "#FDF2F8",
116
+ "pink-400": "#F472B6",
117
+ "pink-600": "#DB2777",
118
+ "pink-800": "#9D174D",
119
+ // Violet
120
+ "violet-50": "#F5F3FF",
121
+ "violet-400": "#A78BFA",
122
+ "violet-600": "#7C3AED",
123
+ "violet-800": "#5B21B6",
124
+ // Indigo
125
+ "indigo-50": "#EEF2FF",
126
+ "indigo-400": "#818CF8",
127
+ "indigo-500": "#6366F1",
128
+ "indigo-600": "#4F46E5",
129
+ "indigo-800": "#3730A3",
130
+ // Cyan
131
+ "cyan-50": "#E7FEFF",
132
+ "cyan-300": "#67E8F9",
133
+ "cyan-600": "#0891B2",
134
+ "cyan-900": "#164E63",
135
+ // Teal
136
+ "teal-50": "#EBFDF9",
137
+ "teal-300": "#5EEAD4",
138
+ "teal-600": "#0D9488",
139
+ // Rose
140
+ "rose-400": "#FB7185",
141
+ // Purple
142
+ "purple-400": "#C084FC",
143
+ // Blue
144
+ "blue-50": "#EFF6FF",
145
+ "blue-100": "#DBEAFE",
146
+ "blue-300": "#93C5FD",
147
+ "blue-400": "#60A5FA",
148
+ "blue-600": "#2563EB",
149
+ "blue-800": "#1E40AF",
150
+ // Sky
151
+ "sky-300": "#7DD3FC",
152
+ // Green
153
+ "green-50": "#ECF9F0",
154
+ "green-100": "#D4F1D9",
155
+ "green-400": "#3DC269",
156
+ "green-700": "#277C43",
157
+ "green-800": "#1C5930",
158
+ // Orange
159
+ "orange-50": "#FFF7ED",
160
+ "orange-100": "#FFEDD5",
161
+ "orange-200": "#FED7AA",
162
+ "orange-500": "#F97316",
163
+ "orange-600": "#EA580C",
164
+ // Red
165
+ "red-50": "#FEF2F2",
166
+ "red-100": "#FEE2E2",
167
+ "red-200": "#FECACA",
168
+ "red-400": "#F7776C",
169
+ "red-500": "#EF4444",
170
+ "red-600": "#DC2626"
171
+ };
172
+
173
+ // src/tokens/typography.ts
174
+ var fontFamilies = {
175
+ GEIST: "Geist",
176
+ CRIMSON_PRO: "Crimson Pro"
177
+ };
178
+ var typographyTypes = {
179
+ // Geist Label Caption (12px)
180
+ GEIST_LABEL_CAPTION_REGULAR: "GEIST_LABEL_CAPTION_REGULAR",
181
+ GEIST_LABEL_CAPTION_MEDIUM: "GEIST_LABEL_CAPTION_MEDIUM",
182
+ GEIST_LABEL_CAPTION_SEMI_BOLD: "GEIST_LABEL_CAPTION_SEMI_BOLD",
183
+ // Geist Body Extra Small (14px)
184
+ GEIST_BODY_XS_REGULAR: "GEIST_BODY_XS_REGULAR",
185
+ GEIST_BODY_XS_MEDIUM: "GEIST_BODY_XS_MEDIUM",
186
+ GEIST_BODY_XS_BOLD: "GEIST_BODY_XS_BOLD",
187
+ // Geist Body Small (16px)
188
+ GEIST_BODY_S_REGULAR: "GEIST_BODY_S_REGULAR",
189
+ GEIST_BODY_S_MEDIUM: "GEIST_BODY_S_MEDIUM",
190
+ GEIST_BODY_S_SEMI_BOLD: "GEIST_BODY_S_SEMI_BOLD",
191
+ // Geist Body Medium (18px)
192
+ GEIST_BODY_M_LIGHT: "GEIST_BODY_M_LIGHT",
193
+ GEIST_BODY_M_REGULAR: "GEIST_BODY_M_REGULAR",
194
+ GEIST_BODY_M_MEDIUM: "GEIST_BODY_M_MEDIUM",
195
+ GEIST_BODY_M_SEMI_BOLD: "GEIST_BODY_M_SEMI_BOLD",
196
+ // Geist Body Large (20px)
197
+ GEIST_BODY_L_REGULAR: "GEIST_BODY_L_REGULAR",
198
+ GEIST_BODY_L_MEDIUM: "GEIST_BODY_L_MEDIUM",
199
+ GEIST_BODY_L_SEMI_BOLD: "GEIST_BODY_L_SEMI_BOLD",
200
+ GEIST_BODY_L_BOLD: "GEIST_BODY_L_BOLD",
201
+ // Geist Heading Small (24px)
202
+ GEIST_HEADING_S_REGULAR: "GEIST_HEADING_S_REGULAR",
203
+ GEIST_HEADING_S_MEDIUM: "GEIST_HEADING_S_MEDIUM",
204
+ GEIST_HEADING_S_BOLD: "GEIST_HEADING_S_BOLD",
205
+ // Geist Heading Medium (28px)
206
+ GEIST_HEADING_M_BOLD: "GEIST_HEADING_M_BOLD",
207
+ // Geist Heading Large (32px)
208
+ GEIST_HEADING_L_REGULAR: "GEIST_HEADING_L_REGULAR",
209
+ GEIST_HEADING_L_MEDIUM: "GEIST_HEADING_L_MEDIUM",
210
+ GEIST_HEADING_L_SEMI_BOLD: "GEIST_HEADING_L_SEMI_BOLD",
211
+ GEIST_HEADING_L_BOLD: "GEIST_HEADING_L_BOLD",
212
+ // Geist Display Large (36px)
213
+ GEIST_DISPLAY_L_MEDIUM: "GEIST_DISPLAY_L_MEDIUM",
214
+ // Crimson Pro Body Small (16px)
215
+ CRIMSON_PRO_BODY_S_LIGHT: "CRIMSON_PRO_BODY_S_LIGHT",
216
+ // Crimson Pro Body Medium (18px)
217
+ CRIMSON_PRO_BODY_M_LIGHT: "CRIMSON_PRO_BODY_M_LIGHT",
218
+ // Crimson Pro Heading Medium (24px)
219
+ CRIMSON_PRO_HEADING_M_MEDIUM: "CRIMSON_PRO_HEADING_M_MEDIUM",
220
+ // Crimson Pro Display Extra Large (46px)
221
+ CRIMSON_PRO_DISPLAY_XL_REGULAR: "CRIMSON_PRO_DISPLAY_XL_REGULAR"
222
+ };
223
+ var typographyStyles = {
224
+ // Geist Label Caption (12px)
225
+ [typographyTypes.GEIST_LABEL_CAPTION_REGULAR]: {
226
+ fontFamily: fontFamilies.GEIST,
227
+ fontSize: 12,
228
+ fontWeight: 400,
229
+ lineHeight: 16
230
+ },
231
+ [typographyTypes.GEIST_LABEL_CAPTION_MEDIUM]: {
232
+ fontFamily: fontFamilies.GEIST,
233
+ fontSize: 12,
234
+ fontWeight: 500,
235
+ lineHeight: 16
236
+ },
237
+ [typographyTypes.GEIST_LABEL_CAPTION_SEMI_BOLD]: {
238
+ fontFamily: fontFamilies.GEIST,
239
+ fontSize: 12,
240
+ fontWeight: 600,
241
+ lineHeight: 16
242
+ },
243
+ // Geist Body Extra Small (14px)
244
+ [typographyTypes.GEIST_BODY_XS_REGULAR]: {
245
+ fontFamily: fontFamilies.GEIST,
246
+ fontSize: 14,
247
+ fontWeight: 400,
248
+ lineHeight: 20
249
+ },
250
+ [typographyTypes.GEIST_BODY_XS_MEDIUM]: {
251
+ fontFamily: fontFamilies.GEIST,
252
+ fontSize: 14,
253
+ fontWeight: 500,
254
+ lineHeight: 20
255
+ },
256
+ [typographyTypes.GEIST_BODY_XS_BOLD]: {
257
+ fontFamily: fontFamilies.GEIST,
258
+ fontSize: 14,
259
+ fontWeight: 600,
260
+ lineHeight: 20
261
+ },
262
+ // Geist Body Small (16px)
263
+ [typographyTypes.GEIST_BODY_S_REGULAR]: {
264
+ fontFamily: fontFamilies.GEIST,
265
+ fontSize: 16,
266
+ fontWeight: 400,
267
+ lineHeight: 24,
268
+ letterSpacing: -0.08
269
+ },
270
+ [typographyTypes.GEIST_BODY_S_MEDIUM]: {
271
+ fontFamily: fontFamilies.GEIST,
272
+ fontSize: 16,
273
+ fontWeight: 500,
274
+ lineHeight: 24,
275
+ letterSpacing: -0.08
276
+ },
277
+ [typographyTypes.GEIST_BODY_S_SEMI_BOLD]: {
278
+ fontFamily: fontFamilies.GEIST,
279
+ fontSize: 16,
280
+ fontWeight: 600,
281
+ lineHeight: 24,
282
+ letterSpacing: -0.08
283
+ },
284
+ // Geist Body Medium (18px)
285
+ [typographyTypes.GEIST_BODY_M_LIGHT]: {
286
+ fontFamily: fontFamilies.GEIST,
287
+ fontSize: 18,
288
+ fontWeight: 300,
289
+ lineHeight: 28,
290
+ letterSpacing: -0.09
291
+ },
292
+ [typographyTypes.GEIST_BODY_M_REGULAR]: {
293
+ fontFamily: fontFamilies.GEIST,
294
+ fontSize: 18,
295
+ fontWeight: 400,
296
+ lineHeight: 28,
297
+ letterSpacing: -0.09
298
+ },
299
+ [typographyTypes.GEIST_BODY_M_MEDIUM]: {
300
+ fontFamily: fontFamilies.GEIST,
301
+ fontSize: 18,
302
+ fontWeight: 500,
303
+ lineHeight: 28,
304
+ letterSpacing: -0.09
305
+ },
306
+ [typographyTypes.GEIST_BODY_M_SEMI_BOLD]: {
307
+ fontFamily: fontFamilies.GEIST,
308
+ fontSize: 18,
309
+ fontWeight: 600,
310
+ lineHeight: 28,
311
+ letterSpacing: -0.09
312
+ },
313
+ // Geist Body Large (20px)
314
+ [typographyTypes.GEIST_BODY_L_REGULAR]: {
315
+ fontFamily: fontFamilies.GEIST,
316
+ fontSize: 20,
317
+ fontWeight: 400,
318
+ lineHeight: 30,
319
+ letterSpacing: -0.2
320
+ },
321
+ [typographyTypes.GEIST_BODY_L_MEDIUM]: {
322
+ fontFamily: fontFamilies.GEIST,
323
+ fontSize: 20,
324
+ fontWeight: 500,
325
+ lineHeight: 30,
326
+ letterSpacing: -0.2
327
+ },
328
+ [typographyTypes.GEIST_BODY_L_SEMI_BOLD]: {
329
+ fontFamily: fontFamilies.GEIST,
330
+ fontSize: 20,
331
+ fontWeight: 600,
332
+ lineHeight: 30,
333
+ letterSpacing: -0.2
334
+ },
335
+ [typographyTypes.GEIST_BODY_L_BOLD]: {
336
+ fontFamily: fontFamilies.GEIST,
337
+ fontSize: 20,
338
+ fontWeight: 700,
339
+ lineHeight: 30,
340
+ letterSpacing: -0.2
341
+ },
342
+ // Geist Heading Small (24px)
343
+ [typographyTypes.GEIST_HEADING_S_REGULAR]: {
344
+ fontFamily: fontFamilies.GEIST,
345
+ fontSize: 24,
346
+ fontWeight: 400,
347
+ lineHeight: 32,
348
+ letterSpacing: -0.48
349
+ },
350
+ [typographyTypes.GEIST_HEADING_S_MEDIUM]: {
351
+ fontFamily: fontFamilies.GEIST,
352
+ fontSize: 24,
353
+ fontWeight: 500,
354
+ lineHeight: 32,
355
+ letterSpacing: -0.48
356
+ },
357
+ [typographyTypes.GEIST_HEADING_S_BOLD]: {
358
+ fontFamily: fontFamilies.GEIST,
359
+ fontSize: 24,
360
+ fontWeight: 700,
361
+ lineHeight: 32,
362
+ letterSpacing: -0.48
363
+ },
364
+ // Geist Heading Medium (28px)
365
+ [typographyTypes.GEIST_HEADING_M_BOLD]: {
366
+ fontFamily: fontFamilies.GEIST,
367
+ fontSize: 28,
368
+ fontWeight: 700,
369
+ lineHeight: 36,
370
+ letterSpacing: -0.6
371
+ },
372
+ // Geist Heading Large (32px)
373
+ [typographyTypes.GEIST_HEADING_L_REGULAR]: {
374
+ fontFamily: fontFamilies.GEIST,
375
+ fontSize: 32,
376
+ fontWeight: 400,
377
+ lineHeight: 40,
378
+ letterSpacing: -0.64
379
+ },
380
+ [typographyTypes.GEIST_HEADING_L_MEDIUM]: {
381
+ fontFamily: fontFamilies.GEIST,
382
+ fontSize: 32,
383
+ fontWeight: 500,
384
+ lineHeight: 40,
385
+ letterSpacing: -0.64
386
+ },
387
+ [typographyTypes.GEIST_HEADING_L_SEMI_BOLD]: {
388
+ fontFamily: fontFamilies.GEIST,
389
+ fontSize: 32,
390
+ fontWeight: 600,
391
+ lineHeight: 40,
392
+ letterSpacing: -0.64
393
+ },
394
+ [typographyTypes.GEIST_HEADING_L_BOLD]: {
395
+ fontFamily: fontFamilies.GEIST,
396
+ fontSize: 32,
397
+ fontWeight: 700,
398
+ lineHeight: 40,
399
+ letterSpacing: -0.64
400
+ },
401
+ // Geist Display Large (36px)
402
+ [typographyTypes.GEIST_DISPLAY_L_MEDIUM]: {
403
+ fontFamily: fontFamilies.GEIST,
404
+ fontSize: 36,
405
+ fontWeight: 500,
406
+ lineHeight: 44,
407
+ letterSpacing: -0.72
408
+ },
409
+ // Crimson Pro Body Small (16px)
410
+ [typographyTypes.CRIMSON_PRO_BODY_S_LIGHT]: {
411
+ fontFamily: fontFamilies.CRIMSON_PRO,
412
+ fontSize: 16,
413
+ fontWeight: 300,
414
+ lineHeight: 20,
415
+ letterSpacing: -0.32,
416
+ fontStyle: "italic"
417
+ },
418
+ // Crimson Pro Body Medium (18px)
419
+ [typographyTypes.CRIMSON_PRO_BODY_M_LIGHT]: {
420
+ fontFamily: fontFamilies.CRIMSON_PRO,
421
+ fontSize: 18,
422
+ fontWeight: 300,
423
+ lineHeight: 28,
424
+ letterSpacing: 0,
425
+ fontStyle: "italic"
426
+ },
427
+ // Crimson Pro Heading Medium (24px)
428
+ [typographyTypes.CRIMSON_PRO_HEADING_M_MEDIUM]: {
429
+ fontFamily: fontFamilies.CRIMSON_PRO,
430
+ fontSize: 24,
431
+ fontWeight: 400,
432
+ lineHeight: 32,
433
+ letterSpacing: -0.48,
434
+ fontStyle: "italic"
435
+ },
436
+ // Crimson Pro Display Extra Large (46px)
437
+ [typographyTypes.CRIMSON_PRO_DISPLAY_XL_REGULAR]: {
438
+ fontFamily: fontFamilies.CRIMSON_PRO,
439
+ fontSize: 46,
440
+ fontWeight: 400,
441
+ lineHeight: 54,
442
+ letterSpacing: -1.38,
443
+ fontStyle: "italic"
444
+ }
445
+ };
446
+ function typographyMixin(type) {
447
+ const style = typographyStyles[type];
448
+ return [
449
+ `font-family: "${style.fontFamily}", sans-serif`,
450
+ `font-size: ${style.fontSize}px`,
451
+ `font-weight: ${style.fontWeight}`,
452
+ `line-height: ${style.lineHeight}px`,
453
+ `letter-spacing: ${style.letterSpacing != null ? `${style.letterSpacing}px` : "inherit"}`,
454
+ `font-style: ${style.fontStyle ?? "normal"}`
455
+ ].join(";\n ");
456
+ }
457
+
458
+ // src/chat/chat-message-content/chat-message-content-styles.ts
459
+ var ContentWrapper = import_styled_components2.default.div`
460
+ ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
461
+ color: ${colors["brown-100"]};
462
+ word-break: break-word;
463
+
464
+ & p {
465
+ margin: 0;
466
+ }
467
+
468
+ & p + p {
469
+ margin-top: 8px;
470
+ }
471
+
472
+ & ul,
473
+ & ol {
474
+ margin: 4px 0;
475
+ padding-left: 20px;
476
+ }
477
+
478
+ & a {
479
+ color: ${colors["brown-100"]};
480
+ text-decoration: underline;
481
+ }
482
+
483
+ & pre {
484
+ overflow-x: auto;
485
+ padding: 8px;
486
+ margin: 4px 0;
487
+ background: ${colors["brown-10"]};
488
+ border: 1px solid ${colors["brown-alpha-12"]};
489
+ border-radius: 8px;
490
+ }
491
+
492
+ & pre code {
493
+ padding: 0;
494
+ background: none;
495
+ border-radius: 0;
496
+ }
497
+
498
+ & code {
499
+ padding: 2px 4px;
500
+ background: ${colors["brown-10"]};
501
+ border-radius: 4px;
502
+ }
503
+
504
+ & table {
505
+ border-collapse: collapse;
506
+ margin: 8px 0;
507
+ width: 100%;
508
+ }
509
+
510
+ & th,
511
+ & td {
512
+ border: 1px solid ${colors["brown-alpha-12"]};
513
+ padding: 6px 12px;
514
+ text-align: left;
515
+ }
516
+
517
+ & th {
518
+ background: ${colors["brown-10"]};
519
+ font-weight: 600;
520
+ }
521
+
522
+ & blockquote {
523
+ margin: 4px 0;
524
+ padding-left: 12px;
525
+ border-left: 3px solid ${colors["brown-30"]};
526
+ color: ${colors["brown-70"]};
527
+ }
528
+ `;
529
+
530
+ // src/chat/chat-message-content/chat-message-content.tsx
531
+ var import_jsx_runtime2 = require("react/jsx-runtime");
532
+ function ChatMessageContent({ content }) {
533
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ContentWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], children: content }) });
534
+ }
535
+
536
+ // src/chat/chat-message-actions/chat-message-actions.tsx
537
+ var import_react7 = require("react");
538
+
539
+ // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
540
+ var import_react3 = require("react");
541
+
542
+ // node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs
543
+ var defaultAttributes = {
544
+ outline: {
545
+ xmlns: "http://www.w3.org/2000/svg",
546
+ width: 24,
547
+ height: 24,
548
+ viewBox: "0 0 24 24",
549
+ fill: "none",
550
+ stroke: "currentColor",
551
+ strokeWidth: 2,
552
+ strokeLinecap: "round",
553
+ strokeLinejoin: "round"
554
+ },
555
+ filled: {
556
+ xmlns: "http://www.w3.org/2000/svg",
557
+ width: 24,
558
+ height: 24,
559
+ viewBox: "0 0 24 24",
560
+ fill: "currentColor",
561
+ stroke: "none"
562
+ }
563
+ };
564
+
565
+ // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
566
+ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
567
+ const Component = (0, import_react3.forwardRef)(
568
+ ({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0, import_react3.createElement)(
569
+ "svg",
570
+ {
571
+ ref,
572
+ ...defaultAttributes[type],
573
+ width: size,
574
+ height: size,
575
+ className: [`tabler-icon`, `tabler-icon-${iconName}`, className].join(" "),
576
+ ...type === "filled" ? {
577
+ fill: color
578
+ } : {
579
+ strokeWidth: stroke,
580
+ stroke: color
581
+ },
582
+ ...rest
583
+ },
584
+ [
585
+ title && (0, import_react3.createElement)("title", { key: "svg-title" }, title),
586
+ ...iconNode.map(([tag, attrs]) => (0, import_react3.createElement)(tag, attrs)),
587
+ ...Array.isArray(children) ? children : [children]
588
+ ]
589
+ )
590
+ );
591
+ Component.displayName = `${iconNamePascal}`;
592
+ return Component;
593
+ };
594
+
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
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
600
+ var __iconNode2 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
601
+ var IconCheck = createReactComponent("outline", "check", "Check", __iconNode2);
602
+
603
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
604
+ var __iconNode3 = [["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" }]];
605
+ var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode3);
606
+
607
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconThumbDown.mjs
608
+ var __iconNode4 = [["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" }]];
609
+ var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", __iconNode4);
610
+
611
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconThumbUp.mjs
612
+ var __iconNode5 = [["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" }]];
613
+ var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode5);
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");
621
+
622
+ // src/icon/icon.tsx
623
+ var import_react4 = require("react");
624
+
625
+ // src/icon/icon-styles.ts
626
+ var import_styled_components3 = __toESM(require("styled-components"), 1);
627
+ var STROKE_WIDTH_BY_SIZE = {
628
+ 12: 1.2,
629
+ 14: 1.2,
630
+ 16: 1.8,
631
+ 18: 1.8,
632
+ 20: 1.8,
633
+ 24: 1.8
634
+ };
635
+ var DEFAULT_STROKE_WIDTH = 1.8;
636
+ function getStrokeWidth(size) {
637
+ return STROKE_WIDTH_BY_SIZE[size] ?? DEFAULT_STROKE_WIDTH;
638
+ }
639
+ var IconWrapper = import_styled_components3.default.span`
640
+ display: inline-flex;
641
+ align-items: center;
642
+ justify-content: center;
643
+ color: ${({ $color }) => $color ?? "currentColor"};
644
+ flex-shrink: 0;
645
+ `;
646
+
647
+ // src/icon/icon.tsx
648
+ var import_jsx_runtime3 = require("react/jsx-runtime");
649
+ var DEFAULT_SIZE = 16;
650
+ var Icon = (0, import_react4.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
651
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
652
+ IconWrapper,
653
+ {
654
+ ref,
655
+ className,
656
+ $color: color,
657
+ "aria-label": ariaLabel,
658
+ role: ariaLabel ? "img" : void 0,
659
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
660
+ }
661
+ );
662
+ });
663
+
664
+ // src/icon-button/icon-button-styles.ts
665
+ var import_styled_components4 = __toESM(require("styled-components"), 1);
666
+ var DIMENSIONS = {
667
+ small: 28,
668
+ medium: 32
669
+ };
670
+ var BORDER_RADIUS = {
671
+ small: 6,
672
+ medium: 10
673
+ };
674
+ var Button = import_styled_components4.default.button`
675
+ display: inline-flex;
676
+ align-items: center;
677
+ justify-content: center;
678
+ width: ${({ $size }) => DIMENSIONS[$size]}px;
679
+ height: ${({ $size }) => DIMENSIONS[$size]}px;
680
+ padding: 0;
681
+ border: none;
682
+ border-radius: ${({ $size }) => BORDER_RADIUS[$size]}px;
683
+ background: ${({ $isSelected }) => $isSelected ? colors["brown-40"] : "transparent"};
684
+ color: ${colors["brown-100"]};
685
+ cursor: pointer;
686
+ transition: background-color 100ms ease;
687
+
688
+ &:hover {
689
+ background: ${({ $isSelected }) => $isSelected ? colors["brown-40"] : colors["brown-20"]};
690
+ }
691
+
692
+ &:active {
693
+ background: ${colors["brown-40"]};
694
+ }
695
+
696
+ &:disabled {
697
+ color: ${colors["brown-50"]};
698
+ background: transparent;
699
+ cursor: not-allowed;
700
+ }
701
+ `;
702
+
703
+ // src/icon-button/icon-button.tsx
704
+ var import_jsx_runtime4 = require("react/jsx-runtime");
705
+ var ICON_SIZE_BY_BUTTON_SIZE = {
706
+ small: 14,
707
+ medium: 16
708
+ };
709
+ var IconButton = (0, import_react5.forwardRef)(function IconButton2({ icon, size = "small", isSelected = false, disabled = false, onClick, className, "aria-label": ariaLabel }, ref) {
710
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
711
+ Button,
712
+ {
713
+ ref,
714
+ className,
715
+ $size: size,
716
+ $isSelected: isSelected,
717
+ disabled,
718
+ onClick: disabled ? void 0 : onClick,
719
+ "aria-label": ariaLabel,
720
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
721
+ }
722
+ );
723
+ });
724
+
725
+ // src/chat/hooks/use-copy-to-clipboard.ts
726
+ var import_react6 = require("react");
727
+
728
+ // src/utils/clipboard.ts
729
+ function copyToClipboard(text, options) {
730
+ navigator.clipboard.writeText(text).then(
731
+ () => options?.onSuccess?.(),
732
+ (error) => options?.onFailure?.(error)
733
+ );
734
+ }
735
+
736
+ // src/chat/hooks/use-copy-to-clipboard.ts
737
+ var RESET_DELAY_MS = 2e3;
738
+ function useCopyToClipboard() {
739
+ const [isCopied, setIsCopied] = (0, import_react6.useState)(false);
740
+ const timeoutRef = (0, import_react6.useRef)(null);
741
+ (0, import_react6.useEffect)(() => {
742
+ return () => {
743
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
744
+ };
745
+ }, []);
746
+ const copy = (0, import_react6.useCallback)((text) => {
747
+ copyToClipboard(text, {
748
+ onSuccess: () => {
749
+ setIsCopied(true);
750
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
751
+ timeoutRef.current = setTimeout(() => {
752
+ setIsCopied(false);
753
+ timeoutRef.current = null;
754
+ }, RESET_DELAY_MS);
755
+ }
756
+ });
757
+ }, []);
758
+ return { isCopied, copy };
759
+ }
760
+
761
+ // src/chat/chat-message-actions/chat-message-actions-styles.ts
762
+ var import_styled_components5 = __toESM(require("styled-components"), 1);
763
+ var ActionsContainer = import_styled_components5.default.div`
764
+ display: flex;
765
+ gap: 2px;
766
+ margin-top: 4px;
767
+ opacity: 0;
768
+ pointer-events: none;
769
+ transition: opacity 150ms ease;
770
+ `;
771
+
772
+ // src/chat/chat-message-actions/chat-message-actions.tsx
773
+ var import_jsx_runtime5 = require("react/jsx-runtime");
774
+ function ChatMessageActions({ messageId, content, role, isHelpful }) {
775
+ const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
776
+ const { isCopied, copy } = useCopyToClipboard();
777
+ const handleCopy = (0, import_react7.useCallback)(() => {
778
+ copy(content);
779
+ onCopyMessage?.(messageId);
780
+ }, [content, messageId, copy, onCopyMessage]);
781
+ const handleThumbUp = (0, import_react7.useCallback)(() => {
782
+ onThumbUpClick?.(messageId, isHelpful === true ? null : true);
783
+ }, [messageId, isHelpful, onThumbUpClick]);
784
+ const handleThumbDown = (0, import_react7.useCallback)(() => {
785
+ onThumbDownClick?.(messageId, isHelpful === false ? null : false);
786
+ }, [messageId, isHelpful, onThumbDownClick]);
787
+ const isAssistant = role === "assistant";
788
+ const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
789
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ActionsContainer, { children: [
790
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
791
+ IconButton,
792
+ {
793
+ icon: isCopied ? IconCheck : IconCopy,
794
+ onClick: handleCopy,
795
+ "aria-label": isCopied ? "Copied" : "Copy message"
796
+ }
797
+ ),
798
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
799
+ IconButton,
800
+ {
801
+ icon: IconThumbUp,
802
+ onClick: handleThumbUp,
803
+ isSelected: isHelpful === true,
804
+ "aria-label": "Good response"
805
+ }
806
+ ),
807
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
808
+ IconButton,
809
+ {
810
+ icon: IconThumbDown,
811
+ onClick: handleThumbDown,
812
+ isSelected: isHelpful === false,
813
+ "aria-label": "Bad response"
814
+ }
815
+ )
816
+ ] });
817
+ }
818
+
819
+ // src/chat/chat-message/chat-message-styles.ts
820
+ var import_styled_components6 = __toESM(require("styled-components"), 1);
821
+ var MessageRow = import_styled_components6.default.div`
822
+ display: flex;
823
+ justify-content: ${({ $role }) => $role === "user" ? "flex-end" : "flex-start"};
824
+ `;
825
+ var MessageContainer = import_styled_components6.default.div`
826
+ display: flex;
827
+ flex-direction: column;
828
+ align-items: ${({ $role }) => $role === "user" ? "flex-end" : "flex-start"};
829
+ max-width: 90%;
830
+
831
+ &:hover ${ActionsContainer} {
832
+ opacity: 1;
833
+ pointer-events: auto;
834
+ }
835
+ `;
836
+ var MessageBubble = import_styled_components6.default.div`
837
+ ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
838
+ color: ${colors["brown-100"]};
839
+ background: ${({ $role }) => $role === "user" ? colors.white : "transparent"};
840
+ padding: ${({ $role }) => $role === "user" ? "12px 16px" : "0"};
841
+ border-radius: ${({ $role }) => $role === "user" ? "16px" : "0"};
842
+ `;
843
+
844
+ // src/chat/chat-message/chat-message.tsx
845
+ var import_jsx_runtime6 = require("react/jsx-runtime");
846
+ function ChatMessage({ message }) {
847
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageRow, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(MessageContainer, { $role: message.role, children: [
848
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatMessageContent, { content: message.content }) }),
849
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
850
+ ChatMessageActions,
851
+ {
852
+ messageId: message.id,
853
+ content: message.content,
854
+ role: message.role,
855
+ isHelpful: message.isHelpful
856
+ }
857
+ )
858
+ ] }) });
859
+ }
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
+ // Annotate the CommonJS export names for ESM import in node:
1096
+ 0 && (module.exports = {
1097
+ Chat
1098
+ });
1099
+ /*! Bundled license information:
1100
+
1101
+ @tabler/icons-react/dist/esm/defaultAttributes.mjs:
1102
+ @tabler/icons-react/dist/esm/createReactComponent.mjs:
1103
+ @tabler/icons-react/dist/esm/icons/IconArrowUp.mjs:
1104
+ @tabler/icons-react/dist/esm/icons/IconCheck.mjs:
1105
+ @tabler/icons-react/dist/esm/icons/IconCopy.mjs:
1106
+ @tabler/icons-react/dist/esm/icons/IconThumbDown.mjs:
1107
+ @tabler/icons-react/dist/esm/icons/IconThumbUp.mjs:
1108
+ @tabler/icons-react/dist/esm/icons/IconPlayerStopFilled.mjs:
1109
+ @tabler/icons-react/dist/esm/tabler-icons-react.mjs:
1110
+ (**
1111
+ * @license @tabler/icons-react v3.37.1 - MIT
1112
+ *
1113
+ * This source code is licensed under the MIT license.
1114
+ * See the LICENSE file in the root directory of this source tree.
1115
+ *)
1116
+ */
1117
+ //# sourceMappingURL=chat.cjs.map