@shapesos/clay 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/chat.cjs +199 -87
  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-EPS4LOOW.js → chunk-PCBRMJJJ.js} +141 -65
  19. package/dist/chunk-PCBRMJJJ.js.map +1 -0
  20. package/dist/chunk-SMTOVZ3O.js +19 -0
  21. package/dist/chunk-SMTOVZ3O.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 +297 -105
  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,144 @@ 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
 
16746
- & p {
16747
- margin: 0;
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)};
16748
16780
  }
16749
16781
 
16750
- & p + p {
16751
- margin-top: 8px;
16782
+ & p {
16783
+ margin-block: 8px;
16752
16784
  }
16753
16785
 
16754
16786
  & ul,
16755
16787
  & ol {
16756
- margin: 4px 0;
16788
+ margin-block: 16px;
16757
16789
  padding-left: 20px;
16758
16790
  }
16759
16791
 
16760
- & a {
16761
- color: ${colors["brown-100"]};
16762
- text-decoration: underline;
16792
+ & li + li {
16793
+ margin-block: 4px;
16763
16794
  }
16764
16795
 
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;
16796
+ & ol {
16797
+ list-style-type: decimal;
16772
16798
  }
16773
16799
 
16774
- & pre code {
16775
- padding: 0;
16776
- background: none;
16777
- border-radius: 0;
16800
+ & ol ol {
16801
+ list-style-type: lower-alpha;
16778
16802
  }
16779
16803
 
16780
- & code {
16781
- padding: 2px 4px;
16782
- background: ${colors["brown-10"]};
16783
- border-radius: 4px;
16804
+ & ol ol ol {
16805
+ list-style-type: lower-roman;
16806
+ }
16807
+
16808
+ & a {
16809
+ color: inherit;
16810
+ text-decoration-line: underline;
16811
+ text-decoration-style: dotted;
16812
+ text-decoration-thickness: auto;
16813
+ text-underline-offset: auto;
16814
+ text-underline-position: from-font;
16815
+ transition: color 75ms ease-in-out;
16816
+
16817
+ &:hover {
16818
+ color: ${colors["blue-600"]};
16819
+ }
16820
+ }
16821
+
16822
+ & hr {
16823
+ border: none;
16824
+ border-top: 1px solid ${colors["brown-40"]};
16825
+ margin-block: 20px;
16784
16826
  }
16785
16827
 
16786
16828
  & table {
16787
- border-collapse: collapse;
16788
- margin: 8px 0;
16829
+ margin: 0;
16789
16830
  width: 100%;
16831
+ border-collapse: collapse;
16790
16832
  }
16791
16833
 
16792
16834
  & th,
16793
16835
  & td {
16794
- border: 1px solid ${colors["brown-alpha-12"]};
16795
- padding: 6px 12px;
16836
+ border: none;
16837
+ border-bottom: 1px solid ${colors["brown-40"]};
16796
16838
  text-align: left;
16797
16839
  }
16798
16840
 
16799
16841
  & th {
16800
- background: ${colors["brown-10"]};
16801
- font-weight: 600;
16842
+ ${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};
16843
+ padding: 8px;
16844
+ }
16845
+
16846
+ & td {
16847
+ ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
16848
+ padding: 16px 8px;
16849
+ min-width: 150px;
16850
+ width: 1%;
16851
+ }
16852
+
16853
+ & td strong {
16854
+ font-weight: inherit;
16855
+ font-size: inherit;
16856
+ line-height: inherit;
16802
16857
  }
16803
16858
 
16804
16859
  & blockquote {
16805
- margin: 4px 0;
16806
- padding-left: 12px;
16807
- border-left: 3px solid ${colors["brown-30"]};
16808
- color: ${colors["brown-70"]};
16860
+ margin-block: 4px;
16861
+ margin-inline: 0px;
16862
+ padding-left: 16px;
16863
+ border-left: 4px solid ${colors["brown-40"]};
16864
+ color: ${colors["brown-80"]};
16809
16865
  }
16810
16866
  `;
16867
+ var TableScroll = import_styled_components.default.div`
16868
+ width: 100%;
16869
+ overflow-x: auto;
16870
+ overflow-y: hidden;
16871
+ margin-block: 8px 16px;
16872
+ `;
16811
16873
 
16812
16874
  // src/chat/chat-message-content/chat-message-content.tsx
16813
16875
  var import_jsx_runtime = require("react/jsx-runtime");
16876
+ function ScrollableTable({ node: _node, ...props }) {
16877
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) });
16878
+ }
16879
+ var markdownComponents = {
16880
+ table: ScrollableTable
16881
+ };
16814
16882
  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 }) });
16883
+ 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
16884
  }
16817
16885
 
16818
16886
  // src/chat/chat-message-actions/chat-message-actions.tsx
16819
- var import_react6 = require("react");
16887
+ var import_react5 = require("react");
16820
16888
 
16821
16889
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
16822
16890
  var import_react = require("react");
@@ -16890,9 +16958,6 @@ var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", _
16890
16958
  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
16959
  var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode4);
16892
16960
 
16893
- // src/components/icon-button/icon-button.tsx
16894
- var import_react3 = require("react");
16895
-
16896
16961
  // src/components/icon/icon.tsx
16897
16962
  var import_react2 = require("react");
16898
16963
 
@@ -16901,8 +16966,8 @@ var import_styled_components2 = __toESM(require("styled-components"), 1);
16901
16966
  var STROKE_WIDTH_BY_SIZE = {
16902
16967
  12: 1.4,
16903
16968
  14: 1.4,
16904
- 16: 1.6,
16905
- 18: 1.6,
16969
+ 16: 1.8,
16970
+ 18: 1.8,
16906
16971
  20: 1.8,
16907
16972
  24: 1.8
16908
16973
  };
@@ -16937,9 +17002,15 @@ var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, s
16937
17002
 
16938
17003
  // src/components/icon-button/icon-button-styles.ts
16939
17004
  var import_styled_components3 = __toESM(require("styled-components"), 1);
16940
- var DIMENSIONS = {
16941
- small: 28,
16942
- medium: 32
17005
+ var PADDING = {
17006
+ short: {
17007
+ small: "4px",
17008
+ medium: "6px"
17009
+ },
17010
+ long: {
17011
+ small: "4px 6px",
17012
+ medium: "6px 10px"
17013
+ }
16943
17014
  };
16944
17015
  var BORDER_RADIUS = {
16945
17016
  small: 6,
@@ -16949,9 +17020,7 @@ var Button = import_styled_components3.default.button`
16949
17020
  display: inline-flex;
16950
17021
  align-items: center;
16951
17022
  justify-content: center;
16952
- width: ${({ $size }) => DIMENSIONS[$size]}px;
16953
- height: ${({ $size }) => DIMENSIONS[$size]}px;
16954
- padding: 0;
17023
+ padding: ${({ $size, $variant }) => PADDING[$variant][$size]};
16955
17024
  border: none;
16956
17025
  border-radius: ${({ $size }) => BORDER_RADIUS[$size]}px;
16957
17026
  background: ${({ $isSelected }) => $isSelected ? colors["brown-40"] : "transparent"};
@@ -16977,16 +17046,29 @@ var Button = import_styled_components3.default.button`
16977
17046
  // src/components/icon-button/icon-button.tsx
16978
17047
  var import_jsx_runtime3 = require("react/jsx-runtime");
16979
17048
  var ICON_SIZE_BY_BUTTON_SIZE = {
16980
- small: 14,
16981
- medium: 16
17049
+ small: 16,
17050
+ medium: 20
16982
17051
  };
16983
- var IconButton = (0, import_react3.forwardRef)(function IconButton2({ icon, size = "small", isSelected = false, disabled = false, onClick, className, "aria-label": ariaLabel }, ref) {
17052
+ function IconButton({
17053
+ icon,
17054
+ size = "small",
17055
+ variant = "short",
17056
+ isSelected = false,
17057
+ disabled = false,
17058
+ onClick,
17059
+ className,
17060
+ id,
17061
+ as,
17062
+ "aria-label": ariaLabel
17063
+ }) {
16984
17064
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
16985
17065
  Button,
16986
17066
  {
16987
- ref,
16988
17067
  className,
17068
+ id,
17069
+ as,
16989
17070
  $size: size,
17071
+ $variant: variant,
16990
17072
  $isSelected: isSelected,
16991
17073
  disabled,
16992
17074
  onClick: disabled ? void 0 : onClick,
@@ -16994,13 +17076,13 @@ var IconButton = (0, import_react3.forwardRef)(function IconButton2({ icon, size
16994
17076
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
16995
17077
  }
16996
17078
  );
16997
- });
17079
+ }
16998
17080
 
16999
17081
  // src/chat/chat-context/chat-context.ts
17000
- var import_react4 = require("react");
17001
- var ChatContext = (0, import_react4.createContext)(null);
17082
+ var import_react3 = require("react");
17083
+ var ChatContext = (0, import_react3.createContext)(null);
17002
17084
  function useChatContext() {
17003
- const context = (0, import_react4.useContext)(ChatContext);
17085
+ const context = (0, import_react3.useContext)(ChatContext);
17004
17086
  if (!context) {
17005
17087
  throw new Error("useChatContext must be used within a Chat.Root component");
17006
17088
  }
@@ -17008,7 +17090,7 @@ function useChatContext() {
17008
17090
  }
17009
17091
 
17010
17092
  // src/chat/hooks/use-copy-to-clipboard.ts
17011
- var import_react5 = require("react");
17093
+ var import_react4 = require("react");
17012
17094
 
17013
17095
  // src/utils/clipboard.ts
17014
17096
  function copyToClipboard(text2, options) {
@@ -17018,18 +17100,33 @@ function copyToClipboard(text2, options) {
17018
17100
  );
17019
17101
  }
17020
17102
 
17103
+ // src/utils/markdown-to-plain-text.ts
17104
+ var PLACEHOLDER_PREFIX = "\u200B\u200BIC";
17105
+ var PLACEHOLDER_SUFFIX = "\u200B\u200B";
17106
+ var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUFFIX}`, "g");
17107
+ function markdownToPlainText(markdown) {
17108
+ if (!markdown) return "";
17109
+ const inlineCodeSnippets = [];
17110
+ let result = markdown.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
17111
+ inlineCodeSnippets.push(code);
17112
+ return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
17113
+ }).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();
17114
+ result = result.replace(PLACEHOLDER_REGEX, (_match, index2) => inlineCodeSnippets[Number(index2)]);
17115
+ return result;
17116
+ }
17117
+
17021
17118
  // src/chat/hooks/use-copy-to-clipboard.ts
17022
17119
  var RESET_DELAY_MS = 2e3;
17023
17120
  function useCopyToClipboard() {
17024
- const [isCopied, setIsCopied] = (0, import_react5.useState)(false);
17025
- const timeoutRef = (0, import_react5.useRef)(null);
17026
- (0, import_react5.useEffect)(() => {
17121
+ const [isCopied, setIsCopied] = (0, import_react4.useState)(false);
17122
+ const timeoutRef = (0, import_react4.useRef)(null);
17123
+ (0, import_react4.useEffect)(() => {
17027
17124
  return () => {
17028
17125
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
17029
17126
  };
17030
17127
  }, []);
17031
- const copy = (0, import_react5.useCallback)((text2) => {
17032
- copyToClipboard(text2, {
17128
+ const copy = (0, import_react4.useCallback)((text2) => {
17129
+ copyToClipboard(markdownToPlainText(text2), {
17033
17130
  onSuccess: () => {
17034
17131
  setIsCopied(true);
17035
17132
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
@@ -17043,35 +17140,48 @@ function useCopyToClipboard() {
17043
17140
  return { isCopied, copy };
17044
17141
  }
17045
17142
 
17143
+ // src/chat/constants.ts
17144
+ var MESSAGE_ROLE = {
17145
+ USER: "user",
17146
+ ASSISTANT: "assistant"
17147
+ };
17148
+
17046
17149
  // src/chat/chat-message-actions/chat-message-actions-styles.ts
17047
17150
  var import_styled_components4 = __toESM(require("styled-components"), 1);
17151
+ var FADE_DURATION_MS = 150;
17152
+ var ANIMATE_DURATION_MS = 200;
17048
17153
  var ActionsContainer = import_styled_components4.default.div`
17049
17154
  display: flex;
17050
- gap: 2px;
17051
- margin-top: 4px;
17052
- opacity: 0;
17053
- pointer-events: none;
17054
- transition: opacity 150ms ease;
17155
+ opacity: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? 1 : 0};
17156
+ pointer-events: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? "auto" : "none"};
17157
+ transition: opacity ${FADE_DURATION_MS}ms ease;
17158
+ `;
17159
+ var AnimatedAction = import_styled_components4.default.div`
17160
+ display: flex;
17161
+ overflow: hidden;
17162
+ max-width: ${({ $visible }) => $visible ? "40px" : "0"};
17163
+ opacity: ${({ $visible }) => $visible ? 1 : 0};
17164
+ transition: max-width ${ANIMATE_DURATION_MS}ms ease, opacity ${ANIMATE_DURATION_MS}ms ease;
17055
17165
  `;
17056
17166
 
17057
17167
  // src/chat/chat-message-actions/chat-message-actions.tsx
17058
17168
  var import_jsx_runtime4 = require("react/jsx-runtime");
17059
- function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17169
+ function ChatMessageActions({ className, messageId, content: content2, role, isHelpful }) {
17060
17170
  const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
17061
17171
  const { isCopied, copy } = useCopyToClipboard();
17062
- const handleCopy = (0, import_react6.useCallback)(() => {
17172
+ const handleCopy = (0, import_react5.useCallback)(() => {
17063
17173
  copy(content2);
17064
17174
  onCopyMessage?.(messageId);
17065
17175
  }, [content2, messageId, copy, onCopyMessage]);
17066
- const handleThumbUp = (0, import_react6.useCallback)(() => {
17176
+ const handleThumbUp = (0, import_react5.useCallback)(() => {
17067
17177
  onThumbUpClick?.(messageId, isHelpful === true ? null : true);
17068
17178
  }, [messageId, isHelpful, onThumbUpClick]);
17069
- const handleThumbDown = (0, import_react6.useCallback)(() => {
17179
+ const handleThumbDown = (0, import_react5.useCallback)(() => {
17070
17180
  onThumbDownClick?.(messageId, isHelpful === false ? null : false);
17071
17181
  }, [messageId, isHelpful, onThumbDownClick]);
17072
- const isAssistant = role === "assistant";
17182
+ const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
17073
17183
  const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
17074
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { children: [
17184
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { $role: role, className, children: [
17075
17185
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17076
17186
  IconButton,
17077
17187
  {
@@ -17080,7 +17190,7 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17080
17190
  "aria-label": isCopied ? "Copied" : "Copy message"
17081
17191
  }
17082
17192
  ),
17083
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17193
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17084
17194
  IconButton,
17085
17195
  {
17086
17196
  icon: IconThumbUp,
@@ -17088,8 +17198,8 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17088
17198
  isSelected: isHelpful === true,
17089
17199
  "aria-label": "Good response"
17090
17200
  }
17091
- ),
17092
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17201
+ ) }),
17202
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17093
17203
  IconButton,
17094
17204
  {
17095
17205
  icon: IconThumbDown,
@@ -17097,7 +17207,7 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17097
17207
  isSelected: isHelpful === false,
17098
17208
  "aria-label": "Bad response"
17099
17209
  }
17100
- )
17210
+ ) })
17101
17211
  ] });
17102
17212
  }
17103
17213
 
@@ -17105,25 +17215,29 @@ function ChatMessageActions({ messageId, content: content2, role, isHelpful }) {
17105
17215
  var import_styled_components5 = __toESM(require("styled-components"), 1);
17106
17216
  var MessageRow = import_styled_components5.default.div`
17107
17217
  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%;
17218
+ justify-content: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
17115
17219
 
17116
17220
  &:hover ${ActionsContainer} {
17117
17221
  opacity: 1;
17118
17222
  pointer-events: auto;
17119
17223
  }
17120
17224
  `;
17225
+ var MessageContainer = import_styled_components5.default.div`
17226
+ display: flex;
17227
+ flex-direction: column;
17228
+ align-items: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
17229
+ max-width: 90%;
17230
+ width: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "auto" : "100%"};
17231
+ gap: 12px;
17232
+ `;
17121
17233
  var MessageBubble = import_styled_components5.default.div`
17122
- ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
17234
+ ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17123
17235
  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"};
17236
+ background: ${({ $role }) => $role === MESSAGE_ROLE.USER ? colors.white : "transparent"};
17237
+ padding: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "12px 16px" : "0"};
17238
+ border-radius: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "16px" : "0"};
17239
+ max-width: 100%;
17240
+ min-width: 0;
17127
17241
  `;
17128
17242
 
17129
17243
  // src/chat/chat-message/chat-message.tsx
@@ -17155,7 +17269,7 @@ var KEYBOARD_SHORTCUT_VARIANTS = {
17155
17269
  // src/components/keyboard-shortcut/keyboard-shortcut-styles.ts
17156
17270
  var variantStyles = {
17157
17271
  [KEYBOARD_SHORTCUT_VARIANTS.OUTLINED]: import_styled_components6.css`
17158
- border: 1px solid ${colors["brown-70"]};
17272
+ border: 1px solid ${colors["white-alpha-40"]};
17159
17273
  color: ${colors["brown-10"]};
17160
17274
  `,
17161
17275
  [KEYBOARD_SHORTCUT_VARIANTS.FILLED]: import_styled_components6.css`
@@ -17172,7 +17286,7 @@ var Key = import_styled_components6.default.kbd`
17172
17286
  display: inline-flex;
17173
17287
  align-items: center;
17174
17288
  justify-content: center;
17175
- padding: 4px;
17289
+ padding: 2px;
17176
17290
  border-radius: 6px;
17177
17291
  ${({ $variant }) => variantStyles[$variant]};
17178
17292
  `;
@@ -17187,9 +17301,9 @@ function KeyboardShortcut({
17187
17301
  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
17302
  }
17189
17303
 
17190
- // src/components/keyboard-shortcut/icons/ctrl-icon.tsx
17304
+ // src/components/keyboard-shortcut/icons/icon-ctrl.tsx
17191
17305
  var import_jsx_runtime7 = require("react/jsx-runtime");
17192
- function CtrlIcon(props) {
17306
+ function IconCtrl(props) {
17193
17307
  const { width: width2 = 24, height: height2 = 24, ...rest } = props;
17194
17308
  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
17309
  "text",
@@ -17200,7 +17314,7 @@ function CtrlIcon(props) {
17200
17314
  textAnchor: "middle",
17201
17315
  fill: "currentColor",
17202
17316
  fontFamily: "Geist, sans-serif",
17203
- fontWeight: 500,
17317
+ fontWeight: 300,
17204
17318
  fontSize: 14,
17205
17319
  children: "Ctrl"
17206
17320
  }
@@ -17208,7 +17322,7 @@ function CtrlIcon(props) {
17208
17322
  }
17209
17323
 
17210
17324
  // src/components/lottie/lottie.tsx
17211
- var import_react8 = require("react");
17325
+ var import_react7 = require("react");
17212
17326
 
17213
17327
  // src/components/lottie/lottie-styles.ts
17214
17328
  var import_styled_components7 = __toESM(require("styled-components"), 1);
@@ -17224,7 +17338,7 @@ var LottieContainer = import_styled_components7.default.div`
17224
17338
  `;
17225
17339
 
17226
17340
  // src/components/lottie/use-lottie.ts
17227
- var import_react7 = require("react");
17341
+ var import_react6 = require("react");
17228
17342
  var import_lottie_web = __toESM(require_lottie(), 1);
17229
17343
  function useLottie({
17230
17344
  animationData: animationData2,
@@ -17239,17 +17353,17 @@ function useLottie({
17239
17353
  onLoopComplete,
17240
17354
  onEnterFrame
17241
17355
  }) {
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);
17356
+ const containerRef = (0, import_react6.useRef)(null);
17357
+ const animationRef = (0, import_react6.useRef)(null);
17358
+ const onAnimationLoadedRef = (0, import_react6.useRef)(onAnimationLoaded);
17359
+ const onCompleteRef = (0, import_react6.useRef)(onComplete);
17360
+ const onLoopCompleteRef = (0, import_react6.useRef)(onLoopComplete);
17361
+ const onEnterFrameRef = (0, import_react6.useRef)(onEnterFrame);
17248
17362
  onAnimationLoadedRef.current = onAnimationLoaded;
17249
17363
  onCompleteRef.current = onComplete;
17250
17364
  onLoopCompleteRef.current = onLoopComplete;
17251
17365
  onEnterFrameRef.current = onEnterFrame;
17252
- (0, import_react7.useEffect)(() => {
17366
+ (0, import_react6.useEffect)(() => {
17253
17367
  if (!containerRef.current) return;
17254
17368
  const anim = import_lottie_web.default.loadAnimation({
17255
17369
  container: containerRef.current,
@@ -17342,7 +17456,7 @@ function createLottieRef(animationRef) {
17342
17456
 
17343
17457
  // src/components/lottie/lottie.tsx
17344
17458
  var import_jsx_runtime8 = require("react/jsx-runtime");
17345
- var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17459
+ var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17346
17460
  animationData: animationData2,
17347
17461
  autoplay,
17348
17462
  loop,
@@ -17372,7 +17486,7 @@ var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17372
17486
  onLoopComplete,
17373
17487
  onEnterFrame
17374
17488
  });
17375
- (0, import_react8.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17489
+ (0, import_react7.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17376
17490
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
17377
17491
  LottieContainer,
17378
17492
  {
@@ -17385,18 +17499,96 @@ var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17385
17499
  }
17386
17500
  );
17387
17501
  });
17502
+
17503
+ // src/components/text-area/text-area.tsx
17504
+ var import_react8 = require("react");
17505
+
17506
+ // src/utils/merge-refs.ts
17507
+ function mergeRefs(...refs) {
17508
+ return (node) => {
17509
+ for (const ref of refs) {
17510
+ if (typeof ref === "function") {
17511
+ ref(node);
17512
+ } else if (ref) {
17513
+ ref.current = node;
17514
+ }
17515
+ }
17516
+ };
17517
+ }
17518
+
17519
+ // src/components/text-area/text-area-styles.ts
17520
+ var import_styled_components8 = __toESM(require("styled-components"), 1);
17521
+ var StyledTextArea = import_styled_components8.default.textarea`
17522
+ ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17523
+ color: ${colors["brown-100"]};
17524
+ border: none;
17525
+ outline: none;
17526
+ resize: none;
17527
+ width: 100%;
17528
+ background: transparent;
17529
+ vertical-align: bottom;
17530
+ max-height: ${({ $maxHeight }) => $maxHeight ? `${$maxHeight}px` : "none"};
17531
+ overflow-y: ${({ $maxHeight }) => $maxHeight ? "auto" : "hidden"};
17532
+
17533
+ &::placeholder {
17534
+ color: ${colors["brown-50"]};
17535
+ }
17536
+
17537
+ &:disabled {
17538
+ opacity: 0.5;
17539
+ cursor: not-allowed;
17540
+ }
17541
+ `;
17542
+
17543
+ // src/components/text-area/text-area.tsx
17544
+ var import_jsx_runtime9 = require("react/jsx-runtime");
17545
+ var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
17546
+ const internalRef = (0, import_react8.useRef)(null);
17547
+ (0, import_react8.useLayoutEffect)(() => {
17548
+ const el = internalRef.current;
17549
+ if (el) {
17550
+ el.style.height = "auto";
17551
+ el.style.height = `${el.scrollHeight}px`;
17552
+ }
17553
+ }, [value2]);
17554
+ const handleChange = (0, import_react8.useCallback)(
17555
+ (e) => {
17556
+ onChange(e.target.value);
17557
+ },
17558
+ [onChange]
17559
+ );
17560
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
17561
+ StyledTextArea,
17562
+ {
17563
+ ref: mergeRefs(internalRef, externalRef),
17564
+ value: value2,
17565
+ onChange: handleChange,
17566
+ placeholder,
17567
+ $maxHeight: maxHeight,
17568
+ rows,
17569
+ autoFocus,
17570
+ onKeyDown,
17571
+ disabled,
17572
+ className
17573
+ }
17574
+ );
17575
+ });
17388
17576
  // Annotate the CommonJS export names for ESM import in node:
17389
17577
  0 && (module.exports = {
17390
17578
  ChatContext,
17391
17579
  ChatMessage,
17392
- CtrlIcon,
17393
17580
  Icon,
17394
17581
  IconButton,
17582
+ IconCtrl,
17395
17583
  KEYBOARD_SHORTCUT_VARIANTS,
17396
17584
  KeyboardShortcut,
17397
17585
  Lottie,
17586
+ MESSAGE_ROLE,
17587
+ TextArea,
17398
17588
  colors,
17399
17589
  fontFamilies,
17590
+ markdownToPlainText,
17591
+ mergeRefs,
17400
17592
  typographyMixin,
17401
17593
  typographyStyles,
17402
17594
  typographyTypes,