@shapesos/clay 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/chat.cjs +201 -85
  2. package/dist/chat.cjs.map +1 -1
  3. package/dist/chat.d.cts +6 -1
  4. package/dist/chat.d.ts +6 -1
  5. package/dist/chat.js +8 -4
  6. package/dist/chunk-DRBRT57F.js +1 -0
  7. package/dist/chunk-DRBRT57F.js.map +1 -0
  8. package/dist/chunk-JC2RQL5O.js +76 -0
  9. package/dist/chunk-JC2RQL5O.js.map +1 -0
  10. package/dist/{chunk-6HNZQ2BF.js → chunk-JF3P66JF.js} +2 -1
  11. package/dist/chunk-JF3P66JF.js.map +1 -0
  12. package/dist/chunk-K2Q5MQWJ.js +17 -0
  13. package/dist/chunk-K2Q5MQWJ.js.map +1 -0
  14. package/dist/chunk-MLCRDVQ2.js +89 -0
  15. package/dist/chunk-MLCRDVQ2.js.map +1 -0
  16. package/dist/chunk-OLJIJYB5.js +46 -0
  17. package/dist/chunk-OLJIJYB5.js.map +1 -0
  18. package/dist/chunk-SMTOVZ3O.js +19 -0
  19. package/dist/chunk-SMTOVZ3O.js.map +1 -0
  20. package/dist/{chunk-EPS4LOOW.js → chunk-SYMZU32H.js} +143 -63
  21. package/dist/chunk-SYMZU32H.js.map +1 -0
  22. package/dist/{chunk-A6DKIFWS.js → chunk-WQ2QTUYA.js} +9 -1
  23. package/dist/chunk-WQ2QTUYA.js.map +1 -0
  24. package/dist/chunk-WZHNMC6P.js +77 -0
  25. package/dist/chunk-WZHNMC6P.js.map +1 -0
  26. package/dist/icon.cjs +31 -16
  27. package/dist/icon.cjs.map +1 -1
  28. package/dist/icon.d.cts +6 -2
  29. package/dist/icon.d.ts +6 -2
  30. package/dist/icon.js +5 -3
  31. package/dist/index.cjs +299 -103
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +5 -20
  34. package/dist/index.d.ts +5 -20
  35. package/dist/index.js +32 -74
  36. package/dist/index.js.map +1 -1
  37. package/dist/keyboard-shortcut.cjs +238 -0
  38. package/dist/keyboard-shortcut.cjs.map +1 -0
  39. package/dist/keyboard-shortcut.d.cts +19 -0
  40. package/dist/keyboard-shortcut.d.ts +19 -0
  41. package/dist/keyboard-shortcut.js +14 -0
  42. package/dist/keyboard-shortcut.js.map +1 -0
  43. package/dist/text-area.cjs +497 -0
  44. package/dist/text-area.cjs.map +1 -0
  45. package/dist/text-area.d.cts +18 -0
  46. package/dist/text-area.d.ts +18 -0
  47. package/dist/text-area.js +11 -0
  48. package/dist/text-area.js.map +1 -0
  49. package/dist/tokens.cjs +9 -0
  50. package/dist/tokens.cjs.map +1 -1
  51. package/dist/tokens.d.cts +2 -0
  52. package/dist/tokens.d.ts +2 -0
  53. package/dist/tokens.js +2 -2
  54. package/dist/utils.cjs +60 -0
  55. package/dist/utils.cjs.map +1 -0
  56. package/dist/utils.d.cts +7 -0
  57. package/dist/utils.d.ts +7 -0
  58. package/dist/utils.js +13 -0
  59. package/dist/utils.js.map +1 -0
  60. package/package.json +17 -1
  61. package/dist/chunk-6HNZQ2BF.js.map +0 -1
  62. package/dist/chunk-A6DKIFWS.js.map +0 -1
  63. package/dist/chunk-AEXYOY5H.js +0 -115
  64. package/dist/chunk-AEXYOY5H.js.map +0 -1
  65. package/dist/chunk-EPS4LOOW.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -16344,14 +16344,18 @@ var src_exports = {};
