@shapesos/clay 0.5.1 → 0.6.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 (52) hide show
  1. package/dist/chat.cjs +17 -15
  2. package/dist/chat.cjs.map +1 -1
  3. package/dist/chat.d.cts +14 -0
  4. package/dist/chat.d.ts +14 -0
  5. package/dist/chat.js +3 -3
  6. package/dist/{chunk-SYMZU32H.js → chunk-J6VPAHO3.js} +16 -16
  7. package/dist/chunk-J6VPAHO3.js.map +1 -0
  8. package/dist/{chunk-K2Q5MQWJ.js → chunk-KNYB3RL7.js} +1 -1
  9. package/dist/chunk-KNYB3RL7.js.map +1 -0
  10. package/dist/{chunk-WZHNMC6P.js → chunk-L6DUGB2E.js} +3 -1
  11. package/dist/chunk-L6DUGB2E.js.map +1 -0
  12. package/dist/{chunk-WQ2QTUYA.js → chunk-SV24ONND.js} +3 -1
  13. package/dist/chunk-SV24ONND.js.map +1 -0
  14. package/dist/{chunk-JC2RQL5O.js → chunk-TDMJUF4A.js} +3 -3
  15. package/dist/{chunk-SMTOVZ3O.js → chunk-WYGH3FKT.js} +1 -1
  16. package/dist/chunk-WYGH3FKT.js.map +1 -0
  17. package/dist/icon.cjs.map +1 -1
  18. package/dist/icon.d.cts +20 -1
  19. package/dist/icon.d.ts +20 -1
  20. package/dist/index.cjs +17 -13
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +6 -6
  25. package/dist/keyboard-shortcut.cjs +2 -0
  26. package/dist/keyboard-shortcut.cjs.map +1 -1
  27. package/dist/keyboard-shortcut.d.cts +9 -0
  28. package/dist/keyboard-shortcut.d.ts +9 -0
  29. package/dist/keyboard-shortcut.js +1 -1
  30. package/dist/lottie.d.cts +26 -0
  31. package/dist/lottie.d.ts +26 -0
  32. package/dist/text-area.cjs +2 -0
  33. package/dist/text-area.cjs.map +1 -1
  34. package/dist/text-area.d.cts +10 -0
  35. package/dist/text-area.d.ts +10 -0
  36. package/dist/text-area.js +3 -3
  37. package/dist/tokens.cjs +2 -0
  38. package/dist/tokens.cjs.map +1 -1
  39. package/dist/tokens.d.cts +16 -0
  40. package/dist/tokens.d.ts +16 -0
  41. package/dist/tokens.js +1 -1
  42. package/dist/utils.cjs.map +1 -1
  43. package/dist/utils.d.cts +17 -0
  44. package/dist/utils.d.ts +17 -0
  45. package/dist/utils.js +2 -2
  46. package/package.json +3 -1
  47. package/dist/chunk-K2Q5MQWJ.js.map +0 -1
  48. package/dist/chunk-SMTOVZ3O.js.map +0 -1
  49. package/dist/chunk-SYMZU32H.js.map +0 -1
  50. package/dist/chunk-WQ2QTUYA.js.map +0 -1
  51. package/dist/chunk-WZHNMC6P.js.map +0 -1
  52. /package/dist/{chunk-JC2RQL5O.js.map → chunk-TDMJUF4A.js.map} +0 -0
package/dist/chat.cjs CHANGED
@@ -27,7 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // src/chat/index.ts
30
+ // src/components/chat/index.ts
31
31
  var chat_exports = {};
