@copilotz/chat-ui 0.9.5 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1273,25 +1273,45 @@ var Message = (0, import_react2.memo)(({
1273
1273
  ] })
1274
1274
  ] }),
1275
1275
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${horizontalOffsetClass}`, children: [
1276
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `relative overflow-hidden text-left ${messageIsUser ? "ml-auto inline-flex max-w-[85%] flex-col rounded-lg bg-primary p-3 text-primary-foreground" : "flex w-full max-w-full flex-col"}`, children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-2", children: [
1276
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `relative overflow-hidden text-left ${messageIsUser ? isEditing ? "ml-auto flex w-full max-w-[min(42rem,85%)] flex-col rounded-xl border bg-background p-2 text-foreground shadow-sm" : "ml-auto inline-flex max-w-[85%] flex-col rounded-lg bg-primary p-3 text-primary-foreground" : "flex w-full max-w-full flex-col"}`, children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-2", children: [
1277
1277
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1278
1278
  Textarea,
1279
1279
  {
1280
1280
  value: editContent,
1281
1281
  onChange: (e) => setEditContent(e.target.value),
1282
- className: "min-h-[100px] resize-none",
1282
+ className: "min-h-28 resize-y bg-muted/30 text-sm leading-6",
1283
1283
  autoFocus: true
1284
1284
  }
1285
1285
  ),
1286
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-2 justify-end", children: [
1287
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Button, { variant: "outline", size: "sm", onClick: handleCancelEdit, children: [
1288
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.X, { className: "h-4 w-4 mr-1" }),
1289
- "Cancelar"
1290
- ] }),
1291
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Button, { size: "sm", onClick: handleEdit, children: [
1292
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Check, { className: "h-4 w-4 mr-1" }),
1293
- "Salvar"
1294
- ] })
1286
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-end gap-2", children: [
1287
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1288
+ Button,
1289
+ {
1290
+ type: "button",
1291
+ variant: "ghost",
1292
+ size: "sm",
1293
+ className: "h-8",
1294
+ onClick: handleCancelEdit,
1295
+ children: [
1296
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.X, { className: "h-4 w-4 mr-1" }),
1297
+ labels?.cancel || "Cancel"
1298
+ ]
1299
+ }
1300
+ ),
1301
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1302
+ Button,
1303
+ {
1304
+ type: "button",
1305
+ size: "sm",
1306
+ className: "h-8",
1307
+ onClick: handleEdit,
1308
+ disabled: !editContent.trim() || editContent.trim() === message.content,
1309
+ children: [
1310
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Check, { className: "h-4 w-4 mr-1" }),
1311
+ "Save"
1312
+ ]
1313
+ }
1314
+ )
1295
1315
  ] })
1296
1316
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1297
1317
  !messageIsUser && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -1327,10 +1347,10 @@ var Message = (0, import_react2.memo)(({
1327
1347
  ) }),
1328
1348
  message.attachments && message.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-3 space-y-2", children: message.attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MediaRenderer, { attachment }, index)) })
1329
1349
  ] }) }),
1330
- !isEditing && (showActions || actionsFocused || copied) && (enableCopy || canEdit) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1350
+ !isEditing && (enableCopy || canEdit) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1331
1351
  "div",
1332
1352
  {
1333
- className: `mt-1 flex items-center gap-1 text-muted-foreground transition-opacity ${messageIsUser ? "justify-end" : "justify-start"}`,
1353
+ className: `mt-1 flex h-7 items-center gap-1 text-muted-foreground transition-opacity duration-150 ${messageIsUser ? "justify-end" : "justify-start"} ${showActions || actionsFocused || copied ? "opacity-100" : "pointer-events-none opacity-0"}`,
1334
1354
  children: [
1335
1355
  canEdit && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1336
1356
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -2614,6 +2634,33 @@ var ThreadTagEditorBadge = ({
2614
2634
  }
2615
2635
  );
2616
2636
  };
2637
+ var ThreadTagOptionButton = ({
2638
+ tag,
2639
+ assigned,
2640
+ onClick
2641
+ }) => {
2642
+ const color = tagColor(tag);
2643
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2644
+ Button,
2645
+ {
2646
+ type: "button",
2647
+ variant: "outline",
2648
+ size: "sm",
2649
+ disabled: assigned,
2650
+ className: "gap-1.5 border font-medium disabled:opacity-70",
2651
+ style: {
2652
+ backgroundColor: color.background,
2653
+ borderColor: color.border,
2654
+ color: color.accent
2655
+ },
2656
+ onClick,
2657
+ children: [
2658
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TagDot, { tag }),
2659
+ tag.name
2660
+ ]
2661
+ }
2662
+ );
2663
+ };
2617
2664
  var Sidebar2 = ({
2618
2665
  threads,
2619
2666
  currentThreadId,
@@ -3097,14 +3144,11 @@ var Sidebar2 = ({
3097
3144
  (threadTag) => threadTag.id === tag.id
3098
3145
  );
3099
3146
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3100
- Button,
3147
+ ThreadTagOptionButton,
3101
3148
  {
3102
- type: "button",
3103
- variant: assigned ? "secondary" : "outline",
3104
- size: "sm",
3105
- disabled: assigned,
3106
- onClick: () => addTagToThread(tagDialogThread, tag),
3107
- children: tag.name
3149
+ tag,
3150
+ assigned,
3151
+ onClick: () => addTagToThread(tagDialogThread, tag)
3108
3152
  },
3109
3153
  tag.id
3110
3154
  );
@@ -4542,6 +4586,18 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
4542
4586
  }).slice(0, 6);
4543
4587
  }, [activeMention, mentionAgents]);
4544
4588
  const isMentionMenuOpen = filteredMentionAgents.length > 0;
4589
+ const resizeTextarea = (0, import_react8.useCallback)(() => {
4590
+ const textarea = textareaRef.current;
4591
+ if (!textarea) return;
4592
+ const viewportWidth = typeof window === "undefined" ? 1024 : window.innerWidth;
4593
+ const maxHeight = viewportWidth > 768 ? 240 : 190;
4594
+ textarea.style.height = "auto";
4595
+ textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
4596
+ textarea.style.overflowY = textarea.scrollHeight > maxHeight ? "auto" : "hidden";
4597
+ }, []);
4598
+ (0, import_react8.useEffect)(() => {
4599
+ resizeTextarea();
4600
+ }, [resizeTextarea, value]);
4545
4601
  const syncMentionState = (0, import_react8.useCallback)((nextValue, nextCaret) => {
4546
4602
  const caret = typeof nextCaret === "number" ? nextCaret : textareaRef.current?.selectionStart ?? nextValue.length;
4547
4603
  const nextMatch = getActiveMentionMatch(nextValue, caret);
@@ -5012,7 +5068,7 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5012
5068
  };
5013
5069
  const canAddMoreAttachments = attachments.length < maxAttachments;
5014
5070
  const showVoiceComposer = enableAudioRecording && isVoiceComposerOpen;
5015
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
5071
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: `border-t bg-background/95 py-2 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "mx-auto w-full max-w-3xl space-y-3 px-3 md:px-2", children: [
5016
5072
  uploadProgress.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5017
5073
  FileUploadItem,
5018
5074
  {
@@ -5076,46 +5132,14 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5076
5132
  void closeVoiceComposer();
5077
5133
  }
5078
5134
  }