16344
16344
  __export(src_exports, {
16345
16345
  ChatContext: () => ChatContext,
16346
16346
  ChatMessage: () => ChatMessage,
16347
- CtrlIcon: () => CtrlIcon,
16348
16347
  Icon: () => Icon,
16349
16348
  IconButton: () => IconButton,
16349
+ IconCtrl: () => IconCtrl,
16350
16350
  KEYBOARD_SHORTCUT_VARIANTS: () => KEYBOARD_SHORTCUT_VARIANTS,
16351
16351
  KeyboardShortcut: () => KeyboardShortcut,
16352
16352
  Lottie: () => Lottie,
16353
+ MESSAGE_ROLE: () => MESSAGE_ROLE,
16354
+ TextArea: () => TextArea,
16353
16355
  colors: () => colors,
16354
16356
  fontFamilies: () => fontFamilies,
16357
+ markdownToPlainText: () => markdownToPlainText,
16358
+ mergeRefs: () => mergeRefs,
16355
16359
  typographyMixin: () => typographyMixin,
16356
16360
  typographyStyles: () => typographyStyles,
16357
16361
  typographyTypes: () => typographyTypes,
@@ -16365,6 +16369,7 @@ var colors = {
16365
16369
  // White
16366
16370
  white: "#FFFFFF",
16367
16371
  "white-alpha-85": "rgba(255, 255, 255, 0.85)",
16372
+ "white-alpha-40": "rgba(255, 255, 255, 0.40)",
16368
16373
  // Brown
16369
16374
  "brown-10": "#FAF9F8",
16370
16375
  "brown-20": "#F5F3F0",
@@ -16465,6 +16470,7 @@ var typographyTypes = {
16465
16470
  GEIST_BODY_S_REGULAR: "GEIST_BODY_S_REGULAR",
16466
16471
  GEIST_BODY_S_MEDIUM: "GEIST_BODY_S_MEDIUM",
16467
16472
  GEIST_BODY_S_SEMI_BOLD: "GEIST_BODY_S_SEMI_BOLD",
16473
+ GEIST_BODY_S_BOLD: "GEIST_BODY_S_BOLD",
16468
16474
  // Geist Body Medium (18px)
16469
16475
  GEIST_BODY_M_LIGHT: "GEIST_BODY_M_LIGHT",
16470
16476
  GEIST_BODY_M_REGULAR: "GEIST_BODY_M_REGULAR",
@@ -16558,6 +16564,13 @@ var typographyStyles = {
16558
16564
  lineHeight: 24,
16559
16565
  letterSpacing: -0.08
16560
16566
  },
16567
+ [typographyTypes.GEIST_BODY_S_BOLD]: {
16568
+ fontFamily: fontFamilies.GEIST,
16569
+ fontSize: 16,
16570
+ fontWeight: 700,
16571
+ lineHeight: 24,
16572
+ letterSpacing: -0.08
16573
+ },
16561
16574
  // Geist Body Medium (18px)
16562
16575
  [typographyTypes.GEIST_BODY_M_LIGHT]: {
16563
16576
  fontFamily: fontFamilies.GEIST,
@@ -16734,89 +16747,148 @@ function typographyMixin(type) {
16734
16747
 
16735
16748
  // src/chat/chat-message-content/chat-message-content.tsx
16736
16749
  var import_react_markdown = __toESM(require("react-markdown"), 1);
16750
+ var import_remark_breaks = __toESM(require("remark-breaks"), 1);
16737
16751
  var import_remark_gfm = __toESM(require("remark-gfm"), 1);
16738
16752
 
16739
16753
  // src/chat/chat-message-content/chat-message-content-styles.ts
16740
16754
  var import_styled_components = __toESM(require("styled-components"), 1);
16741
16755
  var ContentWrapper = import_styled_components.default.div`
16742
- ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
16756
+ ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
16743
16757
  color: ${colors["brown-100"]};
16744
16758
  word-break: break-word;
16745
16759
 
16760
+ & h1 {
16761
+ ${typographyMixin(typographyTypes.GEIST_HEADING_S_BOLD)};
16762
+ margin-block: 20px;
16763
+ }
16764
+
16765
+ & h2 {
16766
+ ${typographyMixin(typographyTypes.GEIST_BODY_L_SEMI_BOLD)};
16767
+ margin-block: 12px;
16768
+ }
16769
+
16770
+ & h3,
16771
+ & h4,
16772
+ & h5,
16773
+ & h6 {
16774
+ ${typographyMixin(typographyTypes.GEIST_BODY_M_SEMI_BOLD)};
16775
+ margin-block: 8px;
16776
+ }
16777
+
16778
+ & strong {
16779
+ ${typographyMixin(typographyTypes.GEIST_BODY_S_SEMI_BOLD)};
16780
+ }
16781
+
16746
16782
  & p {
16747
- margin: 0;
16783
+ margin-block: 0px;
16748
16784
  }
16749
16785
 
16750
16786
  & p + p {
16751
- margin-top: 8px;
16787
+ margin-block: 8px 0px;
16752
16788
  }
16753
16789
 
16754
16790
  & ul,
16755
16791
  & ol {
16756
- margin: 4px 0;
16792
+ margin-block: 16px;
16757
16793
  padding-left: 20px;
16758
16794
  }
16759
16795
 
16760
- & a {
16761
- color: ${colors["brown-100"]};
16762
- text-decoration: underline;
16796
+ & li + li {
16797
+ margin-block: 4px;
16763
16798
  }
16764
16799
 
16765
- & pre {
16766
- overflow-x: auto;
16767
- padding: 8px;
16768
- margin: 4px 0;
16769
- background: ${colors["brown-10"]};
16770
- border: 1px solid ${colors["brown-alpha-12"]};
16771
- border-radius: 8px;
16800
+ & ol {
16801
+ list-style-type: decimal;
16772
16802
  }
16773
16803
 
16774
- & pre code {
16775
- padding: 0;
16776
- background: none;
16777
- border-radius: 0;
16804
+ & ol ol {
16805
+ list-style-type: lower-alpha;
16778
16806
  }
16779
16807
 
16780
- & code {
16781
- padding: 2px 4px;
16782
- background: ${colors["brown-10"]};
16783
- border-radius: 4px;
16808
+ & ol ol ol {
16809
+ list-style-type: lower-roman;
16810
+ }
16811
+
16812
+ & a {
16813
+ color: inherit;
16814
+ text-decoration-line: underline;
16815
+ text-decoration-style: dotted;
16816
+ text-decoration-thickness: auto;
16817
+ text-underline-offset: auto;
16818
+ text-underline-position: from-font;
16819
+ transition: color 75ms ease-in-out;
16820
+
16821
+ &:hover {
16822
+ color: ${colors["blue-600"]};
16823
+ }
16824
+ }
16825
+
16826
+ & hr {
16827
+ border: none;
16828
+ border-top: 1px solid ${colors["brown-40"]};
16829
+ margin-block: 20px;
16784
16830
  }
16785
16831
 
16786
16832
  & table {
16787
- border-collapse: collapse;
16788
- margin: 8px 0;
16833
+ margin: 0;
16789
16834
  width: 100%;
16835
+ border-collapse: collapse;
16790
16836
  }
16791
16837
 
16792
16838
  & th,
16793
16839
  & td {
16794
- border: 1px solid ${colors["brown-alpha-12"]};
16795
- padding: 6px 12px;
16840
+ border: none;
16841
+ border-bottom: 1px solid ${colors["brown-40"]};
16796
16842
  text-align: left;
16797
16843
  }
16798
16844
 
16799
16845
  & th {
16800
- background: ${colors["brown-10"]};
16801
- font-weight: 600;
16846
+ ${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};
16847
+ padding: 8px;
16848
+ }
16849
+
16850
+ & td {
16851
+ ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
16852
+ padding: 16px 8px;
16853
+ min-width: 150px;
16854
+ width: 1%;
16855
+ }
16856
+
16857
+ & td strong {
16858
+ font-weight: inherit;
16859
+ font-size: inherit;
16860
+ line-height: inherit;
16802
16861
  }
16803
16862
 
16804
16863
  & blockquote {
16805
- margin: 4px 0;
16806
- padding-left: 12px;
16807
- border-left: 3px solid ${colors["brown-30"]};
16808
- color: ${colors["brown-70"]};
16864
+ margin-block: 4px;
16865
+ margin-inline: 0px;
16866
+ padding-left: 16px;
16867
+ border-left: 4px solid ${colors["brown-40"]};
16868
+ color: ${colors["brown-80"]};
16809
16869
  }
16810
16870
  `;
16871
+ var TableScroll = import_styled_components.default.div`
16872
+ width: 100%;
16873
+ overflow-x: auto;
16874
+ overflow-y: hidden;
16875
+ margin-block: 8px 16px;
16876
+ `;
16811
16877
 
16812
16878
  // src/chat/chat-message-content/chat-message-content.tsx
16813
16879
  var import_jsx_runtime = require("react/jsx-runtime");
16880
+ function ScrollableTable({ node: _node, ...props }) {
16881
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) });
16882
+ }
16883
+ var markdownComponents = {
16884
+ table: ScrollableTable
16885
+ };
16814
16886
  function ChatMessageContent({ content: content2 }) {
16815
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], children: content2 }) });
16887
+ 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: content2 }) });
16816
16888
  }
