@copilotz/chat-ui 0.9.14 → 0.9.16
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 +63 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +65 -21
- package/dist/index.js.map +1 -1
- package/dist/styles.css +26 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -74,6 +74,9 @@ var defaultChatConfig = {
|
|
|
74
74
|
attachFiles: "Attach Files",
|
|
75
75
|
attachFileTooltip: "Attach file",
|
|
76
76
|
fileTooLarge: "File too large. Max allowed: {{maxSize}}MB",
|
|
77
|
+
fileProcessError: "Failed to process file",
|
|
78
|
+
dropFiles: "Drop files to attach",
|
|
79
|
+
dropFilesHelp: "Up to {{remaining}} more files",
|
|
77
80
|
attachmentsCount: "{{count}}/{{max}} attachments",
|
|
78
81
|
voiceEnter: "Voice input",
|
|
79
82
|
voiceExit: "Use keyboard",
|
|
@@ -4323,6 +4326,9 @@ function formatLabel(template, fallback, values) {
|
|
|
4323
4326
|
(_, key) => String(values[key] ?? "")
|
|
4324
4327
|
);
|
|
4325
4328
|
}
|
|
4329
|
+
function hasDraggedFiles(dataTransfer) {
|
|
4330
|
+
return Array.from(dataTransfer.types || []).includes("Files");
|
|
4331
|
+
}
|
|
4326
4332
|
function resolveTargetFromMentions(value, agents) {
|
|
4327
4333
|
const matches = value.matchAll(/(^|\s)@([\w.-]+)/g);
|
|
4328
4334
|
for (const match of matches) {
|
|
@@ -4586,8 +4592,10 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
|
|
|
4586
4592
|
const [voiceError, setVoiceError] = (0, import_react8.useState)(null);
|
|
4587
4593
|
const [activeMention, setActiveMention] = (0, import_react8.useState)(null);
|
|
4588
4594
|
const [activeMentionIndex, setActiveMentionIndex] = (0, import_react8.useState)(0);
|
|
4595
|
+
const [isDraggingFiles, setIsDraggingFiles] = (0, import_react8.useState)(false);
|
|
4589
4596
|
const textareaRef = (0, import_react8.useRef)(null);
|
|
4590
4597
|
const fileInputRef = (0, import_react8.useRef)(null);
|
|
4598
|
+
const dragDepthRef = (0, import_react8.useRef)(0);
|
|
4591
4599
|
const voiceProviderRef = (0, import_react8.useRef)(null);
|
|
4592
4600
|
const voiceDraftRef = (0, import_react8.useRef)(null);
|
|
4593
4601
|
const voiceAppendBaseRef = (0, import_react8.useRef)(null);
|
|
@@ -4713,7 +4721,7 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
|
|
|
4713
4721
|
handleSubmit(e);
|
|
4714
4722
|
}
|
|
4715
4723
|
};
|
|
4716
|
-
const processFile = async (file) => {
|
|
4724
|
+
const processFile = (0, import_react8.useCallback)(async (file) => {
|
|
4717
4725
|
if (file.size > maxFileSize) {
|
|
4718
4726
|
alert(formatLabel(
|
|
4719
4727
|
config?.labels?.fileTooLarge,
|
|
@@ -4778,39 +4786,63 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
|
|
|
4778
4786
|
newMap.delete(fileId);
|
|
4779
4787
|
return newMap;
|
|
4780
4788
|
});
|
|
4781
|
-
alert("Failed to process file");
|
|
4789
|
+
alert(config?.labels?.fileProcessError || "Failed to process file");
|
|
4782
4790
|
return null;
|
|
4783
4791
|
}
|
|
4784
|
-
};
|
|
4785
|
-
const
|
|
4786
|
-
|
|
4787
|
-
if (!files) return;
|
|
4792
|
+
}, [config?.labels?.fileProcessError, config?.labels?.fileTooLarge, maxFileSize, setContext]);
|
|
4793
|
+
const processFiles = (0, import_react8.useCallback)(async (files) => {
|
|
4794
|
+
if (!enableFileUpload || disabled || files.length === 0) return;
|
|
4788
4795
|
const remainingSlots = maxAttachments - attachments.length;
|
|
4789
|
-
|
|
4796
|
+
if (remainingSlots <= 0) return;
|
|
4797
|
+
const filesToProcess = files.slice(0, remainingSlots);
|
|
4798
|
+
const nextAttachments = [];
|
|
4790
4799
|
for (const file of filesToProcess) {
|
|
4791
4800
|
const attachment = await processFile(file);
|
|
4792
4801
|
if (attachment) {
|
|
4793
|
-
|
|
4802
|
+
nextAttachments.push(attachment);
|
|
4794
4803
|
}
|
|
4795
4804
|
}
|
|
4805
|
+
if (nextAttachments.length > 0) {
|
|
4806
|
+
onAttachmentsChange([...attachments, ...nextAttachments]);
|
|
4807
|
+
}
|
|
4808
|
+
}, [attachments, disabled, enableFileUpload, maxAttachments, onAttachmentsChange, processFile]);
|
|
4809
|
+
const handleFileSelect = async (e) => {
|
|
4810
|
+
const files = e.target.files;
|
|
4811
|
+
if (!files) return;
|
|
4812
|
+
await processFiles(Array.from(files));
|
|
4796
4813
|
e.target.value = "";
|
|
4797
4814
|
};
|
|
4798
4815
|
const handleDrop = (0, import_react8.useCallback)(async (e) => {
|
|
4816
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4799
4817
|
e.preventDefault();
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4818
|
+
dragDepthRef.current = 0;
|
|
4819
|
+
setIsDraggingFiles(false);
|
|
4820
|
+
await processFiles(Array.from(e.dataTransfer.files));
|
|
4821
|
+
}, [enableFileUpload, processFiles]);
|
|
4822
|
+
const handleDragEnter = (0, import_react8.useCallback)((e) => {
|
|
4823
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4824
|
+
e.preventDefault();
|
|
4825
|
+
dragDepthRef.current += 1;
|
|
4826
|
+
if (attachments.length < maxAttachments) {
|
|
4827
|
+
setIsDraggingFiles(true);
|
|
4809
4828
|
}
|
|
4810
|
-
}, [attachments, enableFileUpload, maxAttachments
|
|
4829
|
+
}, [attachments.length, enableFileUpload, maxAttachments]);
|
|
4811
4830
|
const handleDragOver = (0, import_react8.useCallback)((e) => {
|
|
4831
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4812
4832
|
e.preventDefault();
|
|
4813
|
-
|
|
4833
|
+
e.dataTransfer.dropEffect = attachments.length < maxAttachments ? "copy" : "none";
|
|
4834
|
+
if (attachments.length < maxAttachments) {
|
|
4835
|
+
setIsDraggingFiles(true);
|
|
4836
|
+
}
|
|
4837
|
+
}, [attachments.length, enableFileUpload, maxAttachments]);
|
|
4838
|
+
const handleDragLeave = (0, import_react8.useCallback)((e) => {
|
|
4839
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4840
|
+
e.preventDefault();
|
|
4841
|
+
dragDepthRef.current = Math.max(0, dragDepthRef.current - 1);
|
|
4842
|
+
if (dragDepthRef.current === 0) {
|
|
4843
|
+
setIsDraggingFiles(false);
|
|
4844
|
+
}
|
|
4845
|
+
}, [enableFileUpload]);
|
|
4814
4846
|
const resetVoiceComposerState = (0, import_react8.useCallback)((nextState = "idle") => {
|
|
4815
4847
|
setVoiceState(nextState);
|
|
4816
4848
|
setVoiceDraft(null);
|
|
@@ -5163,10 +5195,21 @@ var ChatInput = (0, import_react8.memo)(function ChatInput2({
|
|
|
5163
5195
|
) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("form", { onSubmit: handleSubmit, className: "mb-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
5164
5196
|
"div",
|
|
5165
5197
|
{
|
|
5166
|
-
className:
|
|
5198
|
+
className: `group/composer relative flex w-full flex-col gap-2 overflow-hidden 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 ${isDraggingFiles ? "border-primary/60 bg-primary/5 shadow-md ring-2 ring-primary/15" : ""}`,
|
|
5167
5199
|
onDrop: handleDrop,
|
|
5200
|
+
onDragEnter: handleDragEnter,
|
|
5168
5201
|
onDragOver: handleDragOver,
|
|
5202
|
+
onDragLeave: handleDragLeave,
|
|
5169
5203
|
children: [
|
|
5204
|
+
isDraggingFiles && enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-none absolute inset-0 z-20 flex items-center justify-center rounded-3xl border-2 border-dashed border-primary/60 bg-primary/10 text-primary backdrop-blur-[1px]", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-2 px-4 text-center", children: [
|
|
5205
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "flex h-11 w-11 items-center justify-center rounded-full bg-primary/15", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.UploadCloud, { className: "h-5 w-5" }) }),
|
|
5206
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm font-semibold", children: config?.labels?.dropFiles || "Drop files to attach" }),
|
|
5207
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-xs text-muted-foreground", children: formatLabel(
|
|
5208
|
+
config?.labels?.dropFilesHelp,
|
|
5209
|
+
"Up to {{remaining}} more files",
|
|
5210
|
+
{ remaining: Math.max(0, maxAttachments - attachments.length) }
|
|
5211
|
+
) })
|
|
5212
|
+
] }) }),
|
|
5170
5213
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative min-w-0", children: [
|
|
5171
5214
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5172
5215
|
Textarea,
|