5079
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5135
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("form", { onSubmit: handleSubmit, className: "mb-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5080
5136
  "div",
5081
5137
  {
5082
- className: "flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl",
5138
+ className: "group/composer flex w-full flex-col gap-2 rounded-3xl border border-border/80 bg-card/95 p-2.5 shadow-sm transition-[border-color,box-shadow,background-color] focus-within:border-ring/60 focus-within:bg-card focus-within:shadow-md focus-within:ring-2 focus-within:ring-ring/15",
5083
5139
  onDrop: handleDrop,
5084
5140
  onDragOver: handleDragOver,
5085
5141
  children: [
5086
- enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5087
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5088
- "input",
5089
- {
5090
- ref: fileInputRef,
5091
- type: "file",
5092
- multiple: true,
5093
- accept: acceptedFileTypes.length > 0 ? acceptedFileTypes.join(",") : void 0,
5094
- onChange: handleFileSelect,
5095
- className: "hidden"
5096
- }
5097
- ),
5098
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5099
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5100
- Button,
5101
- {
5102
- type: "button",
5103
- variant: "outline",
5104
- size: "icon",
5105
- className: "h-10 w-10",
5106
- onClick: (e) => {
5107
- e.preventDefault();
5108
- e.stopPropagation();
5109
- fileInputRef.current?.click();
5110
- },
5111
- disabled,
5112
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Paperclip, { className: "h-4 w-4" })
5113
- }
5114
- ) }),
5115
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
5116
- ] })
5117
- ] }),
5118
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative flex-1", children: [
5142
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative min-w-0", children: [
5119
5143
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5120
5144
  Textarea,