16817
16889
 
16818
16890
  // src/chat/chat-message-actions/chat-message-actions.tsx
16819
- var import_react6 = require("react");
16891
+ var import_react5 = require("react");
16820
16892
 
16821
16893
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
16822
16894
  var import_react = require("react");
@@ -16890,9 +16962,6 @@ var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", _
16890
16962
  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" }]];
16891
16963
  var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode4);
16892
16964
 
16893
- // src/components/icon-button/icon-button.tsx
16894
- var import_react3 = require("react");
16895
-
16896
16965
  // src/components/icon/icon.tsx
16897
16966
  var import_react2 = require("react");
16898
16967
 
@@ -16901,8 +16970,8 @@ var import_styled_components2 = __toESM(require("styled-components"), 1);
16901
16970
  var STROKE_WIDTH_BY_SIZE = {
16902
16971
  12: 1.4,
16903
16972
  14: 1.4,
16904
- 16: 1.6,
16905
- 18: 1.6,
16973
+ 16: 1.8,
16974
+ 18: 1.8,
16906
16975
  20: 1.8,
16907
16976
  24: 1.8
16908
16977
  };
@@ -16937,9 +17006,15 @@ var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, s
16937
17006
 
16938
17007
  // src/components/icon-button/icon-button-styles.ts
