Skip to content

Commit dfaea1b

Browse files
authored
fix: Upload drag & drop not working (#625)
* fix: drop logic * fix: preventDefault logic
1 parent 746ab3c commit dfaea1b

File tree

2 files changed

+42
-26
lines changed

2 files changed

+42
-26
lines changed

src/AjaxUploader.tsx

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,14 @@ class AjaxUploader extends Component<UploadProps> {
6666
}
6767
};
6868

69-
onFileDropOrPaste = async (e: React.DragEvent<HTMLDivElement> | ClipboardEvent) => {
70-
if (e.type === 'dragover') {
71-
return;
72-
}
73-
69+
onDataTransferFiles = async (dataTransfer: DataTransfer, existFileCallback?: () => void) => {
7470
const { multiple, accept, directory } = this.props;
75-
let items: DataTransferItem[] = [];
76-
let files: File[] = [];
7771

78-
if (e.type === 'drop') {
79-
const dataTransfer = (e as React.DragEvent<HTMLDivElement>).dataTransfer;
80-
items = [...(dataTransfer.items || [])];
81-
files = [...(dataTransfer.files || [])];
82-
} else if (e.type === 'paste') {
83-
const clipboardData = (e as ClipboardEvent).clipboardData;
84-
items = [...(clipboardData.items || [])];
85-
files = [...(clipboardData.files || [])];
86-
}
72+
const items: DataTransferItem[] = [...(dataTransfer.items || [])];
73+
let files: File[] = [...(dataTransfer.files || [])];
8774

8875
if (files.length > 0 || items.some(item => item.kind === 'file')) {
89-
e.preventDefault();
76+
existFileCallback?.();
9077
}
9178

9279
if (directory) {
@@ -105,11 +92,32 @@ class AjaxUploader extends Component<UploadProps> {
10592
}
10693
};
10794

108-
onPrePaste = (e: ClipboardEvent) => {
95+
onFilePaste = async (e: ClipboardEvent) => {
10996
const { pastable } = this.props;
11097

111-
if (pastable) {
112-
this.onFileDropOrPaste(e);
98+
if (!pastable) {
99+
return;
100+
}
101+
102+
if (e.type === 'paste') {
103+
const clipboardData = (e as ClipboardEvent).clipboardData;
104+
return this.onDataTransferFiles(clipboardData, () => {
105+
e.preventDefault();
106+
});
107+
}
108+
};
109+
110+
onFileDragOver = (e: React.DragEvent<HTMLDivElement>) => {
111+
e.preventDefault();
112+
};
113+
114+
onFileDrop = async (e: React.DragEvent<HTMLDivElement>) => {
115+
e.preventDefault();
116+
117+
if (e.type === 'drop') {
118+
const dataTransfer = (e as React.DragEvent<HTMLDivElement>).dataTransfer;
119+
120+
return this.onDataTransferFiles(dataTransfer);
113121
}
114122
};
115123

@@ -119,23 +127,23 @@ class AjaxUploader extends Component<UploadProps> {
119127
const { pastable } = this.props;
120128

121129
if (pastable) {
122-
document.addEventListener('paste', this.onPrePaste);
130+
document.addEventListener('paste', this.onFilePaste);
123131
}
124132
}
125133

126134
componentWillUnmount() {
127135
this._isMounted = false;
128136
this.abort();
129-
document.removeEventListener('paste', this.onPrePaste);
137+
document.removeEventListener('paste', this.onFilePaste);
130138
}
131139

132140
componentDidUpdate(prevProps: UploadProps) {
133141
const { pastable } = this.props;
134142

135143
if (pastable && !prevProps.pastable) {
136-
document.addEventListener('paste', this.onPrePaste);
144+
document.addEventListener('paste', this.onFilePaste);
137145
} else if (!pastable && prevProps.pastable) {
138-
document.removeEventListener('paste', this.onPrePaste);
146+
document.removeEventListener('paste', this.onFilePaste);
139147
}
140148
}
141149

@@ -335,8 +343,8 @@ class AjaxUploader extends Component<UploadProps> {
335343
onKeyDown: openFileDialogOnClick ? this.onKeyDown : () => {},
336344
onMouseEnter,
337345
onMouseLeave,
338-
onDrop: this.onFileDropOrPaste,
339-
onDragOver: this.onFileDropOrPaste,
346+
onDrop: this.onFileDrop,
347+
onDragOver: this.onFileDragOver,
340348
tabIndex: hasControlInside ? undefined : '0',
341349
};
342350
return (

tests/uploader.spec.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,12 @@ describe('uploader', () => {
735735
},
736736
],
737737
};
738+
739+
const preventDefaultSpy = jest.spyOn(Event.prototype, 'preventDefault');
740+
741+
fireEvent.dragOver(input);
742+
expect(preventDefaultSpy).toHaveBeenCalledTimes(1);
743+
738744
fireEvent.drop(input, { dataTransfer: { items: [makeDataTransferItemAsync(files)] } });
739745
const mockStart = jest.fn();
740746
handlers.onStart = mockStart;
@@ -743,6 +749,8 @@ describe('uploader', () => {
743749
expect(mockStart.mock.calls.length).toBe(1);
744750
done();
745751
}, 1000);
752+
753+
preventDefaultSpy.mockRestore();
746754
});
747755

748756
it('unaccepted type files to upload will not trigger onStart when select directory', done => {

0 commit comments

Comments
 (0)