@copilotz/chat-ui 0.9.4 → 0.9.6

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
@@ -1179,6 +1179,7 @@ var Message = (0, import_react2.memo)(({
1179
1179
  const [isEditing, setIsEditing] = (0, import_react2.useState)(false);
1180
1180
  const [editContent, setEditContent] = (0, import_react2.useState)(message.content);
1181
1181
  const [showActions, setShowActions] = (0, import_react2.useState)(false);
1182
+ const [actionsFocused, setActionsFocused] = (0, import_react2.useState)(false);
1182
1183
  const [copied, setCopied] = (0, import_react2.useState)(false);
1183
1184
  const messageIsUser = isUser ?? message.role === "user";
1184
1185
  if (!hasRenderableAssistantBody(message)) {
@@ -1192,7 +1193,6 @@ var Message = (0, import_react2.memo)(({
1192
1193
  compactMode
1193
1194
  });
1194
1195
  const canEdit = enableEdit && messageIsUser;
1195
- const canRegenerate = enableRegenerate && !messageIsUser;
1196
1196
  const normalizedPreviewChars = Math.max(longMessagePreviewChars, 1);
1197
1197
  const normalizedChunkChars = Math.max(longMessageChunkChars, 1);
1198
1198
  const previewOverride = typeof message.metadata?.previewContent === "string" ? message.metadata.previewContent : void 0;
@@ -1226,9 +1226,6 @@ var Message = (0, import_react2.memo)(({
1226
1226
  setEditContent(message.content);
1227
1227
  setIsEditing(false);
1228
1228
  };
1229
- const handleRegenerate = () => {
1230
- onAction?.({ action: "regenerate", messageId: message.id });
1231
- };
1232
1229
  const handleToggleExpanded = () => {
1233
1230
  onToggleExpanded?.(message.id);
1234
1231
  };
@@ -1244,6 +1241,12 @@ var Message = (0, import_react2.memo)(({
1244
1241
  className: `flex w-full flex-col ${className} max-w-[800px] mx-auto`,
1245
1242
  onMouseEnter: () => setShowActions(true),
1246
1243
  onMouseLeave: () => setShowActions(false),
1244
+ onFocusCapture: () => setActionsFocused(true),
1245
+ onBlurCapture: (event) => {
1246
+ if (!event.currentTarget.contains(event.relatedTarget)) {
1247
+ setActionsFocused(false);
1248
+ }
1249
+ },
1247
1250
  children: [
1248
1251
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `flex gap-3 ${messageIsUser ? "flex-row-reverse" : "flex-row"} w-full mb-1`, children: [
1249
1252
  showAvatar && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `flex-shrink-0 ${compactMode ? "mt-1" : "mt-0"}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -1269,26 +1272,46 @@ var Message = (0, import_react2.memo)(({
1269
1272
  message.isEdited && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Badge, { variant: "outline", className: "text-xs", children: "editado" })
1270
1273
  ] })
1271
1274
  ] }),
1272
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${horizontalOffsetClass}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("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: [
1273
- isEditing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-2", children: [
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 ? 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: [
1274
1277
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1275
1278
  Textarea,
1276
1279
  {
1277
1280
  value: editContent,
1278
1281
  onChange: (e) => setEditContent(e.target.value),
1279
- className: "min-h-[100px] resize-none",
1282
+ className: "min-h-28 resize-y bg-muted/30 text-sm leading-6",
1280
1283
  autoFocus: true
1281
1284
  }
1282
1285
  ),
1283
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-2 justify-end", children: [
1284
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Button, { variant: "outline", size: "sm", onClick: handleCancelEdit, children: [
1285
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.X, { className: "h-4 w-4 mr-1" }),
1286
- "Cancelar"
1287
- ] }),
1288
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Button, { size: "sm", onClick: handleEdit, children: [
1289
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Check, { className: "h-4 w-4 mr-1" }),
1290
- "Salvar"
1291
- ] })
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
+ )
1292
1315
  ] })
1293
1316
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1294
1317
  !messageIsUser && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -1323,49 +1346,44 @@ var Message = (0, import_react2.memo)(({
1323
1346
  }
1324
1347
  ) }),
1325
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)) })
1326
- ] }),
1327
- !isEditing && (showActions || copied) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `absolute -top-2 flex gap-1 ${messageIsUser ? "-left-2" : "-right-2"}`, children: [
1328
- enableCopy && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1329
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1330
- Button,
1331
- {
1332
- variant: "secondary",
1333
- size: "icon",
1334
- className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
1335
- onClick: handleCopy,
1336
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Check, { className: "h-3 w-3 text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Copy, { className: "h-3 w-3" })
1337
- }
1338
- ) }),
1339
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: copied ? "Copiado!" : "Copiar" })
1340
- ] }),
1341
- canEdit && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1342
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1343
- Button,
1344
- {
1345
- variant: "secondary",
1346
- size: "icon",
1347
- className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
1348
- onClick: handleEdit,
1349
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Edit, { className: "h-3 w-3" })
1350
- }
1351
- ) }),
1352
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: "Editar" })
1353
- ] }),
1354
- canRegenerate && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1355
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1356
- Button,
1357
- {
1358
- variant: "secondary",
1359
- size: "icon",
1360
- className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
1361
- onClick: handleRegenerate,
1362
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.RotateCcw, { className: "h-3 w-3" })
1363
- }
1364
- ) }),
1365
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: "Regenerar" })
1366
- ] })
1367
- ] })
1368
- ] }) })
1349
+ ] }) }),
1350
+ !isEditing && (enableCopy || canEdit) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1351
+ "div",
1352
+ {
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"}`,
1354
+ children: [
1355
+ canEdit && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1356
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1357
+ Button,
1358
+ {
1359
+ type: "button",
1360
+ variant: "ghost",
1361
+ size: "icon",
1362
+ className: "h-7 w-7",
1363
+ onClick: handleEdit,
1364
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Edit, { className: "h-3.5 w-3.5" })
1365
+ }
1366
+ ) }),
1367
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: labels?.editMessage || "Edit" })
1368
+ ] }),
1369
+ enableCopy && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1371
+ Button,
1372
+ {
1373
+ type: "button",
1374
+ variant: "ghost",
1375
+ size: "icon",
1376
+ className: "h-7 w-7",
1377
+ onClick: handleCopy,
1378
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Check, { className: "h-3.5 w-3.5 text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react3.Copy, { className: "h-3.5 w-3.5" })
1379
+ }
1380
+ ) }),
1381
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { children: copied ? "Copied" : labels?.copyMessage || "Copy" })
1382
+ ] })
1383
+ ]
1384
+ }
1385
+ )
1386
+ ] })
1369
1387
  ]
1370
1388
  }
1371
1389
  );
@@ -2616,6 +2634,33 @@ var ThreadTagEditorBadge = ({
2616
2634
  }
2617
2635
  );
2618
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
+ };
2619
2664
  var Sidebar2 = ({
2620
2665
  threads,
2621
2666
  currentThreadId,
@@ -3099,14 +3144,11 @@ var Sidebar2 = ({
3099
3144
  (threadTag) => threadTag.id === tag.id
3100
3145
  );
3101
3146
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3102
- Button,
3147
+ ThreadTagOptionButton,
3103
3148
  {
3104
- type: "button",
3105
- variant: assigned ? "secondary" : "outline",
3106
- size: "sm",
3107
- disabled: assigned,
3108
- onClick: () => addTagToThread(tagDialogThread, tag),
3109
- children: tag.name
3149
+ tag,
3150
+ assigned,
3151
+ onClick: () => addTagToThread(tagDialogThread, tag)
3110
3152
  },
3111
3153
  tag.id
3112
3154
  );