16939
17008
  var import_styled_components3 = __toESM(require("styled-components"), 1);
16940
- var DIMENSIONS = {
16941
- small: 28,
16942
- medium: 32
17009
+ var PADDING = {
17010
+ short: {
17011
+ small: "4px",
17012
+ medium: "6px"
17013
+ },
17014
+ long: {
17015
+ small: "4px 6px",
17016
+ medium: "6px 10px"
17017
+ }
16943
17018
  };
16944
17019
  var BORDER_RADIUS = {
16945
17020
  small: 6,
@@ -16949,9 +17024,7 @@ var Button = import_styled_components3.default.button`
16949
17024
  display: inline-flex;
16950
17025
  align-items: center;
16951
17026
  justify-content: center;
16952
- width: ${({ $size }) => DIMENSIONS[$size]}px;
16953
- height: ${({ $size }) => DIMENSIONS[$size]}px;
16954
- padding: 0;
17027
+ padding: ${({ $size, $variant }) => PADDING[$variant][$size]};
16955
17028
  border: none;
16956
17029
  border-radius: ${({ $size }) => BORDER_RADIUS[$size]}px;
16957
17030
  background: ${({ $isSelected }) => $isSelected ? colors["brown-40"] : "transparent"};
@@ -16977,16 +17050,29 @@ var Button = import_styled_components3.default.button`
16977
17050
  // src/components/icon-button/icon-button.tsx
16978
17051
  var import_jsx_runtime3 = require("react/jsx-runtime");
16979
17052
  var ICON_SIZE_BY_BUTTON_SIZE = {
16980
- small: 14,
16981
- medium: 16
17053
+ small: 16,
17054
+ medium: 20
16982
17055
  };
16983
- var IconButton = (0, import_react3.forwardRef)(function IconButton2({ icon, size = "small", isSelected = false, disabled = false, onClick, className, "aria-label": ariaLabel }, ref) {
17056
+ function IconButton({
17057
+ icon,
17058
+ size = "small",
17059
+ variant = "short",
17060
+ isSelected = false,
17061
+ disabled = false,
17062
+ onClick,
17063
+ className,
17064
+ id,
17065
+ as,
17066
+ "aria-label": ariaLabel
17067
+ }) {
16984
17068
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
16985
17069
  Button,
16986
17070
  {
16987
- ref,
16988
17071
  className,
17072
+ id,
17073
+ as,
16989
17074
  $size: size,
17075
+ $variant: variant,
16990
17076
  $isSelected: isSelected,
16991
17077
  disabled,
16992
17078
  onClick: disabled ? void 0 : onClick,
@@ -16994,13 +17080,13 @@ var IconButton = (0, import_react3.forwardRef)(function IconButton2({ icon, size
16994
17080
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
16995
17081
  }
16996
17082
  );
16997
- });
17083
+ }
16998
17084
 
16999
17085
  // src/chat/chat-context/chat-context.ts
17000
- var import_react4 = require("react");
17001
- var ChatContext = (0, import_react4.createContext)(null);
17086
+ var import_react3 = require("react");
17087
+ var ChatContext = (0, import_react3.createContext)(null);
17002
17088
  function useChatContext() {
17003
- const context = (0, import_react4.useContext)(ChatContext);
17089
+ const context = (0, import_react3.useContext)(ChatContext);
17004
17090
  if (!context) {
17005
17091
  throw new Error("useChatContext must be used within a Chat.Root component");
17006
17092
  }
@@ -17008,7 +17094,7 @@ function useChatContext() {
17008
17094
  }
17009
17095
 
17010
17096
  // src/chat/hooks/use-copy-to-clipboard.ts
17011
- var import_react5 = require("react");
17097
+ var import_react4 = require("react");
17012
17098
 
17013
17099
  // src/utils/clipboard.ts
17014
17100
  function copyToClipboard(text2, options) {
@@ -17018,18 +17104,33 @@ function copyToClipboard(text2, options) {
17018
17104
  );
17019
17105
  }
17020
17106
 
17107
+ // src/utils/markdown-to-plain-text.ts
17108
+ var PLACEHOLDER_PREFIX = "\u200B\u200BIC";
17109
+ var PLACEHOLDER_SUFFIX = "\u200B\u200B";
17110
+ var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUFFIX}`, "g");
17111
+ function markdownToPlainText(markdown) {
17112
+ if (!markdown) return "";
17113
+ const inlineCodeSnippets = [];
17114
+ let result = markdown.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
17115
+ inlineCodeSnippets.push(code);
17116
+ return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
17117
+ }).replace(/^#{1,6}\s+/gm, "").replace(/^(?:---|\*\*\*|___)\s*$/gm, "").replace(/\*{3}(.+?)\*{3}/g, "$1").replace(/\*{2}(.+?)\*{2}/g, "$1").replace(/_{2}(.+?)_{2}/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/_(.+?)_/g, "$1").replace(/~~(.+?)~~/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s?/gm, "").replace(/^\|[-:\s|]+\|\s*$/gm, "").replace(/^\|\s?/gm, "").replace(/\s?\|$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
17118
+ result = result.replace(PLACEHOLDER_REGEX, (_match, index2) => inlineCodeSnippets[Number(index2)]);
17119
+ return result;
17120
+ }
17121
+
17021
17122
  // src/chat/hooks/use-copy-to-clipboard.ts
17022
17123
  var RESET_DELAY_MS = 2e3;
17023
17124
  function useCopyToClipboard() {
17024
- const [isCopied, setIsCopied] = (0, import_react5.useState)(false);
17025
- const timeoutRef = (0, import_react5.useRef)(null);
17026
- (0, import_react5.useEffect)(() => {
17125
+ const [isCopied, setIsCopied] = (0, import_react4.useState)(false);
17126
+ const timeoutRef = (0, import_react4.useRef)(null);
17127
+ (0, import_react4.useEffect)(() => {
17027
17128
  return () => {
17028
17129
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
17029
17130
  };
17030
17131
  }, []);
17031
- const copy = (0, import_react5.useCallback)((text2) => {
17032
- copyToClipboard(text2, {
17132
+ const copy = (0, import_react4.useCallback)((text2) => {
17133
+ copyToClipboard(markdownToPlainText(text2), {
17033
17134
  onSuccess: () => {
17034
17135
  setIsCopied(true);
17035
17136
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
@@ -17043,35 +17144,48 @@ function useCopyToClipboard() {
17043
17144
  return { isCopied, copy };
17044
17145
  }
17045
17146
 
17147
+ // src/chat/constants.ts
17148
+ var MESSAGE_ROLE = {
17149
+ USER: "user",
17150
+ ASSISTANT: "assistant"
17151
+ };
17152
+
17046
17153
  // src/chat/chat-message-actions/chat-message-actions-styles.ts
17047
17154
  var import_styled_components4 = __toESM(require("styled-components"), 1);
17155
+ var FADE_DURATION_MS = 150;
17156
+ var ANIMATE_DURATION_MS = 200;
17048
17157
  var ActionsContainer = import_styled_components4.default.div`
17049
17158
  display: flex;
17050
- gap: 2px;
17051
- margin-top: 4px;
17052
- opacity: 0;
17053
- pointer-events: none;
17054
- transition: opacity 150ms ease;
17159
+ opacity: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? 1 : 0};
17160
+ pointer-events: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? "auto" : "none"};
17161
+ transition: opacity ${FADE_DURATION_MS}ms ease;
17162
+ `;
17163
+ var AnimatedAction = import_styled_components4.default.div`
17164
+ display: flex;
17165
+ overflow: hidden;
17166
+ max-width: ${({ $visible }) => $visible ? "40px" : "0"};
17167
+ opacity: ${({ $visible }) => $visible ? 1 : 0};
17168
+ transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;
17055
17169
  `;
17056
17170
 
17057
17171
  // src/chat/chat-message-actions/chat-message-actions.tsx
17058
17172
  var import_jsx_runtime4 = require("react/jsx-runtime");
17059
- function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17173
+ function ChatMessageActions({ className, messageId, content: content2, role, isHelpful }) {
17060
17174
  const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
17061
17175
  const { isCopied, copy } = useCopyToClipboard();
17062
- const handleCopy = (0, import_react6.useCallback)(() => {
17176
+ const handleCopy = (0, import_react5.useCallback)(() => {
17063
17177
  copy(content2);
17064
17178
  onCopyMessage?.(messageId);
17065
17179
  }, [content2, messageId, copy, onCopyMessage]);
17066
- const handleThumbUp = (0, import_react6.useCallback)(() => {
17180
+ const handleThumbUp = (0, import_react5.useCallback)(() => {
17067
17181
  onThumbUpClick?.(messageId, isHelpful === true ? null : true);
17068
17182
  }, [messageId, isHelpful, onThumbUpClick]);
17069
- const handleThumbDown = (0, import_react6.useCallback)(() => {
17183
+ const handleThumbDown = (0, import_react5.useCallback)(() => {
17070
17184
  onThumbDownClick?.(messageId, isHelpful === false ? null : false);
17071
17185
  }, [messageId, isHelpful, onThumbDownClick]);
17072
- const isAssistant = role === "assistant";
17186
+ const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
17073
17187
  const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
17074
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { children: [
17188
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { $role: role, className, children: [
17075
17189
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17076
17190
  IconButton,
17077
17191
  {
@@ -17080,7 +17194,7 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17080
17194
  "aria-label": isCopied ? "Copied" : "Copy message"
17081
17195
  }
17082
17196
  ),
17083
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17197
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17084
17198
  IconButton,
17085
17199
  {
17086
17200
  icon: IconThumbUp,
@@ -17088,8 +17202,8 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17088
17202
  isSelected: isHelpful === true,
17089
17203
  "aria-label": "Good response"
17090
17204
  }
17091
- ),
17092
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17205
+ ) }),
17206
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17093
17207
  IconButton,
17094
17208
  {
17095
17209
  icon: IconThumbDown,
@@ -17097,7 +17211,7 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17097
17211
  isSelected: isHelpful === false,
17098
17212
  "aria-label": "Bad response"
17099
17213
  }
17100
- )
17214
+ ) })
17101
17215
  ] });
17102
17216
  }
17103
17217
 
@@ -17105,25 +17219,29 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17105
17219
  var import_styled_components5 = __toESM(require("styled-components"), 1);
17106
17220
  var MessageRow = import_styled_components5.default.div`
17107
17221
  display: flex;
17108
- justify-content: ${({ $role }) => $role === "user" ? "flex-end" : "flex-start"};
17109
- `;
17110
- var MessageContainer = import_styled_components5.default.div`
17111
- display: flex;
17112
- flex-direction: column;
17113
- align-items: ${({ $role }) => $role === "user" ? "flex-end" : "flex-start"};
17114
- max-width: 90%;
17222
+ justify-content: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
17115
17223
 
17116
17224
  &:hover ${ActionsContainer} {
17117
17225
  opacity: 1;
17118
17226
  pointer-events: auto;
17119
17227
  }
17120
17228
  `;
17229
+ var MessageContainer = import_styled_components5.default.div`
17230
+ display: flex;
17231
+ flex-direction: column;
17232
+ align-items: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
17233
+ max-width: 90%;
17234
+ width: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "auto" : "100%"};
17235
+ gap: 12px;
17236
+ `;
17121
17237
  var MessageBubble = import_styled_components5.default.div`
17122
- ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
17238
+ ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17123
17239
  color: ${colors["brown-100"]};
17124
- background: ${({ $role }) => $role === "user" ? colors.white : "transparent"};
17125
- padding: ${({ $role }) => $role === "user" ? "12px 16px" : "0"};
17126
- border-radius: ${({ $role }) => $role === "user" ? "16px" : "0"};
17240
+ background: ${({ $role }) => $role === MESSAGE_ROLE.USER ? colors.white : "transparent"};
17241
+ padding: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "12px 16px" : "0"};
17242
+ border-radius: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "16px" : "0"};
17243
+ max-width: 100%;
17244
+ min-width: 0;
17127
17245
  `;
17128
17246
 
17129
17247
  // src/chat/chat-message/chat-message.tsx
@@ -17155,7 +17273,7 @@ var KEYBOARD_SHORTCUT_VARIANTS = {
17155
17273
  // src/components/keyboard-shortcut/keyboard-shortcut-styles.ts
17156
17274
  var variantStyles = {
17157
17275
  [KEYBOARD_SHORTCUT_VARIANTS.OUTLINED]: import_styled_components6.css`
