diff --git a/.changeset/dull-cheetahs-deliver.md b/.changeset/dull-cheetahs-deliver.md
new file mode 100644
index 00000000000..e173bce57e7
--- /dev/null
+++ b/.changeset/dull-cheetahs-deliver.md
@@ -0,0 +1,8 @@
+---
+"@aws-amplify/ui-react-storage": patch
+"@aws-amplify/ui-react": patch
+---
+
+fix(storage): fixing drop handler for file extensions
+
+Previously, adding a file extension for an `acceptedFileTypes` when a customer would drop a file it would show as rejected even if it was a valid file type. This fixes that issue.
diff --git a/examples/next/pages/ui/components/storage/storage-manager/accept-file-extension/aws-exports.js b/examples/next/pages/ui/components/storage/storage-manager/accept-file-extension/aws-exports.js
new file mode 100644
index 00000000000..4245c81a219
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-manager/accept-file-extension/aws-exports.js
@@ -0,0 +1,2 @@
+import awsExports from '@environments/storage/file-uploader/src/aws-exports';
+export default awsExports;
diff --git a/examples/next/pages/ui/components/storage/storage-manager/accept-file-extension/index.page.tsx b/examples/next/pages/ui/components/storage/storage-manager/accept-file-extension/index.page.tsx
new file mode 100644
index 00000000000..ef00f4f1e16
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-manager/accept-file-extension/index.page.tsx
@@ -0,0 +1,19 @@
+import { Amplify } from 'aws-amplify';
+import { StorageManager } from '@aws-amplify/ui-react-storage';
+import '@aws-amplify/ui-react/styles.css';
+import awsExports from './aws-exports';
+Amplify.configure(awsExports);
+
+export function StorageManagerExample() {
+ return (
+ <>
+
+ >
+ );
+}
+export default StorageManagerExample;
diff --git a/packages/react/src/primitives/DropZone/__tests__/filterAllowedFiles.test.ts b/packages/react/src/primitives/DropZone/__tests__/filterAllowedFiles.test.ts
new file mode 100644
index 00000000000..f877c724c12
--- /dev/null
+++ b/packages/react/src/primitives/DropZone/__tests__/filterAllowedFiles.test.ts
@@ -0,0 +1,32 @@
+import { filterAllowedFiles } from '../filterAllowedFiles';
+
+describe('filterAllowFiles', () => {
+ const droppedFiles = [
+ new File([], 'test.jpg', { type: 'image/jpg' }),
+ new File([], 'test.png', { type: 'image/png' }),
+ ];
+
+ it('should work with * MIME types', () => {
+ const { acceptedFiles, rejectedFiles } = filterAllowedFiles(droppedFiles, [
+ 'image/*',
+ ]);
+ expect(rejectedFiles).toHaveLength(0);
+ expect(acceptedFiles).toHaveLength(2);
+ });
+
+ it('should work with extension types', () => {
+ const { acceptedFiles, rejectedFiles } = filterAllowedFiles(droppedFiles, [
+ '.png',
+ ]);
+ expect(rejectedFiles).toHaveLength(1);
+ expect(acceptedFiles).toHaveLength(1);
+ });
+
+ it('should work with *', () => {
+ const { acceptedFiles, rejectedFiles } = filterAllowedFiles(droppedFiles, [
+ '*',
+ ]);
+ expect(rejectedFiles).toHaveLength(0);
+ expect(acceptedFiles).toHaveLength(2);
+ });
+});
diff --git a/packages/react/src/primitives/DropZone/filterAllowedFiles.ts b/packages/react/src/primitives/DropZone/filterAllowedFiles.ts
new file mode 100644
index 00000000000..3b26fa3d756
--- /dev/null
+++ b/packages/react/src/primitives/DropZone/filterAllowedFiles.ts
@@ -0,0 +1,50 @@
+// Drag event file shape is different than the drop event fileshape
+type DragFile =
+ | {
+ kind: string;
+ type: string;
+ name?: string;
+ }
+ | File;
+
+export function filterAllowedFiles(
+ files: FileType[],
+ acceptedFileTypes: string[]
+): { acceptedFiles: FileType[]; rejectedFiles: FileType[] } {
+ // Allow any files if acceptedFileTypes is undefined, empty array, or contains '*'
+ if (
+ !acceptedFileTypes ||
+ acceptedFileTypes.length === 0 ||
+ acceptedFileTypes.includes('*')
+ ) {
+ return { acceptedFiles: files, rejectedFiles: [] };
+ }
+ const acceptedFiles: FileType[] = [];
+ const rejectedFiles: FileType[] = [];
+
+ function filterFile(file: DragFile) {
+ const { type = '', name = '' } = file;
+ const mimeType = type.toLowerCase();
+ const baseMimeType = mimeType.split('/')[0];
+
+ return acceptedFileTypes.some((type) => {
+ const validType = type.trim().toLowerCase();
+ // if the accepted file type is a file extension
+ // it will start with '.', check against the file name
+ if (validType.charAt(0) === '.') {
+ return name.toLowerCase().endsWith(validType);
+ }
+ // This is something like a image/* mime type
+ if (validType.endsWith('/*')) {
+ return baseMimeType === validType.split('/')[0];
+ }
+ return mimeType === validType;
+ });
+ }
+
+ files.forEach((file) => {
+ (filterFile(file) ? acceptedFiles : rejectedFiles).push(file);
+ });
+
+ return { acceptedFiles, rejectedFiles };
+}
diff --git a/packages/react/src/primitives/DropZone/useDropZone.ts b/packages/react/src/primitives/DropZone/useDropZone.ts
index 102a64a2281..377b67095db 100644
--- a/packages/react/src/primitives/DropZone/useDropZone.ts
+++ b/packages/react/src/primitives/DropZone/useDropZone.ts
@@ -1,49 +1,7 @@
import { useState } from 'react';
import { UseDropZoneProps, UseDropZoneReturn, DragState } from './types';
import { isFunction } from '@aws-amplify/ui';
-
-type DragFile =
- | {
- kind: string;
- type: string;
- }
- | File;
-
-function filterAllowedFiles(
- files: FileType[],
- acceptedFileTypes: string[]
-): { acceptedFiles: FileType[]; rejectedFiles: FileType[] } {
- // Allow any files if acceptedFileTypes is undefined, empty array, or contains '*'
- if (
- !acceptedFileTypes ||
- acceptedFileTypes.length === 0 ||
- acceptedFileTypes.includes('*')
- ) {
- return { acceptedFiles: files, rejectedFiles: [] };
- }
- const acceptedFiles: FileType[] = [];
- const rejectedFiles: FileType[] = [];
-
- function filterFile({ type = '' }) {
- const mimeType = type.toLowerCase();
- const baseMimeType = mimeType.split('/')[0];
-
- return acceptedFileTypes.some((type) => {
- const validType = type.trim().toLowerCase();
- if (validType.endsWith('/*')) {
- // This is something like a image/* mime type
- return baseMimeType === validType.split('/')[0];
- }
- return mimeType === validType;
- });
- }
-
- files.forEach((file) => {
- (filterFile(file) ? acceptedFiles : rejectedFiles).push(file);
- });
-
- return { acceptedFiles, rejectedFiles };
-}
+import { filterAllowedFiles } from './filterAllowedFiles';
export function useDropZone({
onDropComplete,