@copilotz/chat-ui 0.9.20 → 0.9.22

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.js CHANGED
@@ -4328,6 +4328,9 @@ import {
4328
4328
  UploadCloud
4329
4329
  } from "lucide-react";
4330
4330
  import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
4331
+ function createStagedSendId() {
4332
+ return typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).slice(2)}`;
4333
+ }
4331
4334
  function getActiveMentionMatch(value, caret) {
4332
4335
  const prefix = value.slice(0, caret);
4333
4336
  const match = /(^|\s)@([\w.-]*)$/.exec(prefix);
@@ -4613,6 +4616,7 @@ var ChatInput = memo4(function ChatInput2({
4613
4616
  const [activeMention, setActiveMention] = useState7(null);
4614
4617
  const [activeMentionIndex, setActiveMentionIndex] = useState7(0);
4615
4618
  const [isDraggingFiles, setIsDraggingFiles] = useState7(false);
4619
+ const [stagedSends, setStagedSends] = useState7([]);
4616
4620
  const textareaRef = useRef5(null);
4617
4621
  const fileInputRef = useRef5(null);
4618
4622
  const dragDepthRef = useRef5(0);
@@ -4705,18 +4709,48 @@ var ChatInput = memo4(function ChatInput2({
4705
4709
  textareaRef.current?.setSelectionRange(nextCaret, nextCaret);
4706
4710
  });
4707
4711
  }, [activeMention, draftValue, onTargetAgentChange, updateDraftValue]);
4708
- const handleSubmit = (e) => {
4709
- e.preventDefault();
4710
- if (!draftValue.trim() && attachments.length === 0 || disabled || isGenerating) return;
4711
- const mentionedAgent = resolveTargetFromMentions(draftValue, mentionAgents);
4712
- if (mentionedAgent) {
4713
- onTargetAgentChange?.(mentionedAgent.id);
4714
- }
4715
- onSubmit(draftValue.trim(), attachments);
4712
+ const clearComposer = useCallback3(() => {
4716
4713
  updateDraftValue("");
4717
4714
  onAttachmentsChange([]);
4718
4715
  setActiveMention(null);
4719
4716
  setActiveMentionIndex(0);
4717
+ }, [onAttachmentsChange, updateDraftValue]);
4718
+ const submitResolvedMessage = useCallback3((content, messageAttachments) => {
4719
+ const mentionedAgent = resolveTargetFromMentions(content, mentionAgents);
4720
+ if (mentionedAgent) {
4721
+ onTargetAgentChange?.(mentionedAgent.id);
4722
+ }
4723
+ onSubmit(content.trim(), messageAttachments);
4724
+ }, [mentionAgents, onSubmit, onTargetAgentChange]);
4725
+ const stageCurrentDraft = useCallback3(() => {
4726
+ const content = draftValue.trim();
4727
+ if (!content && attachments.length === 0) return;
4728
+ setStagedSends((prev) => [
4729
+ ...prev,
4730
+ {
4731
+ id: createStagedSendId(),
4732
+ content,
4733
+ attachments: [...attachments]
4734
+ }
4735
+ ]);
4736
+ clearComposer();
4737
+ }, [attachments, clearComposer, draftValue]);
4738
+ const sendStagedMessage = useCallback3((staged) => {
4739
+ setStagedSends((prev) => prev.filter((item) => item.id !== staged.id));
4740
+ submitResolvedMessage(staged.content, staged.attachments);
4741
+ }, [submitResolvedMessage]);
4742
+ const removeStagedMessage = useCallback3((id) => {
4743
+ setStagedSends((prev) => prev.filter((item) => item.id !== id));
4744
+ }, []);
4745
+ const handleSubmit = (e) => {
4746
+ e.preventDefault();
4747
+ if (!draftValue.trim() && attachments.length === 0 || disabled) return;
4748
+ if (isGenerating) {
4749
+ stageCurrentDraft();
4750
+ return;
4751
+ }
4752
+ submitResolvedMessage(draftValue.trim(), attachments);
4753
+ clearComposer();
4720
4754
  };
4721
4755
  const handleKeyDown = (e) => {
4722
4756
  if (isMentionMenuOpen) {
@@ -5240,6 +5274,50 @@ var ChatInput = memo4(function ChatInput2({
5240
5274
  { remaining: Math.max(0, maxAttachments - attachments.length) }
5241
5275
  ) })
5242
5276
  ] }) }),
5277
+ stagedSends.length > 0 && /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-1.5", children: stagedSends.map((staged) => /* @__PURE__ */ jsxs15(
5278
+ "div",
5279
+ {
5280
+ className: "flex min-h-10 items-center gap-2 rounded-2xl border border-border/80 bg-muted/45 px-2.5 py-1.5",
5281
+ children: [
5282
+ /* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
5283
+ /* @__PURE__ */ jsx25("div", { className: "truncate text-sm text-foreground", children: staged.content || staged.attachments[0]?.fileName || config?.labels?.attachmentsCount || "Attachment" }),
5284
+ staged.attachments.length > 0 && /* @__PURE__ */ jsx25("div", { className: "text-xs text-muted-foreground", children: formatLabel(
5285
+ config?.labels?.attachmentsCount,
5286
+ "{{count}}/{{max}} attachments",
5287
+ { count: staged.attachments.length, max: maxAttachments }
5288
+ ) })
5289
+ ] }),
5290
+ /* @__PURE__ */ jsxs15(Tooltip, { children: [
5291
+ /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(
5292
+ Button,
5293
+ {
5294
+ type: "button",
5295
+ size: "icon",
5296
+ className: "h-8 w-8 rounded-full",
5297
+ onClick: () => sendStagedMessage(staged),
5298
+ children: /* @__PURE__ */ jsx25(Send2, { className: "h-4 w-4" })
5299
+ }
5300
+ ) }),
5301
+ /* @__PURE__ */ jsx25(TooltipContent, { children: config?.labels?.sendMessageTooltip })
5302
+ ] }),
5303
+ /* @__PURE__ */ jsxs15(Tooltip, { children: [
5304
+ /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(
5305
+ Button,
5306
+ {
5307
+ type: "button",
5308
+ variant: "ghost",
5309
+ size: "icon",
5310
+ className: "h-8 w-8 rounded-full text-muted-foreground hover:text-foreground",
5311
+ onClick: () => removeStagedMessage(staged.id),
5312
+ children: /* @__PURE__ */ jsx25(X5, { className: "h-4 w-4" })
5313
+ }
5314
+ ) }),
5315
+ /* @__PURE__ */ jsx25(TooltipContent, { children: config?.labels?.voiceCancel })
5316
+ ] })
5317
+ ]
5318
+ },
5319
+ staged.id
5320
+ )) }),
5243
5321
  /* @__PURE__ */ jsxs15("div", { className: "relative min-w-0", children: [
5244
5322
  /* @__PURE__ */ jsx25(
5245
5323
  Textarea,
@@ -5347,19 +5425,34 @@ var ChatInput = memo4(function ChatInput2({
5347
5425
  ) }),
5348
5426
  /* @__PURE__ */ jsx25(TooltipContent, { children: config?.labels?.voiceEnter })
5349
5427
  ] }),
5350
- isGenerating ? /* @__PURE__ */ jsxs15(Tooltip, { children: [
5351
- /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(
5352
- Button,
5353
- {
5354
- type: "button",
5355
- variant: "secondary",
5356
- size: "icon",
5357
- className: "h-9 w-9 rounded-full",
5358
- onClick: onStopGeneration,
5359
- children: /* @__PURE__ */ jsx25(Square2, { className: "h-4 w-4" })
5360
- }
5361
- ) }),
5362
- /* @__PURE__ */ jsx25(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
5428
+ isGenerating ? /* @__PURE__ */ jsxs15(Fragment6, { children: [
5429
+ (draftValue.trim() || attachments.length > 0) && /* @__PURE__ */ jsxs15(Tooltip, { children: [
5430
+ /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(
5431
+ Button,
5432
+ {
5433
+ type: "submit",
5434
+ size: "icon",
5435
+ className: "h-9 w-9 rounded-full",
5436
+ disabled,
5437
+ children: /* @__PURE__ */ jsx25(Send2, { className: "h-4 w-4" })
5438
+ }
5439
+ ) }),
5440
+ /* @__PURE__ */ jsx25(TooltipContent, { children: config?.labels?.sendMessageTooltip })
5441
+ ] }),
5442
+ /* @__PURE__ */ jsxs15(Tooltip, { children: [
5443
+ /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(
5444
+ Button,
5445
+ {
5446
+ type: "button",
5447
+ variant: "secondary",
5448
+ size: "icon",
5449
+ className: "h-9 w-9 rounded-full",
5450
+ onClick: onStopGeneration,
5451
+ children: /* @__PURE__ */ jsx25(Square2, { className: "h-4 w-4" })
5452
+ }
5453
+ ) }),
5454
+ /* @__PURE__ */ jsx25(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
5455
+ ] })
5363
5456
  ] }) : /* @__PURE__ */ jsxs15(Tooltip, { children: [
5364
5457
  /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(
5365
5458
  Button,