Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: adjust CvFileUploader drop handler to not ignore 'multiple' attribute #1693

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/CvFileUploader/CvFileUploader.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ export const argTypes = {
// attributes
multiple: {
type: 'boolean',
defaultValue: true,
table: {
type: { summary: 'boolean' },
category: 'attributes',
category: 'props',
},
description: 'standard input attribute for file type, allow multiple files to be added in a single prompt',
},
Expand Down
10 changes: 9 additions & 1 deletion src/components/CvFileUploader/CvFileUploader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
:disabled="disabled || null"
type="file"
v-bind="$attrs"
:multiple="multiple"
data-file-uploader
data-target="[data-file-container]"
@change="onChange"
Expand Down Expand Up @@ -73,6 +74,7 @@
:disabled="disabled || null"
type="file"
v-bind="$attrs"
:multiple="multiple"
tabindex="-1"
data-file-uploader
data-target="[data-file-container]"
Expand Down Expand Up @@ -147,6 +149,7 @@ const props = defineProps({
},
label: { type: String, default: undefined },
modelValue: { type: Array, default: () => [] },
multiple: { type: Boolean, default: true },
removable: Boolean,
removeAriaLabel: { type: String, default: undefined },
...cvIdProps,
Expand Down Expand Up @@ -271,7 +274,12 @@ function onDragEvent(evt) {

if (evt.type === 'drop') {
evt.preventDefault();
addFiles(evt.dataTransfer.files);
if (props.multiple) {
addFiles(evt.dataTransfer.files);
} else {
internalFiles.value = [];
addFiles([evt.dataTransfer.files[0]]);
}
allowDrop.value = false;
}
}
Expand Down
99 changes: 99 additions & 0 deletions src/components/CvFileUploader/__tests__/CvFileUploader.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,105 @@ describe('CvFileUploader', () => {
expect(emitResult[0]).toHaveLength(1);
expect(emitResult[0][0].file.name).toBe(dummyFile.name);
});

it('emits a single file when attr multiple is falsy', async () => {
const dummyFiles = [
new File(['file content'], 'dummy-file1.txt', {
type: 'text/plain',
}),
new File(['file content'], 'dummy-file2.txt', {
type: 'text/plain',
}),
];
const { container, emitted } = render(CvFileUploader, {
props: { multiple: false },
});

const dropZone = container.querySelector(
`div.${carbonPrefix}--file-browse-btn`
);
await fireEvent.drop(dropZone, {
dataTransfer: {
files: dummyFiles,
types: ['Files'],
},
});

const emitResult = emitted('update:modelValue').at(0);
expect(emitResult[0]).toHaveLength(1);
});

it('emits a single file on multiple iterations when attr multiple is falsy', async () => {
const initialDummyFiles = [
new File(['file content'], 'dummy-file1.txt', {
type: 'text/plain',
}),
new File(['file content'], 'dummy-file2.txt', {
type: 'text/plain',
}),
];
const secondDummyFiles = [
new File(['file content'], 'dummy-file3.txt', {
type: 'text/plain',
}),
new File(['file content'], 'dummy-file4.txt', {
type: 'text/plain',
}),
];

const { container, emitted } = render(CvFileUploader, {
props: { multiple: false },
});

const dropZone = container.querySelector(
`div.${carbonPrefix}--file-browse-btn`
);
await fireEvent.drop(dropZone, {
dataTransfer: {
files: initialDummyFiles,
types: ['Files'],
},
});
await fireEvent.drop(dropZone, {
dataTransfer: {
files: secondDummyFiles,
types: ['Files'],
},
});

const emitResult = emitted('update:modelValue').at(0);
expect(emitResult[0]).toHaveLength(1);
});

it('emits all dropped files when attr multiple is truthy', async () => {
const dummyFiles = [
new File(['file content'], 'dummy-file1.txt', {
type: 'text/plain',
}),
new File(['file content'], 'dummy-file2.txt', {
type: 'text/plain',
}),
new File(['file content'], 'dummy-file3.txt', {
type: 'text/plain',
}),
];
const { container, emitted } = render(CvFileUploader, {
props: { multiple: true },
});

const dropZone = container.querySelector(
`div.${carbonPrefix}--file-browse-btn`
);
await fireEvent.drop(dropZone, {
dataTransfer: {
files: dummyFiles,
types: ['Files'],
},
});

const emitResult = emitted('update:modelValue').at(0);
expect(emitResult[0]).toHaveLength(3);
});
});

describe('File listing', () => {
Expand Down
Loading