@copilotz/chat-ui 0.9.15 → 0.9.17
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 +64 -21
- 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 +66 -22
- package/dist/index.js.map +1 -1
- package/dist/styles.css +32 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -173,6 +173,9 @@ interface ChatConfig {
|
|
|
173
173
|
attachFiles?: string;
|
|
174
174
|
attachFileTooltip?: string;
|
|
175
175
|
fileTooLarge?: string;
|
|
176
|
+
fileProcessError?: string;
|
|
177
|
+
dropFiles?: string;
|
|
178
|
+
dropFilesHelp?: string;
|
|
176
179
|
attachmentsCount?: string;
|
|
177
180
|
voiceEnter?: string;
|
|
178
181
|
voiceExit?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -173,6 +173,9 @@ interface ChatConfig {
|
|
|
173
173
|
attachFiles?: string;
|
|
174
174
|
attachFileTooltip?: string;
|
|
175
175
|
fileTooLarge?: string;
|
|
176
|
+
fileProcessError?: string;
|
|
177
|
+
dropFiles?: string;
|
|
178
|
+
dropFilesHelp?: string;
|
|
176
179
|
attachmentsCount?: string;
|
|
177
180
|
voiceEnter?: string;
|
|
178
181
|
voiceExit?: string;
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,9 @@ var defaultChatConfig = {
|
|
|
35
35
|
attachFiles: "Attach Files",
|
|
36
36
|
attachFileTooltip: "Attach file",
|
|
37
37
|
fileTooLarge: "File too large. Max allowed: {{maxSize}}MB",
|
|
38
|
+
fileProcessError: "Failed to process file",
|
|
39
|
+
dropFiles: "Drop files to attach",
|
|
40
|
+
dropFilesHelp: "Up to {{remaining}} more files",
|
|
38
41
|
attachmentsCount: "{{count}}/{{max}} attachments",
|
|
39
42
|
voiceEnter: "Voice input",
|
|
40
43
|
voiceExit: "Use keyboard",
|
|
@@ -4321,7 +4324,8 @@ import {
|
|
|
4321
4324
|
Square as Square2,
|
|
4322
4325
|
Play,
|
|
4323
4326
|
Pause,
|
|
4324
|
-
Loader2 as Loader22
|
|
4327
|
+
Loader2 as Loader22,
|
|
4328
|
+
UploadCloud
|
|
4325
4329
|
} from "lucide-react";
|
|
4326
4330
|
import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4327
4331
|
function getActiveMentionMatch(value, caret) {
|
|
@@ -4341,6 +4345,9 @@ function formatLabel(template, fallback, values) {
|
|
|
4341
4345
|
(_, key) => String(values[key] ?? "")
|
|
4342
4346
|
);
|
|
4343
4347
|
}
|
|
4348
|
+
function hasDraggedFiles(dataTransfer) {
|
|
4349
|
+
return Array.from(dataTransfer.types || []).includes("Files");
|
|
4350
|
+
}
|
|
4344
4351
|
function resolveTargetFromMentions(value, agents) {
|
|
4345
4352
|
const matches = value.matchAll(/(^|\s)@([\w.-]+)/g);
|
|
4346
4353
|
for (const match of matches) {
|
|
@@ -4604,8 +4611,10 @@ var ChatInput = memo4(function ChatInput2({
|
|
|
4604
4611
|
const [voiceError, setVoiceError] = useState7(null);
|
|
4605
4612
|
const [activeMention, setActiveMention] = useState7(null);
|
|
4606
4613
|
const [activeMentionIndex, setActiveMentionIndex] = useState7(0);
|
|
4614
|
+
const [isDraggingFiles, setIsDraggingFiles] = useState7(false);
|
|
4607
4615
|
const textareaRef = useRef5(null);
|
|
4608
4616
|
const fileInputRef = useRef5(null);
|
|
4617
|
+
const dragDepthRef = useRef5(0);
|
|
4609
4618
|
const voiceProviderRef = useRef5(null);
|
|
4610
4619
|
const voiceDraftRef = useRef5(null);
|
|
4611
4620
|
const voiceAppendBaseRef = useRef5(null);
|
|
@@ -4731,7 +4740,7 @@ var ChatInput = memo4(function ChatInput2({
|
|
|
4731
4740
|
handleSubmit(e);
|
|
4732
4741
|
}
|
|
4733
4742
|
};
|
|
4734
|
-
const processFile = async (file) => {
|
|
4743
|
+
const processFile = useCallback3(async (file) => {
|
|
4735
4744
|
if (file.size > maxFileSize) {
|
|
4736
4745
|
alert(formatLabel(
|
|
4737
4746
|
config?.labels?.fileTooLarge,
|
|
@@ -4796,39 +4805,63 @@ var ChatInput = memo4(function ChatInput2({
|
|
|
4796
4805
|
newMap.delete(fileId);
|
|
4797
4806
|
return newMap;
|
|
4798
4807
|
});
|
|
4799
|
-
alert("Failed to process file");
|
|
4808
|
+
alert(config?.labels?.fileProcessError || "Failed to process file");
|
|
4800
4809
|
return null;
|
|
4801
4810
|
}
|
|
4802
|
-
};
|
|
4803
|
-
const
|
|
4804
|
-
|
|
4805
|
-
if (!files) return;
|
|
4811
|
+
}, [config?.labels?.fileProcessError, config?.labels?.fileTooLarge, maxFileSize, setContext]);
|
|
4812
|
+
const processFiles = useCallback3(async (files) => {
|
|
4813
|
+
if (!enableFileUpload || disabled || files.length === 0) return;
|
|
4806
4814
|
const remainingSlots = maxAttachments - attachments.length;
|
|
4807
|
-
|
|
4815
|
+
if (remainingSlots <= 0) return;
|
|
4816
|
+
const filesToProcess = files.slice(0, remainingSlots);
|
|
4817
|
+
const nextAttachments = [];
|
|
4808
4818
|
for (const file of filesToProcess) {
|
|
4809
4819
|
const attachment = await processFile(file);
|
|
4810
4820
|
if (attachment) {
|
|
4811
|
-
|
|
4821
|
+
nextAttachments.push(attachment);
|
|
4812
4822
|
}
|
|
4813
4823
|
}
|
|
4824
|
+
if (nextAttachments.length > 0) {
|
|
4825
|
+
onAttachmentsChange([...attachments, ...nextAttachments]);
|
|
4826
|
+
}
|
|
4827
|
+
}, [attachments, disabled, enableFileUpload, maxAttachments, onAttachmentsChange, processFile]);
|
|
4828
|
+
const handleFileSelect = async (e) => {
|
|
4829
|
+
const files = e.target.files;
|
|
4830
|
+
if (!files) return;
|
|
4831
|
+
await processFiles(Array.from(files));
|
|
4814
4832
|
e.target.value = "";
|
|
4815
4833
|
};
|
|
4816
4834
|
const handleDrop = useCallback3(async (e) => {
|
|
4835
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4817
4836
|
e.preventDefault();
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4837
|
+
dragDepthRef.current = 0;
|
|
4838
|
+
setIsDraggingFiles(false);
|
|
4839
|
+
await processFiles(Array.from(e.dataTransfer.files));
|
|
4840
|
+
}, [enableFileUpload, processFiles]);
|
|
4841
|
+
const handleDragEnter = useCallback3((e) => {
|
|
4842
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4843
|
+
e.preventDefault();
|
|
4844
|
+
dragDepthRef.current += 1;
|
|
4845
|
+
if (attachments.length < maxAttachments) {
|
|
4846
|
+
setIsDraggingFiles(true);
|
|
4827
4847
|
}
|
|
4828
|
-
}, [attachments, enableFileUpload, maxAttachments
|
|
4848
|
+
}, [attachments.length, enableFileUpload, maxAttachments]);
|
|
4829
4849
|
const handleDragOver = useCallback3((e) => {
|
|
4850
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4830
4851
|
e.preventDefault();
|
|
4831
|
-
|
|
4852
|
+
e.dataTransfer.dropEffect = attachments.length < maxAttachments ? "copy" : "none";
|
|
4853
|
+
if (attachments.length < maxAttachments) {
|
|
4854
|
+
setIsDraggingFiles(true);
|
|
4855
|
+
}
|
|
4856
|
+
}, [attachments.length, enableFileUpload, maxAttachments]);
|
|
4857
|
+
const handleDragLeave = useCallback3((e) => {
|
|
4858
|
+
if (!enableFileUpload || !hasDraggedFiles(e.dataTransfer)) return;
|
|
4859
|
+
e.preventDefault();
|
|
4860
|
+
dragDepthRef.current = Math.max(0, dragDepthRef.current - 1);
|
|
4861
|
+
if (dragDepthRef.current === 0) {
|
|
4862
|
+
setIsDraggingFiles(false);
|
|
4863
|
+
}
|
|
4864
|
+
}, [enableFileUpload]);
|
|
4832
4865
|
const resetVoiceComposerState = useCallback3((nextState = "idle") => {
|
|
4833
4866
|
setVoiceState(nextState);
|
|
4834
4867
|
setVoiceDraft(null);
|
|
@@ -5181,10 +5214,21 @@ var ChatInput = memo4(function ChatInput2({
|
|
|
5181
5214
|
) }) : /* @__PURE__ */ jsx25("form", { onSubmit: handleSubmit, className: "mb-1", children: /* @__PURE__ */ jsxs15(
|
|
5182
5215
|
"div",
|
|
5183
5216
|
{
|
|
5184
|
-
className:
|
|
5217
|
+
className: `group/composer relative flex w-full flex-col gap-2 overflow-visible 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" : ""}`,
|
|
5185
5218
|
onDrop: handleDrop,
|
|
5219
|
+
onDragEnter: handleDragEnter,
|
|
5186
5220
|
onDragOver: handleDragOver,
|
|
5221
|
+
onDragLeave: handleDragLeave,
|
|
5187
5222
|
children: [
|
|
5223
|
+
isDraggingFiles && enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ jsx25("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__ */ jsxs15("div", { className: "flex flex-col items-center gap-2 px-4 text-center", children: [
|
|
5224
|
+
/* @__PURE__ */ jsx25("span", { className: "flex h-11 w-11 items-center justify-center rounded-full bg-primary/15", children: /* @__PURE__ */ jsx25(UploadCloud, { className: "h-5 w-5" }) }),
|
|
5225
|
+
/* @__PURE__ */ jsx25("span", { className: "text-sm font-semibold", children: config?.labels?.dropFiles || "Drop files to attach" }),
|
|
5226
|
+
/* @__PURE__ */ jsx25("span", { className: "text-xs text-muted-foreground", children: formatLabel(
|
|
5227
|
+
config?.labels?.dropFilesHelp,
|
|
5228
|
+
"Up to {{remaining}} more files",
|
|
5229
|
+
{ remaining: Math.max(0, maxAttachments - attachments.length) }
|
|
5230
|
+
) })
|
|
5231
|
+
] }) }),
|
|
5188
5232
|
/* @__PURE__ */ jsxs15("div", { className: "relative min-w-0", children: [
|
|
5189
5233
|
/* @__PURE__ */ jsx25(
|
|
5190
5234
|
Textarea,
|
|
@@ -5211,7 +5255,7 @@ var ChatInput = memo4(function ChatInput2({
|
|
|
5211
5255
|
rows: 1
|
|
5212
5256
|
}
|
|
5213
5257
|
),
|
|
5214
|
-
isMentionMenuOpen && /* @__PURE__ */ jsx25("div", { className: "absolute bottom-full left-0 right-0 mb-2 overflow-hidden rounded-md border bg-popover shadow-md", children: /* @__PURE__ */ jsx25("div", { className: "p-1", children: filteredMentionAgents.map((agent, index) => /* @__PURE__ */ jsxs15(
|
|
5258
|
+
isMentionMenuOpen && /* @__PURE__ */ jsx25("div", { className: "absolute bottom-full left-0 right-0 z-30 mb-2 overflow-hidden rounded-md border bg-popover shadow-md", children: /* @__PURE__ */ jsx25("div", { className: "p-1", children: filteredMentionAgents.map((agent, index) => /* @__PURE__ */ jsxs15(
|
|
5215
5259
|
"button",
|
|
5216
5260
|
{
|
|
5217
5261
|
type: "button",
|