@stack-spot/ai-chat-widget 1.28.1 → 1.29.0

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/app-metadata.json +2 -2
  3. package/dist/layout.css +19 -0
  4. package/dist/utils/upload/UploadManager.d.ts +2 -0
  5. package/dist/utils/upload/UploadManager.d.ts.map +1 -1
  6. package/dist/utils/upload/UploadManager.js +32 -25
  7. package/dist/utils/upload/UploadManager.js.map +1 -1
  8. package/dist/utils/upload/use-paste-upload.d.ts +8 -0
  9. package/dist/utils/upload/use-paste-upload.d.ts.map +1 -0
  10. package/dist/utils/upload/use-paste-upload.js +19 -0
  11. package/dist/utils/upload/use-paste-upload.js.map +1 -0
  12. package/dist/views/MessageInput/UploadDragNDrop.d.ts +14 -0
  13. package/dist/views/MessageInput/UploadDragNDrop.d.ts.map +1 -0
  14. package/dist/views/MessageInput/UploadDragNDrop.js +52 -0
  15. package/dist/views/MessageInput/UploadDragNDrop.js.map +1 -0
  16. package/dist/views/MessageInput/dictionary.d.ts +1 -1
  17. package/dist/views/MessageInput/dictionary.d.ts.map +1 -1
  18. package/dist/views/MessageInput/dictionary.js +10 -0
  19. package/dist/views/MessageInput/dictionary.js.map +1 -1
  20. package/dist/views/MessageInput/index.d.ts.map +1 -1
  21. package/dist/views/MessageInput/index.js +11 -1
  22. package/dist/views/MessageInput/index.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/app-metadata.json +2 -2
  25. package/src/layout.css +19 -0
  26. package/src/utils/upload/UploadManager.ts +32 -23
  27. package/src/utils/upload/use-paste-upload.tsx +30 -0
  28. package/src/views/MessageInput/UploadDragNDrop.tsx +82 -0
  29. package/src/views/MessageInput/dictionary.ts +10 -0
  30. package/src/views/MessageInput/index.tsx +15 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.29.0](https://github.com/stack-spot/portal-ai-chat-widget/compare/ai-chat-widget@v1.28.1...ai-chat-widget@v1.29.0) (2025-07-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * Adds drag-and-drop and paste upload functionality ([#192](https://github.com/stack-spot/portal-ai-chat-widget/issues/192)) ([a052b9e](https://github.com/stack-spot/portal-ai-chat-widget/commit/a052b9e8108b6a0971d96596f25c6be873664980))
9
+
3
10
  ## [1.28.1](https://github.com/stack-spot/portal-ai-chat-widget/compare/ai-chat-widget@v1.28.0...ai-chat-widget@v1.28.1) (2025-07-03)
4
11
 
5
12
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.28.1",
4
- "date": "Thu Jul 03 2025 16:56:42 GMT+0000 (Coordinated Universal Time)",
3
+ "version": "1.29.0",
4
+ "date": "Thu Jul 03 2025 20:22:32 GMT+0000 (Coordinated Universal Time)",
5
5
  "dependencies": [
6
6
  {
7
7
  "name": "@stack-spot/app-metadata",
package/dist/layout.css CHANGED
@@ -94,6 +94,7 @@
94
94
  }
95
95
 
96
96
  .chat-container {
97
+ position: relative;
97
98
  padding: 20px;
98
99
  max-width: 1200px;
99
100
  width: calc(100% - 40px);
@@ -186,4 +187,22 @@
186
187
  border: 1px solid var(--primary-500);
187
188
  border-left: none;
188
189
  color: var(--light-contrastText);
190
+ }
191
+
192
+ .upload-drag-drop {
193
+ display: flex;
194
+ background-color: #00000090;
195
+ background-color: color-mix(in srgb, var(--light-300) 80%, transparent);
196
+ position: absolute;
197
+ width: 99%;
198
+ height: 99%;
199
+ top: 0;
200
+ left: 0;
201
+ flex-direction: column;
202
+ justify-content: center;
203
+ align-items: center;
204
+ border: 1px dashed var(--secondary-500);
205
+ z-index: 9999;
206
+ pointer-events: auto;
207
+ color: var(--light-contrastText)
189
208
  }
@@ -24,12 +24,14 @@ export declare class UploadManager {
24
24
  private runChangeListeners;
25
25
  private runStatusListeners;
26
26
  private hasEquivalentFile;
27
+ private processFiles;
27
28
  private attachEventListeners;
28
29
  private createInput;
29
30
  private computeStatus;
30
31
  open(): void;
31
32
  get(): FileUpload[];
32
33
  reset(): void;
34
+ add(files?: File | File[]): void;
33
35
  remove(file: FileUpload): void;
34
36
  onChange(listener: UploadChangeListener): () => void;
35
37
  onChangeStatus(listener: UploadStatusChangeListener): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"UploadManager.d.ts","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAsD,WAAW,EAAE,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAGzC,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAA;AAChE,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;AAC9E,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,CAAA;AACjE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAA;AAEhE,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,MAAM,EAAE,mBAAmB,CAAS;gBAExB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAMlF,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IASrB,IAAI;IAKJ,GAAG,IAAI,UAAU,EAAE;IAInB,KAAK;IAML,MAAM,CAAC,IAAI,EAAE,UAAU;IAOvB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB;IAOvC,cAAc,CAAC,QAAQ,EAAE,0BAA0B;IAOnD,OAAO,CAAC,QAAQ,EAAE,mBAAmB;IAOrC,MAAM;IAIN,OAAO;CAIR"}
1
+ {"version":3,"file":"UploadManager.d.ts","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAsD,WAAW,EAAE,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAGzC,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAA;AAChE,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;AAC9E,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,CAAA;AACjE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAA;AAEhE,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,MAAM,EAAE,mBAAmB,CAAS;gBAExB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAMlF,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IASrB,IAAI;IAKJ,GAAG,IAAI,UAAU,EAAE;IAInB,KAAK;IAML,GAAG,CAAC,KAAK,GAAE,IAAI,GAAG,IAAI,EAAO;IAK7B,MAAM,CAAC,IAAI,EAAE,UAAU;IAOvB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB;IAOvC,cAAc,CAAC,QAAQ,EAAE,0BAA0B;IAOnD,OAAO,CAAC,QAAQ,EAAE,mBAAmB;IAOrC,MAAM;IAIN,OAAO;CAIR"}
@@ -32,34 +32,37 @@ export class UploadManager {
32
32
  const id = getFileId(file);
33
33
  return this.value.some(f => id === f.id);
34
34
  }
35
- attachEventListeners() {
36
- const handleChange = () => {
37
- const newFiles = [];
38
- const errors = [];
39
- for (const f of this.input?.files ?? []) {
40
- if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
41
- errors.push(new FileIsTooLarge(f.name, this.maxSize));
42
- }
43
- else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
44
- errors.push(new MaxFilesReached(f.name, this.maxItems));
45
- }
46
- else if (this.hasEquivalentFile(f)) {
47
- errors.push(new FileAlreadyExists(f.name));
48
- }
49
- else {
50
- const upload = new FileUpload(f);
51
- newFiles.push(upload);
52
- upload.onChange(() => this.runStatusListeners());
53
- }
35
+ processFiles(files) {
36
+ const newFiles = [];
37
+ const errors = [];
38
+ for (const f of files ?? []) {
39
+ if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
40
+ errors.push(new FileIsTooLarge(f.name, this.maxSize));
41
+ }
42
+ else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
43
+ errors.push(new MaxFilesReached(f.name, this.maxItems));
54
44
  }
55
- if (newFiles.length) {
56
- this.value = [...this.value, ...newFiles];
57
- this.runChangeListeners();
58
- this.runStatusListeners();
45
+ else if (this.hasEquivalentFile(f)) {
46
+ errors.push(new FileAlreadyExists(f.name));
59
47
  }
60
- if (errors.length) {
61
- this.errorListeners.forEach(l => l(errors));
48
+ else {
49
+ const upload = new FileUpload(f);
50
+ newFiles.push(upload);
51
+ upload.onChange(() => this.runStatusListeners());
62
52
  }
53
+ }
54
+ if (newFiles.length) {
55
+ this.value = [...this.value, ...newFiles];
56
+ this.runChangeListeners();
57
+ this.runStatusListeners();
58
+ }
59
+ if (errors.length) {
60
+ this.errorListeners.forEach(l => l(errors));
61
+ }
62
+ }
63
+ attachEventListeners() {
64
+ const handleChange = () => {
65
+ this.processFiles(this.input?.files || []);
63
66
  this.destroy();
64
67
  };
65
68
  this.onDestroy = () => this.input?.removeEventListener('change', handleChange);
@@ -96,6 +99,10 @@ export class UploadManager {
96
99
  this.value = [];
97
100
  this.runChangeListeners();
98
101
  }
102
+ add(files = []) {
103
+ const fileList = Array.isArray(files) ? files : [files];
104
+ this.processFiles(fileList);
105
+ }
99
106
  remove(file) {
100
107
  file.destroy();
101
108
  this.value = this.value.filter(f => f !== file);
@@ -1 +1 @@
1
- {"version":3,"file":"UploadManager.js","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UploadManager.js","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ interface UsePasteUploadProps {
2
+ textAreaRef: React.RefObject<HTMLTextAreaElement>;
3
+ onUploadFiles: (files: File[]) => void;
4
+ enabled?: boolean;
5
+ }
6
+ export declare const usePasteUpload: ({ textAreaRef, onUploadFiles, enabled, }: UsePasteUploadProps) => void;
7
+ export {};
8
+ //# sourceMappingURL=use-paste-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-paste-upload.d.ts","sourceRoot":"","sources":["../../../src/utils/upload/use-paste-upload.tsx"],"names":[],"mappings":"AAEA,UAAU,mBAAmB;IAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAClD,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,6CAIxB,mBAAmB,SAiBrB,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { useEffect } from 'react';
2
+ export const usePasteUpload = ({ textAreaRef, onUploadFiles, enabled = true, }) => {
3
+ useEffect(() => {
4
+ const textarea = textAreaRef.current;
5
+ if (!textarea || !enabled)
6
+ return;
7
+ const handlePaste = (e) => {
8
+ if (e.clipboardData?.files?.length) {
9
+ onUploadFiles(Array.from(e.clipboardData.files));
10
+ e.preventDefault();
11
+ }
12
+ };
13
+ textarea.addEventListener('paste', handlePaste);
14
+ return () => {
15
+ textarea.removeEventListener('paste', handlePaste);
16
+ };
17
+ }, [onUploadFiles, textAreaRef, enabled]);
18
+ };
19
+ //# sourceMappingURL=use-paste-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-paste-upload.js","sourceRoot":"","sources":["../../../src/utils/upload/use-paste-upload.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQjC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAC7B,WAAW,EACX,aAAa,EACb,OAAO,GAAG,IAAI,GACM,EAAE,EAAE;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAA;QACpC,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO;YAAE,OAAM;QAEjC,MAAM,WAAW,GAAG,CAAC,CAAiB,EAAE,EAAE;YACxC,IAAI,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;gBACnC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;gBAChD,CAAC,CAAC,cAAc,EAAE,CAAA;YACpB,CAAC;QACH,CAAC,CAAA;QAED,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAC/C,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QACpD,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAA;AAC3C,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { DragEvent } from 'react';
2
+ export declare function useUploadDragDrop(containerSelector?: string): {
3
+ isDragging: boolean;
4
+ handleDrop: (e: DragEvent) => void;
5
+ handleDragLeave: (e: DragEvent) => void;
6
+ };
7
+ interface UploadDragNDropProps {
8
+ isDragging?: boolean;
9
+ onDrop?: (e: DragEvent) => void;
10
+ onDragLeave?: (e: DragEvent) => void;
11
+ }
12
+ export declare const UploadDragNDrop: ({ isDragging, onDrop, onDragLeave }: UploadDragNDropProps) => import("react/jsx-runtime").JSX.Element | null;
13
+ export {};
14
+ //# sourceMappingURL=UploadDragNDrop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UploadDragNDrop.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/UploadDragNDrop.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAoC,MAAM,OAAO,CAAA;AAInE,wBAAgB,iBAAiB,CAAC,iBAAiB,GAAE,MAA0B;;oBAI1C,SAAS;yBASJ,SAAS;EA2BlD;AAED,UAAU,oBAAoB;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,eAAe,wCAAyC,oBAAoB,mDA2BxF,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconBox } from '@citric/core';
3
+ import { Document } from '@citric/icons';
4
+ import { useCallback, useEffect, useState } from 'react';
5
+ import { useCurrentChat } from '../../context/hooks.js';
6
+ import { useMessageInputDictionary } from './dictionary.js';
7
+ export function useUploadDragDrop(containerSelector = '.chat-container') {
8
+ const [isDragging, setIsDragging] = useState(false);
9
+ const chat = useCurrentChat();
10
+ const handleDrop = useCallback((e) => {
11
+ e.preventDefault();
12
+ e.stopPropagation();
13
+ setIsDragging(false);
14
+ if (e.dataTransfer?.files?.length) {
15
+ chat.uploadManager.add(Array.from(e.dataTransfer.files));
16
+ }
17
+ }, [chat]);
18
+ const handleDragLeave = useCallback((e) => {
19
+ e.preventDefault();
20
+ if (e.currentTarget && !e.currentTarget.contains(e.relatedTarget)) {
21
+ setIsDragging(false);
22
+ }
23
+ }, []);
24
+ useEffect(() => {
25
+ const container = document.querySelector(containerSelector);
26
+ if (!container)
27
+ return;
28
+ const nativeHandleDragEnter = (e) => {
29
+ e.preventDefault();
30
+ setIsDragging(true);
31
+ };
32
+ container.addEventListener('dragenter', nativeHandleDragEnter);
33
+ return () => {
34
+ container.removeEventListener('dragenter', nativeHandleDragEnter);
35
+ };
36
+ }, [containerSelector]);
37
+ return {
38
+ isDragging,
39
+ handleDrop,
40
+ handleDragLeave,
41
+ };
42
+ }
43
+ export const UploadDragNDrop = ({ isDragging, onDrop, onDragLeave }) => {
44
+ const t = useMessageInputDictionary();
45
+ if (!isDragging)
46
+ return null;
47
+ return (_jsxs("div", { className: "upload-drag-drop", role: "dialog", "aria-modal": "true", "aria-labelledby": "upload-drag-drop-title", "aria-describedby": "upload-drag-drop-description", tabIndex: -1, onDrop: onDrop, onDragLeave: onDragLeave, onDragOver: e => {
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+ }, children: [_jsx(IconBox, { size: "lg", "aria-hidden": true, children: _jsx(Document, {}) }), _jsx("h2", { id: "upload-drag-drop-title", children: t.uploadDragDropTitle }), _jsx("p", { id: "upload-drag-drop-description", children: t.uploadDragDropDescription })] }));
51
+ };
52
+ //# sourceMappingURL=UploadDragNDrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UploadDragNDrop.js","sourceRoot":"","sources":["../../../src/views/MessageInput/UploadDragNDrop.tsx"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const useMessageInputDictionary: () => Record<"code" | "placeholder" | "selected" | "send" | "cancel" | "stack" | "knowledgeSource" | "agent" | "upload" | "remove" | "collapse" | "spot" | "removeConfig" | "removeStack" | "removeWorkspace" | "removeKS" | "removeSelection" | "expand" | "uploadSizeError" | "uploadItemLimitError" | "cantSendBecauseOfUploadError" | "cantSendBecauseOfUploadProgress" | "cantSendBecauseOfEmptyContent" | "chatAgent", string>;
1
+ export declare const useMessageInputDictionary: () => Record<"code" | "placeholder" | "selected" | "send" | "cancel" | "stack" | "knowledgeSource" | "agent" | "upload" | "remove" | "collapse" | "spot" | "typing" | "removeConfig" | "removeStack" | "removeWorkspace" | "removeKS" | "removeSelection" | "expand" | "uploadSizeError" | "uploadItemLimitError" | "uploadError" | "uploadDragging" | "uploadDragDropTitle" | "uploadDragDropDescription" | "unknownUploadError" | "cantSendBecauseOfUploadError" | "cantSendBecauseOfUploadProgress" | "cantSendBecauseOfEmptyContent" | "chatAgent", string>;
2
2
  //# sourceMappingURL=dictionary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dictionary.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AA2DA,eAAO,MAAM,yBAAyB,saAAiC,CAAA"}
1
+ {"version":3,"file":"dictionary.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AAqEA,eAAO,MAAM,yBAAyB,iiBAAiC,CAAA"}
@@ -8,6 +8,7 @@ const dictionary = {
8
8
  agent: 'Select agent',
9
9
  send: 'Send message',
10
10
  placeholder: 'Send a message to $0. For commands, use @ or /',
11
+ typing: 'Type your message...',
11
12
  cancel: 'Cancel',
12
13
  removeConfig: 'Remove all the configuration',
13
14
  removeStack: 'Stop using the current stack',
@@ -21,6 +22,11 @@ const dictionary = {
21
22
  collapse: 'Collapse options',
22
23
  uploadSizeError: 'The following files were not added to the upload list because they\'re larger than $1:',
23
24
  uploadItemLimitError: 'The following files were not added because no more than $1 items may be uploaded at a time:',
25
+ uploadError: 'An error occurred while uploading the file "$0".',
26
+ uploadDragging: 'Drop the file here to upload',
27
+ uploadDragDropTitle: 'Drop your files here',
28
+ uploadDragDropDescription: 'Drag or drop files to share in the conversation',
29
+ unknownUploadError: 'An error occurred while uploading the files.',
24
30
  cantSendBecauseOfUploadError: 'Can\'t send the message because one of the files in the upload list could not be uploaded. Please, retry it or remove it from the list.',
25
31
  cantSendBecauseOfUploadProgress: 'Please wait until all files are uploaded before sending the message. You can also cancel the upload by removing it from the list of uploads.',
26
32
  cantSendBecauseOfEmptyContent: 'You can\'t send empty messages. Please write some text or upload a file.',
@@ -34,6 +40,7 @@ const dictionary = {
34
40
  agent: 'Selecionar agente',
35
41
  send: 'Enviar mensagem',
36
42
  placeholder: 'Envie uma mensagem para $0. Para comandos, use @ ou /',
43
+ typing: 'Digite sua mensagem...',
37
44
  cancel: 'Cancelar',
38
45
  removeConfig: 'Remover todas as configurações',
39
46
  removeStack: 'Parar de usar a stack atual',
@@ -48,6 +55,9 @@ const dictionary = {
48
55
  uploadSizeError: 'Os seguintes arquivos não foram adicionados à lista de upload porque eles são maiores que $0:',
49
56
  uploadItemLimitError: 'Os seguintes arquivos não foram adicionados à lista de upload porque é permitido enviar no máximo $0 arquivos por vez:',
50
57
  uploadError: 'Ocorreu um erro ao enviar o arquivo "$0".',
58
+ uploadDragging: 'Solte o arquivo aqui para fazer upload',
59
+ uploadDragDropTitle: 'Solte seus arquivos aqui',
60
+ uploadDragDropDescription: 'Arraste ou solte arquivos para compartilhar na conversa',
51
61
  unknownUploadError: 'Ocorreu um erro ao enviar os arquivos.',
52
62
  cantSendBecauseOfUploadError: 'Não é possível enviar a mensagem, pois um dos arquivos na lista de uploads não pôde ser enviado. Por favor, tente enviá-lo novamente ou remova-o da lista.',
53
63
  cantSendBecauseOfUploadProgress: 'Por favor aguarde todos os uploads de arquivos antes de enviar a mensagem. Você pode cancelar o upload removendo o arquivo da lista de uploads.',
@@ -1 +1 @@
1
- {"version":3,"file":"dictionary.js","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAEvE,MAAM,UAAU,GAAG;IACjB,EAAE,EAAE;QACF,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,aAAa;QACnB,eAAe,EAAE,0BAA0B;QAC3C,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,gDAAgD;QAC7D,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,8BAA8B;QAC5C,WAAW,EAAE,8BAA8B;QAC3C,eAAe,EAAE,6BAA6B;QAC9C,QAAQ,EAAE,kCAAkC;QAC5C,QAAQ,EAAE,UAAU;QACpB,eAAe,EAAE,+BAA+B;QAChD,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,kBAAkB;QAC5B,eAAe,EAAE,wFAAwF;QACzG,oBAAoB,EAAE,6FAA6F;QACnH,4BAA4B,EAAE,yIAAyI;QACvK,+BAA+B,EAAE,8IAA8I;QAC/K,6BAA6B,EAAE,0EAA0E;QACzG,SAAS,EAAE,QAAQ;KACpB;IACD,EAAE,EAAE;QACF,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,wBAAwB;QAC9B,IAAI,EAAE,iBAAiB;QACvB,eAAe,EAAE,8BAA8B;QAC/C,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,uDAAuD;QACpE,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,gCAAgC;QAC9C,WAAW,EAAE,6BAA6B;QAC1C,eAAe,EAAE,4BAA4B;QAC7C,QAAQ,EAAE,qCAAqC;QAC/C,QAAQ,EAAE,aAAa;QACvB,eAAe,EAAE,4BAA4B;QAC7C,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,eAAe,EAAE,+FAA+F;QAChH,oBAAoB,EAAE,wHAAwH;QAC9I,WAAW,EAAE,2CAA2C;QACxD,kBAAkB,EAAE,wCAAwC;QAC5D,4BAA4B,EAAE,4JAA4J;QAC1L,+BAA+B,EAAE,iJAAiJ;QAClL,6BAA6B,EAAE,6FAA6F;QAC5H,SAAS,EAAE,SAAS;KACrB;CACmB,CAAA;AAEtB,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA"}
1
+ {"version":3,"file":"dictionary.js","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAEvE,MAAM,UAAU,GAAG;IACjB,EAAE,EAAE;QACF,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,aAAa;QACnB,eAAe,EAAE,0BAA0B;QAC3C,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,gDAAgD;QAC7D,MAAM,EAAE,sBAAsB;QAC9B,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,8BAA8B;QAC5C,WAAW,EAAE,8BAA8B;QAC3C,eAAe,EAAE,6BAA6B;QAC9C,QAAQ,EAAE,kCAAkC;QAC5C,QAAQ,EAAE,UAAU;QACpB,eAAe,EAAE,+BAA+B;QAChD,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,kBAAkB;QAC5B,eAAe,EAAE,wFAAwF;QACzG,oBAAoB,EAAE,6FAA6F;QACnH,WAAW,EAAE,kDAAkD;QAC/D,cAAc,EAAE,8BAA8B;QAC9C,mBAAmB,EAAE,sBAAsB;QAC3C,yBAAyB,EAAE,iDAAiD;QAC5E,kBAAkB,EAAE,8CAA8C;QAClE,4BAA4B,EAAE,yIAAyI;QACvK,+BAA+B,EAAE,8IAA8I;QAC/K,6BAA6B,EAAE,0EAA0E;QACzG,SAAS,EAAE,QAAQ;KACpB;IACD,EAAE,EAAE;QACF,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,wBAAwB;QAC9B,IAAI,EAAE,iBAAiB;QACvB,eAAe,EAAE,8BAA8B;QAC/C,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,uDAAuD;QACpE,MAAM,EAAE,wBAAwB;QAChC,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,gCAAgC;QAC9C,WAAW,EAAE,6BAA6B;QAC1C,eAAe,EAAE,4BAA4B;QAC7C,QAAQ,EAAE,qCAAqC;QAC/C,QAAQ,EAAE,aAAa;QACvB,eAAe,EAAE,4BAA4B;QAC7C,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,eAAe,EAAE,+FAA+F;QAChH,oBAAoB,EAAE,wHAAwH;QAC9I,WAAW,EAAE,2CAA2C;QACxD,cAAc,EAAE,wCAAwC;QACxD,mBAAmB,EAAE,0BAA0B;QAC/C,yBAAyB,EAAE,yDAAyD;QACpF,kBAAkB,EAAE,wCAAwC;QAC5D,4BAA4B,EAAE,4JAA4J;QAC1L,+BAA+B,EAAE,iJAAiJ;QAClL,6BAA6B,EAAE,6FAA6F;QAC5H,SAAS,EAAE,SAAS;KACrB;CACmB,CAAA;AAEtB,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,eAAO,MAAM,YAAY,+CA8GxB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH,eAAO,MAAM,YAAY,+CA0HxB,CAAA"}
@@ -9,6 +9,7 @@ import { quickCommandRegex } from '../../regex.js';
9
9
  import { ChatEntry } from '../../state/ChatEntry.js';
10
10
  import { checkIsTrial } from '../../utils/check-is-trial.js';
11
11
  import { UploadProvider } from '../../utils/upload/context.js';
12
+ import { usePasteUpload } from '../../utils/upload/use-paste-upload.js';
12
13
  import { AgentSelector } from './AgentSelector.js';
13
14
  import { ButtonAgent } from './ButtonAgent.js';
14
15
  import { ButtonBar } from './ButtonBar.js';
@@ -18,6 +19,7 @@ import { useMessageInputDictionary } from './dictionary.js';
18
19
  import { QuickCommandSelector } from './QuickCommandSelector.js';
19
20
  import { MAX_INPUT_HEIGHT, MessageInputBox, MIN_INPUT_HEIGHT } from './styled.js';
20
21
  import { UploadBar } from './UploadBar.js';
22
+ import { UploadDragNDrop, useUploadDragDrop } from './UploadDragNDrop.js';
21
23
  /**
22
24
  * This renders the MessageInput part of the layout which includes the progress bar, the actual textarea, the badges telling what is
23
25
  * going to be used for the question and the buttons to send, cancel, set the workspace, among others. This also includes the Quick
@@ -36,6 +38,12 @@ export const MessageInput = () => {
36
38
  const agentLabel = useCurrentChatState('agent')?.label;
37
39
  const { handleKeyDown, handleKeyUp } = useUserEntryHistoryShortcut();
38
40
  const isTrial = checkIsTrial();
41
+ const { isDragging, handleDrop, handleDragLeave } = useUploadDragDrop();
42
+ usePasteUpload({
43
+ textAreaRef,
44
+ onUploadFiles: files => chat.uploadManager.add(files),
45
+ enabled: !isLoading,
46
+ });
39
47
  const checkSendRequirements = useCallback(() => {
40
48
  if (chat.uploadManager.status === 'error') {
41
49
  chat.pushMessage(new ChatEntry({
@@ -96,6 +104,8 @@ export const MessageInput = () => {
96
104
  if (!isLoading)
97
105
  textAreaRef.current?.focus();
98
106
  }, [isLoading]);
99
- return (_jsx(UploadProvider, { value: chat.uploadManager, children: _jsxs(MessageInputBox, { "aria-busy": isLoading, className: "message-input", "$inputFocused": focused, children: [_jsxs("div", { className: "wrapper-action", children: [_jsx(QuickCommandSelector, { inputRef: textAreaRef, isTrial: isTrial }), _jsx(AgentSelector, { inputRef: textAreaRef, isTrial: isTrial }), _jsxs("div", { className: listToClass(['action-box', focused && 'focused', isLoading && 'disabled']), children: [_jsx(ButtonAgent, {}), _jsx(AdaptiveTextArea, { ref: textAreaRef, placeholder: agentLabel && interpolate(t.placeholder, agentLabel), onChange: e => chat.set('nextMessage', e.target.value), value: value, onFocus: () => setFocused(true), onBlur: () => setFocused(false), onKeyDown: onKeyDown, onKeyUp: handleKeyUp, onIncreaseSize: () => setExpanded(false), onResetSize: () => !expansionLocked.current && setExpanded(true), maxHeight: isMinimized ? MIN_INPUT_HEIGHT : MAX_INPUT_HEIGHT })] })] }), _jsx(ProgressBar, { visible: true, animate: isLoading, backgroundColor: isLoading || !focused ? theme.color.light[500] : theme.color.primary[500] }), _jsx(ContextBar, {}), chat.get('features').upload && _jsx(UploadBar, {}), _jsx(ButtonBar, { onSend: onSend, isLoading: isLoading })] }) }));
107
+ return (_jsxs(UploadProvider, { value: chat.uploadManager, children: [_jsxs(MessageInputBox, { "aria-busy": isLoading, className: "message-input", "$inputFocused": focused, children: [_jsxs("div", { className: "wrapper-action", children: [_jsx(QuickCommandSelector, { inputRef: textAreaRef, isTrial: isTrial }), _jsx(AgentSelector, { inputRef: textAreaRef, isTrial: isTrial }), _jsxs("div", { className: listToClass(['action-box', focused && 'focused', isLoading && 'disabled']), children: [_jsx(ButtonAgent, {}), _jsx(AdaptiveTextArea, { ref: textAreaRef, placeholder: agentLabel
108
+ ? interpolate(t.placeholder, agentLabel)
109
+ : t.typing, onChange: e => chat.set('nextMessage', e.target.value), value: value, onFocus: () => setFocused(true), onBlur: () => setFocused(false), onKeyDown: onKeyDown, onKeyUp: handleKeyUp, onIncreaseSize: () => setExpanded(false), onResetSize: () => !expansionLocked.current && setExpanded(true), maxHeight: isMinimized ? MIN_INPUT_HEIGHT : MAX_INPUT_HEIGHT })] })] }), _jsx(ProgressBar, { visible: true, animate: isLoading, backgroundColor: isLoading || !focused ? theme.color.light[500] : theme.color.primary[500] }), _jsx(ContextBar, {}), chat.get('features').upload && _jsx(UploadBar, {}), _jsx(ButtonBar, { onSend: onSend, isLoading: isLoading })] }), _jsx(UploadDragNDrop, { isDragging: isDragging, onDrop: handleDrop, onDragLeave: handleDragLeave })] }));
100
110
  };
101
111
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.28.1",
3
+ "version": "1.29.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.28.1",
4
- "date": "Thu Jul 03 2025 16:56:42 GMT+0000 (Coordinated Universal Time)",
3
+ "version": "1.29.0",
4
+ "date": "Thu Jul 03 2025 20:22:32 GMT+0000 (Coordinated Universal Time)",
5
5
  "dependencies": [
6
6
  {
7
7
  "name": "@stack-spot/app-metadata",
package/src/layout.css CHANGED
@@ -94,6 +94,7 @@
94
94
  }
95
95
 
96
96
  .chat-container {
97
+ position: relative;
97
98
  padding: 20px;
98
99
  max-width: 1200px;
99
100
  width: calc(100% - 40px);
@@ -186,4 +187,22 @@
186
187
  border: 1px solid var(--primary-500);
187
188
  border-left: none;
188
189
  color: var(--light-contrastText);
190
+ }
191
+
192
+ .upload-drag-drop {
193
+ display: flex;
194
+ background-color: #00000090;
195
+ background-color: color-mix(in srgb, var(--light-300) 80%, transparent);
196
+ position: absolute;
197
+ width: 99%;
198
+ height: 99%;
199
+ top: 0;
200
+ left: 0;
201
+ flex-direction: column;
202
+ justify-content: center;
203
+ align-items: center;
204
+ border: 1px dashed var(--secondary-500);
205
+ z-index: 9999;
206
+ pointer-events: auto;
207
+ color: var(--light-contrastText)
189
208
  }
@@ -43,31 +43,35 @@ export class UploadManager {
43
43
  return this.value.some(f => id === f.id)
44
44
  }
45
45
 
46
+ private processFiles(files: FileList | File[]) {
47
+ const newFiles: FileUpload[] = []
48
+ const errors: UploadError[] = []
49
+ for (const f of files ?? []) {
50
+ if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
51
+ errors.push(new FileIsTooLarge(f.name, this.maxSize))
52
+ } else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
53
+ errors.push(new MaxFilesReached(f.name, this.maxItems))
54
+ } else if (this.hasEquivalentFile(f)) {
55
+ errors.push(new FileAlreadyExists(f.name))
56
+ } else {
57
+ const upload = new FileUpload(f)
58
+ newFiles.push(upload)
59
+ upload.onChange(() => this.runStatusListeners())
60
+ }
61
+ }
62
+ if (newFiles.length) {
63
+ this.value = [...this.value, ...newFiles]
64
+ this.runChangeListeners()
65
+ this.runStatusListeners()
66
+ }
67
+ if (errors.length) {
68
+ this.errorListeners.forEach(l => l(errors))
69
+ }
70
+ }
71
+
46
72
  private attachEventListeners() {
47
73
  const handleChange = () => {
48
- const newFiles: FileUpload[] = []
49
- const errors: UploadError[] = []
50
- for (const f of this.input?.files ?? []) {
51
- if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
52
- errors.push(new FileIsTooLarge(f.name, this.maxSize))
53
- } else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
54
- errors.push(new MaxFilesReached(f.name, this.maxItems))
55
- } else if (this.hasEquivalentFile(f)) {
56
- errors.push(new FileAlreadyExists(f.name))
57
- } else {
58
- const upload = new FileUpload(f)
59
- newFiles.push(upload)
60
- upload.onChange(() => this.runStatusListeners())
61
- }
62
- }
63
- if (newFiles.length) {
64
- this.value = [...this.value, ...newFiles]
65
- this.runChangeListeners()
66
- this.runStatusListeners()
67
- }
68
- if (errors.length) {
69
- this.errorListeners.forEach(l => l(errors))
70
- }
74
+ this.processFiles(this.input?.files || [])
71
75
  this.destroy()
72
76
  }
73
77
  this.onDestroy = () => this.input?.removeEventListener('change', handleChange)
@@ -108,6 +112,11 @@ export class UploadManager {
108
112
  this.runChangeListeners()
109
113
  }
110
114
 
115
+ add(files: File | File[] = []) {
116
+ const fileList = Array.isArray(files) ? files : [files]
117
+ this.processFiles(fileList)
118
+ }
119
+
111
120
  remove(file: FileUpload) {
112
121
  file.destroy()
113
122
  this.value = this.value.filter(f => f !== file)
@@ -0,0 +1,30 @@
1
+ import { useEffect } from 'react'
2
+
3
+ interface UsePasteUploadProps {
4
+ textAreaRef: React.RefObject<HTMLTextAreaElement>,
5
+ onUploadFiles: (files: File[]) => void,
6
+ enabled?: boolean,
7
+ }
8
+
9
+ export const usePasteUpload = ({
10
+ textAreaRef,
11
+ onUploadFiles,
12
+ enabled = true,
13
+ }: UsePasteUploadProps) => {
14
+ useEffect(() => {
15
+ const textarea = textAreaRef.current
16
+ if (!textarea || !enabled) return
17
+
18
+ const handlePaste = (e: ClipboardEvent) => {
19
+ if (e.clipboardData?.files?.length) {
20
+ onUploadFiles(Array.from(e.clipboardData.files))
21
+ e.preventDefault()
22
+ }
23
+ }
24
+
25
+ textarea.addEventListener('paste', handlePaste)
26
+ return () => {
27
+ textarea.removeEventListener('paste', handlePaste)
28
+ }
29
+ }, [onUploadFiles, textAreaRef, enabled])
30
+ }
@@ -0,0 +1,82 @@
1
+ import { IconBox } from '@citric/core'
2
+ import { Document } from '@citric/icons'
3
+ import { DragEvent, useCallback, useEffect, useState } from 'react'
4
+ import { useCurrentChat } from '../../context/hooks'
5
+ import { useMessageInputDictionary } from './dictionary'
6
+
7
+ export function useUploadDragDrop(containerSelector: string = '.chat-container') {
8
+ const [isDragging, setIsDragging] = useState(false)
9
+ const chat = useCurrentChat()
10
+
11
+ const handleDrop = useCallback((e: DragEvent) => {
12
+ e.preventDefault()
13
+ e.stopPropagation()
14
+ setIsDragging(false)
15
+ if (e.dataTransfer?.files?.length) {
16
+ chat.uploadManager.add(Array.from(e.dataTransfer.files))
17
+ }
18
+ }, [chat])
19
+
20
+ const handleDragLeave = useCallback((e: DragEvent) => {
21
+ e.preventDefault()
22
+ if (e.currentTarget && !e.currentTarget.contains(e.relatedTarget as Node)) {
23
+ setIsDragging(false)
24
+ }
25
+ }, [])
26
+
27
+ useEffect(() => {
28
+ const container = document.querySelector(containerSelector) as HTMLDivElement | null
29
+ if (!container) return
30
+
31
+ const nativeHandleDragEnter = (e: Event) => {
32
+ e.preventDefault()
33
+ setIsDragging(true)
34
+ }
35
+
36
+ container.addEventListener('dragenter', nativeHandleDragEnter)
37
+ return () => {
38
+ container.removeEventListener('dragenter', nativeHandleDragEnter)
39
+ }
40
+ }, [containerSelector])
41
+
42
+ return {
43
+ isDragging,
44
+ handleDrop,
45
+ handleDragLeave,
46
+ }
47
+ }
48
+
49
+ interface UploadDragNDropProps {
50
+ isDragging?: boolean,
51
+ onDrop?: (e: DragEvent) => void,
52
+ onDragLeave?: (e: DragEvent) => void,
53
+ }
54
+
55
+ export const UploadDragNDrop = ({ isDragging, onDrop, onDragLeave }: UploadDragNDropProps) => {
56
+ const t = useMessageInputDictionary()
57
+
58
+ if (!isDragging) return null
59
+
60
+ return (
61
+ <div
62
+ className="upload-drag-drop"
63
+ role="dialog"
64
+ aria-modal="true"
65
+ aria-labelledby="upload-drag-drop-title"
66
+ aria-describedby="upload-drag-drop-description"
67
+ tabIndex={-1}
68
+ onDrop={onDrop}
69
+ onDragLeave={onDragLeave}
70
+ onDragOver={e => {
71
+ e.preventDefault()
72
+ e.stopPropagation()
73
+ }}
74
+ >
75
+ <IconBox size="lg" aria-hidden={true}>
76
+ <Document />
77
+ </IconBox>
78
+ <h2 id="upload-drag-drop-title">{t.uploadDragDropTitle}</h2>
79
+ <p id="upload-drag-drop-description">{t.uploadDragDropDescription}</p>
80
+ </div>
81
+ )
82
+ }
@@ -9,6 +9,7 @@ const dictionary = {
9
9
  agent: 'Select agent',
10
10
  send: 'Send message',
11
11
  placeholder: 'Send a message to $0. For commands, use @ or /',
12
+ typing: 'Type your message...',
12
13
  cancel: 'Cancel',
13
14
  removeConfig: 'Remove all the configuration',
14
15
  removeStack: 'Stop using the current stack',
@@ -22,6 +23,11 @@ const dictionary = {
22
23
  collapse: 'Collapse options',
23
24
  uploadSizeError: 'The following files were not added to the upload list because they\'re larger than $1:',
24
25
  uploadItemLimitError: 'The following files were not added because no more than $1 items may be uploaded at a time:',
26
+ uploadError: 'An error occurred while uploading the file "$0".',
27
+ uploadDragging: 'Drop the file here to upload',
28
+ uploadDragDropTitle: 'Drop your files here',
29
+ uploadDragDropDescription: 'Drag or drop files to share in the conversation',
30
+ unknownUploadError: 'An error occurred while uploading the files.',
25
31
  cantSendBecauseOfUploadError: 'Can\'t send the message because one of the files in the upload list could not be uploaded. Please, retry it or remove it from the list.',
26
32
  cantSendBecauseOfUploadProgress: 'Please wait until all files are uploaded before sending the message. You can also cancel the upload by removing it from the list of uploads.',
27
33
  cantSendBecauseOfEmptyContent: 'You can\'t send empty messages. Please write some text or upload a file.',
@@ -35,6 +41,7 @@ const dictionary = {
35
41
  agent: 'Selecionar agente',
36
42
  send: 'Enviar mensagem',
37
43
  placeholder: 'Envie uma mensagem para $0. Para comandos, use @ ou /',
44
+ typing: 'Digite sua mensagem...',
38
45
  cancel: 'Cancelar',
39
46
  removeConfig: 'Remover todas as configurações',
40
47
  removeStack: 'Parar de usar a stack atual',
@@ -49,6 +56,9 @@ const dictionary = {
49
56
  uploadSizeError: 'Os seguintes arquivos não foram adicionados à lista de upload porque eles são maiores que $0:',
50
57
  uploadItemLimitError: 'Os seguintes arquivos não foram adicionados à lista de upload porque é permitido enviar no máximo $0 arquivos por vez:',
51
58
  uploadError: 'Ocorreu um erro ao enviar o arquivo "$0".',
59
+ uploadDragging: 'Solte o arquivo aqui para fazer upload',
60
+ uploadDragDropTitle: 'Solte seus arquivos aqui',
61
+ uploadDragDropDescription: 'Arraste ou solte arquivos para compartilhar na conversa',
52
62
  unknownUploadError: 'Ocorreu um erro ao enviar os arquivos.',
53
63
  cantSendBecauseOfUploadError: 'Não é possível enviar a mensagem, pois um dos arquivos na lista de uploads não pôde ser enviado. Por favor, tente enviá-lo novamente ou remova-o da lista.',
54
64
  cantSendBecauseOfUploadProgress: 'Por favor aguarde todos os uploads de arquivos antes de enviar a mensagem. Você pode cancelar o upload removendo o arquivo da lista de uploads.',
@@ -8,6 +8,7 @@ import { quickCommandRegex } from '../../regex'
8
8
  import { ChatEntry } from '../../state/ChatEntry'
9
9
  import { checkIsTrial } from '../../utils/check-is-trial'
10
10
  import { UploadProvider } from '../../utils/upload/context'
11
+ import { usePasteUpload } from '../../utils/upload/use-paste-upload'
11
12
  import { AgentSelector } from './AgentSelector'
12
13
  import { ButtonAgent } from './ButtonAgent'
13
14
  import { ButtonBar } from './ButtonBar'
@@ -17,6 +18,7 @@ import { useMessageInputDictionary } from './dictionary'
17
18
  import { QuickCommandSelector } from './QuickCommandSelector'
18
19
  import { MAX_INPUT_HEIGHT, MessageInputBox, MIN_INPUT_HEIGHT } from './styled'
19
20
  import { UploadBar } from './UploadBar'
21
+ import { UploadDragNDrop, useUploadDragDrop } from './UploadDragNDrop'
20
22
 
21
23
  /**
22
24
  * This renders the MessageInput part of the layout which includes the progress bar, the actual textarea, the badges telling what is
@@ -36,6 +38,13 @@ export const MessageInput = () => {
36
38
  const agentLabel = useCurrentChatState('agent')?.label
37
39
  const { handleKeyDown, handleKeyUp } = useUserEntryHistoryShortcut()
38
40
  const isTrial = checkIsTrial()
41
+ const { isDragging, handleDrop, handleDragLeave } = useUploadDragDrop()
42
+
43
+ usePasteUpload({
44
+ textAreaRef,
45
+ onUploadFiles: files => chat.uploadManager.add(files),
46
+ enabled: !isLoading,
47
+ })
39
48
 
40
49
  const checkSendRequirements = useCallback(() => {
41
50
  if (chat.uploadManager.status === 'error') {
@@ -112,7 +121,11 @@ export const MessageInput = () => {
112
121
  <ButtonAgent />
113
122
  <AdaptiveTextArea
114
123
  ref={textAreaRef}
115
- placeholder={agentLabel && interpolate(t.placeholder, agentLabel)}
124
+ placeholder={
125
+ agentLabel
126
+ ? interpolate(t.placeholder, agentLabel)
127
+ : t.typing
128
+ }
116
129
  onChange={e => chat.set('nextMessage', e.target.value)}
117
130
  value={value}
118
131
  onFocus={() => setFocused(true)}
@@ -131,6 +144,7 @@ export const MessageInput = () => {
131
144
  {chat.get('features').upload && <UploadBar />}
132
145
  <ButtonBar onSend={onSend} isLoading={isLoading} />
133
146
  </MessageInputBox>
147
+ <UploadDragNDrop isDragging={isDragging} onDrop={handleDrop} onDragLeave={handleDragLeave} />
134
148
  </UploadProvider>
135
149
  )
136
150
  }