@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.cjs CHANGED
@@ -4309,6 +4309,9 @@ var VoiceComposer = ({
4309
4309
  // src/components/chat/ChatInput.tsx
4310
4310
  var import_lucide_react12 = require("lucide-react");
4311
4311
  var import_jsx_runtime25 = require("react/jsx-runtime");
4312
+ function createStagedSendId() {
4313
+ return typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).slice(2)}`;
4314
+ }
4312
4315
  function getActiveMentionMatch(value, caret) {
4313
4316
  const prefix = value.slice(0, caret);
4314
4317
  const match = /(^|\s)@([\w.-]*)$/.exec(prefix);
@@ -4594,6 +4597,7 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
4594
4597
  const [activeMention, setActiveMention] = (0, import_react8.useState)(null);
4595
4598
  const [activeMentionIndex, setActiveMentionIndex] = (0, import_react8.useState)(0);
4596
4599
  const [isDraggingFiles, setIsDraggingFiles] = (0, import_react8.useState)(false);
4600
+ const [stagedSends, setStagedSends] = (0, import_react8.useState)([]);
4597
4601
  const textareaRef = (0, import_react8.useRef)(null);
4598
4602
  const fileInputRef = (0, import_react8.useRef)(null);
4599
4603
  const dragDepthRef = (0, import_react8.useRef)(0);
@@ -4686,18 +4690,48 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
4686
4690
  textareaRef.current?.setSelectionRange(nextCaret, nextCaret);
4687
4691
  });
4688
4692
  }, [activeMention, draftValue, onTargetAgentChange, updateDraftValue]);
4689
- const handleSubmit = (e) => {
4690
- e.preventDefault();
4691
- if (!draftValue.trim() && attachments.length === 0 || disabled || isGenerating) return;
4692
- const mentionedAgent = resolveTargetFromMentions(draftValue, mentionAgents);
4693
- if (mentionedAgent) {
4694
- onTargetAgentChange?.(mentionedAgent.id);
4695
- }
4696
- onSubmit(draftValue.trim(), attachments);
4693
+ const clearComposer = (0, import_react8.useCallback)(() => {
4697
4694
  updateDraftValue("");
4698
4695
  onAttachmentsChange([]);
4699
4696
  setActiveMention(null);
4700
4697
  setActiveMentionIndex(0);
4698
+ }, [onAttachmentsChange, updateDraftValue]);
4699
+ const submitResolvedMessage = (0, import_react8.useCallback)((content, messageAttachments) => {
4700
+ const mentionedAgent = resolveTargetFromMentions(content, mentionAgents);
4701
+ if (mentionedAgent) {
4702
+ onTargetAgentChange?.(mentionedAgent.id);
4703
+ }
4704
+ onSubmit(content.trim(), messageAttachments);
4705
+ }, [mentionAgents, onSubmit, onTargetAgentChange]);
4706
+ const stageCurrentDraft = (0, import_react8.useCallback)(() => {
4707
+ const content = draftValue.trim();
4708
+ if (!content && attachments.length === 0) return;
4709
+ setStagedSends((prev) => [
4710
+ ...prev,
4711
+ {
4712
+ id: createStagedSendId(),
4713
+ content,
4714
+ attachments: [...attachments]
4715
+ }
4716
+ ]);
4717
+ clearComposer();
4718
+ }, [attachments, clearComposer, draftValue]);
4719
+ const sendStagedMessage = (0, import_react8.useCallback)((staged) => {
4720
+ setStagedSends((prev) => prev.filter((item) => item.id !== staged.id));
4721
+ submitResolvedMessage(staged.content, staged.attachments);
4722
+ }, [submitResolvedMessage]);
4723
+ const removeStagedMessage = (0, import_react8.useCallback)((id) => {
4724
+ setStagedSends((prev) => prev.filter((item) => item.id !== id));
4725
+ }, []);
4726
+ const handleSubmit = (e) => {
4727
+ e.preventDefault();
4728
+ if (!draftValue.trim() && attachments.length === 0 || disabled) return;
4729
+ if (isGenerating) {
4730
+ stageCurrentDraft();
4731
+ return;
4732
+ }
4733
+ submitResolvedMessage(draftValue.trim(), attachments);
4734
+ clearComposer();
4701
4735
  };
4702
4736
  const handleKeyDown = (e) => {
4703
4737
  if (isMentionMenuOpen) {
@@ -5221,6 +5255,50 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5221
5255
  { remaining: Math.max(0, maxAttachments - attachments.length) }
5222
5256
  ) })
5223
5257
  ] }) }),
5258
+ stagedSends.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-col gap-1.5", children: stagedSends.map((staged) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5259
+ "div",
5260
+ {
5261
+ className: "flex min-h-10 items-center gap-2 rounded-2xl border border-border/80 bg-muted/45 px-2.5 py-1.5",
5262
+ children: [
5263
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "min-w-0 flex-1", children: [
5264
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "truncate text-sm text-foreground", children: staged.content || staged.attachments[0]?.fileName || config?.labels?.attachmentsCount || "Attachment" }),
5265
+ staged.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-xs text-muted-foreground", children: formatLabel(
5266
+ config?.labels?.attachmentsCount,
5267
+ "{{count}}/{{max}} attachments",
5268
+ { count: staged.attachments.length, max: maxAttachments }
5269
+ ) })
5270
+ ] }),
5271
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5272
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5273
+ Button,
5274
+ {
5275
+ type: "button",
5276
+ size: "icon",
5277
+ className: "h-8 w-8 rounded-full",
5278
+ onClick: () => sendStagedMessage(staged),
5279
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Send, { className: "h-4 w-4" })
5280
+ }
5281
+ ) }),
5282
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
5283
+ ] }),
5284
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5285
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5286
+ Button,
5287
+ {
5288
+ type: "button",
5289
+ variant: "ghost",
5290
+ size: "icon",
5291
+ className: "h-8 w-8 rounded-full text-muted-foreground hover:text-foreground",
5292
+ onClick: () => removeStagedMessage(staged.id),
5293
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-4 w-4" })
5294
+ }
5295
+ ) }),
5296
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.voiceCancel })
5297
+ ] })
5298
+ ]
5299
+ },
5300
+ staged.id
5301
+ )) }),
5224
5302
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative min-w-0", children: [
5225
5303
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5226
5304
  Textarea,
@@ -5328,19 +5406,34 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
5328
5406
  ) }),
5329
5407
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.voiceEnter })
5330
5408
  ] }),
5331
- isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5332
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5333
- Button,
5334
- {
5335
- type: "button",
5336
- variant: "secondary",
5337
- size: "icon",
5338
- className: "h-9 w-9 rounded-full",
5339
- onClick: onStopGeneration,
5340
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Square, { className: "h-4 w-4" })
5341
- }
5342
- ) }),
5343
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
5409
+ isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5410
+ (draftValue.trim() || attachments.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5411
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5412
+ Button,
5413
+ {
5414
+ type: "submit",
5415
+ size: "icon",
5416
+ className: "h-9 w-9 rounded-full",
5417
+ disabled,
5418
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Send, { className: "h-4 w-4" })
5419
+ }
5420
+ ) }),
5421
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
5422
+ ] }),
5423
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5424
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5425
+ Button,
5426
+ {
5427
+ type: "button",
5428
+ variant: "secondary",
5429
+ size: "icon",
5430
+ className: "h-9 w-9 rounded-full",
5431
+ onClick: onStopGeneration,
5432
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Square, { className: "h-4 w-4" })
5433
+ }
5434
+ ) }),
5435
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
5436
+ ] })
5344
5437
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Tooltip, { children: [
5345
5438
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5346
5439
  Button,