17158
- border: 1px solid ${colors["brown-70"]};
17276
+ border: 1px solid ${colors["white-alpha-40"]};
17159
17277
  color: ${colors["brown-10"]};
17160
17278
  `,
17161
17279
  [KEYBOARD_SHORTCUT_VARIANTS.FILLED]: import_styled_components6.css`
@@ -17172,7 +17290,7 @@ var Key = import_styled_components6.default.kbd`
17172
17290
  display: inline-flex;
17173
17291
  align-items: center;
17174
17292
  justify-content: center;
17175
- padding: 4px;
17293
+ padding: 2px;
17176
17294
  border-radius: 6px;
17177
17295
  ${({ $variant }) => variantStyles[$variant]};
17178
17296
  `;
@@ -17187,9 +17305,9 @@ function KeyboardShortcut({
17187
17305
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Wrapper, { className, children: keys.map((KeyComponent, index2) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Key, { $variant: variant, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { icon: KeyComponent, size: 12 }) }, index2)) });
17188
17306
  }
17189
17307
 
17190
- // src/components/keyboard-shortcut/icons/ctrl-icon.tsx
17308
+ // src/components/keyboard-shortcut/icons/icon-ctrl.tsx
17191
17309
  var import_jsx_runtime7 = require("react/jsx-runtime");