5121
5145
  {
@@ -5124,6 +5148,7 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5124
5148
  onChange: (e) => {
5125
5149
  onChange(e.target.value);
5126
5150
  syncMentionState(e.target.value, e.target.selectionStart ?? e.target.value.length);
5151
+ requestAnimationFrame(resizeTextarea);
5127
5152
  },
5128
5153
  onSelect: (e) => {
5129
5154
  const target = e.target;
@@ -5136,7 +5161,7 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5136
5161
  onKeyDown: handleKeyDown,
5137
5162
  placeholder,
5138
5163
  disabled,
5139
- className: "max-h-[120px] resize-none border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0",
5164
+ className: "min-h-11 resize-none overflow-hidden rounded-2xl border-0 bg-transparent px-3 py-2.5 text-base leading-6 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 md:text-sm",
5140
5165
  rows: 1
5141
5166
  }
5142
5167
  ),
@@ -5157,48 +5182,84 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5157
5182
  agent.id
5158
5183
  )) }) })
5159
5184
  ] }),
5160
- enableAudioRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5161
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5162
- Button,
5163
- {
5164
- type: "button",
5165
- variant: "outline",
5166
- size: "icon",
5167
- className: "h-10 w-10",
5168
- onClick: () => {
5169
- void startVoiceCapture();
5170
- },
5171
- disabled: disabled || isGenerating,
5172
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Mic, { className: "h-4 w-4" })
5173
- }
5174
- ) }),
5175
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.voiceEnter })
5176
- ] }),
5177
- isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5178
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5179
- Button,
5180
- {
5181
- type: "button",
5182
- variant: "outline",
5183
- size: "icon",
5184
- className: "h-10 w-10",
5185
- onClick: onStopGeneration,
5186
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Square, { className: "h-4 w-4" })
5187
- }
5188
- ) }),
5189
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
5190
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5191
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5192
- Button,
5193
- {
5194
- type: "submit",
5195
- size: "icon",
5196
- className: "h-10 w-10",
5197
- disabled: disabled || !value.trim() && attachments.length === 0,
5198
- children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Send, { className: "h-4 w-4" })
5199
- }
5200
- ) }),
5201
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
5185
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex min-h-10 items-center justify-between gap-2", children: [
5186
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex min-w-0 items-center gap-1", children: enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5187
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5188
+ "input",
5189
+ {
5190
+ ref: fileInputRef,
5191
+ type: "file",
5192
+ multiple: true,
5193
+ accept: acceptedFileTypes.length > 0 ? acceptedFileTypes.join(",") : void 0,
5194
+ onChange: handleFileSelect,
5195
+ className: "hidden"
5196
+ }
5197
+ ),
5198
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5199
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5200
+ Button,
5201
+ {
5202
+ type: "button",
5203
+ variant: "ghost",
5204
+ size: "icon",
5205
+ className: "h-9 w-9 rounded-full text-muted-foreground hover:text-foreground",
5206
+ onClick: (e) => {
5207
+ e.preventDefault();
5208
+ e.stopPropagation();
5209
+ fileInputRef.current?.click();
5210
+ },
5211
+ disabled,
5212
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Paperclip, { className: "h-4 w-4" })
5213
+ }
5214
+ ) }),
5215
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
5216
+ ] })
5217
+ ] }) }),
5218
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex shrink-0 items-center gap-1", children: [
5219
+ enableAudioRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5220
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5221
+ Button,
5222
+ {
5223
+ type: "button",
5224
+ variant: "ghost",
5225
+ size: "icon",
5226
+ className: "h-9 w-9 rounded-full text-muted-foreground hover:text-foreground",
5227
+ onClick: () => {
5228
+ void startVoiceCapture();
5229
+ },
5230
+ disabled: disabled || isGenerating,
5231
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Mic, { className: "h-4 w-4" })
5232
+ }
5233
+ ) }),
5234
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.voiceEnter })
5235
+ ] }),
5236
+ isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5237
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5238
+ Button,
5239
+ {
5240
+ type: "button",
5241
+ variant: "secondary",
5242
+ size: "icon",
5243
+ className: "h-9 w-9 rounded-full",
5244
+ onClick: onStopGeneration,
5245
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Square, { className: "h-4 w-4" })
5246
+ }
5247
+ ) }),
5248
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
5249
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5250
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5251
+ Button,
5252
+ {
5253
+ type: "submit",
5254
+ size: "icon",
5255
+ className: "h-9 w-9 rounded-full",
5256
+ disabled: disabled || !value.trim() && attachments.length === 0,
5257
+ children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Send, { className: "h-4 w-4" })
5258
+ }
5259
+ ) }),
5260
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
5261
+ ] })
5262
+ ] })
5202
5263
  ] })
5203
5264
  ]
5204
5265
  }