diff --git a/.changeset/new-spies-hammer.md b/.changeset/new-spies-hammer.md new file mode 100644 index 0000000000..ac3522dbed --- /dev/null +++ b/.changeset/new-spies-hammer.md @@ -0,0 +1,14 @@ +--- +"@twilio-paste/file-uploader": patch +--- + +fix(FileUploaderDropzone): honor acceptedMimeTypes prop during drag and drop operations +Previously, the FileUploaderDropzone component would ignore the acceptedMimeTypes prop when files were dragged and dropped, only validating file types when using the native file picker. This fix ensures that MIME type validation is consistently applied to both drag-and-drop and file input selection methods. + +Added MIME type validation to drag and drop event handler +Added support for wildcard MIME type patterns (e.g., "image/\*") +Added console warnings for rejected file types +Maintained backward compatibility - no breaking changes to existing API +Added comprehensive test coverage for validation scenarios + +Fixes #4377 diff --git a/packages/paste-core/components/file-uploader/src/FileUploaderDropzone.tsx b/packages/paste-core/components/file-uploader/src/FileUploaderDropzone.tsx index 42d9e6ad84..4006454f58 100644 --- a/packages/paste-core/components/file-uploader/src/FileUploaderDropzone.tsx +++ b/packages/paste-core/components/file-uploader/src/FileUploaderDropzone.tsx @@ -5,7 +5,7 @@ import type { HTMLPasteProps } from "@twilio-paste/types"; import * as React from "react"; import { FileUploaderContext } from "./FileUploaderContext"; -import { arrayToCsv } from "./utils"; +import { arrayToCsv, isValidMimeType } from "./utils"; export interface FileUploaderDropzoneProps extends Omit< @@ -181,6 +181,15 @@ export const FileUploaderDropzone = React.forwardRef prev + 1); setDragActive(false); + if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) { + for (let file of event.dataTransfer.files) { + if (!isValidMimeType(file.type, acceptedMimeTypes)) { + console.warn(`File type not accepted: ${file.type}`); + return; + } + } + } + if (onDrop) { onDrop(event); } diff --git a/packages/paste-core/components/file-uploader/src/utils.ts b/packages/paste-core/components/file-uploader/src/utils.ts index fb27126a22..70e0a25233 100644 --- a/packages/paste-core/components/file-uploader/src/utils.ts +++ b/packages/paste-core/components/file-uploader/src/utils.ts @@ -16,3 +16,21 @@ export const arrayToCsv = (value: string[]): string => { return value.join(","); }; + +/** + * + * Checks if a file's mime type matches any of the accepted types, including wildcard types + * @param fileType: string + * @param acceptedTypes: string[] + * @returns boolean + */ +export const isValidMimeType = (fileType: string, acceptedTypes: string[]): boolean => { + return acceptedTypes.some((acceptedType: string) => { + if (acceptedType.endsWith('/*')) { + const baseType = acceptedType.slice(0, -2); + return fileType.startsWith(baseType + '/'); + } + + return fileType === acceptedType; + }) +} \ No newline at end of file