17192
- function CtrlIcon(props) {
17310
+ function IconCtrl(props) {
17193
17311
  const { width: width2 = 24, height: height2 = 24, ...rest } = props;
17194
17312
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: width2, height: height2, fill: "none", ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
17195
17313
  "text",
@@ -17200,7 +17318,7 @@ function CtrlIcon(props) {
17200
17318
  textAnchor: "middle",
17201
17319
  fill: "currentColor",
17202
17320
  fontFamily: "Geist, sans-serif",
17203
- fontWeight: 500,
17321
+ fontWeight: 300,
17204
17322
  fontSize: 14,
17205
17323
  children: "Ctrl"
17206
17324
  }
@@ -17208,7 +17326,7 @@ function CtrlIcon(props) {
17208
17326
  }
17209
17327
 
17210
17328
  // src/components/lottie/lottie.tsx
17211
- var import_react8 = require("react");
17329
+ var import_react7 = require("react");
17212
17330
 
17213
17331
  // src/components/lottie/lottie-styles.ts
17214
17332
  var import_styled_components7 = __toESM(require("styled-components"), 1);
@@ -17224,7 +17342,7 @@ var LottieContainer = import_styled_components7.default.div`
17224
17342
  `;
17225
17343
 
17226
17344
  // src/components/lottie/use-lottie.ts
17227
- var import_react7 = require("react");
17345
+ var import_react6 = require("react");
17228
17346
  var import_lottie_web = __toESM(require_lottie(), 1);
17229
17347
  function useLottie({
17230
17348
  animationData: animationData2,
@@ -17239,17 +17357,17 @@ function useLottie({
17239
17357
  onLoopComplete,
17240
17358
  onEnterFrame
17241
17359
  }) {
17242
- const containerRef = (0, import_react7.useRef)(null);
17243
- const animationRef = (0, import_react7.useRef)(null);
17244
- const onAnimationLoadedRef = (0, import_react7.useRef)(onAnimationLoaded);
17245
- const onCompleteRef = (0, import_react7.useRef)(onComplete);
17246
- const onLoopCompleteRef = (0, import_react7.useRef)(onLoopComplete);
17247
- const onEnterFrameRef = (0, import_react7.useRef)(onEnterFrame);
17360
+ const containerRef = (0, import_react6.useRef)(null);
17361
+ const animationRef = (0, import_react6.useRef)(null);
17362
+ const onAnimationLoadedRef = (0, import_react6.useRef)(onAnimationLoaded);
17363
+ const onCompleteRef = (0, import_react6.useRef)(onComplete);
17364
+ const onLoopCompleteRef = (0, import_react6.useRef)(onLoopComplete);
17365
+ const onEnterFrameRef = (0, import_react6.useRef)(onEnterFrame);
17248
17366
  onAnimationLoadedRef.current = onAnimationLoaded;
17249
17367
  onCompleteRef.current = onComplete;
17250
17368
  onLoopCompleteRef.current = onLoopComplete;
17251
17369
  onEnterFrameRef.current = onEnterFrame;
17252
- (0, import_react7.useEffect)(() => {
17370
+ (0, import_react6.useEffect)(() => {
17253
17371
  if (!containerRef.current) return;
17254
17372
  const anim = import_lottie_web.default.loadAnimation({
17255
17373
  container: containerRef.current,
@@ -17342,7 +17460,7 @@ function createLottieRef(animationRef) {
17342
17460
 
17343
17461
  // src/components/lottie/lottie.tsx
17344
17462
  var import_jsx_runtime8 = require("react/jsx-runtime");
17345
- var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17463
+ var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17346
17464
  animationData: animationData2,
17347
17465
  autoplay,
17348
17466
  loop,
@@ -17372,7 +17490,7 @@ var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17372
17490
  onLoopComplete,
17373
17491
  onEnterFrame
17374
17492
  });
17375
- (0, import_react8.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17493
+ (0, import_react7.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17376
17494
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
17377
17495
  LottieContainer,
17378
17496
  {
@@ -17385,18 +17503,96 @@ var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17385
17503
  }
17386
17504
  );
17387
17505
  });
17506
+
17507
+ // src/components/text-area/text-area.tsx
17508
+ var import_react8 = require("react");
17509
+
17510
+ // src/utils/merge-refs.ts
17511
+ function mergeRefs(...refs) {
17512
+ return (node) => {
17513
+ for (const ref of refs) {
17514
+ if (typeof ref === "function") {
17515
+ ref(node);
17516
+ } else if (ref) {
17517
+ ref.current = node;
17518
+ }
17519
+ }
17520
+ };
17521
+ }
17522
+
17523
+ // src/components/text-area/text-area-styles.ts
17524
+ var import_styled_components8 = __toESM(require("styled-components"), 1);
17525
+ var StyledTextArea = import_styled_components8.default.textarea`
17526
+ ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17527
+ color: ${colors["brown-100"]};
17528
+ border: none;
17529
+ outline: none;
17530
+ resize: none;
17531
+ width: 100%;
17532
+ background: transparent;
17533
+ vertical-align: bottom;
17534
+ max-height: ${({ $maxHeight }) => $maxHeight ? `${$maxHeight}px` : "none"};
17535
+ overflow-y: ${({ $maxHeight }) => $maxHeight ? "auto" : "hidden"};
17536
+
17537
+ &::placeholder {
17538
+ color: ${colors["brown-50"]};
17539
+ }
17540
+
17541
+ &:disabled {
17542
+ opacity: 0.5;
17543
+ cursor: not-allowed;
17544
+ }
17545
+ `;
17546
+
17547
+ // src/components/text-area/text-area.tsx
17548
+ var import_jsx_runtime9 = require("react/jsx-runtime");
17549
+ var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
17550
+ const internalRef = (0, import_react8.useRef)(null);
17551
+ (0, import_react8.useLayoutEffect)(() => {
17552
+ const el = internalRef.current;
17553
+ if (el) {
17554
+ el.style.height = "auto";
17555
+ el.style.height = `${el.scrollHeight}px`;
17556
+ }
17557
+ }, [value2]);
17558
+ const handleChange = (0, import_react8.useCallback)(
17559
+ (e) => {
17560
+ onChange(e.target.value);
17561
+ },
17562
+ [onChange]
17563
+ );
17564
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
17565
+ StyledTextArea,
17566
+ {
17567
+ ref: mergeRefs(internalRef, externalRef),
17568
+ value: value2,
17569
+ onChange: handleChange,
17570
+ placeholder,
17571
+ $maxHeight: maxHeight,
17572
+ rows,
17573
+ autoFocus,
17574
+ onKeyDown,
17575
+ disabled,
17576
+ className
17577
+ }
17578
+ );
17579
+ });
17388
17580
  // Annotate the CommonJS export names for ESM import in node:
17389
17581
  0 && (module.exports = {
17390
17582
  ChatContext,
17391
17583
  ChatMessage,
17392
- CtrlIcon,
17393
17584
  Icon,
17394
17585
  IconButton,
17586
+ IconCtrl,
17395
17587
  KEYBOARD_SHORTCUT_VARIANTS,
17396
17588
  KeyboardShortcut,
17397
17589
  Lottie,
17590
+ MESSAGE_ROLE,
17591
+ TextArea,
17398
17592
  colors,
17399
17593
  fontFamilies,
17594
+ markdownToPlainText,
17595
+ mergeRefs,
17400
17596
  typographyMixin,
17401
17597
  typographyStyles,
17402
17598
  typographyTypes,