Skip to content

Commit 9f4fc4e

Browse files
authored
chore: fix dropzone handler to preserve folder structure for dropped files (#6151)
* chore: fix issue where drag and drop doesn't respect folder structure * chore: add tests for webkitRelativePath * chore: bump size limit for storage
1 parent 0d4d2b9 commit 9f4fc4e

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

packages/react-core/src/utils/__tests__/processDroppedEntries.spec.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe('processDroppedItems', () => {
88
isFile: true,
99
isDirectory: false,
1010
name: file.name,
11-
fullPath: `/${file.name}`,
11+
fullPath: `path/${file.name}`,
1212
filesystem: {
1313
name: 'temporary',
1414
root: {} as FileSystemDirectoryEntry,
@@ -96,6 +96,7 @@ describe('processDroppedItems', () => {
9696
expect(result).toHaveLength(2);
9797
expect(result[0].name).toBe('dir-file1.txt');
9898
expect(result[1].name).toBe('dir-file2.txt');
99+
expect(result[0].webkitRelativePath).toBe('path/dir-file1.txt');
99100
});
100101

101102
it('should process mixed files and directories', async () => {
@@ -117,6 +118,28 @@ describe('processDroppedItems', () => {
117118
expect(result.map((f) => f.name)).toContain('single.txt');
118119
expect(result.map((f) => f.name)).toContain('dir-file1.txt');
119120
expect(result.map((f) => f.name)).toContain('dir-file2.txt');
121+
expect(result[1].webkitRelativePath).toBe('path/dir-file1.txt');
122+
});
123+
124+
it('should not overwrite webkitRelativePath if present', async () => {
125+
const singleFile = new File([mockFileData], 'single.txt', {
126+
type: 'text/plain',
127+
});
128+
Object.defineProperties(singleFile, {
129+
webkitRelativePath: {
130+
writable: true,
131+
},
132+
});
133+
// intentionally overwriting webkitRelativePath
134+
// @ts-expect-error
135+
singleFile.webkitRelativePath = 'webkitpath/single.txt';
136+
137+
const items = [createMockDataTransferItem(createMockFileEntry(singleFile))];
138+
139+
const result = await processDroppedItems(items);
140+
141+
expect(result).toHaveLength(1);
142+
expect(result[0].webkitRelativePath).toBe('webkitpath/single.txt');
120143
});
121144

122145
it('should handle empty items array', async () => {

packages/react-core/src/utils/processDroppedItems.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ export async function processDroppedItems(
3737
): Promise<void> => {
3838
if (entry.isFile) {
3939
const file = await getFileFromEntry(entry as FileSystemFileEntry);
40+
// drag and dropped files do not have a webkitRelativePath property,
41+
// but they do have a fullPath property which has the same information
42+
// https://github.com/ant-design/ant-design/issues/16426
43+
if (entry.fullPath && !file.webkitRelativePath) {
44+
Object.defineProperties(file, {
45+
webkitRelativePath: {
46+
writable: true,
47+
},
48+
});
49+
50+
// intentionally overwriting webkitRelativePath
51+
// @ts-expect-error
52+
file.webkitRelativePath = entry.fullPath.replace(/^\//, '');
53+
54+
Object.defineProperties(file, {
55+
webkitRelativePath: {
56+
writable: false,
57+
},
58+
});
59+
}
4060
files.push(file);
4161
} else if (entry.isDirectory) {
4262
const dirReader = (entry as FileSystemDirectoryEntry).createReader();

packages/react-storage/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"name": "FileUploader",
5858
"path": "dist/esm/index.mjs",
5959
"import": "{ FileUploader }",
60-
"limit": "21.6 kB"
60+
"limit": "22 kB"
6161
},
6262
{
6363
"name": "StorageImage",
@@ -69,7 +69,7 @@
6969
"name": "StorageManager",
7070
"path": "dist/esm/index.mjs",
7171
"import": "{ StorageManager }",
72-
"limit": "21.6 kB"
72+
"limit": "22 kB"
7373
}
7474
]
7575
}

0 commit comments

Comments
 (0)