Skip to content

Commit 2d907c4

Browse files
fix(FileUploaderDropContainer): enforce multiple prop on drag-and-drop (#18669)
Co-authored-by: Nikhil Tomar <63502271+2nikhiltom@users.noreply.github.com>
1 parent 701f8e6 commit 2d907c4

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

packages/react/src/components/FileUploader/FileUploaderDropContainer.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2016, 2023
2+
* Copyright IBM Corp. 2016, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -150,13 +150,15 @@ function FileUploaderDropContainer({
150150

151151
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
152152
const files = [...(event.target.files ?? [])];
153-
const addedFiles = validateFiles(files);
153+
const filesToValidate = multiple ? files : [files[0]];
154+
const addedFiles = validateFiles(filesToValidate);
154155
return onAddFiles(event, { addedFiles });
155156
}
156157

157158
function handleDrop(event: React.DragEvent<HTMLDivElement>) {
158159
const files = [...event.dataTransfer.files];
159-
const addedFiles = validateFiles(files);
160+
const filesToValidate = multiple ? files : [files[0]];
161+
const addedFiles = validateFiles(filesToValidate);
160162
return onAddFiles(event, { addedFiles });
161163
}
162164

packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2016, 2023
2+
* Copyright IBM Corp. 2016, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -80,7 +80,11 @@ describe('FileUploaderDropContainer', () => {
8080
it('should call `onAddFiles` when a file is selected', () => {
8181
const onAddFiles = jest.fn();
8282
const { container } = render(
83-
<FileUploaderDropContainer onAddFiles={onAddFiles} {...requiredProps} />
83+
<FileUploaderDropContainer
84+
multiple
85+
onAddFiles={onAddFiles}
86+
{...requiredProps}
87+
/>
8488
);
8589
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
8690
const input = container.querySelector('input');
@@ -105,8 +109,9 @@ describe('FileUploaderDropContainer', () => {
105109
const onAddFiles = jest.fn();
106110
const { container } = render(
107111
<FileUploaderDropContainer
108-
onAddFiles={onAddFiles}
109112
accept={['.txt']}
113+
multiple
114+
onAddFiles={onAddFiles}
110115
{...requiredProps}
111116
/>
112117
);
@@ -152,8 +157,9 @@ describe('FileUploaderDropContainer', () => {
152157
const onAddFiles = jest.fn();
153158
const { container } = render(
154159
<FileUploaderDropContainer
155-
onAddFiles={onAddFiles}
156160
accept={['.jpeg']}
161+
multiple
162+
onAddFiles={onAddFiles}
157163
{...requiredProps}
158164
/>
159165
);
@@ -195,8 +201,9 @@ describe('FileUploaderDropContainer', () => {
195201
const onAddFiles = jest.fn();
196202
const { container } = render(
197203
<FileUploaderDropContainer
198-
onAddFiles={onAddFiles}
199204
accept={['.txt', '.a_a', '.b-b', '.a-b_c']}
205+
multiple
206+
onAddFiles={onAddFiles}
200207
pattern=".[0-9a-z-_]+$"
201208
{...requiredProps}
202209
/>
@@ -259,6 +266,7 @@ describe('FileUploaderDropContainer', () => {
259266
const { container } = render(
260267
<FileUploaderDropContainer
261268
accept={['.png']}
269+
multiple
262270
onAddFiles={onAddFiles}
263271
{...requiredProps}
264272
/>
@@ -501,4 +509,31 @@ describe('FileUploaderDropContainer', () => {
501509
dropArea.dispatchEvent(dropEvent);
502510
expect(handleDrop).not.toHaveBeenCalled();
503511
});
512+
513+
it('should only emit one file when multiple files are dropped and `multiple` is false', () => {
514+
const onAddFiles = jest.fn();
515+
const { container } = render(
516+
<FileUploaderDropContainer
517+
onAddFiles={onAddFiles}
518+
multiple={false}
519+
{...requiredProps}
520+
/>
521+
);
522+
const dropArea = container.firstChild;
523+
const files = [
524+
new File(['content'], 'file1.txt', { type: 'text/plain' }),
525+
new File(['content'], 'file2.txt', { type: 'text/plain' }),
526+
];
527+
const dropEvent = {
528+
dataTransfer: { files },
529+
preventDefault: jest.fn(),
530+
stopPropagation: jest.fn(),
531+
};
532+
533+
fireEvent.drop(dropArea, dropEvent);
534+
535+
expect(onAddFiles).toHaveBeenCalledWith(expect.anything(), {
536+
addedFiles: [files[0]],
537+
});
538+
});
504539
});

0 commit comments

Comments
 (0)