32
32
  __export(chat_exports, {
33
33
  ChatContext: () => ChatContext,
@@ -38,12 +38,12 @@ __export(chat_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(chat_exports);
40
40
 
41
- // src/chat/chat-message-content/chat-message-content.tsx
41
+ // src/components/chat/chat-message-content/chat-message-content.tsx
42
42
  var import_react_markdown = __toESM(require("react-markdown"), 1);
43
43
  var import_remark_breaks = __toESM(require("remark-breaks"), 1);
44
44
  var import_remark_gfm = __toESM(require("remark-gfm"), 1);
45
45
 
46
- // src/chat/chat-message-content/chat-message-content-styles.ts
46
+ // src/components/chat/chat-message-content/chat-message-content-styles.ts
47
47
  var import_styled_components = __toESM(require("styled-components"), 1);
48
48
 
49
49
  // src/tokens/colors.ts
@@ -136,7 +136,9 @@ var colors = {
136
136
 
137
137
  // src/tokens/typography.ts
138
138
  var fontFamilies = {
139
+ /** Geist — primary UI font for body text, labels, headings, and display. */
139
140
  GEIST: "Geist",
141
+ /** Crimson Pro — editorial/serif font, always italic. Used for decorative headings and pull quotes. */
140
142
  CRIMSON_PRO: "Crimson Pro"
141
143
  };
142
144
  var typographyTypes = {
@@ -427,7 +429,7 @@ function typographyMixin(type) {
427
429
  ].join(";\n ");
428
430
  }
429
431
 
430
- // src/chat/chat-message-content/chat-message-content-styles.ts
432
+ // src/components/chat/chat-message-content/chat-message-content-styles.ts
431
433
  var ContentWrapper = import_styled_components.default.div`
432
434
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
433
435
  color: ${colors["brown-100"]};
@@ -551,7 +553,7 @@ var TableScroll = import_styled_components.default.div`
551
553
  margin-block: 8px 16px;
552
554
  `;
553
555
 
554
- // src/chat/chat-message-content/chat-message-content.tsx
556
+ // src/components/chat/chat-message-content/chat-message-content.tsx
555
557
  var import_jsx_runtime = require("react/jsx-runtime");
556
558
  function ScrollableTable({ node: _node, ...props }) {
557
559
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) });
@@ -563,7 +565,7 @@ function ChatMessageContent({ content }) {
563
565
  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 }) });
564
566
  }
565
567
 
566
- // src/chat/chat-message-actions/chat-message-actions.tsx
568
+ // src/components/chat/chat-message-actions/chat-message-actions.tsx
567
569
  var import_react5 = require("react");
568
570
 
569
571
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
@@ -758,7 +760,7 @@ function IconButton({
758
760
  );
759
761
  }
760
762
 
761
- // src/chat/chat-context/chat-context.ts
763
+ // src/components/chat/chat-context/chat-context.ts
762
764
  var import_react3 = require("react");
763
765
  var ChatContext = (0, import_react3.createContext)(null);
764
766
  function useChatContext() {
@@ -769,7 +771,7 @@ function useChatContext() {
769
771
  return context;
770
772
  }
771
773
 
772
- // src/chat/hooks/use-copy-to-clipboard.ts
774
+ // src/components/chat/hooks/use-copy-to-clipboard.ts
773
775
  var import_react4 = require("react");
774
776
 
775
777
  // src/utils/clipboard.ts
@@ -795,7 +797,7 @@ function markdownToPlainText(markdown) {
795
797
  return result;
796
798
  }
797
799
 
798
- // src/chat/hooks/use-copy-to-clipboard.ts
800
+ // src/components/chat/hooks/use-copy-to-clipboard.ts
799
801
  var RESET_DELAY_MS = 2e3;
800
802
  function useCopyToClipboard() {
801
803
  const [isCopied, setIsCopied] = (0, import_react4.useState)(false);
@@ -820,13 +822,13 @@ function useCopyToClipboard() {
820
822
  return { isCopied, copy };
821
823
  }
822
824
 
823
- // src/chat/constants.ts
825
+ // src/components/chat/constants.ts
824
826
  var MESSAGE_ROLE = {
825
827
  USER: "user",
826
828
  ASSISTANT: "assistant"
827
829
  };
828
830
 
829
- // src/chat/chat-message-actions/chat-message-actions-styles.ts
831
+ // src/components/chat/chat-message-actions/chat-message-actions-styles.ts
830
832
  var import_styled_components4 = __toESM(require("styled-components"), 1);
831
833
  var FADE_DURATION_MS = 150;
832
834
  var ANIMATE_DURATION_MS = 200;
@@ -844,7 +846,7 @@ var AnimatedAction = import_styled_components4.default.div`
844
846
  transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;
845
847
  `;
846
848
 
847
- // src/chat/chat-message-actions/chat-message-actions.tsx
849
+ // src/components/chat/chat-message-actions/chat-message-actions.tsx
848
850
  var import_jsx_runtime4 = require("react/jsx-runtime");
849
851
  function ChatMessageActions({ className, messageId, content, role, isHelpful }) {
850
852
  const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
@@ -891,7 +893,7 @@ function ChatMessageActions({ className, messageId, content, role, isHelpful })
891
893
  ] });
892
894
  }
893
895
 
894
- // src/chat/chat-message/chat-message-styles.ts
896
+ // src/components/chat/chat-message/chat-message-styles.ts
895
897
  var import_styled_components5 = __toESM(require("styled-components"), 1);
896
898
  var MessageRow = import_styled_components5.default.div`
897
899
  display: flex;
@@ -920,10 +922,10 @@ var MessageBubble = import_styled_components5.default.div`
920
922
  min-width: 0;
921
923
  `;
922
924
 
923
- // src/chat/chat-message/chat-message.tsx
925
+ // src/components/chat/chat-message/chat-message.tsx
924
926
  var import_jsx_runtime5 = require("react/jsx-runtime");
925
927
  function ChatMessage({ message }) {
926
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageRow, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageContainer, { $role: message.role, children: [
928
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageRow, { $role: message.role, role: "article", "aria-label": `${message.role} message`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageContainer, { $role: message.role, children: [
927
929
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatMessageContent, { content: message.content }) }),
928
930
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
929
931
  ChatMessageActions,
package/dist/chat.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chat/index.ts","../src/chat/chat-message-content/chat-message-content.tsx","../src/chat/chat-message-content/chat-message-content-styles.ts","../src/tokens/colors.ts","../src/tokens/typography.ts","../src/chat/chat-message-actions/chat-message-actions.tsx","../node_modules/@tabler/icons-react/src/defaultAttributes.ts","../node_modules/@tabler/icons-react/src/createReactComponent.ts","../node_modules/@tabler/icons-react/src/icons/IconCheck.ts","../node_modules/@tabler/icons-react/src/icons/IconCopy.ts","../node_modules/@tabler/icons-react/src/icons/IconThumbDown.ts","../node_modules/@tabler/icons-react/src/icons/IconThumbUp.ts","../src/components/icon/icon.tsx","../src/components/icon/icon-styles.ts","../src/components/icon-button/icon-button-styles.ts","../src/components/icon-button/icon-button.tsx","../src/chat/chat-context/chat-context.ts","../src/chat/hooks/use-copy-to-clipboard.ts","../src/utils/clipboard.ts","../src/utils/markdown-to-plain-text.ts","../src/chat/constants.ts","../src/chat/chat-message-actions/chat-message-actions-styles.ts","../src/chat/chat-message/chat-message-styles.ts","../src/chat/chat-message/chat-message.tsx"],"sourcesContent":["export { ChatMessage } from \"./chat-message/chat-message\";\nexport { useChatContext, ChatContext } from \"./chat-context/chat-context\";\nexport { useCopyToClipboard } from \"./hooks/use-copy-to-clipboard\";\nexport { MESSAGE_ROLE } from \"./constants\";\nexport type { ChatMessage as ChatMessageType, MessageRole, ChatContextValue } from \"./types\";\n","import type { ReactNode } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { ContentWrapper, TableScroll } from \"./chat-message-content-styles\";\n\ninterface ChatMessageContentProps {\n content: string;\n}\n\nfunction ScrollableTable({ node: _node, ...props }: { node?: unknown; children?: ReactNode }): ReactNode {\n return (\n <TableScroll>\n <table {...props} />\n </TableScroll>\n );\n}\n\nconst markdownComponents = {\n table: ScrollableTable as React.ComponentType<unknown>,\n};\n\nexport function ChatMessageContent({ content }: ChatMessageContentProps) {\n return (\n <ContentWrapper>\n <ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]} components={markdownComponents}>\n {content}\n </ReactMarkdown>\n </ContentWrapper>\n );\n}\n","import styled from \"styled-components\";\n\nimport { colors } from \"../../tokens/colors\";\nimport { typographyMixin, typographyTypes } from \"../../tokens/typography\";\n\nexport const ContentWrapper = styled.div`\n ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};\n color: ${colors[\"brown-100\"]};\n word-break: break-word;\n\n & h1 {\n ${typographyMixin(typographyTypes.GEIST_HEADING_S_BOLD)};\n margin-block: 20px;\n }\n\n & h2 {\n ${typographyMixin(typographyTypes.GEIST_BODY_L_SEMI_BOLD)};\n margin-block: 12px;\n }\n\n & h3,\n & h4,\n & h5,\n & h6 {\n ${typographyMixin(typographyTypes.GEIST_BODY_M_SEMI_BOLD)};\n margin-block: 8px;\n }\n\n & strong {\n ${typographyMixin(typographyTypes.GEIST_BODY_S_SEMI_BOLD)};\n }\n\n & p {\n margin-block: 0px;\n }\n\n & p + p {\n margin-block: 8px 0px;\n }\n\n & ul,\n & ol {\n margin-block: 16px;\n padding-left: 20px;\n }\n\n & li + li {\n margin-block: 4px;\n }\n\n & ol {\n list-style-type: decimal;\n }\n\n & ol ol {\n list-style-type: lower-alpha;\n }\n\n & ol ol ol {\n list-style-type: lower-roman;\n }\n\n & a {\n color: inherit;\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: auto;\n text-underline-offset: auto;\n text-underline-position: from-font;\n transition: color 75ms ease-in-out;\n\n &:hover {\n color: ${colors[\"blue-600\"]};\n }\n }\n\n & hr {\n border: none;\n border-top: 1px solid ${colors[\"brown-40\"]};\n margin-block: 20px;\n }\n\n & table {\n margin: 0;\n width: 100%;\n border-collapse: collapse;\n }\n\n & th,\n & td {\n border: none;\n border-bottom: 1px solid ${colors[\"brown-40\"]};\n text-align: left;\n }\n\n & th {\n ${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};\n padding: 8px;\n }\n\n & td {\n ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};\n padding: 16px 8px;\n min-width: 150px;\n width: 1%;\n }\n\n & td strong {\n font-weight: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n\n & blockquote {\n margin-block: 4px;\n margin-inline: 0px;\n padding-left: 16px;\n border-left: 4px solid ${colors[\"brown-40\"]};\n color: ${colors[\"brown-80\"]};\n }\n`;\n\nexport const TableScroll = styled.div`\n width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n margin-block: 8px 16px;\n`;\n","export const colors = {\n // White\n white: \"#FFFFFF\",\n \"white-alpha-85\": \"rgba(255, 255, 255, 0.85)\",\n \"white-alpha-40\": \"rgba(255, 255, 255, 0.40)\",\n\n // Brown\n \"brown-10\": \"#FAF9F8\",\n \"brown-20\": \"#F5F3F0\",\n \"brown-30\": \"#EEEBE5\",\n \"brown-40\": \"#E6E2DA\",\n \"brown-50\": \"#CFCBC4\",\n \"brown-60\": \"#A19E99\",\n \"brown-70\": \"#73716D\",\n \"brown-80\": \"#5C5A57\",\n \"brown-90\": \"#2E2D2C\",\n \"brown-100\": \"#171716\",\n \"brown-alpha-12\": \"rgba(23, 23, 22, 0.12)\",\n \"brown-alpha-20\": \"rgba(23, 23, 22, 0.20)\",\n \"brown-alpha-55\": \"rgba(23, 23, 22, 0.55)\",\n \"brown-alpha-70\": \"rgba(23, 23, 22, 0.70)\",\n \"brown-alpha-80\": \"rgba(23, 23, 22, 0.80)\",\n \"brown-alpha-90\": \"rgba(23, 23, 22, 0.90)\",\n\n // Fuchsia\n \"fuchsia-50\": \"#FAF5FF\",\n \"fuchsia-300\": \"#F0ABFC\",\n \"fuchsia-500\": \"#D946EF\",\n \"fuchsia-600\": \"#C026D3\",\n \"fuchsia-800\": \"#86198F\",\n\n // Pink\n \"pink-50\": \"#FDF2F8\",\n \"pink-400\": \"#F472B6\",\n \"pink-600\": \"#DB2777\",\n \"pink-800\": \"#9D174D\",\n\n // Violet\n \"violet-50\": \"#F5F3FF\",\n \"violet-400\": \"#A78BFA\",\n \"violet-600\": \"#7C3AED\",\n \"violet-800\": \"#5B21B6\",\n\n // Indigo\n \"indigo-50\": \"#EEF2FF\",\n \"indigo-400\": \"#818CF8\",\n \"indigo-500\": \"#6366F1\",\n \"indigo-600\": \"#4F46E5\",\n \"indigo-800\": \"#3730A3\",\n\n // Cyan\n \"cyan-50\": \"#E7FEFF\",\n \"cyan-300\": \"#67E8F9\",\n \"cyan-600\": \"#0891B2\",\n \"cyan-900\": \"#164E63\",\n\n // Teal\n \"teal-50\": \"#EBFDF9\",\n \"teal-300\": \"#5EEAD4\",\n \"teal-600\": \"#0D9488\",\n\n // Rose\n \"rose-400\": \"#FB7185\",\n\n // Purple\n \"purple-400\": \"#C084FC\",\n\n // Blue\n \"blue-50\": \"#EFF6FF\",\n \"blue-100\": \"#DBEAFE\",\n \"blue-300\": \"#93C5FD\",\n \"blue-400\": \"#60A5FA\",\n \"blue-600\": \"#2563EB\",\n \"blue-800\": \"#1E40AF\",\n\n // Sky\n \"sky-300\": \"#7DD3FC\",\n\n // Green\n \"green-50\": \"#ECF9F0\",\n \"green-100\": \"#D4F1D9\",\n \"green-400\": \"#3DC269\",\n \"green-700\": \"#277C43\",\n \"green-800\": \"#1C5930\",\n\n // Orange\n \"orange-50\": \"#FFF7ED\",\n \"orange-100\": \"#FFEDD5\",\n \"orange-200\": \"#FED7AA\",\n \"orange-500\": \"#F97316\",\n \"orange-600\": \"#EA580C\",\n\n // Red\n \"red-50\": \"#FEF2F2\",\n \"red-100\": \"#FEE2E2\",\n \"red-200\": \"#FECACA\",\n \"red-400\": \"#F7776C\",\n \"red-500\": \"#EF4444\",\n \"red-600\": \"#DC2626\",\n} as const;\n\nexport type ColorToken = keyof typeof colors;\n","export const fontFamilies = {\n GEIST: \"Geist\",\n CRIMSON_PRO: \"Crimson Pro\",\n} as const;\n\nexport const typographyTypes = {\n // Geist Label Caption (12px)\n GEIST_LABEL_CAPTION_REGULAR: \"GEIST_LABEL_CAPTION_REGULAR\",\n GEIST_LABEL_CAPTION_MEDIUM: \"GEIST_LABEL_CAPTION_MEDIUM\",\n GEIST_LABEL_CAPTION_SEMI_BOLD: \"GEIST_LABEL_CAPTION_SEMI_BOLD\",\n\n // Geist Body Extra Small (14px)\n GEIST_BODY_XS_REGULAR: \"GEIST_BODY_XS_REGULAR\",\n GEIST_BODY_XS_MEDIUM: \"GEIST_BODY_XS_MEDIUM\",\n GEIST_BODY_XS_BOLD: \"GEIST_BODY_XS_BOLD\",\n\n // Geist Body Small (16px)\n GEIST_BODY_S_REGULAR: \"GEIST_BODY_S_REGULAR\",\n GEIST_BODY_S_MEDIUM: \"GEIST_BODY_S_MEDIUM\",\n GEIST_BODY_S_SEMI_BOLD: \"GEIST_BODY_S_SEMI_BOLD\",\n GEIST_BODY_S_BOLD: \"GEIST_BODY_S_BOLD\",\n\n // Geist Body Medium (18px)\n GEIST_BODY_M_LIGHT: \"GEIST_BODY_M_LIGHT\",\n GEIST_BODY_M_REGULAR: \"GEIST_BODY_M_REGULAR\",\n GEIST_BODY_M_MEDIUM: \"GEIST_BODY_M_MEDIUM\",\n GEIST_BODY_M_SEMI_BOLD: \"GEIST_BODY_M_SEMI_BOLD\",\n\n // Geist Body Large (20px)\n GEIST_BODY_L_REGULAR: \"GEIST_BODY_L_REGULAR\",\n GEIST_BODY_L_MEDIUM: \"GEIST_BODY_L_MEDIUM\",\n GEIST_BODY_L_SEMI_BOLD: \"GEIST_BODY_L_SEMI_BOLD\",\n GEIST_BODY_L_BOLD: \"GEIST_BODY_L_BOLD\",\n\n // Geist Heading Small (24px)\n GEIST_HEADING_S_REGULAR: \"GEIST_HEADING_S_REGULAR\",\n GEIST_HEADING_S_MEDIUM: \"GEIST_HEADING_S_MEDIUM\",\n GEIST_HEADING_S_BOLD: \"GEIST_HEADING_S_BOLD\",\n\n // Geist Heading Medium (28px)\n GEIST_HEADING_M_BOLD: \"GEIST_HEADING_M_BOLD\",\n\n // Geist Heading Large (32px)\n GEIST_HEADING_L_REGULAR: \"GEIST_HEADING_L_REGULAR\",\n GEIST_HEADING_L_MEDIUM: \"GEIST_HEADING_L_MEDIUM\",\n GEIST_HEADING_L_SEMI_BOLD: \"GEIST_HEADING_L_SEMI_BOLD\",\n GEIST_HEADING_L_BOLD: \"GEIST_HEADING_L_BOLD\",\n\n // Geist Display Large (36px)\n GEIST_DISPLAY_L_MEDIUM: \"GEIST_DISPLAY_L_MEDIUM\",\n\n // Crimson Pro Body Small (16px)\n CRIMSON_PRO_BODY_S_LIGHT: \"CRIMSON_PRO_BODY_S_LIGHT\",\n\n // Crimson Pro Body Medium (18px)\n CRIMSON_PRO_BODY_M_LIGHT: \"CRIMSON_PRO_BODY_M_LIGHT\",\n\n // Crimson Pro Heading Medium (24px)\n CRIMSON_PRO_HEADING_M_MEDIUM: \"CRIMSON_PRO_HEADING_M_MEDIUM\",\n\n // Crimson Pro Display Extra Large (46px)\n CRIMSON_PRO_DISPLAY_XL_REGULAR: \"CRIMSON_PRO_DISPLAY_XL_REGULAR\",\n} as const;\n\nexport type TypographyType = (typeof typographyTypes)[keyof typeof typographyTypes];\n\nexport interface TypographyStyle {\n fontFamily: string;\n fontSize: number;\n fontWeight: number;\n lineHeight: number;\n letterSpacing?: number;\n fontStyle?: string;\n}\n\nexport const typographyStyles: Record<TypographyType, TypographyStyle> = {\n // Geist Label Caption (12px)\n [typographyTypes.GEIST_LABEL_CAPTION_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 400,\n lineHeight: 16,\n },\n [typographyTypes.GEIST_LABEL_CAPTION_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 500,\n lineHeight: 16,\n },\n [typographyTypes.GEIST_LABEL_CAPTION_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 600,\n lineHeight: 16,\n },\n\n // Geist Body Extra Small (14px)\n [typographyTypes.GEIST_BODY_XS_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 400,\n lineHeight: 20,\n },\n [typographyTypes.GEIST_BODY_XS_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 500,\n lineHeight: 20,\n },\n [typographyTypes.GEIST_BODY_XS_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 600,\n lineHeight: 20,\n },\n\n // Geist Body Small (16px)\n [typographyTypes.GEIST_BODY_S_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 400,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 500,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 600,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 700,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n\n // Geist Body Medium (18px)\n [typographyTypes.GEIST_BODY_M_LIGHT]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 300,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 400,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 500,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 600,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n\n // Geist Body Large (20px)\n [typographyTypes.GEIST_BODY_L_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 400,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 500,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 600,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 700,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n\n // Geist Heading Small (24px)\n [typographyTypes.GEIST_HEADING_S_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 400,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n [typographyTypes.GEIST_HEADING_S_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 500,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n [typographyTypes.GEIST_HEADING_S_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n\n // Geist Heading Medium (28px)\n [typographyTypes.GEIST_HEADING_M_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 28,\n fontWeight: 700,\n lineHeight: 36,\n letterSpacing: -0.6,\n },\n\n // Geist Heading Large (32px)\n [typographyTypes.GEIST_HEADING_L_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 400,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 500,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 600,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 700,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n\n // Geist Display Large (36px)\n [typographyTypes.GEIST_DISPLAY_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 36,\n fontWeight: 500,\n lineHeight: 44,\n letterSpacing: -0.72,\n },\n\n // Crimson Pro Body Small (16px)\n [typographyTypes.CRIMSON_PRO_BODY_S_LIGHT]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 16,\n fontWeight: 300,\n lineHeight: 20,\n letterSpacing: -0.32,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Body Medium (18px)\n [typographyTypes.CRIMSON_PRO_BODY_M_LIGHT]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 18,\n fontWeight: 300,\n lineHeight: 28,\n letterSpacing: 0,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Heading Medium (24px)\n [typographyTypes.CRIMSON_PRO_HEADING_M_MEDIUM]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 24,\n fontWeight: 400,\n lineHeight: 32,\n letterSpacing: -0.48,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Display Extra Large (46px)\n [typographyTypes.CRIMSON_PRO_DISPLAY_XL_REGULAR]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 46,\n fontWeight: 400,\n lineHeight: 54,\n letterSpacing: -1.38,\n fontStyle: \"italic\",\n },\n};\n\nexport function typographyMixin(type: TypographyType): string {\n const style = typographyStyles[type];\n return [\n `font-family: \"${style.fontFamily}\", sans-serif`,\n `font-size: ${style.fontSize}px`,\n `font-weight: ${style.fontWeight}`,\n `line-height: ${style.lineHeight}px`,\n `letter-spacing: ${style.letterSpacing != null ? `${style.letterSpacing}px` : \"inherit\"}`,\n `font-style: ${style.fontStyle ?? \"normal\"}`,\n ].join(\";\\n \");\n}\n","import { useCallback } from \"react\";\nimport { IconCopy, IconCheck, IconThumbUp, IconThumbDown } from \"@tabler/icons-react\";\n\nimport { IconButton } from \"../../components/icon-button/icon-button\";\nimport { useChatContext } from \"../chat-context/chat-context\";\nimport { useCopyToClipboard } from \"../hooks/use-copy-to-clipboard\";\nimport { MESSAGE_ROLE } from \"../constants\";\nimport type { MessageRole } from \"../types\";\nimport { ActionsContainer, AnimatedAction } from \"./chat-message-actions-styles\";\n\ninterface ChatMessageActionsProps {\n className?: string;\n messageId: string;\n content: string;\n role: MessageRole;\n isHelpful?: boolean | null;\n}\n\nexport function ChatMessageActions({ className, messageId, content, role, isHelpful }: ChatMessageActionsProps) {\n const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();\n const { isCopied, copy } = useCopyToClipboard();\n\n const handleCopy = useCallback(() => {\n copy(content);\n onCopyMessage?.(messageId);\n }, [content, messageId, copy, onCopyMessage]);\n\n const handleThumbUp = useCallback(() => {\n onThumbUpClick?.(messageId, isHelpful === true ? null : true);\n }, [messageId, isHelpful, onThumbUpClick]);\n\n const handleThumbDown = useCallback(() => {\n onThumbDownClick?.(messageId, isHelpful === false ? null : false);\n }, [messageId, isHelpful, onThumbDownClick]);\n\n const isAssistant = role === MESSAGE_ROLE.ASSISTANT;\n const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);\n\n return (\n <ActionsContainer $role={role} className={className}>\n <IconButton\n icon={isCopied ? IconCheck : IconCopy}\n onClick={handleCopy}\n aria-label={isCopied ? \"Copied\" : \"Copy message\"}\n />\n\n {hasFeedback && (\n <AnimatedAction $visible={isHelpful !== false}>\n <IconButton\n icon={IconThumbUp}\n onClick={handleThumbUp}\n isSelected={isHelpful === true}\n aria-label=\"Good response\"\n />\n </AnimatedAction>\n )}\n\n {hasFeedback && (\n <AnimatedAction $visible={isHelpful !== true}>\n <IconButton\n icon={IconThumbDown}\n onClick={handleThumbDown}\n isSelected={isHelpful === false}\n aria-label=\"Bad response\"\n />\n </AnimatedAction>\n )}\n </ActionsContainer>\n );\n}\n","export default {\n outline: {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n },\n filled: {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'currentColor',\n stroke: 'none',\n },\n};\n","import { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport type { IconNode, IconProps, Icon } from './types';\n\nconst createReactComponent = (\n type: 'outline' | 'filled',\n iconName: string,\n iconNamePascal: string,\n iconNode: IconNode,\n) => {\n const Component = forwardRef<SVGSVGElement, IconProps>(\n (\n { color = 'currentColor', size = 24, stroke = 2, title, className, children, ...rest }: IconProps,\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes[type],\n width: size,\n height: size,\n className: [`tabler-icon`, `tabler-icon-${iconName}`, className].join(' '),\n ...(type === 'filled'\n ? {\n fill: color,\n }\n : {\n strokeWidth: stroke,\n stroke: color,\n }),\n ...rest,\n },\n [\n title && createElement('title', { key: 'svg-title' }, title),\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n );\n\n Component.displayName = `${iconNamePascal}`;\n\n return Component;\n};\n\nexport default createReactComponent;\n","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"path\",{\"d\":\"M5 12l5 5l10 -10\",\"key\":\"svg-0\"}]]\n\nconst IconCheck = createReactComponent('outline', 'check', 'Check', __iconNode);\n\nexport default IconCheck;","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"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\"}]]\n\nconst IconCopy = createReactComponent('outline', 'copy', 'Copy', __iconNode);\n\nexport default IconCopy;","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"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\"}]]\n\nconst IconThumbDown = createReactComponent('outline', 'thumb-down', 'ThumbDown', __iconNode);\n\nexport default IconThumbDown;","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"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\"}]]\n\nconst IconThumbUp = createReactComponent('outline', 'thumb-up', 'ThumbUp', __iconNode);\n\nexport default IconThumbUp;","import { forwardRef } from \"react\";\n\nimport { IconWrapper, getStrokeWidth } from \"./icon-styles\";\nimport type { IconProps } from \"./types\";\n\nconst DEFAULT_SIZE = 16;\n\nexport const Icon = forwardRef<HTMLSpanElement, IconProps>(function Icon(\n { icon: IconComponent, size = DEFAULT_SIZE, color, className, \"aria-label\": ariaLabel },\n ref\n) {\n return (\n <IconWrapper\n ref={ref}\n className={className}\n $color={color}\n aria-label={ariaLabel}\n role={ariaLabel ? \"img\" : undefined}\n >\n <IconComponent width={size} height={size} strokeWidth={getStrokeWidth(size)} />\n </IconWrapper>\n );\n});\n","import styled from \"styled-components\";\n\nexport const STROKE_WIDTH_BY_SIZE: Record<number, number> = {\n 12: 1.4,\n 14: 1.4,\n 16: 1.8,\n 18: 1.8,\n 20: 1.8,\n 24: 1.8,\n};\n\nexport const DEFAULT_STROKE_WIDTH = 1.8;\n\nexport function getStrokeWidth(size: number): number {\n return STROKE_WIDTH_BY_SIZE[size] ?? DEFAULT_STROKE_WIDTH;\n}\n\nexport const IconWrapper = styled.span<{ $color?: string }>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: ${({ $color }) => $color ?? \"currentColor\"};\n flex-shrink: 0;\n`;\n","import styled from \"styled-components\";\n\nimport { colors } from \"../../tokens/colors\";\nimport type { IconButtonSize, IconButtonVariant } from \"./types\";\n\nconst PADDING: Record<IconButtonVariant, Record<IconButtonSize, string>> = {\n short: {\n small: \"4px\",\n medium: \"6px\",\n },\n long: {\n small: \"4px 6px\",\n medium: \"6px 10px\",\n },\n};\n\nconst BORDER_RADIUS: Record<IconButtonSize, number> = {\n small: 6,\n medium: 10,\n};\n\nexport const Button = styled.button<{\n $size: IconButtonSize;\n $variant: IconButtonVariant;\n $isSelected: boolean;\n}>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: ${({ $size, $variant }) => PADDING[$variant][$size]};\n border: none;\n border-radius: ${({ $size }) => BORDER_RADIUS[$size]}px;\n background: ${({ $isSelected }) => ($isSelected ? colors[\"brown-40\"] : \"transparent\")};\n color: ${colors[\"brown-100\"]};\n cursor: pointer;\n transition: background-color 100ms ease;\n\n &:hover {\n background: ${({ $isSelected }) => ($isSelected ? colors[\"brown-40\"] : colors[\"brown-20\"])};\n }\n\n &:active {\n background: ${colors[\"brown-40\"]};\n }\n\n &:disabled {\n color: ${colors[\"brown-50\"]};\n background: transparent;\n cursor: not-allowed;\n }\n`;\n","import { Icon } from \"../icon/icon\";\nimport { Button } from \"./icon-button-styles\";\nimport type { IconButtonProps, IconButtonSize } from \"./types\";\n\nconst ICON_SIZE_BY_BUTTON_SIZE: Record<IconButtonSize, number> = {\n small: 16,\n medium: 20,\n};\n\nexport function IconButton({\n icon,\n size = \"small\",\n variant = \"short\",\n isSelected = false,\n disabled = false,\n onClick,\n className,\n id,\n as,\n \"aria-label\": ariaLabel,\n}: IconButtonProps): React.ReactNode {\n return (\n <Button\n className={className}\n id={id}\n as={as}\n $size={size}\n $variant={variant}\n $isSelected={isSelected}\n disabled={disabled}\n onClick={disabled ? undefined : onClick}\n aria-label={ariaLabel}\n >\n <Icon icon={icon} size={ICON_SIZE_BY_BUTTON_SIZE[size]} />\n </Button>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport type { ChatContextValue } from \"../types\";\n\nexport const ChatContext = createContext<ChatContextValue | null>(null);\n\nexport function useChatContext(): ChatContextValue {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error(\"useChatContext must be used within a Chat.Root component\");\n }\n return context;\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\n\nimport { copyToClipboard } from \"@/utils/clipboard\";\nimport { markdownToPlainText } from \"@/utils/markdown-to-plain-text\";\n\nconst RESET_DELAY_MS = 2000;\n\ninterface UseCopyToClipboardResult {\n isCopied: boolean;\n copy: (text: string) => void;\n}\n\nexport function useCopyToClipboard(): UseCopyToClipboardResult {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const copy = useCallback((text: string) => {\n copyToClipboard(markdownToPlainText(text), {\n onSuccess: () => {\n setIsCopied(true);\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => {\n setIsCopied(false);\n timeoutRef.current = null;\n }, RESET_DELAY_MS);\n },\n });\n }, []);\n\n return { isCopied, copy };\n}\n","interface CopyToClipboardOptions {\n onSuccess?: () => void;\n onFailure?: (error: unknown) => void;\n}\n\nexport function copyToClipboard(text: string, options?: CopyToClipboardOptions): void {\n navigator.clipboard.writeText(text).then(\n () => options?.onSuccess?.(),\n (error) => options?.onFailure?.(error)\n );\n}\n","const PLACEHOLDER_PREFIX = \"\\u200B\\u200BIC\";\nconst PLACEHOLDER_SUFFIX = \"\\u200B\\u200B\";\nconst PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\\\d+)${PLACEHOLDER_SUFFIX}`, \"g\");\n\nexport function markdownToPlainText(markdown: string): string {\n if (!markdown) return \"\";\n\n // Protect inline code content from bold/italic stripping by replacing with placeholders\n const inlineCodeSnippets: string[] = [];\n let result = markdown\n // Code blocks (must come first)\n .replace(/```[\\s\\S]*?```/g, \"\")\n // Inline code → placeholder\n .replace(/`([^`]+)`/g, (_match, code: string) => {\n inlineCodeSnippets.push(code);\n return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;\n })\n // Remove headings markers, keep text\n .replace(/^#{1,6}\\s+/gm, \"\")\n // Remove horizontal rules\n .replace(/^(?:---|\\*\\*\\*|___)\\s*$/gm, \"\")\n // Bold + italic\n .replace(/\\*{3}(.+?)\\*{3}/g, \"$1\")\n // Bold\n .replace(/\\*{2}(.+?)\\*{2}/g, \"$1\")\n .replace(/_{2}(.+?)_{2}/g, \"$1\")\n // Italic\n .replace(/\\*(.+?)\\*/g, \"$1\")\n .replace(/_(.+?)_/g, \"$1\")\n // Strikethrough\n .replace(/~~(.+?)~~/g, \"$1\")\n // Images: ![alt](url) → alt (must come before links)\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, \"$1\")\n // Links: [text](url) → text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n // Blockquote markers\n .replace(/^>\\s?/gm, \"\")\n // Table separator rows (|---|---|)\n .replace(/^\\|[-:\\s|]+\\|\\s*$/gm, \"\")\n // Table rows: | a | b | → a | b\n .replace(/^\\|\\s?/gm, \"\")\n .replace(/\\s?\\|$/gm, \"\")\n // Collapse multiple blank lines\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n\n // Restore inline code content\n result = result.replace(PLACEHOLDER_REGEX, (_match, index: string) => inlineCodeSnippets[Number(index)]);\n\n return result;\n}\n","export const MESSAGE_ROLE = {\n USER: \"user\",\n ASSISTANT: \"assistant\",\n} as const;\n","import styled from \"styled-components\";\n\nimport { MESSAGE_ROLE } from \"../constants\";\nimport type { MessageRole } from \"../types\";\n\nconst FADE_DURATION_MS = 150;\nconst ANIMATE_DURATION_MS = 200;\n\nexport const ActionsContainer = styled.div<{ $role: MessageRole }>`\n display: flex;\n opacity: ${({ $role }) => ($role === MESSAGE_ROLE.ASSISTANT ? 1 : 0)};\n pointer-events: ${({ $role }) => ($role === MESSAGE_ROLE.ASSISTANT ? \"auto\" : \"none\")};\n transition: opacity ${FADE_DURATION_MS}ms ease;\n`;\n\nexport const AnimatedAction = styled.div<{ $visible: boolean }>`\n display: flex;\n overflow: hidden;\n max-width: ${({ $visible }) => ($visible ? \"40px\" : \"0\")};\n opacity: ${({ $visible }) => ($visible ? 1 : 0)};\n transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;\n`;\n","import styled from \"styled-components\";\n\nimport { colors } from \"../../tokens/colors\";\nimport { typographyMixin, typographyTypes } from \"../../tokens/typography\";\nimport { ActionsContainer } from \"../chat-message-actions/chat-message-actions-styles\";\nimport { MESSAGE_ROLE } from \"../constants\";\nimport type { MessageRole } from \"../types\";\n\nexport const MessageRow = styled.div<{ $role: MessageRole }>`\n display: flex;\n justify-content: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"flex-end\" : \"flex-start\")};\n\n &:hover ${ActionsContainer} {\n opacity: 1;\n pointer-events: auto;\n }\n`;\n\nexport const MessageContainer = styled.div<{ $role: MessageRole }>`\n display: flex;\n flex-direction: column;\n align-items: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"flex-end\" : \"flex-start\")};\n max-width: 90%;\n width: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"auto\" : \"100%\")};\n gap: 12px;\n`;\n\nexport const MessageBubble = styled.div<{ $role: MessageRole }>`\n ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};\n color: ${colors[\"brown-100\"]};\n background: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? colors.white : \"transparent\")};\n padding: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"12px 16px\" : \"0\")};\n border-radius: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"16px\" : \"0\")};\n max-width: 100%;\n min-width: 0;\n`;\n","import type { ChatMessage as ChatMessageType } from \"../types\";\nimport { ChatMessageContent } from \"../chat-message-content/chat-message-content\";\nimport { ChatMessageActions } from \"../chat-message-actions/chat-message-actions\";\nimport { MessageRow, MessageBubble, MessageContainer } from \"./chat-message-styles\";\n\ninterface ChatMessageProps {\n message: ChatMessageType;\n}\n\nexport function ChatMessage({ message }: ChatMessageProps) {\n return (\n <MessageRow $role={message.role}>\n <MessageContainer $role={message.role}>\n <MessageBubble $role={message.role}>\n <ChatMessageContent content={message.content} />\n </MessageBubble>\n <ChatMessageActions\n messageId={message.id}\n content={message.content}\n role={message.role}\n isHelpful={message.isHelpful}\n />\n </MessageContainer>\n </MessageRow>\n );\n}\n"],"mappings":"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","names":["styled","ReactMarkdown","remarkGfm","remarkBreaks","import_react","__iconNode","__iconNode","__iconNode","import_react","import_styled_components","styled","import_jsx_runtime","Icon","import_styled_components","styled","import_jsx_runtime","import_react","import_react","import_styled_components","styled","import_jsx_runtime","import_styled_components","styled","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/components/chat/index.ts","../src/components/chat/chat-message-content/chat-message-content.tsx","../src/components/chat/chat-message-content/chat-message-content-styles.ts","../src/tokens/colors.ts","../src/tokens/typography.ts","../src/components/chat/chat-message-actions/chat-message-actions.tsx","../node_modules/@tabler/icons-react/src/defaultAttributes.ts","../node_modules/@tabler/icons-react/src/createReactComponent.ts","../node_modules/@tabler/icons-react/src/icons/IconCheck.ts","../node_modules/@tabler/icons-react/src/icons/IconCopy.ts","../node_modules/@tabler/icons-react/src/icons/IconThumbDown.ts","../node_modules/@tabler/icons-react/src/icons/IconThumbUp.ts","../src/components/icon/icon.tsx","../src/components/icon/icon-styles.ts","../src/components/icon-button/icon-button-styles.ts","../src/components/icon-button/icon-button.tsx","../src/components/chat/chat-context/chat-context.ts","../src/components/chat/hooks/use-copy-to-clipboard.ts","../src/utils/clipboard.ts","../src/utils/markdown-to-plain-text.ts","../src/components/chat/constants.ts","../src/components/chat/chat-message-actions/chat-message-actions-styles.ts","../src/components/chat/chat-message/chat-message-styles.ts","../src/components/chat/chat-message/chat-message.tsx"],"sourcesContent":["export { ChatMessage } from \"./chat-message/chat-message\";\nexport { useChatContext, ChatContext } from \"./chat-context/chat-context\";\nexport { useCopyToClipboard } from \"./hooks/use-copy-to-clipboard\";\nexport { MESSAGE_ROLE } from \"./constants\";\nexport type { ChatMessage as ChatMessageType, MessageRole, ChatContextValue } from \"./types\";\n","import type { ReactNode } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { ContentWrapper, TableScroll } from \"./chat-message-content-styles\";\n\ninterface ChatMessageContentProps {\n content: string;\n}\n\nfunction ScrollableTable({ node: _node, ...props }: { node?: unknown; children?: ReactNode }): ReactNode {\n return (\n <TableScroll>\n <table {...props} />\n </TableScroll>\n );\n}\n\nconst markdownComponents = {\n table: ScrollableTable as React.ComponentType<unknown>,\n};\n\nexport function ChatMessageContent({ content }: ChatMessageContentProps) {\n return (\n <ContentWrapper>\n <ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]} components={markdownComponents}>\n {content}\n </ReactMarkdown>\n </ContentWrapper>\n );\n}\n","import styled from \"styled-components\";\n\nimport { colors } from \"../../../tokens/colors\";\nimport { typographyMixin, typographyTypes } from \"../../../tokens/typography\";\n\nexport const ContentWrapper = styled.div`\n ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};\n color: ${colors[\"brown-100\"]};\n word-break: break-word;\n\n & h1 {\n ${typographyMixin(typographyTypes.GEIST_HEADING_S_BOLD)};\n margin-block: 20px;\n }\n\n & h2 {\n ${typographyMixin(typographyTypes.GEIST_BODY_L_SEMI_BOLD)};\n margin-block: 12px;\n }\n\n & h3,\n & h4,\n & h5,\n & h6 {\n ${typographyMixin(typographyTypes.GEIST_BODY_M_SEMI_BOLD)};\n margin-block: 8px;\n }\n\n & strong {\n ${typographyMixin(typographyTypes.GEIST_BODY_S_SEMI_BOLD)};\n }\n\n & p {\n margin-block: 0px;\n }\n\n & p + p {\n margin-block: 8px 0px;\n }\n\n & ul,\n & ol {\n margin-block: 16px;\n padding-left: 20px;\n }\n\n & li + li {\n margin-block: 4px;\n }\n\n & ol {\n list-style-type: decimal;\n }\n\n & ol ol {\n list-style-type: lower-alpha;\n }\n\n & ol ol ol {\n list-style-type: lower-roman;\n }\n\n & a {\n color: inherit;\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: auto;\n text-underline-offset: auto;\n text-underline-position: from-font;\n transition: color 75ms ease-in-out;\n\n &:hover {\n color: ${colors[\"blue-600\"]};\n }\n }\n\n & hr {\n border: none;\n border-top: 1px solid ${colors[\"brown-40\"]};\n margin-block: 20px;\n }\n\n & table {\n margin: 0;\n width: 100%;\n border-collapse: collapse;\n }\n\n & th,\n & td {\n border: none;\n border-bottom: 1px solid ${colors[\"brown-40\"]};\n text-align: left;\n }\n\n & th {\n ${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};\n padding: 8px;\n }\n\n & td {\n ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};\n padding: 16px 8px;\n min-width: 150px;\n width: 1%;\n }\n\n & td strong {\n font-weight: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n\n & blockquote {\n margin-block: 4px;\n margin-inline: 0px;\n padding-left: 16px;\n border-left: 4px solid ${colors[\"brown-40\"]};\n color: ${colors[\"brown-80\"]};\n }\n`;\n\nexport const TableScroll = styled.div`\n width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n margin-block: 8px 16px;\n`;\n","export const colors = {\n // White\n white: \"#FFFFFF\",\n \"white-alpha-85\": \"rgba(255, 255, 255, 0.85)\",\n \"white-alpha-40\": \"rgba(255, 255, 255, 0.40)\",\n\n // Brown\n \"brown-10\": \"#FAF9F8\",\n \"brown-20\": \"#F5F3F0\",\n \"brown-30\": \"#EEEBE5\",\n \"brown-40\": \"#E6E2DA\",\n \"brown-50\": \"#CFCBC4\",\n \"brown-60\": \"#A19E99\",\n \"brown-70\": \"#73716D\",\n \"brown-80\": \"#5C5A57\",\n \"brown-90\": \"#2E2D2C\",\n \"brown-100\": \"#171716\",\n \"brown-alpha-12\": \"rgba(23, 23, 22, 0.12)\",\n \"brown-alpha-20\": \"rgba(23, 23, 22, 0.20)\",\n \"brown-alpha-55\": \"rgba(23, 23, 22, 0.55)\",\n \"brown-alpha-70\": \"rgba(23, 23, 22, 0.70)\",\n \"brown-alpha-80\": \"rgba(23, 23, 22, 0.80)\",\n \"brown-alpha-90\": \"rgba(23, 23, 22, 0.90)\",\n\n // Fuchsia\n \"fuchsia-50\": \"#FAF5FF\",\n \"fuchsia-300\": \"#F0ABFC\",\n \"fuchsia-500\": \"#D946EF\",\n \"fuchsia-600\": \"#C026D3\",\n \"fuchsia-800\": \"#86198F\",\n\n // Pink\n \"pink-50\": \"#FDF2F8\",\n \"pink-400\": \"#F472B6\",\n \"pink-600\": \"#DB2777\",\n \"pink-800\": \"#9D174D\",\n\n // Violet\n \"violet-50\": \"#F5F3FF\",\n \"violet-400\": \"#A78BFA\",\n \"violet-600\": \"#7C3AED\",\n \"violet-800\": \"#5B21B6\",\n\n // Indigo\n \"indigo-50\": \"#EEF2FF\",\n \"indigo-400\": \"#818CF8\",\n \"indigo-500\": \"#6366F1\",\n \"indigo-600\": \"#4F46E5\",\n \"indigo-800\": \"#3730A3\",\n\n // Cyan\n \"cyan-50\": \"#E7FEFF\",\n \"cyan-300\": \"#67E8F9\",\n \"cyan-600\": \"#0891B2\",\n \"cyan-900\": \"#164E63\",\n\n // Teal\n \"teal-50\": \"#EBFDF9\",\n \"teal-300\": \"#5EEAD4\",\n \"teal-600\": \"#0D9488\",\n\n // Rose\n \"rose-400\": \"#FB7185\",\n\n // Purple\n \"purple-400\": \"#C084FC\",\n\n // Blue\n \"blue-50\": \"#EFF6FF\",\n \"blue-100\": \"#DBEAFE\",\n \"blue-300\": \"#93C5FD\",\n \"blue-400\": \"#60A5FA\",\n \"blue-600\": \"#2563EB\",\n \"blue-800\": \"#1E40AF\",\n\n // Sky\n \"sky-300\": \"#7DD3FC\",\n\n // Green\n \"green-50\": \"#ECF9F0\",\n \"green-100\": \"#D4F1D9\",\n \"green-400\": \"#3DC269\",\n \"green-700\": \"#277C43\",\n \"green-800\": \"#1C5930\",\n\n // Orange\n \"orange-50\": \"#FFF7ED\",\n \"orange-100\": \"#FFEDD5\",\n \"orange-200\": \"#FED7AA\",\n \"orange-500\": \"#F97316\",\n \"orange-600\": \"#EA580C\",\n\n // Red\n \"red-50\": \"#FEF2F2\",\n \"red-100\": \"#FEE2E2\",\n \"red-200\": \"#FECACA\",\n \"red-400\": \"#F7776C\",\n \"red-500\": \"#EF4444\",\n \"red-600\": \"#DC2626\",\n} as const;\n\nexport type ColorToken = keyof typeof colors;\n","/** Available font families in the Shapes.co design system. */\nexport const fontFamilies = {\n /** Geist — primary UI font for body text, labels, headings, and display. */\n GEIST: \"Geist\",\n /** Crimson Pro — editorial/serif font, always italic. Used for decorative headings and pull quotes. */\n CRIMSON_PRO: \"Crimson Pro\",\n} as const;\n\nexport const typographyTypes = {\n // Geist Label Caption (12px)\n GEIST_LABEL_CAPTION_REGULAR: \"GEIST_LABEL_CAPTION_REGULAR\",\n GEIST_LABEL_CAPTION_MEDIUM: \"GEIST_LABEL_CAPTION_MEDIUM\",\n GEIST_LABEL_CAPTION_SEMI_BOLD: \"GEIST_LABEL_CAPTION_SEMI_BOLD\",\n\n // Geist Body Extra Small (14px)\n GEIST_BODY_XS_REGULAR: \"GEIST_BODY_XS_REGULAR\",\n GEIST_BODY_XS_MEDIUM: \"GEIST_BODY_XS_MEDIUM\",\n GEIST_BODY_XS_BOLD: \"GEIST_BODY_XS_BOLD\",\n\n // Geist Body Small (16px)\n GEIST_BODY_S_REGULAR: \"GEIST_BODY_S_REGULAR\",\n GEIST_BODY_S_MEDIUM: \"GEIST_BODY_S_MEDIUM\",\n GEIST_BODY_S_SEMI_BOLD: \"GEIST_BODY_S_SEMI_BOLD\",\n GEIST_BODY_S_BOLD: \"GEIST_BODY_S_BOLD\",\n\n // Geist Body Medium (18px)\n GEIST_BODY_M_LIGHT: \"GEIST_BODY_M_LIGHT\",\n GEIST_BODY_M_REGULAR: \"GEIST_BODY_M_REGULAR\",\n GEIST_BODY_M_MEDIUM: \"GEIST_BODY_M_MEDIUM\",\n GEIST_BODY_M_SEMI_BOLD: \"GEIST_BODY_M_SEMI_BOLD\",\n\n // Geist Body Large (20px)\n GEIST_BODY_L_REGULAR: \"GEIST_BODY_L_REGULAR\",\n GEIST_BODY_L_MEDIUM: \"GEIST_BODY_L_MEDIUM\",\n GEIST_BODY_L_SEMI_BOLD: \"GEIST_BODY_L_SEMI_BOLD\",\n GEIST_BODY_L_BOLD: \"GEIST_BODY_L_BOLD\",\n\n // Geist Heading Small (24px)\n GEIST_HEADING_S_REGULAR: \"GEIST_HEADING_S_REGULAR\",\n GEIST_HEADING_S_MEDIUM: \"GEIST_HEADING_S_MEDIUM\",\n GEIST_HEADING_S_BOLD: \"GEIST_HEADING_S_BOLD\",\n\n // Geist Heading Medium (28px)\n GEIST_HEADING_M_BOLD: \"GEIST_HEADING_M_BOLD\",\n\n // Geist Heading Large (32px)\n GEIST_HEADING_L_REGULAR: \"GEIST_HEADING_L_REGULAR\",\n GEIST_HEADING_L_MEDIUM: \"GEIST_HEADING_L_MEDIUM\",\n GEIST_HEADING_L_SEMI_BOLD: \"GEIST_HEADING_L_SEMI_BOLD\",\n GEIST_HEADING_L_BOLD: \"GEIST_HEADING_L_BOLD\",\n\n // Geist Display Large (36px)\n GEIST_DISPLAY_L_MEDIUM: \"GEIST_DISPLAY_L_MEDIUM\",\n\n // Crimson Pro Body Small (16px)\n CRIMSON_PRO_BODY_S_LIGHT: \"CRIMSON_PRO_BODY_S_LIGHT\",\n\n // Crimson Pro Body Medium (18px)\n CRIMSON_PRO_BODY_M_LIGHT: \"CRIMSON_PRO_BODY_M_LIGHT\",\n\n // Crimson Pro Heading Medium (24px)\n CRIMSON_PRO_HEADING_M_MEDIUM: \"CRIMSON_PRO_HEADING_M_MEDIUM\",\n\n // Crimson Pro Display Extra Large (46px)\n CRIMSON_PRO_DISPLAY_XL_REGULAR: \"CRIMSON_PRO_DISPLAY_XL_REGULAR\",\n} as const;\n\n/** Union of all typography type string constants. Used as keys into `typographyStyles`. */\nexport type TypographyType = (typeof typographyTypes)[keyof typeof typographyTypes];\n\n/** CSS properties for a single typography type. All numeric values are in pixels. */\nexport interface TypographyStyle {\n /** Font family name (e.g., \"Geist\"). */\n fontFamily: string;\n /** Font size in pixels. */\n fontSize: number;\n /** Font weight (100–900). */\n fontWeight: number;\n /** Line height in pixels. */\n lineHeight: number;\n /** Letter spacing in pixels. Omitted when the font's default spacing is correct. */\n letterSpacing?: number;\n /** CSS font-style value (e.g., \"italic\"). Omitted for normal style. */\n fontStyle?: string;\n}\n\nexport const typographyStyles: Record<TypographyType, TypographyStyle> = {\n // Geist Label Caption (12px)\n [typographyTypes.GEIST_LABEL_CAPTION_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 400,\n lineHeight: 16,\n },\n [typographyTypes.GEIST_LABEL_CAPTION_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 500,\n lineHeight: 16,\n },\n [typographyTypes.GEIST_LABEL_CAPTION_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 600,\n lineHeight: 16,\n },\n\n // Geist Body Extra Small (14px)\n [typographyTypes.GEIST_BODY_XS_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 400,\n lineHeight: 20,\n },\n [typographyTypes.GEIST_BODY_XS_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 500,\n lineHeight: 20,\n },\n [typographyTypes.GEIST_BODY_XS_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 600,\n lineHeight: 20,\n },\n\n // Geist Body Small (16px)\n [typographyTypes.GEIST_BODY_S_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 400,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 500,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 600,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 700,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n\n // Geist Body Medium (18px)\n [typographyTypes.GEIST_BODY_M_LIGHT]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 300,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 400,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 500,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 600,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n\n // Geist Body Large (20px)\n [typographyTypes.GEIST_BODY_L_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 400,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 500,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 600,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 700,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n\n // Geist Heading Small (24px)\n [typographyTypes.GEIST_HEADING_S_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 400,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n [typographyTypes.GEIST_HEADING_S_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 500,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n [typographyTypes.GEIST_HEADING_S_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n\n // Geist Heading Medium (28px)\n [typographyTypes.GEIST_HEADING_M_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 28,\n fontWeight: 700,\n lineHeight: 36,\n letterSpacing: -0.6,\n },\n\n // Geist Heading Large (32px)\n [typographyTypes.GEIST_HEADING_L_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 400,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 500,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 600,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 700,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n\n // Geist Display Large (36px)\n [typographyTypes.GEIST_DISPLAY_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 36,\n fontWeight: 500,\n lineHeight: 44,\n letterSpacing: -0.72,\n },\n\n // Crimson Pro Body Small (16px)\n [typographyTypes.CRIMSON_PRO_BODY_S_LIGHT]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 16,\n fontWeight: 300,\n lineHeight: 20,\n letterSpacing: -0.32,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Body Medium (18px)\n [typographyTypes.CRIMSON_PRO_BODY_M_LIGHT]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 18,\n fontWeight: 300,\n lineHeight: 28,\n letterSpacing: 0,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Heading Medium (24px)\n [typographyTypes.CRIMSON_PRO_HEADING_M_MEDIUM]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 24,\n fontWeight: 400,\n lineHeight: 32,\n letterSpacing: -0.48,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Display Extra Large (46px)\n [typographyTypes.CRIMSON_PRO_DISPLAY_XL_REGULAR]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 46,\n fontWeight: 400,\n lineHeight: 54,\n letterSpacing: -1.38,\n fontStyle: \"italic\",\n },\n};\n\n/**\n * Generates a CSS string for a given typography type, suitable for use in styled-components template literals.\n * @param type - The typography type constant (e.g., `typographyTypes.GEIST_BODY_S_REGULAR`).\n * @returns A semicolon-separated CSS string with font-family, font-size, font-weight, line-height, letter-spacing, and font-style.\n */\nexport function typographyMixin(type: TypographyType): string {\n const style = typographyStyles[type];\n return [\n `font-family: \"${style.fontFamily}\", sans-serif`,\n `font-size: ${style.fontSize}px`,\n `font-weight: ${style.fontWeight}`,\n `line-height: ${style.lineHeight}px`,\n `letter-spacing: ${style.letterSpacing != null ? `${style.letterSpacing}px` : \"inherit\"}`,\n `font-style: ${style.fontStyle ?? \"normal\"}`,\n ].join(\";\\n \");\n}\n","import { useCallback } from \"react\";\nimport { IconCopy, IconCheck, IconThumbUp, IconThumbDown } from \"@tabler/icons-react\";\n\nimport { IconButton } from \"../../icon-button/icon-button\";\nimport { useChatContext } from \"../chat-context/chat-context\";\nimport { useCopyToClipboard } from \"../hooks/use-copy-to-clipboard\";\nimport { MESSAGE_ROLE } from \"../constants\";\nimport type { MessageRole } from \"../types\";\nimport { ActionsContainer, AnimatedAction } from \"./chat-message-actions-styles\";\n\ninterface ChatMessageActionsProps {\n className?: string;\n messageId: string;\n content: string;\n role: MessageRole;\n isHelpful?: boolean | null;\n}\n\nexport function ChatMessageActions({ className, messageId, content, role, isHelpful }: ChatMessageActionsProps) {\n const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();\n const { isCopied, copy } = useCopyToClipboard();\n\n const handleCopy = useCallback(() => {\n copy(content);\n onCopyMessage?.(messageId);\n }, [content, messageId, copy, onCopyMessage]);\n\n const handleThumbUp = useCallback(() => {\n onThumbUpClick?.(messageId, isHelpful === true ? null : true);\n }, [messageId, isHelpful, onThumbUpClick]);\n\n const handleThumbDown = useCallback(() => {\n onThumbDownClick?.(messageId, isHelpful === false ? null : false);\n }, [messageId, isHelpful, onThumbDownClick]);\n\n const isAssistant = role === MESSAGE_ROLE.ASSISTANT;\n const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);\n\n return (\n <ActionsContainer $role={role} className={className}>\n <IconButton\n icon={isCopied ? IconCheck : IconCopy}\n onClick={handleCopy}\n aria-label={isCopied ? \"Copied\" : \"Copy message\"}\n />\n\n {hasFeedback && (\n <AnimatedAction $visible={isHelpful !== false}>\n <IconButton\n icon={IconThumbUp}\n onClick={handleThumbUp}\n isSelected={isHelpful === true}\n aria-label=\"Good response\"\n />\n </AnimatedAction>\n )}\n\n {hasFeedback && (\n <AnimatedAction $visible={isHelpful !== true}>\n <IconButton\n icon={IconThumbDown}\n onClick={handleThumbDown}\n isSelected={isHelpful === false}\n aria-label=\"Bad response\"\n />\n </AnimatedAction>\n )}\n </ActionsContainer>\n );\n}\n","export default {\n outline: {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n },\n filled: {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'currentColor',\n stroke: 'none',\n },\n};\n","import { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport type { IconNode, IconProps, Icon } from './types';\n\nconst createReactComponent = (\n type: 'outline' | 'filled',\n iconName: string,\n iconNamePascal: string,\n iconNode: IconNode,\n) => {\n const Component = forwardRef<SVGSVGElement, IconProps>(\n (\n { color = 'currentColor', size = 24, stroke = 2, title, className, children, ...rest }: IconProps,\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes[type],\n width: size,\n height: size,\n className: [`tabler-icon`, `tabler-icon-${iconName}`, className].join(' '),\n ...(type === 'filled'\n ? {\n fill: color,\n }\n : {\n strokeWidth: stroke,\n stroke: color,\n }),\n ...rest,\n },\n [\n title && createElement('title', { key: 'svg-title' }, title),\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n );\n\n Component.displayName = `${iconNamePascal}`;\n\n return Component;\n};\n\nexport default createReactComponent;\n","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"path\",{\"d\":\"M5 12l5 5l10 -10\",\"key\":\"svg-0\"}]]\n\nconst IconCheck = createReactComponent('outline', 'check', 'Check', __iconNode);\n\nexport default IconCheck;","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"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\"}]]\n\nconst IconCopy = createReactComponent('outline', 'copy', 'Copy', __iconNode);\n\nexport default IconCopy;","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"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\"}]]\n\nconst IconThumbDown = createReactComponent('outline', 'thumb-down', 'ThumbDown', __iconNode);\n\nexport default IconThumbDown;","import createReactComponent from '../createReactComponent';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [[\"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\"}]]\n\nconst IconThumbUp = createReactComponent('outline', 'thumb-up', 'ThumbUp', __iconNode);\n\nexport default IconThumbUp;","import { forwardRef } from \"react\";\n\nimport { IconWrapper, getStrokeWidth } from \"./icon-styles\";\nimport type { IconProps } from \"./types\";\n\nconst DEFAULT_SIZE = 16;\n\nexport const Icon = forwardRef<HTMLSpanElement, IconProps>(function Icon(\n { icon: IconComponent, size = DEFAULT_SIZE, color, className, \"aria-label\": ariaLabel },\n ref\n) {\n return (\n <IconWrapper\n ref={ref}\n className={className}\n $color={color}\n aria-label={ariaLabel}\n role={ariaLabel ? \"img\" : undefined}\n >\n <IconComponent width={size} height={size} strokeWidth={getStrokeWidth(size)} />\n </IconWrapper>\n );\n});\n","import styled from \"styled-components\";\n\nexport const STROKE_WIDTH_BY_SIZE: Record<number, number> = {\n 12: 1.4,\n 14: 1.4,\n 16: 1.8,\n 18: 1.8,\n 20: 1.8,\n 24: 1.8,\n};\n\nexport const DEFAULT_STROKE_WIDTH = 1.8;\n\nexport function getStrokeWidth(size: number): number {\n return STROKE_WIDTH_BY_SIZE[size] ?? DEFAULT_STROKE_WIDTH;\n}\n\nexport const IconWrapper = styled.span<{ $color?: string }>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: ${({ $color }) => $color ?? \"currentColor\"};\n flex-shrink: 0;\n`;\n","import styled from \"styled-components\";\n\nimport { colors } from \"../../tokens/colors\";\nimport type { IconButtonSize, IconButtonVariant } from \"./types\";\n\nconst PADDING: Record<IconButtonVariant, Record<IconButtonSize, string>> = {\n short: {\n small: \"4px\",\n medium: \"6px\",\n },\n long: {\n small: \"4px 6px\",\n medium: \"6px 10px\",\n },\n};\n\nconst BORDER_RADIUS: Record<IconButtonSize, number> = {\n small: 6,\n medium: 10,\n};\n\nexport const Button = styled.button<{\n $size: IconButtonSize;\n $variant: IconButtonVariant;\n $isSelected: boolean;\n}>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: ${({ $size, $variant }) => PADDING[$variant][$size]};\n border: none;\n border-radius: ${({ $size }) => BORDER_RADIUS[$size]}px;\n background: ${({ $isSelected }) => ($isSelected ? colors[\"brown-40\"] : \"transparent\")};\n color: ${colors[\"brown-100\"]};\n cursor: pointer;\n transition: background-color 100ms ease;\n\n &:hover {\n background: ${({ $isSelected }) => ($isSelected ? colors[\"brown-40\"] : colors[\"brown-20\"])};\n }\n\n &:active {\n background: ${colors[\"brown-40\"]};\n }\n\n &:disabled {\n color: ${colors[\"brown-50\"]};\n background: transparent;\n cursor: not-allowed;\n }\n`;\n","import { Icon } from \"../icon/icon\";\nimport { Button } from \"./icon-button-styles\";\nimport type { IconButtonProps, IconButtonSize } from \"./types\";\n\nconst ICON_SIZE_BY_BUTTON_SIZE: Record<IconButtonSize, number> = {\n small: 16,\n medium: 20,\n};\n\nexport function IconButton({\n icon,\n size = \"small\",\n variant = \"short\",\n isSelected = false,\n disabled = false,\n onClick,\n className,\n id,\n as,\n \"aria-label\": ariaLabel,\n}: IconButtonProps): React.ReactNode {\n return (\n <Button\n className={className}\n id={id}\n as={as}\n $size={size}\n $variant={variant}\n $isSelected={isSelected}\n disabled={disabled}\n onClick={disabled ? undefined : onClick}\n aria-label={ariaLabel}\n >\n <Icon icon={icon} size={ICON_SIZE_BY_BUTTON_SIZE[size]} />\n </Button>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport type { ChatContextValue } from \"../types\";\n\nexport const ChatContext = createContext<ChatContextValue | null>(null);\n\nexport function useChatContext(): ChatContextValue {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error(\"useChatContext must be used within a Chat.Root component\");\n }\n return context;\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\n\nimport { copyToClipboard } from \"@/utils/clipboard\";\nimport { markdownToPlainText } from \"@/utils/markdown-to-plain-text\";\n\nconst RESET_DELAY_MS = 2000;\n\ninterface UseCopyToClipboardResult {\n isCopied: boolean;\n copy: (text: string) => void;\n}\n\nexport function useCopyToClipboard(): UseCopyToClipboardResult {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const copy = useCallback((text: string) => {\n copyToClipboard(markdownToPlainText(text), {\n onSuccess: () => {\n setIsCopied(true);\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => {\n setIsCopied(false);\n timeoutRef.current = null;\n }, RESET_DELAY_MS);\n },\n });\n }, []);\n\n return { isCopied, copy };\n}\n","/** Options for the {@link copyToClipboard} function. */\ninterface CopyToClipboardOptions {\n /** Called after the text has been successfully written to the clipboard. */\n onSuccess?: () => void;\n /** Called if the clipboard write fails (e.g., permission denied). */\n onFailure?: (error: unknown) => void;\n}\n\n/**\n * Copies text to the system clipboard using the Clipboard API.\n * @param text - The string to copy.\n * @param options - Optional success/failure callbacks.\n */\nexport function copyToClipboard(text: string, options?: CopyToClipboardOptions): void {\n navigator.clipboard.writeText(text).then(\n () => options?.onSuccess?.(),\n (error) => options?.onFailure?.(error)\n );\n}\n","const PLACEHOLDER_PREFIX = \"\\u200B\\u200BIC\";\nconst PLACEHOLDER_SUFFIX = \"\\u200B\\u200B\";\nconst PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\\\d+)${PLACEHOLDER_SUFFIX}`, \"g\");\n\n/**\n * Converts a Markdown string to plain text by stripping all formatting syntax.\n *\n * Handles headings, bold/italic/strikethrough, links, images, blockquotes, code blocks,\n * inline code, tables, and horizontal rules. Inline code content is preserved literally\n * (formatting inside backticks is not stripped).\n *\n * @param markdown - The Markdown source string.\n * @returns A plain-text string with all Markdown syntax removed.\n */\nexport function markdownToPlainText(markdown: string): string {\n if (!markdown) return \"\";\n\n // Protect inline code content from bold/italic stripping by replacing with placeholders\n const inlineCodeSnippets: string[] = [];\n let result = markdown\n // Code blocks (must come first)\n .replace(/```[\\s\\S]*?```/g, \"\")\n // Inline code → placeholder\n .replace(/`([^`]+)`/g, (_match, code: string) => {\n inlineCodeSnippets.push(code);\n return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;\n })\n // Remove headings markers, keep text\n .replace(/^#{1,6}\\s+/gm, \"\")\n // Remove horizontal rules\n .replace(/^(?:---|\\*\\*\\*|___)\\s*$/gm, \"\")\n // Bold + italic\n .replace(/\\*{3}(.+?)\\*{3}/g, \"$1\")\n // Bold\n .replace(/\\*{2}(.+?)\\*{2}/g, \"$1\")\n .replace(/_{2}(.+?)_{2}/g, \"$1\")\n // Italic\n .replace(/\\*(.+?)\\*/g, \"$1\")\n .replace(/_(.+?)_/g, \"$1\")\n // Strikethrough\n .replace(/~~(.+?)~~/g, \"$1\")\n // Images: ![alt](url) → alt (must come before links)\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, \"$1\")\n // Links: [text](url) → text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n // Blockquote markers\n .replace(/^>\\s?/gm, \"\")\n // Table separator rows (|---|---|)\n .replace(/^\\|[-:\\s|]+\\|\\s*$/gm, \"\")\n // Table rows: | a | b | → a | b\n .replace(/^\\|\\s?/gm, \"\")\n .replace(/\\s?\\|$/gm, \"\")\n // Collapse multiple blank lines\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n\n // Restore inline code content\n result = result.replace(PLACEHOLDER_REGEX, (_match, index: string) => inlineCodeSnippets[Number(index)]);\n\n return result;\n}\n","export const MESSAGE_ROLE = {\n USER: \"user\",\n ASSISTANT: \"assistant\",\n} as const;\n","import styled from \"styled-components\";\n\nimport { MESSAGE_ROLE } from \"../constants\";\nimport type { MessageRole } from \"../types\";\n\nconst FADE_DURATION_MS = 150;\nconst ANIMATE_DURATION_MS = 200;\n\nexport const ActionsContainer = styled.div<{ $role: MessageRole }>`\n display: flex;\n opacity: ${({ $role }) => ($role === MESSAGE_ROLE.ASSISTANT ? 1 : 0)};\n pointer-events: ${({ $role }) => ($role === MESSAGE_ROLE.ASSISTANT ? \"auto\" : \"none\")};\n transition: opacity ${FADE_DURATION_MS}ms ease;\n`;\n\nexport const AnimatedAction = styled.div<{ $visible: boolean }>`\n display: flex;\n overflow: hidden;\n max-width: ${({ $visible }) => ($visible ? \"40px\" : \"0\")};\n opacity: ${({ $visible }) => ($visible ? 1 : 0)};\n transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;\n`;\n","import styled from \"styled-components\";\n\nimport { colors } from \"../../../tokens/colors\";\nimport { typographyMixin, typographyTypes } from \"../../../tokens/typography\";\nimport { ActionsContainer } from \"../chat-message-actions/chat-message-actions-styles\";\nimport { MESSAGE_ROLE } from \"../constants\";\nimport type { MessageRole } from \"../types\";\n\nexport const MessageRow = styled.div<{ $role: MessageRole }>`\n display: flex;\n justify-content: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"flex-end\" : \"flex-start\")};\n\n &:hover ${ActionsContainer} {\n opacity: 1;\n pointer-events: auto;\n }\n`;\n\nexport const MessageContainer = styled.div<{ $role: MessageRole }>`\n display: flex;\n flex-direction: column;\n align-items: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"flex-end\" : \"flex-start\")};\n max-width: 90%;\n width: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"auto\" : \"100%\")};\n gap: 12px;\n`;\n\nexport const MessageBubble = styled.div<{ $role: MessageRole }>`\n ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};\n color: ${colors[\"brown-100\"]};\n background: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? colors.white : \"transparent\")};\n padding: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"12px 16px\" : \"0\")};\n border-radius: ${({ $role }) => ($role === MESSAGE_ROLE.USER ? \"16px\" : \"0\")};\n max-width: 100%;\n min-width: 0;\n`;\n","import type { ChatMessage as ChatMessageType } from \"../types\";\nimport { ChatMessageContent } from \"../chat-message-content/chat-message-content\";\nimport { ChatMessageActions } from \"../chat-message-actions/chat-message-actions\";\nimport { MessageRow, MessageBubble, MessageContainer } from \"./chat-message-styles\";\n\ninterface ChatMessageProps {\n message: ChatMessageType;\n}\n\nexport function ChatMessage({ message }: ChatMessageProps) {\n return (\n <MessageRow $role={message.role} role=\"article\" aria-label={`${message.role} message`}>\n <MessageContainer $role={message.role}>\n <MessageBubble $role={message.role}>\n <ChatMessageContent content={message.content} />\n </MessageBubble>\n <ChatMessageActions\n messageId={message.id}\n content={message.content}\n role={message.role}\n isHelpful={message.isHelpful}\n />\n </MessageContainer>\n </MessageRow>\n );\n}\n"],"mappings":"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","names":["styled","ReactMarkdown","remarkGfm","remarkBreaks","import_react","__iconNode","__iconNode","__iconNode","import_react","import_styled_components","styled","import_jsx_runtime","Icon","import_styled_components","styled","import_jsx_runtime","import_react","import_react","import_styled_components","styled","import_jsx_runtime","import_styled_components","styled","import_jsx_runtime"]}
package/dist/chat.d.cts CHANGED
@@ -1,20 +1,34 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
 
4
+ /** The sender of a chat message. */
4
5
  type MessageRole = "user" | "assistant";
6
+ /** A single message in the chat conversation. */
5
7
  interface ChatMessage$1 {
8
+ /** Unique identifier for the message. */
6
9
  id: string;
10
+ /** Who sent this message — the end-user or the AI assistant. */
7
11
  role: MessageRole;
12
+ /** Message body, rendered as Markdown. */
8
13
  content: string;
14
+ /** Feedback state: `true` = helpful, `false` = not helpful, `null`/`undefined` = no feedback given. */
9
15
  isHelpful?: boolean | null;
10
16
  }
17
+ /** Value provided by the Chat context to all child components. */
11
18
  interface ChatContextValue {
19
+ /** The full list of messages in the conversation. */
12
20
  messages: ChatMessage$1[];
21
+ /** Called when the user submits a new message. Receives the raw text content. */
13
22
  onSendMessage: (content: string) => void;
23
+ /** Whether the assistant is currently generating a response. */
14
24
  isLoading: boolean;
25
+ /** Called when the user clicks "stop" to abort a streaming response. */
15
26
  onStop?: () => void;
27
+ /** Called when a message's content is copied to clipboard. Receives the message ID. */
16
28
  onCopyMessage?: (messageId: string) => void;
29
+ /** Called when the user clicks the "thumbs up" button. Receives the message ID and the new feedback value (`true` = selected, `null` = deselected). */
17
30
  onThumbUpClick?: (messageId: string, isHelpful: boolean | null) => void;
31
+ /** Called when the user clicks the "thumbs down" button. Receives the message ID and the new feedback value (`false` = selected, `null` = deselected). */
18
32
  onThumbDownClick?: (messageId: string, isHelpful: boolean | null) => void;
19
33
  }
20
34
 
package/dist/chat.d.ts CHANGED
@@ -1,20 +1,34 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
 
4
+ /** The sender of a chat message. */
4
5
  type MessageRole = "user" | "assistant";
6
+ /** A single message in the chat conversation. */
5
7
  interface ChatMessage$1 {
8
+ /** Unique identifier for the message. */
6
9
  id: string;
10
+ /** Who sent this message — the end-user or the AI assistant. */
7
11
  role: MessageRole;
12
+ /** Message body, rendered as Markdown. */
8
13
  content: string;
14
+ /** Feedback state: `true` = helpful, `false` = not helpful, `null`/`undefined` = no feedback given. */
9
15
  isHelpful?: boolean | null;
10
16
  }
17
+ /** Value provided by the Chat context to all child components. */
11
18
  interface ChatContextValue {
19
+ /** The full list of messages in the conversation. */
12
20
  messages: ChatMessage$1[];
21
+ /** Called when the user submits a new message. Receives the raw text content. */
13
22
  onSendMessage: (content: string) => void;
23
+ /** Whether the assistant is currently generating a response. */
14
24
  isLoading: boolean;
25
+ /** Called when the user clicks "stop" to abort a streaming response. */
15
26
  onStop?: () => void;
27
+ /** Called when a message's content is copied to clipboard. Receives the message ID. */
16
28
  onCopyMessage?: (messageId: string) => void;
29
+ /** Called when the user clicks the "thumbs up" button. Receives the message ID and the new feedback value (`true` = selected, `null` = deselected). */
17
30
  onThumbUpClick?: (messageId: string, isHelpful: boolean | null) => void;
31
+ /** Called when the user clicks the "thumbs down" button. Receives the message ID and the new feedback value (`false` = selected, `null` = deselected). */
18
32
  onThumbDownClick?: (messageId: string, isHelpful: boolean | null) => void;
19
33
  }
20
34
 
package/dist/chat.js CHANGED
@@ -4,12 +4,12 @@ import {
4
4
  MESSAGE_ROLE,
5
5
  useChatContext,
6
6
  useCopyToClipboard
7
- } from "./chunk-SYMZU32H.js";
7
+ } from "./chunk-J6VPAHO3.js";
8
8
  import "./chunk-MLCRDVQ2.js";
9
- import "./chunk-WQ2QTUYA.js";
9
+ import "./chunk-SV24ONND.js";
10
10
  import "./chunk-OLJIJYB5.js";
11
11
  import "./chunk-JF3P66JF.js";
12
- import "./chunk-SMTOVZ3O.js";
12
+ import "./chunk-WYGH3FKT.js";
13
13
  import "./chunk-5WRI5ZAA.js";
14
14
  export {
15
15
  ChatContext,
@@ -4,20 +4,20 @@ import {
4
4
  import {
5
5
  typographyMixin,
6
6
  typographyTypes
7
- } from "./chunk-WQ2QTUYA.js";
7
+ } from "./chunk-SV24ONND.js";
8
8
  import {
9
9
  colors
10
10
  } from "./chunk-JF3P66JF.js";
11
11
  import {
12
12
  markdownToPlainText
13
- } from "./chunk-SMTOVZ3O.js";
13
+ } from "./chunk-WYGH3FKT.js";
14
14
 
15
- // src/chat/chat-message-content/chat-message-content.tsx
15
+ // src/components/chat/chat-message-content/chat-message-content.tsx
16
16
  import ReactMarkdown from "react-markdown";
17
17
  import remarkBreaks from "remark-breaks";
18
18
  import remarkGfm from "remark-gfm";
19
19
 
20
- // src/chat/chat-message-content/chat-message-content-styles.ts
20
+ // src/components/chat/chat-message-content/chat-message-content-styles.ts
21
21
  import styled from "styled-components";
22
22
  var ContentWrapper = styled.div`
23
23
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
@@ -142,7 +142,7 @@ var TableScroll = styled.div`
142
142
  margin-block: 8px 16px;
143
143
  `;
144
144
 
145
- // src/chat/chat-message-content/chat-message-content.tsx
145
+ // src/components/chat/chat-message-content/chat-message-content.tsx
146
146
  import { jsx } from "react/jsx-runtime";
147
147
  function ScrollableTable({ node: _node, ...props }) {
148
148
  return /* @__PURE__ */ jsx(TableScroll, { children: /* @__PURE__ */ jsx("table", { ...props }) });
@@ -154,7 +154,7 @@ function ChatMessageContent({ content }) {
154
154
  return /* @__PURE__ */ jsx(ContentWrapper, { children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm, remarkBreaks], components: markdownComponents, children: content }) });
155
155
  }
156
156
 
157
- // src/chat/chat-message-actions/chat-message-actions.tsx
157
+ // src/components/chat/chat-message-actions/chat-message-actions.tsx
158
158
  import { useCallback as useCallback2 } from "react";
159
159
 
160
160
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
@@ -229,7 +229,7 @@ var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", _
229
229
  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" }]];
230
230
  var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode4);
231
231
 
232
- // src/chat/chat-context/chat-context.ts
232
+ // src/components/chat/chat-context/chat-context.ts
233
233
  import { createContext, useContext } from "react";
234
234
  var ChatContext = createContext(null);
235
235
  function useChatContext() {
@@ -240,7 +240,7 @@ function useChatContext() {
240
240
  return context;
241
241
  }
242
242
 
243
- // src/chat/hooks/use-copy-to-clipboard.ts
243
+ // src/components/chat/hooks/use-copy-to-clipboard.ts
244
244
  import { useState, useCallback, useRef, useEffect } from "react";
245
245
 
246
246
  // src/utils/clipboard.ts
@@ -251,7 +251,7 @@ function copyToClipboard(text, options) {
251
251
  );
252
252
  }
253
253
 
254
- // src/chat/hooks/use-copy-to-clipboard.ts
254
+ // src/components/chat/hooks/use-copy-to-clipboard.ts
255
255
  var RESET_DELAY_MS = 2e3;
256
256
  function useCopyToClipboard() {
257
257
  const [isCopied, setIsCopied] = useState(false);
@@ -276,13 +276,13 @@ function useCopyToClipboard() {
276
276
  return { isCopied, copy };
277
277
  }
278
278
 
279
- // src/chat/constants.ts
279
+ // src/components/chat/constants.ts
280
280
  var MESSAGE_ROLE = {
281
281
  USER: "user",
282
282
  ASSISTANT: "assistant"
283
283
  };
284
284
 
285
- // src/chat/chat-message-actions/chat-message-actions-styles.ts
285
+ // src/components/chat/chat-message-actions/chat-message-actions-styles.ts
286
286
  import styled2 from "styled-components";
287
287
  var FADE_DURATION_MS = 150;
288
288
  var ANIMATE_DURATION_MS = 200;
@@ -300,7 +300,7 @@ var AnimatedAction = styled2.div`
300
300
  transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;
301
301
  `;
302
302
 
303
- // src/chat/chat-message-actions/chat-message-actions.tsx
303
+ // src/components/chat/chat-message-actions/chat-message-actions.tsx
304
304
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
305
305
  function ChatMessageActions({ className, messageId, content, role, isHelpful }) {
306
306
  const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
@@ -347,7 +347,7 @@ function ChatMessageActions({ className, messageId, content, role, isHelpful })
347
347
  ] });
348
348
  }
349
349
 
350
- // src/chat/chat-message/chat-message-styles.ts
350
+ // src/components/chat/chat-message/chat-message-styles.ts
351
351
  import styled3 from "styled-components";
352
352
  var MessageRow = styled3.div`
353
353
  display: flex;
@@ -376,10 +376,10 @@ var MessageBubble = styled3.div`
376
376
  min-width: 0;
377
377
  `;
378
378
 
379
- // src/chat/chat-message/chat-message.tsx
379
+ // src/components/chat/chat-message/chat-message.tsx
380
380
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
381
381
  function ChatMessage({ message }) {
382
- return /* @__PURE__ */ jsx3(MessageRow, { $role: message.role, children: /* @__PURE__ */ jsxs2(MessageContainer, { $role: message.role, children: [
382
+ return /* @__PURE__ */ jsx3(MessageRow, { $role: message.role, role: "article", "aria-label": `${message.role} message`, children: /* @__PURE__ */ jsxs2(MessageContainer, { $role: message.role, children: [
383
383
  /* @__PURE__ */ jsx3(MessageBubble, { $role: message.role, children: /* @__PURE__ */ jsx3(ChatMessageContent, { content: message.content }) }),
384
384
  /* @__PURE__ */ jsx3(
385
385
  ChatMessageActions,
@@ -416,4 +416,4 @@ export {
416
416
  * See the LICENSE file in the root directory of this source tree.
417
417
  *)
418
418
  */
419
- //# sourceMappingURL=chunk-SYMZU32H.js.map
419
+ //# sourceMappingURL=chunk-J6VPAHO3.js.map